]> git.pld-linux.org Git - packages/gcc.git/commitdiff
- remove *.orig
authorRafał Janiczek <rafal.janiczek@gmail.com>
Fri, 12 Sep 2003 13:49:34 +0000 (13:49 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    gcc-3.3.1-propolice.patch -> 1.2

gcc-3.3.1-propolice.patch

index 5036cef8a030e593963080fe21167fb6b827e378..60176d1dbf40d110dacc13056ad70407e0b13e29 100644 (file)
@@ -1,6 +1,6 @@
-diff -ruN gcc-3.3.1/gcc/Makefile.in gcc-3.3.1.pp/gcc/Makefile.in
+diff -urN gcc-3.3.1/gcc/Makefile.in gcc-3.3.1-pp/gcc/Makefile.in
 --- gcc-3.3.1/gcc/Makefile.in  2003-08-03 15:48:36.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/Makefile.in       2003-09-05 12:00:02.000000000 +0000
++++ gcc-3.3.1-pp/gcc/Makefile.in       2003-09-12 13:40:28.000000000 +0000
 @@ -387,7 +387,7 @@
  # Options to use when compiling libgcc2.a.
  #
@@ -45,3767 +45,9 @@ diff -ruN gcc-3.3.1/gcc/Makefile.in gcc-3.3.1.pp/gcc/Makefile.in
  
  $(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 \
-diff -ruN gcc-3.3.1/gcc/Makefile.in.orig gcc-3.3.1.pp/gcc/Makefile.in.orig
---- gcc-3.3.1/gcc/Makefile.in.orig     1970-01-01 00:00:00.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/Makefile.in.orig  2003-09-05 11:58:58.000000000 +0000
-@@ -0,0 +1,3754 @@
-+# Makefile for GNU C compiler.
-+#   Copyright (C) 1987, 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
-+#   1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-+
-+#This file is part of GCC.
-+
-+#GCC is free software; you can redistribute it and/or modify
-+#it under the terms of the GNU General Public License as published by
-+#the Free Software Foundation; either version 2, or (at your option)
-+#any later version.
-+
-+#GCC is distributed in the hope that it will be useful,
-+#but WITHOUT ANY WARRANTY; without even the implied warranty of
-+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+#GNU General Public License for more details.
-+
-+#You should have received a copy of the GNU General Public License
-+#along with GCC; see the file COPYING.  If not, write to
-+#the Free Software Foundation, 59 Temple Place - Suite 330,
-+#Boston MA 02111-1307, USA.
-+
-+# The targets for external use include:
-+# all, doc, proto, install, install-cross, install-cross-rest,
-+# uninstall, TAGS, mostlyclean, clean, distclean, maintainer-clean,
-+# stage1, stage2, stage3, stage4.
-+
-+# This is the default target.
-+all:
-+
-+# Suppress smart makes who think they know how to automake Yacc files
-+.y.c:
-+
-+# Directory where sources are, from where we are.
-+srcdir = @srcdir@
-+VPATH = @srcdir@
-+
-+# Pointer to the GCC Project website
-+website=http://gcc.gnu.org
-+
-+# Variables that exist for you to override.
-+# See below for how to change them for certain systems.
-+
-+# List of language subdirectories.
-+# This is overridden by configure.
-+SUBDIRS =@subdirs@
-+
-+# Selection of languages to be made.
-+# This is overridden by configure.
-+CONFIG_LANGUAGES = @all_languages@
-+LANGUAGES = c gcov$(exeext) $(CONFIG_LANGUAGES)
-+
-+# Selection of languages to be made during stage1 build.
-+# This is overridden by configure.
-+BOOT_LANGUAGES = c @all_boot_languages@
-+
-+# Various ways of specifying flags for compilations:
-+# CFLAGS is for the user to override to, e.g., do a cross build with -O2.
-+# For recursive  bootstrap builds CFLAGS is used to pass in STAGE1_CFLAGS
-+# or BOOT_CFLAGS
-+# STAGE1_CFLAGS is set by configure on some targets or passed from toplevel
-+# and sets the CFLAGS passed to stage1 of a bootstrap compilation.
-+# BOOT_CFLAGS is the value of CFLAGS to pass to the stage2, stage3 and stage4
-+# bootstrap compilations.
-+# XCFLAGS is used for most compilations but not when using the GCC just built.
-+# TCFLAGS is used for compilations with the GCC just built.
-+XCFLAGS =
-+TCFLAGS =
-+CFLAGS = -g
-+STAGE1_CFLAGS = -g @stage1_cflags@
-+BOOT_CFLAGS = -g -O2
-+
-+# Flags to determine code coverage. When coverage is disabled, this will
-+# contain the optimization flags, as you normally want code coverage
-+# without optimization. The -dumpbase $@ makes sure that the auxilary
-+# files end up near the object files.
-+COVERAGE_FLAGS = @coverage_flags@
-+coverageexts = .{da,bb,bbg}
-+
-+# The warning flags are separate from BOOT_CFLAGS because people tend to
-+# override optimization flags and we'd like them to still have warnings
-+# turned on.  These flags are also used to pass other stage dependent
-+# flags from configure.  The user is free to explicitly turn these flags
-+# off if they wish.
-+# LOOSE_WARN are the warning flags to use when compiling something
-+# which is only compiled with gcc, such as libgcc and the frontends
-+# other than C.
-+# STRICT_WARN and STRICT2_WARN are the additional warning flags to
-+# apply to the back end and the C front end, which may be compiled
-+# with other compilers.  This is partially controlled by configure in
-+# stage1, as not all versions of gcc understand -Wno-long-long.
-+LOOSE_WARN = -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes
-+STRICT_WARN = -Wtraditional @strict1_warn@
-+STRICT2_WARN = -Wtraditional -pedantic -Wno-long-long
-+
-+# This is set by --enable-checking.  The idea is to catch forgotten
-+# "extern" tags in header files.
-+NOCOMMON_FLAG = @nocommon_flag@
-+
-+# These are set by --enable-checking=valgrind.
-+RUN_GEN = @valgrind_command@
-+VALGRIND_DRIVER_DEFINES = @valgrind_path_defines@
-+
-+# This is how we control whether or not the additional warnings are applied.
-+.-warn = $(STRICT_WARN)
-+GCC_WARN_CFLAGS = $(LOOSE_WARN) $($(@D)-warn) $(NOCOMMON_FLAG)
-+
-+# All warnings have to be shut off in stage1 if the compiler used then
-+# isn't gcc; configure determines that.  WARN_CFLAGS will be either
-+# $(GCC_WARN_CFLAGS), or nothing.
-+WARN_CFLAGS = @warn_cflags@
-+
-+# These exists to be overridden by the x-* and t-* files, respectively.
-+X_CFLAGS =
-+T_CFLAGS =
-+
-+X_CPPFLAGS =
-+T_CPPFLAGS =
-+
-+ADAC = @ADAC@
-+AWK = @AWK@
-+CC = @CC@
-+BISON = @BISON@
-+BISONFLAGS =
-+FLEX = @FLEX@
-+FLEXFLAGS =
-+AR = ar
-+AR_FLAGS = rc
-+DLLTOOL = dlltool
-+RANLIB = @RANLIB@
-+SHELL = @SHELL@
-+# pwd command to use.  Allow user to override default by setting PWDCMD in
-+# the environment to account for automounters.  The make variable must not
-+# be called PWDCMD, otherwise the value set here is passed to make
-+# subprocesses and overrides the setting from the user's environment.
-+# Don't use PWD since it is a common shell environment variable and we
-+# don't want to corrupt it.
-+PWD_COMMAND = $${PWDCMD-pwd}
-+# on sysV, define this as cp.
-+INSTALL = @INSTALL@
-+# Some systems may be missing symbolic links, regular links, or both.
-+# Allow configure to check this and use "ln -s", "ln", or "cp" as appropriate.
-+LN=@LN@
-+LN_S=@LN_S@
-+# These permit overriding just for certain files.
-+INSTALL_PROGRAM = @INSTALL_PROGRAM@
-+INSTALL_DATA = @INSTALL_DATA@
-+INSTALL_SCRIPT = @INSTALL@
-+MAKEINFO = @MAKEINFO@
-+MAKEINFOFLAGS =
-+TEXI2DVI = texi2dvi
-+TEXI2POD = perl $(srcdir)/../contrib/texi2pod.pl
-+POD2MAN = pod2man --center="GNU" --release="gcc-$(version)"
-+# For GNUmake: let us decide what gets passed to recursive makes.
-+MAKEOVERRIDES =
-+@SET_MAKE@
-+# Some compilers can't handle cc -c blah.c -o foo/blah.o.
-+# In stage2 and beyond, we force this to "-o $@" since we know we're using gcc.
-+OUTPUT_OPTION = @OUTPUT_OPTION@
-+
-+# Some versions of `touch' (such as the version on Solaris 2.8)
-+# do not correctly set the timestamp due to buggy versions of `utime'
-+# in the kernel.  So, we use `echo' instead.
-+STAMP = echo timestamp >
-+
-+# This is where we get zlib from.  zlibdir is -L../zlib and zlibinc is
-+# -I../zlib, unless we were configured with --with-system-zlib, in which
-+# case both are empty.
-+ZLIB = @zlibdir@ -lz
-+ZLIBINC = @zlibinc@
-+
-+# Substitution type for target's getgroups 2nd arg.
-+TARGET_GETGROUPS_T = @TARGET_GETGROUPS_T@
-+
-+# Target to use when installing include directory.  Either
-+# install-headers-tar, install-headers-cpio or install-headers-cp.
-+INSTALL_HEADERS_DIR = @build_install_headers_dir@
-+
-+# Header files that are made available under the same name
-+# to programs compiled with GCC.
-+USER_H = $(srcdir)/ginclude/float.h \
-+       $(srcdir)/ginclude/iso646.h \
-+       $(srcdir)/ginclude/stdarg.h \
-+       $(srcdir)/ginclude/stdbool.h \
-+       $(srcdir)/ginclude/stddef.h \
-+       $(srcdir)/ginclude/varargs.h \
-+       $(srcdir)/unwind.h \
-+       $(EXTRA_HEADERS)
-+
-+# The GCC to use for compiling libgcc.a and crt*.o.
-+# Usually the one we just built.
-+# Don't use this as a dependency--use $(GCC_PASSES) or $(GCC_PARTS).
-+GCC_FOR_TARGET = $(STAGE_CC_WRAPPER) ./xgcc -B./ -B$(build_tooldir)/bin/ -isystem $(build_tooldir)/include -isystem $(build_tooldir)/sys-include
-+
-+# This is used instead of ALL_CFLAGS when compiling with GCC_FOR_TARGET.
-+# It omits XCFLAGS, and specifies -B./.
-+# It also specifies -isystem ./include to find, e.g., stddef.h.
-+GCC_CFLAGS=$(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(LOOSE_WARN) -isystem ./include $(TCFLAGS)
-+
-+# Sed command to transform gcc to installed name.  Overwritten by configure.
-+program_transform_name = @program_transform_name@
-+program_transform_cross_name = s,^,$(target_alias)-,
-+
-+build_canonical = @build_canonical@
-+host_canonical = @host_canonical@
-+
-+# Tools to use when building a cross-compiler.
-+# These are used because `configure' appends `cross-make'
-+# to the makefile when making a cross-compiler.
-+
-+# Use the tools from the build tree, if they are available.
-+
-+# objdir is set by configure.
-+objdir = @objdir@
-+
-+AR_FOR_TARGET = ` \
-+  if [ -f $(objdir)/../binutils/ar ] ; then \
-+    echo $(objdir)/../binutils/ar ; \
-+  else \
-+    if [ "$(host_canonical)" = "$(target)" ] ; then \
-+      echo ar; \
-+    else \
-+       t='$(program_transform_cross_name)'; echo ar | sed -e $$t ; \
-+    fi; \
-+  fi`
-+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 ; \
-+  else \
-+    if [ "$(host_canonical)" = "$(target)" ] ; then \
-+      echo ranlib; \
-+    else \
-+       t='$(program_transform_cross_name)'; echo ranlib | sed -e $$t ; \
-+    fi; \
-+  fi`
-+RANLIB_TEST_FOR_TARGET = \
-+  [ -f $(RANLIB_FOR_TARGET) ] \
-+  || ( [ "$(host_canonical)" = "$(target)" ] \
-+       && [ -f /usr/bin/ranlib -o -f /bin/ranlib ] )
-+NM_FOR_TARGET = ` \
-+  if [ -f ./nm ] ; then \
-+    echo ./nm ; \
-+  elif [ -f $(objdir)/../binutils/nm-new ] ; then \
-+    echo $(objdir)/../binutils/nm-new ; \
-+  else \
-+    if [ "$(host_canonical)" = "$(target)" ] ; then \
-+      echo nm; \
-+    else \
-+       t='$(program_transform_cross_name)'; echo nm | sed -e $$t ; \
-+    fi; \
-+  fi`
-+
-+# Where to find some libiberty headers.
-+HASHTAB_H   = $(srcdir)/../include/hashtab.h
-+OBSTACK_H   = $(srcdir)/../include/obstack.h
-+SPLAY_TREE_H= $(srcdir)/../include/splay-tree.h
-+FIBHEAP_H   = $(srcdir)/../include/fibheap.h
-+PARTITION_H = $(srcdir)/../include/partition.h
-+
-+# Default native SYSTEM_HEADER_DIR, to be overridden by targets.
-+NATIVE_SYSTEM_HEADER_DIR = /usr/include
-+# Default cross SYSTEM_HEADER_DIR, to be overridden by targets.
-+CROSS_SYSTEM_HEADER_DIR = $(build_tooldir)/sys-include
-+
-+# autoconf sets SYSTEM_HEADER_DIR to one of the above.
-+SYSTEM_HEADER_DIR = @SYSTEM_HEADER_DIR@
-+
-+# Control whether to run fixproto and fixincludes.
-+STMP_FIXPROTO = @STMP_FIXPROTO@
-+STMP_FIXINC = @STMP_FIXINC@
-+
-+# Test to see whether <limits.h> exists in the system header files.
-+LIMITS_H_TEST = [ -f $(SYSTEM_HEADER_DIR)/limits.h ]
-+
-+target=@target@
-+target_alias=@target_alias@
-+xmake_file=@dep_host_xmake_file@
-+tmake_file=@dep_tmake_file@
-+out_file=$(srcdir)/config/@out_file@
-+out_object_file=@out_object_file@
-+md_file=$(srcdir)/config/@md_file@
-+tm_defines=@tm_defines@
-+tm_p_file_list=@tm_p_file_list@
-+tm_p_file=@tm_p_file@
-+build_xm_file_list=@build_xm_file_list@
-+build_xm_file=@build_xm_file@
-+build_xm_defines=@build_xm_defines@
-+host_xm_file_list=@host_xm_file_list@
-+host_xm_file=@host_xm_file@
-+host_xm_defines=@host_xm_defines@
-+xm_file=@xm_file@
-+xm_defines=@xm_defines@
-+lang_specs_files=@lang_specs_files@
-+lang_options_files=@lang_options_files@
-+lang_tree_files=@lang_tree_files@
-+target_cpu_default=@target_cpu_default@
-+GCC_THREAD_FILE=@thread_file@
-+OBJC_BOEHM_GC=@objc_boehm_gc@
-+GTHREAD_FLAGS=@gthread_flags@
-+# Be prepared for gcc2 merges.
-+gcc_version=@gcc_version@
-+gcc_version_trigger=@gcc_version_trigger@
-+version=$(gcc_version)
-+mainversion=`grep version_string $(srcdir)/version.c | sed -e 's/.*\"\([0-9]*\.[0-9]*\).*/\1/'`
-+
-+# Common prefix for installation directories.
-+# NOTE: This directory must exist when you start installation.
-+prefix = @prefix@
-+# Directory in which to put localized header files. On the systems with
-+# gcc as the native cc, `local_prefix' may not be `prefix' which is
-+# `/usr'.
-+# NOTE: local_prefix *should not* default from prefix.
-+local_prefix = @local_prefix@
-+# Directory in which to put host dependent programs and libraries
-+exec_prefix = @exec_prefix@
-+# Directory in which to put the executable for the command `gcc'
-+bindir = @bindir@
-+# Directory in which to put the directories used by the compiler.
-+libdir = @libdir@
-+# Directory in which the compiler finds executables, libraries, etc.
-+libsubdir = $(libdir)/gcc-lib/$(target_alias)/$(version)
-+# Used to produce a relative $(gcc_tooldir) in gcc.o
-+unlibsubdir = ../../..
-+# Directory in which to find other cross-compilation tools and headers.
-+dollar = @dollar@
-+# Used in install-cross.
-+gcc_tooldir = @gcc_tooldir@
-+# Used to install the shared libgcc.
-+slibdir = @slibdir@
-+# Since gcc_tooldir does not exist at build-time, use -B$(build_tooldir)/bin/
-+build_tooldir = $(exec_prefix)/$(target_alias)
-+# Directory in which the compiler finds target-independent g++ includes.
-+gcc_gxx_include_dir = @gcc_gxx_include_dir@
-+# Directory to search for site-specific includes.
-+local_includedir = $(local_prefix)/include
-+includedir = $(prefix)/include
-+# where the info files go
-+infodir = @infodir@
-+# Where cpp should go besides $prefix/bin if necessary
-+cpp_install_dir = @cpp_install_dir@
-+# where the locale files go
-+datadir = @datadir@
-+localedir = $(datadir)/locale
-+# Extension (if any) to put in installed man-page filename.
-+man1ext = .1
-+man7ext = .7
-+objext = .o
-+exeext = @host_exeext@
-+build_exeext = @build_exeext@
-+
-+# Directory in which to put man pages.
-+mandir = @mandir@
-+man1dir = $(mandir)/man1
-+man7dir = $(mandir)/man7
-+# Dir for temp files.
-+tmpdir = /tmp
-+
-+# Top build directory, relative to here.
-+top_builddir = .
-+
-+# Whether we were configured with NLS.
-+USE_NLS = @USE_NLS@
-+
-+# Internationalization library.
-+INTLLIBS = @INTLLIBS@
-+INTLDEPS = @INTLDEPS@
-+
-+# Character encoding conversion library.
-+LIBICONV = @LIBICONV@
-+
-+# List of internationalization subdirectories.
-+INTL_SUBDIRS = intl
-+
-+# The GC method to be used on this system.
-+GGC=@GGC@.o
-+
-+# If a supplementary library is being used for the GC.
-+GGC_LIB=
-+
-+# libgcc.a may be built directly or via stmp-multilib,
-+# and installed likewise.  Overridden by t-fragment.
-+LIBGCC = libgcc.a
-+INSTALL_LIBGCC = install-libgcc
-+
-+# Options to use when compiling libgcc2.a.
-+#
-+LIBGCC2_DEBUG_CFLAGS = -g
-+LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED @inhibit_libc@
-+
-+# Additional options to use when compiling libgcc2.a.
-+# Some targets override this to -isystem include
-+LIBGCC2_INCLUDES =
-+
-+# Additional target-dependent options for compiling libgcc2.a.
-+TARGET_LIBGCC2_CFLAGS =
-+
-+# Options to use when compiling crtbegin/end.
-+CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \
-+  -finhibit-size-directive -fno-inline-functions -fno-exceptions \
-+  -fno-zero-initialized-in-bss
-+
-+# Additional sources to handle exceptions; overridden on ia64.
-+LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \
-+  $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
-+LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h
-+
-+# nm flags to list global symbols in libgcc object files.
-+SHLIB_NM_FLAGS = -pg
-+
-+# List of extra executables that should be compiled for this target machine
-+# that are used for compiling from source code to object code.
-+# The rules for compiling them should be in the t-* file for the machine.
-+EXTRA_PASSES =@extra_passes@
-+
-+# Like EXTRA_PASSES, but these are used when linking.
-+EXTRA_PROGRAMS = @extra_programs@
-+
-+# List of extra object files that should be compiled for this target machine.
-+# The rules for compiling them should be in the t-* file for the machine.
-+EXTRA_PARTS = @extra_parts@
-+
-+# List of extra object files that should be compiled and linked with
-+# compiler proper (cc1, cc1obj, cc1plus).
-+EXTRA_OBJS = @extra_objs@
-+
-+# List of extra object files that should be compiled and linked with
-+# the gcc driver.
-+EXTRA_GCC_OBJS =@host_extra_gcc_objs@
-+
-+# List of additional header files to install.
-+# Often this is edited directly by `configure'.
-+EXTRA_HEADERS =@extra_headers_list@
-+
-+# It is convenient for configure to add the assignment at the beginning,
-+# so don't override it here.
-+USE_COLLECT2 = collect2$(exeext)
-+
-+# List of extra C and assembler files to add to static and shared libgcc2.
-+# Assembler files should have names ending in `.asm'.
-+LIB2FUNCS_EXTRA =
-+
-+# List of extra C and assembler files to add to static libgcc2.
-+# Assembler files should have names ending in `.asm'.
-+LIB2FUNCS_STATIC_EXTRA =
-+
-+# Program to convert libraries.
-+LIBCONVERT =
-+
-+# Control whether header files are installed.
-+INSTALL_HEADERS=install-headers install-mkheaders
-+
-+# Control whether Info documentation is built and installed.
-+BUILD_INFO = @BUILD_INFO@
-+
-+# Control whether manpages generated by texi2pod.pl can be rebuilt.
-+GENERATED_MANPAGES = @GENERATED_MANPAGES@
-+
-+# Additional directories of header files to run fixincludes on.
-+# These should be directories searched automatically by default
-+# just as /usr/include is.
-+# *Do not* use this for directories that happen to contain
-+# header files, but are not searched automatically by default.
-+# On most systems, this is empty.
-+OTHER_FIXINCLUDES_DIRS=
-+
-+# A list of all the language-specific executables.
-+# This is overridden by configure.
-+COMPILERS = cc1$(exeext) @all_compilers@
-+
-+# List of things which should already be built whenever we try to use xgcc
-+# to compile anything (without linking).
-+GCC_PASSES=xgcc$(exeext) cc1$(exeext) specs $(EXTRA_PASSES)
-+
-+# List of things which should already be built whenever we try to use xgcc
-+# to link anything.
-+GCC_PARTS=$(GCC_PASSES) $(LIBGCC) $(EXTRA_PROGRAMS) $(USE_COLLECT2) $(EXTRA_PARTS)
-+
-+# Directory to link to, when using the target `maketest'.
-+DIR = ../gcc
-+
-+# Flags to use when cross-building GCC.
-+# Prefix to apply to names of object files when using them
-+# to run on the machine we are compiling on.
-+BUILD_PREFIX = @BUILD_PREFIX@
-+# Prefix to apply to names of object files when compiling them
-+# to run on the machine we are compiling on.
-+# The default for this variable is chosen to keep these rules
-+# out of the way of the other rules for compiling the same source files.
-+BUILD_PREFIX_1 = @BUILD_PREFIX_1@
-+# Native compiler for the build machine and its switches.
-+HOST_CC = @HOST_CC@
-+HOST_CFLAGS= @HOST_CFLAGS@ -DGENERATOR_FILE
-+
-+# Native linker and preprocessor flags.  For x-fragment overrides.
-+HOST_LDFLAGS=$(LDFLAGS)
-+HOST_CPPFLAGS=$(ALL_CPPFLAGS)
-+
-+# Actual name to use when installing a native compiler.
-+GCC_INSTALL_NAME = `echo gcc|sed '$(program_transform_name)'`
-+GCC_TARGET_INSTALL_NAME = $(target_alias)-`echo gcc|sed '$(program_transform_name)'`
-+CPP_INSTALL_NAME = `echo cpp|sed '$(program_transform_name)'`
-+PROTOIZE_INSTALL_NAME = `echo protoize|sed '$(program_transform_name)'`
-+UNPROTOIZE_INSTALL_NAME = `echo unprotoize|sed '$(program_transform_name)'`
-+GCOV_INSTALL_NAME = `echo gcov|sed '$(program_transform_name)'`
-+GCCBUG_INSTALL_NAME = `echo gccbug|sed '$(program_transform_name)'`
-+
-+# Actual name to use when installing a cross-compiler.
-+GCC_CROSS_NAME = `echo gcc|sed '$(program_transform_cross_name)'`
-+CPP_CROSS_NAME = `echo cpp|sed '$(program_transform_cross_name)'`
-+PROTOIZE_CROSS_NAME = `echo protoize|sed '$(program_transform_cross_name)'`
-+UNPROTOIZE_CROSS_NAME = `echo unprotoize|sed '$(program_transform_cross_name)'`
-+
-+# Set by autoconf to "all.internal" for a native build, or
-+# "all.cross" to build a cross compiler.
-+ALL = @ALL@
-+
-+# Setup the testing framework, if you have one
-+EXPECT = `if [ -f $${rootme}/../expect/expect ] ; then \
-+            echo $${rootme}/../expect/expect ; \
-+          else echo expect ; fi`
-+
-+RUNTEST = `if [ -f $${srcdir}/../dejagnu/runtest ] ; then \
-+             echo $${srcdir}/../dejagnu/runtest ; \
-+          else echo runtest; fi`
-+RUNTESTFLAGS =
-+
-+# Extra symbols for fixproto to define when parsing headers.
-+FIXPROTO_DEFINES =
-+
-+# Extra flags to use when compiling crt{begin,end}.o.
-+CRTSTUFF_T_CFLAGS =
-+
-+# Extra flags to use when compiling [m]crt0.o.
-+CRT0STUFF_T_CFLAGS =
-+
-+# "t" or nothing, for building multilibbed versions of, say, crtbegin.o.
-+T =
-+
-+# Should T contain a `=', libgcc.mk will make T_TARGET, setting
-+# $(T_TARGET) to the name of the actual target filename.
-+T_TARGET =
-+T_TARGET : $(T_TARGET)
-+
-+# End of variables for you to override.
-+
-+# Definition of `all' is here so that new rules inserted by sed
-+# do not specify the default target.
-+# The real definition is under `all.internal' (for native compilers)
-+# or `all.cross' (for cross compilers).
-+all: all.indirect
-+
-+# This tells GNU Make version 3 not to put all variables in the environment.
-+.NOEXPORT:
-+
-+# GCONFIG_H lists the config files that the generator files depend on, while
-+# CONFIG_H lists the ones ordinary gcc files depend on, which includes
-+# several files generated by those generators.
-+GCONFIG_H = config.h $(host_xm_file_list)
-+HCONFIG_H = hconfig.h $(build_xm_file_list)
-+CONFIG_H = $(GCONFIG_H) insn-constants.h insn-flags.h
-+TCONFIG_H = tconfig.h $(xm_file_list)
-+TARGET_H = target.h
-+HOOKS_H = hooks.h
-+LANGHOOKS_DEF_H = langhooks-def.h $(HOOKS_H)
-+TARGET_DEF_H = target-def.h $(HOOKS_H)
-+TM_P_H = tm_p.h $(tm_p_file_list) tm-preds.h
-+
-+MACHMODE_H = machmode.h machmode.def @extra_modes_file@
-+RTL_BASE_H = rtl.h rtl.def $(MACHMODE_H)
-+RTL_H = $(RTL_BASE_H) genrtl.h
-+PARAMS_H = params.h params.def
-+TREE_H = tree.h tree.def $(MACHMODE_H) tree-check.h version.h builtins.def \
-+          location.h
-+BASIC_BLOCK_H = basic-block.h bitmap.h sbitmap.h varray.h $(PARTITION_H) \
-+          hard-reg-set.h
-+DEMANGLE_H = $(srcdir)/../include/demangle.h
-+RECOG_H = recog.h
-+EXPR_H = expr.h
-+OPTABS_H = optabs.h insn-codes.h
-+REGS_H = regs.h varray.h $(MACHMODE_H)
-+INTEGRATE_H = integrate.h varray.h
-+LOOP_H = loop.h varray.h bitmap.h
-+GCC_H = gcc.h version.h
-+GGC_H = ggc.h varray.h gtype-desc.h
-+TIMEVAR_H = timevar.h timevar.def
-+INSN_ATTR_H = insn-attr.h $(srcdir)/insn-addr.h $(srcdir)/varray.h
-+C_COMMON_H = c-common.h $(SPLAY_TREE_H) $(CPPLIB_H)
-+C_TREE_H = c-tree.h $(C_COMMON_H)
-+SYSTEM_H = system.h hwint.h $(srcdir)/../include/libiberty.h
-+PREDICT_H = predict.h predict.def
-+CPPLIB_H = cpplib.h line-map.h
-+
-+# sed inserts variable overrides after the following line.
-+####target overrides
-+@target_overrides@
-+
-+####host overrides
-+@host_overrides@
-+#\f
-+# Now figure out from those variables how to compile and link.
-+
-+all.indirect: $(ALL)
-+
-+# IN_GCC distinguishes between code compiled into GCC itself and other
-+# programs built during a bootstrap.
-+# autoconf inserts -DCROSS_COMPILE if we are building a cross compiler.
-+INTERNAL_CFLAGS = -DIN_GCC @CROSS@
-+
-+# This is the variable actually used when we compile.
-+# If you change this line, you probably also need to change the definition
-+# of HOST_CFLAGS in build-make to match.
-+ALL_CFLAGS = $(X_CFLAGS) $(T_CFLAGS) \
-+  $(CFLAGS) $(INTERNAL_CFLAGS) $(COVERAGE_FLAGS) $(WARN_CFLAGS) $(XCFLAGS) @DEFS@
-+
-+# Likewise.
-+ALL_CPPFLAGS = $(CPPFLAGS) $(X_CPPFLAGS) $(T_CPPFLAGS)
-+
-+# Build and host support libraries.  FORBUILD is either
-+# .. or ../$(build_alias) depending on whether host != build.
-+LIBIBERTY = ../libiberty/libiberty.a
-+BUILD_LIBIBERTY = @FORBUILD@/libiberty/libiberty.a
-+
-+# Dependencies on the intl and portability libraries.
-+LIBDEPS= $(INTLDEPS) $(LIBIBERTY)
-+
-+# Likewise, for use in the tools that must run on this machine
-+# even if we are cross-building GCC.
-+HOST_LIBDEPS= $(BUILD_LIBIBERTY)
-+
-+# How to link with both our special library facilities
-+# and the system's installed libraries.
-+LIBS =        $(INTLLIBS) @LIBS@ $(LIBIBERTY)
-+
-+# Any system libraries needed just for GNAT.
-+SYSLIBS = @GNAT_LIBEXC@
-+
-+# Libs needed (at present) just for jcf-dump.
-+LDEXP_LIB = @LDEXP_LIB@
-+
-+# Likewise, for use in the tools that must run on this machine
-+# even if we are cross-building GCC.
-+HOST_LIBS = $(BUILD_LIBIBERTY)
-+
-+HOST_RTL = $(BUILD_PREFIX)rtl.o read-rtl.o $(BUILD_PREFIX)bitmap.o \
-+              $(BUILD_PREFIX)ggc-none.o
-+HOST_SUPPORT = gensupport.o insn-conditions.o
-+HOST_EARLY_SUPPORT = gensupport.o dummy-conditions.o
-+
-+HOST_PRINT = print-rtl1.o
-+HOST_ERRORS = $(BUILD_PREFIX)errors.o
-+HOST_VARRAY = $(BUILD_PREFIX)varray.o
-+
-+# Specify the directories to be searched for header files.
-+# Both . and srcdir are used, in that order,
-+# so that *config.h will be found in the compilation
-+# subdirectory rather than in the source directory.
-+# -I$(@D) and -I$(srcdir)/$(@D) cause the subdirectory of the file
-+# currently being compiled, in both source trees, to be examined as well.
-+INCLUDES = -I. -I$(@D) -I$(srcdir) -I$(srcdir)/$(@D) \
-+         -I$(srcdir)/config -I$(srcdir)/../include
-+
-+# Always use -I$(srcdir)/config when compiling.
-+.c.o:
-+      $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-+
-+# This tells GNU make version 3 not to export all the variables
-+# defined in this file into the environment.
-+.NOEXPORT:
-+#\f
-+# Support for additional languages (other than c and objc).
-+# ??? objc can be supported this way too (leave for later).
-+
-+# These next lines are overridden by configure.
-+LANG_MAKEFILES = @all_lang_makefiles@
-+LANG_STAGESTUFF = @all_stagestuff@
-+
-+# Flags to pass to recursive makes.
-+# CC is set by configure.  Hosts without symlinks need special handling
-+# because we need CC="stage1/xgcc -Bstage1/" to work in the language
-+# subdirectories.
-+# ??? The choices here will need some experimenting with.
-+ORDINARY_FLAGS_TO_PASS = \
-+      "AR=$(AR)" \
-+      "AR_FLAGS_FOR_TARGET=$(AR_FLAGS_FOR_TARGET)" \
-+      "AR_CREATE_FOR_TARGET=$(AR_CREATE_FOR_TARGET)" \
-+      "AR_EXTRACT_FOR_TARGET=$(AR_EXTRACT_FOR_TARGET)" \
-+      "AR_FOR_TARGET=$(AR_FOR_TARGET)" \
-+      "BISON=$(BISON)" \
-+      "BISONFLAGS=$(BISONFLAGS)" \
-+      "CFLAGS=$(CFLAGS) $(WARN_CFLAGS)" \
-+      "DESTDIR=$(DESTDIR)" \
-+      "GCC_FOR_TARGET=$(GCC_FOR_TARGET)" \
-+      "LDFLAGS=$(LDFLAGS)" \
-+      "FLEX=$(FLEX)" \
-+      "FLEXFLAGS=$(FLEXFLAGS)" \
-+      "LN=$(LN)" \
-+      "LN_S=$(LN_S)" \
-+      "MAKEINFO=$(MAKEINFO)" \
-+      "MAKEINFOFLAGS=$(MAKEINFOFLAGS)" \
-+      "MAKEOVERRIDES=" \
-+      "RANLIB_FOR_TARGET=$(RANLIB_FOR_TARGET)" \
-+      "RANLIB_TEST_FOR_TARGET=$(RANLIB_TEST_FOR_TARGET)" \
-+      "SHELL=$(SHELL)" \
-+      "exeext=$(exeext)" \
-+      "build_exeext=$(build_exeext)" \
-+      "objext=$(objext)" \
-+      "exec_prefix=$(exec_prefix)" \
-+      "prefix=$(prefix)" \
-+      "local_prefix=$(local_prefix)" \
-+      "gxx_include_dir=$(gcc_gxx_include_dir)" \
-+      "build_tooldir=$(build_tooldir)" \
-+      "gcc_tooldir=$(gcc_tooldir)" \
-+      "bindir=$(bindir)" \
-+      "libsubdir=$(libsubdir)" \
-+      "datadir=$(datadir)" \
-+      "localedir=$(localedir)"
-+FLAGS_TO_PASS = $(ORDINARY_FLAGS_TO_PASS) "CC=@cc_set_by_configure@" \
-+      "STAGE_PREFIX=@stage_prefix_set_by_configure@"
-+PREPEND_DOTDOT_TO_RELATIVE_PATHS = sed \
-+      -e 's|^ *[^ /][^ /]*/|%&|' \
-+      -e 's| -B| -B%|g' \
-+      -e 's|% *[^- /]|%&|g' \
-+      -e 's|%% *|../|g' \
-+      -e 's|%||g'
-+SUBDIR_FLAGS_TO_PASS = $(ORDINARY_FLAGS_TO_PASS) \
-+      "CC=`echo @quoted_cc_set_by_configure@ | $(PREPEND_DOTDOT_TO_RELATIVE_PATHS)`" \
-+      "STAGE_PREFIX=`echo @quoted_stage_prefix_set_by_configure@ | $(PREPEND_DOTDOT_TO_RELATIVE_PATHS)`"
-+#\f
-+# Lists of files for various purposes.
-+
-+# Target specific, C specific object file
-+C_TARGET_OBJS=@c_target_objs@
-+
-+# Target specific, C++ specific object file
-+CXX_TARGET_OBJS=@cxx_target_objs@
-+
-+# Language-specific object files for C and Objective C.
-+C_AND_OBJC_OBJS = attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \
-+  c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \
-+  c-objc-common.o c-dump.o libcpp.a $(C_TARGET_OBJS)
-+
-+# Language-specific object files for C.
-+C_OBJS = c-parse.o c-lang.o c-pretty-print.o $(C_AND_OBJC_OBJS)
-+
-+# Language-independent object files.
-+
-+OBJS = alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o    \
-+ cfg.o cfganal.o cfgbuild.o cfgcleanup.o cfglayout.o cfgloop.o                   \
-+ cfgrtl.o combine.o conflict.o convert.o cse.o cselib.o dbxout.o         \
-+ debug.o df.o diagnostic.o doloop.o dominance.o                                  \
-+ dwarf2asm.o dwarf2out.o dwarfout.o emit-rtl.o except.o explow.o         \
-+ expmed.o expr.o final.o flow.o fold-const.o function.o gcse.o                   \
-+ genrtl.o ggc-common.o global.o graph.o gtype-desc.o                     \
-+ haifa-sched.o hashtable.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o    \
-+ insn-extract.o insn-opinit.o insn-output.o insn-peep.o insn-recog.o     \
-+ integrate.o intl.o jump.o  langhooks.o lcm.o lists.o local-alloc.o      \
-+ loop.o mbchar.o optabs.o params.o predict.o print-rtl.o print-tree.o    \
-+ profile.o ra.o ra-build.o ra-colorize.o ra-debug.o ra-rewrite.o         \
-+ real.o recog.o reg-stack.o regclass.o regmove.o regrename.o             \
-+ reload.o reload1.o reorg.o resource.o rtl.o rtlanal.o rtl-error.o       \
-+ sbitmap.o sched-deps.o sched-ebb.o sched-rgn.o sched-vis.o sdbout.o     \
-+ sibcall.o simplify-rtx.o ssa.o ssa-ccp.o ssa-dce.o stmt.o               \
-+ stor-layout.o stringpool.o timevar.o toplev.o tracer.o tree.o tree-dump.o \
-+ tree-inline.o unroll.o varasm.o varray.o version.o vmsdbgout.o xcoffout.o \
-+ et-forest.o protector.o $(GGC) $(out_object_file) $(EXTRA_OBJS)
-+
-+BACKEND = main.o libbackend.a
-+
-+# Files to be copied away after each stage in building.
-+STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
-+ insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \
-+ insn-attr.h insn-attrtab.c insn-opinit.c insn-constants.h tm-preds.h \
-+ tree-check.h insn-conditions.c \
-+ s-flags s-config s-codes s-mlib s-genrtl s-gtype gtyp-gen.h \
-+ s-output s-recog s-emit s-extract s-peep s-check s-conditions \
-+ s-attr s-attrtab s-opinit s-preds s-constants s-crt0 \
-+ genemit$(build_exeext) genoutput$(build_exeext) genrecog$(build_exeext) \
-+ genextract$(build_exeext) genflags$(build_exeext) gencodes$(build_exeext) \
-+ genconfig$(build_exeext) genpeep$(build_exeext) genattrtab$(build_exeext) \
-+ genattr$(build_exeext) genopinit$(build_exeext) gengenrtl$(build_exeext) \
-+ gencheck$(build_exeext) genpreds$(build_exeext) genconstants$(build_exeext) \
-+ gengtype$(build_exeext) genconditions$(build_exeext) \
-+ genrtl.c genrtl.h gt-*.h gtype-*.h gtype-desc.c \
-+ xgcc$(exeext) cpp$(exeext) cc1$(exeext) $(EXTRA_PASSES) \
-+ $(EXTRA_PARTS) $(EXTRA_PROGRAMS) gcc-cross$(exeext) cc1obj$(exeext) \
-+ protoize$(exeext) unprotoize$(exeext) \
-+ specs collect2$(exeext) $(USE_COLLECT2) \
-+ gcov$(exeext) *.[0-9][0-9].* *.[si] libcpp.a libbackend.a libgcc.mk \
-+ $(LANG_STAGESTUFF)
-+
-+# Library members defined in libgcc2.c.
-+# Variable length limited to 255 charactes when passed to a shell script.
-+LIB2FUNCS_1 = _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _ffsdi2 _clz \
-+    _cmpdi2 _ucmpdi2 _floatdidf _floatdisf _fixunsdfsi _fixunssfsi \
-+    _fixunsdfdi _fixdfdi _fixunssfdi _fixsfdi _fixxfdi _fixunsxfdi
-+
-+LIB2FUNCS_2 = _floatdixf _fixunsxfsi _fixtfdi _fixunstfdi _floatditf \
-+    _clear_cache _trampoline __main _exit _absvsi2 _absvdi2 _addvsi3 \
-+    _addvdi3 _subvsi3 _subvdi3 _mulvsi3 _mulvdi3 _negvsi2 _negvdi2 _ctors _stack_smash_handler
-+
-+# Defined in libgcc2.c, included only in the static library.
-+LIB2FUNCS_ST = _eprintf _bb __gcc_bcmp
-+
-+FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \
-+    _fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \
-+    _lt_sf _le_sf _unord_sf _si_to_sf _sf_to_si _negate_sf _make_sf \
-+    _sf_to_df _sf_to_tf _thenan_sf _sf_to_usi _usi_to_sf
-+
-+DPBIT_FUNCS = _pack_df _unpack_df _addsub_df _mul_df _div_df \
-+    _fpcmp_parts_df _compare_df _eq_df _ne_df _gt_df _ge_df \
-+    _lt_df _le_df _unord_df _si_to_df _df_to_si _negate_df _make_df \
-+    _df_to_sf _df_to_tf _thenan_df _df_to_usi _usi_to_df
-+
-+TPBIT_FUNCS = _pack_tf _unpack_tf _addsub_tf _mul_tf _div_tf \
-+    _fpcmp_parts_tf _compare_tf _eq_tf _ne_tf _gt_tf _ge_tf \
-+    _lt_tf _le_tf _unord_tf _si_to_tf _tf_to_si _negate_tf _make_tf \
-+    _tf_to_df _tf_to_sf _thenan_tf _tf_to_usi _usi_to_tf
-+
-+# These might cause a divide overflow trap and so are compiled with
-+# unwinder info.
-+LIB2_DIVMOD_FUNCS = _divdi3 _moddi3 _udivdi3 _umoddi3 _udiv_w_sdiv _udivmoddi4
-+
-+# The only suffixes we want for implicit rules are .c and .o, so clear
-+# the list and add them.  This speeds up GNU Make, and allows -r to work.
-+# For i18n support, we also need .gmo, .po, .pox.
-+# This must come before the language makefile fragments to allow them to
-+# add suffixes and rules of their own.
-+.SUFFIXES:
-+.SUFFIXES: .c .o .po .pox .gmo
-+
-+#\f
-+# Language makefile fragments.
-+
-+# The following targets define the interface between us and the languages.
-+#
-+# all.cross, start.encap, rest.encap,
-+# info, dvi,
-+# install-normal, install-common, install-info, install-man,
-+# uninstall,
-+# mostlyclean, clean, distclean, extraclean, maintainer-clean,
-+# stage1, stage2, stage3, stage4
-+#
-+# Each language is linked in with a series of hooks (since we can't use `::'
-+# targets).  The name of each hooked is "lang.${target_name}" (eg: lang.info).
-+# Configure computes and adds these here.
-+
-+####language hooks
-+@language_hooks@
-+
-+# sed inserts language fragments after the following line.
-+####language fragments
-+@language_fragments@
-+
-+# End of language makefile fragments.
-+#\f
-+
-+Makefile: $(srcdir)/Makefile.in config.status $(srcdir)/version.c \
-+   $(xmake_file) $(tmake_file) $(LANG_MAKEFILES)
-+      $(SHELL) $(srcdir)/configure.frag $(srcdir) "$(SUBDIRS)" \
-+              "$(xmake_file)" "$(tmake_file)"
-+      cp config.status config.run
-+      LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.run
-+      rm -f config.run
-+
-+config.h: cs-config.h ; @true
-+hconfig.h: cs-hconfig.h ; @true
-+tconfig.h: cs-tconfig.h ; @true
-+tm_p.h: cs-tm_p.h ; @true
-+
-+cs-config.h: Makefile
-+      TM_DEFINES="$(tm_defines)" \
-+      HEADERS="$(host_xm_file)" XM_DEFINES="$(host_xm_defines)" \
-+      TARGET_CPU_DEFAULT="$(target_cpu_default)" \
-+      $(SHELL) $(srcdir)/mkconfig.sh config.h
-+
-+cs-hconfig.h: Makefile
-+      TM_DEFINES="$(tm_defines)" \
-+      HEADERS="$(build_xm_file)" XM_DEFINES="$(build_xm_defines)" \
-+      TARGET_CPU_DEFAULT="$(target_cpu_default)" \
-+      $(SHELL) $(srcdir)/mkconfig.sh hconfig.h
-+
-+cs-tconfig.h: Makefile
-+      TM_DEFINES="$(tm_defines)" \
-+      HEADERS="$(xm_file)" XM_DEFINES="$(xm_defines)" \
-+      TARGET_CPU_DEFAULT="" \
-+      $(SHELL) $(srcdir)/mkconfig.sh tconfig.h
-+
-+cs-tm_p.h: Makefile
-+      TM_DEFINES="" \
-+      HEADERS="$(tm_p_file)" XM_DEFINES="" TARGET_CPU_DEFAULT="" \
-+      $(SHELL) $(srcdir)/mkconfig.sh tm_p.h
-+
-+# Don't automatically run autoconf, since configure.in might be accidentally
-+# newer than configure.  Also, this writes into the source directory which
-+# might be on a read-only file system.  If configured for maintainer mode
-+# then do allow autoconf to be run.
-+
-+$(srcdir)/configure: @MAINT@ $(srcdir)/configure.in
-+      (cd $(srcdir) && autoconf)
-+
-+gccbug:       $(srcdir)/gccbug.in
-+      CONFIG_FILES=gccbug CONFIG_HEADERS= ./config.status
-+
-+mklibgcc: $(srcdir)/mklibgcc.in
-+      CONFIG_FILES=mklibgcc CONFIG_HEADERS= ./config.status
-+
-+mkheaders: $(srcdir)/mkheaders.in
-+      CONFIG_FILES=mkheaders 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
-+# nothing has changed.
-+# It remains in the source directory and is part of the distribution.
-+# This follows what is done in shellutils, fileutils, etc.
-+# "echo timestamp" is used instead of touch to be consistent with other
-+# packages that use autoconf (??? perhaps also to avoid problems with patch?).
-+# ??? Newer versions have a maintainer mode that may be useful here.
-+
-+# Don't run autoheader automatically either.
-+# Only run it if maintainer mode is enabled.
-+@MAINT@ $(srcdir)/config.in: $(srcdir)/cstamp-h.in
-+@MAINT@ $(srcdir)/cstamp-h.in: $(srcdir)/configure.in $(srcdir)/acconfig.h
-+@MAINT@       (cd $(srcdir) && autoheader)
-+@MAINT@       @rm -f $(srcdir)/cstamp-h.in
-+@MAINT@       echo timestamp > $(srcdir)/cstamp-h.in
-+auto-host.h: cstamp-h ; @true
-+cstamp-h: config.in config.status
-+      CONFIG_HEADERS=auto-host.h:config.in LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.status
-+
-+# Really, really stupid make features, such as SUN's KEEP_STATE, may force
-+# a target to build even if it is up-to-date.  So we must verify that
-+# config.status does not exist before failing.
-+config.status: $(srcdir)/configure $(srcdir)/config.gcc version.c
-+      @if [ ! -f config.status ] ; then \
-+        echo You must configure gcc.  Look at http://gcc.gnu.org/install/ for details.; \
-+        false; \
-+      else \
-+        LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.status --recheck; \
-+      fi
-+
-+all.internal: start.encap rest.encap doc
-+# This is what to compile if making a cross-compiler.
-+all.cross: native gcc-cross cpp$(exeext) specs \
-+      $(LIBGCC) $(EXTRA_PARTS) lang.all.cross doc
-+# This is what must be made before installing GCC and converting libraries.
-+start.encap: native xgcc$(exeext) cpp$(exeext) specs \
-+      xlimits.h lang.start.encap
-+# These can't be made until after GCC can run.
-+rest.encap: $(STMP_FIXPROTO) $(LIBGCC) $(EXTRA_PARTS) lang.rest.encap
-+# This is what is made with the host's compiler
-+# whether making a cross compiler or not.
-+native: config.status auto-host.h intl.all build-@POSUB@ $(LANGUAGES) \
-+      $(EXTRA_PASSES) $(EXTRA_PROGRAMS) $(USE_COLLECT2)
-+
-+# Define the names for selecting languages in LANGUAGES.
-+C c: cc1$(exeext)
-+PROTO: proto
-+
-+# Tell GNU make these are phony targets.
-+.PHONY: C c PROTO proto
-+
-+# On the target machine, finish building a cross compiler.
-+# This does the things that can't be done on the host machine.
-+rest.cross: $(LIBGCC) specs
-+
-+# Recompile all the language-independent object files.
-+# This is used only if the user explicitly asks for it.
-+compilations: $(BACKEND)
-+
-+# Like libcpp.a, this archive is strictly for the host.
-+libbackend.a: $(OBJS)
-+      -rm -rf libbackend.a
-+      $(AR) $(AR_FLAGS) libbackend.a $(OBJS)
-+      -$(RANLIB) libbackend.a
-+
-+# We call this executable `xgcc' rather than `gcc'
-+# to avoid confusion if the current directory is in the path
-+# and CC is `gcc'.  It is renamed to `gcc' when it is installed.
-+xgcc$(exeext): gcc.o gccspec.o version.o intl.o prefix.o \
-+   version.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
-+      $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gcc.o gccspec.o intl.o \
-+        prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS)
-+
-+# cpp is to cpp0 as gcc is to cc1.
-+# The only difference from xgcc is that it's linked with cppspec.o
-+# instead of gccspec.o.
-+cpp$(exeext): gcc.o cppspec.o version.o intl.o prefix.o \
-+   version.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
-+      $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gcc.o cppspec.o intl.o \
-+        prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS)
-+
-+# Dump a specs file to make -B./ read these specs over installed ones.
-+specs: xgcc$(exeext)
-+      $(GCC_FOR_TARGET) -dumpspecs > tmp-specs
-+      mv tmp-specs specs
-+
-+# We do want to create an executable named `xgcc', so we can use it to
-+# compile libgcc2.a.
-+# Also create gcc-cross, so that install-common will install properly.
-+gcc-cross: xgcc$(exeext)
-+      cp xgcc$(exeext) gcc-cross$(exeext)
-+
-+cc1$(exeext): $(C_OBJS) $(BACKEND) $(LIBDEPS)
-+      $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cc1$(exeext) \
-+              $(C_OBJS) $(BACKEND) $(LIBS)
-+
-+# Build the version of limits.h that we will install.
-+xlimits.h: glimits.h limitx.h limity.h
-+      if $(LIMITS_H_TEST) ; then \
-+        cat $(srcdir)/limitx.h $(srcdir)/glimits.h $(srcdir)/limity.h > tmp-xlimits.h; \
-+      else \
-+        cat $(srcdir)/glimits.h > tmp-xlimits.h; \
-+      fi
-+      mv tmp-xlimits.h xlimits.h
-+#\f
-+# Build libgcc.a.
-+
-+LIB2ADD = $(LIB2FUNCS_EXTRA)
-+LIB2ADD_ST = $(LIB2FUNCS_STATIC_EXTRA)
-+
-+libgcc.mk: config.status Makefile mklibgcc $(LIB2ADD) $(LIB2ADD_ST) xgcc$(exeext) specs
-+      objext='$(objext)' \
-+      LIB1ASMFUNCS='$(LIB1ASMFUNCS)' \
-+      LIB2FUNCS_1='$(LIB2FUNCS_1)' \
-+      LIB2FUNCS_2='$(LIB2FUNCS_2)' \
-+      LIB2FUNCS_ST='$(LIB2FUNCS_ST)' \
-+      LIB2ADD='$(LIB2ADD)' \
-+      LIB2ADD_ST='$(LIB2ADD_ST)' \
-+      LIB2ADDEH='$(LIB2ADDEH)' \
-+      LIB2ADDEHDEP='$(LIB2ADDEHDEP)' \
-+      FPBIT='$(FPBIT)' \
-+      FPBIT_FUNCS='$(FPBIT_FUNCS)' \
-+      LIB2_DIVMOD_FUNCS='$(LIB2_DIVMOD_FUNCS)' \
-+      DPBIT='$(DPBIT)' \
-+      DPBIT_FUNCS='$(DPBIT_FUNCS)' \
-+      TPBIT='$(TPBIT)' \
-+      TPBIT_FUNCS='$(TPBIT_FUNCS)' \
-+      MULTILIBS=`$(GCC_FOR_TARGET) --print-multi-lib` \
-+      EXTRA_MULTILIB_PARTS='$(EXTRA_MULTILIB_PARTS)' \
-+      SHLIB_LINK='$(SHLIB_LINK)' \
-+      SHLIB_INSTALL='$(SHLIB_INSTALL)' \
-+      SHLIB_EXT='$(SHLIB_EXT)' \
-+      SHLIB_MULTILIB='$(SHLIB_MULTILIB)' \
-+      SHLIB_MKMAP='$(SHLIB_MKMAP)' \
-+      SHLIB_MKMAP_OPTS='$(SHLIB_MKMAP_OPTS)' \
-+      SHLIB_MAPFILES='$(SHLIB_MAPFILES)' \
-+      SHLIB_NM_FLAGS='$(SHLIB_NM_FLAGS)' \
-+      MULTILIB_OSDIRNAMES='$(MULTILIB_OSDIRNAMES)' \
-+      mkinstalldirs='$(SHELL) $(srcdir)/mkinstalldirs' \
-+        $(SHELL) mklibgcc > tmp-libgcc.mk
-+      mv tmp-libgcc.mk libgcc.mk
-+
-+# All the things that might cause us to want to recompile bits of libgcc.
-+LIBGCC_DEPS = $(GCC_PASSES) $(LANGUAGES) stmp-int-hdrs $(STMP_FIXPROTO) \
-+      libgcc.mk $(srcdir)/libgcc2.c $(TCONFIG_H) \
-+      $(MACHMODE_H) longlong.h gbl-ctors.h config.status stmp-int-hdrs \
-+      tsystem.h $(FPBIT) $(DPBIT) $(TPBIT) $(LIB2ADD) \
-+      $(LIB2ADD_ST) $(LIB2ADDEH) $(LIB2ADDEHDEP) $(EXTRA_PARTS) \
-+      $(srcdir)/config/$(LIB1ASMSRC)
-+
-+libgcc.a: $(LIBGCC_DEPS)
-+      $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
-+        BUILD_PREFIX="$(BUILD_PREFIX)" BUILD_PREFIX_1="$(BUILD_PREFIX_1)" \
-+        AR_FOR_TARGET="$(AR_FOR_TARGET)" \
-+        AR_CREATE_FOR_TARGET="$(AR_CREATE_FOR_TARGET)" \
-+        AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
-+        CFLAGS="$(CFLAGS) $(WARN_CFLAGS)" \
-+        RANLIB_FOR_TARGET="$(RANLIB_FOR_TARGET)" \
-+        RANLIB_TEST_FOR_TARGET="$(RANLIB_TEST_FOR_TARGET)" \
-+        NM_FOR_TARGET="$(NM_FOR_TARGET)" AWK="$(AWK)" \
-+        LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS)" \
-+        INCLUDES="$(INCLUDES)" \
-+        CONFIG_H="$(TCONFIG_H)" MACHMODE_H="$(MACHMODE_H)" \
-+        LIB1ASMSRC='$(LIB1ASMSRC)' \
-+        MAKEOVERRIDES= \
-+        -f libgcc.mk all
-+
-+# Use the genmultilib shell script to generate the information the gcc
-+# driver program needs to select the library directory based on the
-+# switches.
-+multilib.h: s-mlib; @true
-+s-mlib: $(srcdir)/genmultilib Makefile
-+      if test @enable_multilib@ = yes \
-+         || test -n "$(MULTILIB_OSDIRNAMES)"; then \
-+        $(SHELL) $(srcdir)/genmultilib \
-+          "$(MULTILIB_OPTIONS)" \
-+          "$(MULTILIB_DIRNAMES)" \
-+          "$(MULTILIB_MATCHES)" \
-+          "$(MULTILIB_EXCEPTIONS)" \
-+          "$(MULTILIB_EXTRA_OPTS)" \
-+          "$(MULTILIB_EXCLUSIONS)" \
-+          "$(MULTILIB_OSDIRNAMES)" \
-+          "@enable_multilib@" \
-+          > tmp-mlib.h; \
-+      else \
-+        $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' no \
-+          > tmp-mlib.h; \
-+      fi
-+      $(SHELL) $(srcdir)/move-if-change tmp-mlib.h multilib.h
-+      $(STAMP) s-mlib
-+
-+# Build multiple copies of libgcc.a, one for each target switch.
-+stmp-multilib: $(LIBGCC_DEPS)
-+      $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
-+        BUILD_PREFIX="$(BUILD_PREFIX)" BUILD_PREFIX_1="$(BUILD_PREFIX_1)" \
-+        AR_FOR_TARGET="$(AR_FOR_TARGET)" \
-+        AR_CREATE_FOR_TARGET="$(AR_CREATE_FOR_TARGET)" \
-+        AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
-+        CFLAGS="$(CFLAGS) $(WARN_CFLAGS)" \
-+        RANLIB_FOR_TARGET="$(RANLIB_FOR_TARGET)" \
-+        RANLIB_TEST_FOR_TARGET="$(RANLIB_TEST_FOR_TARGET)" \
-+        NM_FOR_TARGET="$(NM_FOR_TARGET)" AWK="$(AWK)" \
-+        LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS)" \
-+        INCLUDES="$(INCLUDES)" \
-+        CONFIG_H="$(CONFIG_H)" MACHMODE_H="$(MACHMODE_H)" \
-+        LIB1ASMSRC='$(LIB1ASMSRC)' \
-+        MAKEOVERRIDES= \
-+        -f libgcc.mk all
-+      $(STAMP) stmp-multilib
-+
-+# Compile two additional files that are linked with every program
-+# linked using GCC on systems using COFF or ELF, for the sake of C++
-+# constructors.
-+$(T)crtbegin.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
-+  gbl-ctors.h stmp-int-hdrs tsystem.h
-+      $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \
-+        @inhibit_libc@ -c $(srcdir)/crtstuff.c -DCRT_BEGIN \
-+        -o $(T)crtbegin$(objext)
-+
-+$(T)crtend.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
-+  gbl-ctors.h stmp-int-hdrs tsystem.h
-+      $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \
-+        @inhibit_libc@ -c $(srcdir)/crtstuff.c -DCRT_END \
-+        -o $(T)crtend$(objext)
-+
-+# These are versions of crtbegin and crtend for shared libraries.
-+$(T)crtbeginS.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
-+  gbl-ctors.h stmp-int-hdrs tsystem.h
-+      $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS_S) \
-+        @inhibit_libc@ -c $(srcdir)/crtstuff.c -DCRT_BEGIN -DCRTSTUFFS_O \
-+        -o $(T)crtbeginS$(objext)
-+
-+$(T)crtendS.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
-+  gbl-ctors.h stmp-int-hdrs tsystem.h
-+      $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS_S) \
-+        @inhibit_libc@ -c $(srcdir)/crtstuff.c -DCRT_END -DCRTSTUFFS_O \
-+        -o $(T)crtendS$(objext)
-+
-+# This is a version of crtbegin for -static links.
-+$(T)crtbeginT.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
-+  gbl-ctors.h stmp-int-hdrs tsystem.h
-+      $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \
-+        @inhibit_libc@ -c $(srcdir)/crtstuff.c -DCRT_BEGIN -DCRTSTUFFT_O \
-+        -o $(T)crtbeginT$(objext)
-+
-+# Compile the start modules crt0.o and mcrt0.o that are linked with
-+# every program
-+crt0.o: s-crt0 ; @true
-+mcrt0.o: s-crt0; @true
-+
-+s-crt0:       $(CRT0_S) $(MCRT0_S) $(GCC_PASSES) $(CONFIG_H)
-+      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \
-+        -o crt0.o -c $(CRT0_S)
-+      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \
-+        -o mcrt0.o -c $(MCRT0_S)
-+      $(STAMP) s-crt0
-+#\f
-+# Compiling object files from source files.
-+
-+# Note that dependencies on obstack.h are not written
-+# because that file is not part of GCC.
-+
-+# C language specific files.
-+
-+c-errors.o: c-errors.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) flags.h \
-+    diagnostic.h $(TM_P_H)
-+c-parse.o : $(srcdir)/c-parse.c $(CONFIG_H) $(TREE_H) $(GGC_H) intl.h \
-+    $(C_TREE_H) input.h flags.h $(SYSTEM_H) toplev.h output.h $(CPPLIB_H) \
-+    gt-c-parse.h
-+      $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+             -c $(srcdir)/c-parse.c $(OUTPUT_OPTION)
-+
-+$(srcdir)/c-parse.c: $(srcdir)/c-parse.y
-+      cd $(srcdir) && \
-+      if $(BISON) $(BISONFLAGS) -o c-p$$$$.c c-parse.y; then \
-+        test -f c-p$$$$.output && mv -f c-p$$$$.output c-parse.output ; \
-+        mv -f c-p$$$$.c c-parse.c ; \
-+      else \
-+        rm -f c-p$$$$.* ; \
-+        false ; \
-+      fi
-+
-+$(srcdir)/c-parse.y: c-parse.in
-+      echo '/*WARNING: This file is automatically generated!*/' >tmp-c-parse.y
-+      sed -e "/^ifobjc$$/,/^end ifobjc$$/d" \
-+        -e "/^ifc$$/d" -e "/^end ifc$$/d" \
-+        $(srcdir)/c-parse.in >>tmp-c-parse.y
-+      $(SHELL) $(srcdir)/move-if-change tmp-c-parse.y $(srcdir)/c-parse.y
-+
-+c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) $(C_TREE_H) \
-+    $(GGC_H) $(TARGET_H) flags.h function.h output.h $(EXPR_H) \
-+    debug.h toplev.h intl.h $(TM_P_H) tree-inline.h $(TIMEVAR_H) c-pragma.h \
-+    gt-c-decl.h libfuncs.h except.h
-+c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
-+    $(TARGET_H) flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h $(TM_P_H)
-+c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
-+    $(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) c-common.h gtype-c.h
-+c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) \
-+    debug.h $(C_TREE_H) c-common.h real.h \
-+    c-pragma.h input.h intl.h flags.h toplev.h output.h \
-+    mbchar.h $(CPPLIB_H) $(EXPR_H) $(TM_P_H)
-+c-objc-common.o : c-objc-common.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
-+    $(C_TREE_H) $(RTL_H) insn-config.h integrate.h $(EXPR_H) $(C_TREE_H) \
-+    flags.h toplev.h tree-inline.h diagnostic.h integrate.h $(VARRAY_H) \
-+    langhooks.h $(GGC_H) gt-c-objc-common.h $(TARGET_H)
-+c-aux-info.o : c-aux-info.c  $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
-+    flags.h toplev.h
-+c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h toplev.h \
-+    $(C_COMMON_H)
-+c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) function.h \
-+    c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H) $(C_COMMON_H) gt-c-pragma.h
-+mbchar.o: mbchar.c $(CONFIG_H) $(SYSTEM_H) mbchar.h
-+graph.o: graph.c $(CONFIG_H) $(SYSTEM_H) toplev.h flags.h output.h $(RTL_H) \
-+    function.h hard-reg-set.h $(BASIC_BLOCK_H) graph.h
-+sbitmap.o: sbitmap.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h hard-reg-set.h \
-+    $(BASIC_BLOCK_H)
-+
-+COLLECT2_OBJS = collect2.o tlink.o intl.o version.o
-+COLLECT2_LIBS = @COLLECT2_LIBS@
-+collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
-+# Don't try modifying collect2 (aka ld) in place--it might be linking this.
-+      $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o T$@ \
-+              $(COLLECT2_OBJS) $(LIBS) $(COLLECT2_LIBS)
-+      mv -f T$@ $@
-+
-+collect2.o : collect2.c $(CONFIG_H) $(SYSTEM_H) gstab.h intl.h \
-+      $(OBSTACK_H) $(DEMANGLE_H) collect2.h version.h
-+      $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES)  \
-+      -DTARGET_MACHINE=\"$(target_alias)\" \
-+      -c $(srcdir)/collect2.c $(OUTPUT_OPTION)
-+
-+tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB_H) $(CONFIG_H) $(SYSTEM_H) \
-+    $(OBSTACK_H) collect2.h intl.h
-+
-+# A file used by all variants of C.
-+
-+c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(OBSTACK_H) \
-+      $(C_COMMON_H) flags.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
-+      $(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def $(TARGET_H) \
-+      diagnostic.h except.h gt-c-common.h real.h langhooks.h c-tree.h
-+c-pretty-print.o : c-pretty-print.c c-pretty-print.h pretty-print.h \
-+      $(C_COMMON_H) $(CONFIG_H) $(SYSTEM_H) real.h
-+
-+c-opts.o : c-opts.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_COMMON_H) \
-+        c-pragma.h flags.h toplev.h langhooks.h tree-inline.h diagnostic.h \
-+      intl.h
-+
-+# A file used by all variants of C and some other languages.
-+
-+attribs.o : attribs.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h \
-+      toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) $(EXPR_H) $(TM_P_H) \
-+      builtin-types.def $(TARGET_H) langhooks.h
-+
-+c-format.o : c-format.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) langhooks.h \
-+      $(C_COMMON_H) flags.h toplev.h intl.h diagnostic.h
-+
-+c-semantics.o : c-semantics.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
-+      flags.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
-+      $(EXPR_H) $(PREDICT_H)
-+
-+c-dump.o : c-dump.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) tree-dump.h
-+
-+# Language-independent files.
-+
-+DRIVER_DEFINES = \
-+  -DSTANDARD_STARTFILE_PREFIX=\"$(unlibsubdir)/\" \
-+  -DSTANDARD_EXEC_PREFIX=\"$(libdir)/gcc-lib/\" \
-+  -DDEFAULT_TARGET_VERSION=\"$(version)\" \
-+  -DDEFAULT_TARGET_MACHINE=\"$(target_alias)\" \
-+  -DSTANDARD_BINDIR_PREFIX=\"$(bindir)/\" \
-+  -DTOOLDIR_BASE_PREFIX=\"$(unlibsubdir)/../\" \
-+  $(VALGRIND_DRIVER_DEFINES) \
-+  `test "X$${SHLIB_LINK}" = "X" || test "@enable_shared@" != "yes" || echo "-DENABLE_SHARED_LIBGCC"` \
-+  `test "X$${SHLIB_MULTILIB}" = "X" || echo "-DNO_SHARED_LIBGCC_MULTILIB"`
-+
-+gcc.o: gcc.c $(CONFIG_H) $(SYSTEM_H) intl.h multilib.h \
-+    Makefile $(lang_specs_files) specs.h prefix.h $(GCC_H)
-+      (SHLIB_LINK='$(SHLIB_LINK)' \
-+      SHLIB_MULTILIB='$(SHLIB_MULTILIB)'; \
-+      $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+  $(DRIVER_DEFINES) \
-+  -c $(srcdir)/gcc.c $(OUTPUT_OPTION))
-+
-+gccspec.o: gccspec.c $(CONFIG_H) $(SYSTEM_H) $(GCC_H)
-+      (SHLIB_LINK='$(SHLIB_LINK)' \
-+      SHLIB_MULTILIB='$(SHLIB_MULTILIB)'; \
-+      $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+  $(DRIVER_DEFINES) \
-+  -c $(srcdir)/gccspec.c $(OUTPUT_OPTION))
-+
-+cppspec.o: cppspec.c $(CONFIG_H) $(SYSTEM_H) $(GCC_H)
-+
-+tree-check.h: s-check ; @true
-+s-check : gencheck$(build_exeext) $(srcdir)/move-if-change
-+      $(RUN_GEN) ./gencheck$(build_exeext) > tmp-check.h
-+      $(SHELL) $(srcdir)/move-if-change tmp-check.h tree-check.h
-+      $(STAMP) s-check
-+
-+gencheck$(build_exeext) : gencheck.o $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       gencheck.o $(HOST_LIBS)
-+
-+gencheck.o : gencheck.c gencheck.h tree.def $(HCONFIG_H) $(SYSTEM_H) \
-+             $(lang_tree_files)
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
-+        $(srcdir)/gencheck.c $(OUTPUT_OPTION)
-+
-+gencheck.h : s-gencheck ; @true
-+s-gencheck : Makefile
-+      ltf="$(lang_tree_files)"; for f in $$ltf; do \
-+          echo "#include \"$$f\""; \
-+      done | sed 's|$(srcdir)/||' > tmp-gencheck.h
-+      $(SHELL) $(srcdir)/move-if-change tmp-gencheck.h gencheck.h
-+      $(STAMP) s-gencheck
-+
-+options.h : s-options ; @true
-+s-options : Makefile
-+      lof="$(lang_options_files)"; for f in $$lof; do \
-+          echo "#include \"$$f\""; \
-+      done | sed 's|$(srcdir)/||' > tmp-options.h
-+      $(SHELL) $(srcdir)/move-if-change tmp-options.h options.h
-+      $(STAMP) s-options
-+
-+specs.h : s-specs ; @true
-+s-specs : Makefile
-+      lsf="$(lang_specs_files)"; for f in $$lsf; do \
-+          echo "#include \"$$f\""; \
-+      done | sed 's|$(srcdir)/||' > tmp-specs.h
-+      $(SHELL) $(srcdir)/move-if-change tmp-specs.h specs.h
-+      $(STAMP) s-specs
-+
-+dumpvers: dumpvers.c
-+
-+version.o: version.c version.h
-+
-+gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) varray.h $(HASHTAB_H) \
-+      $(TREE_H) $(RTL_H) function.h insn-config.h $(EXPR_H) $(OPTABS_H) \
-+      libfuncs.h debug.h $(GGC_H) bitmap.h $(BASIC_BLOCK_H) hard-reg-set.h \
-+      ssa.h cselib.h insn-addr.h
-+
-+ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
-+      flags.h $(GGC_H) varray.h $(HASHTAB_H) $(TM_P_H) langhooks.h \
-+      $(PARAMS_H)
-+
-+ggc-simple.o: ggc-simple.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
-+      $(GGC_H) varray.h $(TIMEVAR_H) $(TM_P_H) $(PARAMS_H)
-+
-+ggc-page.o: ggc-page.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
-+      toplev.h $(GGC_H) $(TIMEVAR_H) $(TM_P_H)
-+
-+stringpool.o: stringpool.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(OBSTACK_H) \
-+      flags.h toplev.h $(GGC_H)
-+
-+hashtable.o: hashtable.c hashtable.h $(CONFIG_H) $(SYSTEM_H) $(OBSTACK_H)
-+
-+line-map.o: line-map.c line-map.h intl.h $(CONFIG_H) $(SYSTEM_H)
-+
-+ggc-none.o: ggc-none.c $(GCONFIG_H) $(SYSTEM_H) $(GGC_H)
-+      $(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-+
-+prefix.o: prefix.c $(CONFIG_H) $(SYSTEM_H) Makefile prefix.h
-+      $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+      -DPREFIX=\"$(prefix)\" \
-+        -c $(srcdir)/prefix.c $(OUTPUT_OPTION)
-+
-+convert.o: convert.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h convert.h \
-+   toplev.h langhooks.h
-+
-+langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) toplev.h \
-+   tree-inline.h $(RTL_H) insn-config.h integrate.h langhooks.h \
-+   $(LANGHOOKS_DEF_H) flags.h
-+tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h function.h toplev.h \
-+   $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \
-+   real.h gt-tree.h
-+tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
-+   flags.h langhooks.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
-+   $(EXPR_H) $(SPLAY_TREE_H) tree-dump.h
-+tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) \
-+   expr.h flags.h params.h input.h insn-config.h $(INTEGRATE_H) \
-+   $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h langhooks.h \
-+   $(C_COMMON_H) tree-inline.h
-+print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GGC_H) \
-+   langhooks.h real.h
-+stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h \
-+   function.h $(EXPR_H) $(RTL_H) toplev.h $(GGC_H) $(TM_P_H) $(TARGET_H) \
-+   langhooks.h
-+fold-const.o : fold-const.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h real.h \
-+   toplev.h $(HASHTAB_H) $(EXPR_H) $(RTL_H) $(GGC_H) $(TM_P_H) langhooks.h
-+diagnostic.o : diagnostic.c diagnostic.h real.h diagnostic.def \
-+   $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_P_H) flags.h $(GGC_H) \
-+   input.h toplev.h intl.h langhooks.h $(LANGHOOKS_DEF_H)
-+toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) function.h \
-+   flags.h xcoffout.h input.h $(INSN_ATTR_H) output.h diagnostic.h \
-+   debug.h insn-config.h intl.h $(RECOG_H) Makefile toplev.h \
-+   dwarf2out.h sdbout.h dbxout.h $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) \
-+   graph.h $(LOOP_H) except.h $(REGS_H) $(TIMEVAR_H) $(lang_options_files) \
-+   ssa.h $(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \
-+   langhooks.h insn-flags.h options.h cfglayout.h real.h
-+      $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+        -DTARGET_NAME=\"$(target_alias)\" \
-+        -c $(srcdir)/toplev.c $(OUTPUT_OPTION)
-+main.o : main.c $(CONFIG_H) $(SYSTEM_H) toplev.h
-+
-+rtl-error.o: rtl-error.c system.h $(RTL_H) $(INSN_ATTR_H) insn-config.h \
-+   input.h toplev.h intl.h diagnostic.h $(CONFIG_H)
-+
-+rtl.o : rtl.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) real.h $(GGC_H) errors.h
-+      $(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-+
-+print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
-+    hard-reg-set.h $(BASIC_BLOCK_H) real.h
-+rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) toplev.h $(RTL_H) \
-+   hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) real.h flags.h
-+
-+errors.o : errors.c $(GCONFIG_H) $(SYSTEM_H) errors.h
-+      $(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-+
-+varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \
-+   function.h $(EXPR_H) hard-reg-set.h $(REGS_H) \
-+   output.h c-pragma.h toplev.h xcoffout.h debug.h $(GGC_H) $(TM_P_H) \
-+   $(HASHTAB_H) $(TARGET_H) langhooks.h gt-varasm.h real.h
-+function.o : function.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
-+   function.h $(EXPR_H) libfuncs.h $(REGS_H) hard-reg-set.h \
-+   insn-config.h $(RECOG_H) output.h toplev.h except.h $(HASHTAB_H) $(GGC_H) \
-+   $(TM_P_H) langhooks.h gt-function.h
-+stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h function.h  \
-+   insn-config.h hard-reg-set.h $(EXPR_H) libfuncs.h except.h \
-+   $(LOOP_H) $(RECOG_H) toplev.h output.h varray.h $(GGC_H) $(TM_P_H) \
-+   langhooks.h $(PREDICT_H) gt-stmt.h
-+except.o : except.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
-+   except.h function.h $(EXPR_H) libfuncs.h integrate.h langhooks.h \
-+   insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \
-+   dwarf2asm.h dwarf2out.h toplev.h $(HASHTAB_H) intl.h $(GGC_H) \
-+   gt-except.h
-+expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h function.h \
-+   $(REGS_H) $(EXPR_H) $(OPTABS_H) libfuncs.h insn-attr.h insn-config.h \
-+   $(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \
-+   except.h reload.h $(GGC_H) langhooks.h intl.h $(TM_P_H) real.h
-+builtins.o : builtins.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
-+   $(TARGET_H) function.h $(REGS_H) $(EXPR_H) $(OPTABS_H) insn-config.h \
-+   $(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \
-+   except.h $(TM_P_H) $(PREDICT_H) libfuncs.h real.h langhooks.h
-+calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
-+   $(EXPR_H) langhooks.h $(TARGET_H) \
-+   libfuncs.h $(REGS_H) toplev.h output.h function.h $(TIMEVAR_H) $(TM_P_H) \
-+   except.h
-+expmed.o : expmed.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h  \
-+   insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) real.h \
-+   toplev.h $(TM_P_H) langhooks.h
-+explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
-+   hard-reg-set.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) \
-+   toplev.h function.h ggc.h $(TM_P_H) gt-explow.h
-+optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h  \
-+   insn-config.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(RECOG_H) reload.h \
-+   toplev.h $(GGC_H) real.h $(TM_P_H) except.h gt-optabs.h $(BASIC_BLOCK_H)
-+dbxout.o : dbxout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \
-+    $(REGS_H) debug.h $(TM_P_H) $(TARGET_H) function.h langhooks.h \
-+   insn-config.h reload.h gstab.h xcoffout.h output.h dbxout.h toplev.h
-+debug.o : debug.c debug.h $(CONFIG_H) $(SYSTEM_H)
-+sdbout.o : sdbout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \
-+   function.h $(EXPR_H) output.h hard-reg-set.h $(REGS_H) real.h \
-+   insn-config.h xcoffout.h c-pragma.h ggc.h \
-+   sdbout.h toplev.h $(TM_P_H) except.h debug.h langhooks.h gt-sdbout.h
-+dwarfout.o : dwarfout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) dwarf.h \
-+   flags.h insn-config.h reload.h output.h toplev.h $(TM_P_H) \
-+   debug.h langhooks.h
-+dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) dwarf2.h \
-+   debug.h flags.h insn-config.h reload.h output.h diagnostic.h real.h \
-+   hard-reg-set.h $(REGS_H) $(EXPR_H) libfuncs.h toplev.h dwarf2out.h varray.h \
-+   $(GGC_H) except.h dwarf2asm.h $(TM_P_H) langhooks.h $(HASHTAB_H) gt-dwarf2out.h
-+dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) flags.h $(RTL_H) $(TREE_H) \
-+   output.h dwarf2asm.h $(TM_P_H) $(GGC_H)
-+vmsdbgout.o : vmsdbgout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \
-+   output.h vmsdbg.h debug.h langhooks.h function.h
-+xcoffout.o : xcoffout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) xcoffout.h \
-+   flags.h toplev.h output.h dbxout.h $(GGC_H) $(TARGET_H)
-+emit-rtl.o : emit-rtl.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
-+   function.h $(REGS_H) insn-config.h $(RECOG_H) real.h $(GGC_H) \
-+   $(EXPR_H) $(srcdir)/../include/obstack.h hard-reg-set.h bitmap.h toplev.h \
-+   $(HASHTAB_H) $(TM_P_H) debug.h langhooks.h
-+real.o : real.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) toplev.h $(TM_P_H)
-+integrate.o : integrate.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
-+   debug.h $(INTEGRATE_H) insn-config.h $(EXPR_H) real.h $(REGS_H) \
-+   intl.h function.h output.h $(RECOG_H) except.h toplev.h $(LOOP_H) \
-+   $(PARAMS_H) $(TM_P_H) $(TARGET_H) langhooks.h gt-integrate.h
-+jump.o : jump.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h hard-reg-set.h $(REGS_H) \
-+   insn-config.h $(RECOG_H) $(EXPR_H) real.h except.h function.h \
-+   toplev.h $(INSN_ATTR_H) $(TM_P_H) reload.h $(PREDICT_H)
-+
-+simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) \
-+   hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
-+   output.h function.h $(GGC_H) $(OBSTACK_H) $(TM_P_H) $(TREE_H)
-+cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) \
-+   hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
-+   output.h function.h cselib.h $(GGC_H) $(TM_P_H) gt-cselib.h
-+cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \
-+   real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h output.h function.h \
-+   $(BASIC_BLOCK_H) $(GGC_H) $(TM_P_H) $(TIMEVAR_H)
-+gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) hard-reg-set.h \
-+   flags.h real.h insn-config.h ggc.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) \
-+   function.h output.h toplev.h $(TM_P_H) $(PARAMS_H) except.h gt-gcse.h
-+sibcall.o : sibcall.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) function.h \
-+   hard-reg-set.h flags.h insn-config.h $(RECOG_H) $(BASIC_BLOCK_H)
-+resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h $(SYSTEM_H) \
-+   $(BASIC_BLOCK_H) $(REGS_H) flags.h output.h resource.h function.h toplev.h \
-+   $(INSN_ATTR_H) except.h $(PARAMS_H) $(TM_P_H)
-+lcm.o : lcm.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \
-+   real.h insn-config.h $(INSN_ATTR_H) $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) \
-+   $(TM_P_H) df.h
-+ssa.o : ssa.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) varray.h $(EXPR_H) \
-+   hard-reg-set.h flags.h function.h real.h insn-config.h $(RECOG_H)  \
-+   $(BASIC_BLOCK_H) output.h ssa.h
-+ssa-dce.o : ssa-dce.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) hard-reg-set.h \
-+   $(BASIC_BLOCK_H) ssa.h insn-config.h $(RECOG_H) output.h
-+ssa-ccp.o : ssa-ccp.c $(CONFIG_H) system.h $(RTL_H) hard-reg-set.h \
-+    $(BASIC_BLOCK_H) ssa.h insn-config.h $(RECOG_H) output.h \
-+    errors.h $(GGC_H) df.h function.h
-+df.o : df.c $(CONFIG_H) system.h $(RTL_H) insn-config.h $(RECOG_H) \
-+   function.h $(REGS_H) $(OBSTACK_H) hard-reg-set.h $(BASIC_BLOCK_H) df.h \
-+   $(FIBHEAP_H)
-+conflict.o : conflict.c $(CONFIG_H) $(SYSTEM_H) $(OBSTACK_H) $(HASHTAB_H) \
-+   $(RTL_H) hard-reg-set.h $(BASIC_BLOCK_H)
-+profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
-+   insn-config.h output.h $(REGS_H) $(EXPR_H) function.h \
-+   gcov-io.h toplev.h $(GGC_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TARGET_H) \
-+   langhooks.h profile.h libfuncs.h gt-profile.h
-+loop.o : loop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h $(LOOP_H) \
-+   insn-config.h $(REGS_H) hard-reg-set.h $(RECOG_H) $(EXPR_H) \
-+   real.h $(PREDICT_H) $(BASIC_BLOCK_H) function.h \
-+   toplev.h varray.h except.h cselib.h $(OPTABS_H) $(TM_P_H)
-+doloop.o : doloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h $(LOOP_H) \
-+   $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) toplev.h
-+unroll.o : unroll.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) insn-config.h function.h \
-+   $(INTEGRATE_H) $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) $(LOOP_H) toplev.h \
-+   hard-reg-set.h varray.h $(BASIC_BLOCK_H) $(TM_P_H) $(PREDICT_H) $(PARAMS_H)
-+flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h insn-config.h \
-+   $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
-+   function.h except.h $(EXPR_H) ssa.h $(GGC_H) $(TM_P_H)
-+cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h insn-config.h \
-+   $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
-+   function.h except.h $(GGC_H) $(TM_P_H)
-+cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h insn-config.h \
-+   $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
-+   function.h except.h $(GGC_H) $(TM_P_H) insn-config.h
-+cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(BASIC_BLOCK_H) \
-+   hard-reg-set.h insn-config.h $(RECOG_H) $(GGC_H) $(TM_P_H)
-+cfgbuild.o : cfgbuild.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h insn-config.h \
-+   $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
-+   function.h except.h $(GGC_H)
-+cfgcleanup.o : cfgcleanup.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TIMEVAR_H)\
-+   $(BASIC_BLOCK_H) hard-reg-set.h output.h flags.h $(RECOG_H) toplev.h \
-+   $(GGC_H) insn-config.h cselib.h $(TARGET_H) $(TM_P_H) $(PARAMS_H)
-+cfgloop.o : cfgloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
-+   $(BASIC_BLOCK_H) hard-reg-set.h
-+dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) hard-reg-set.h \
-+   $(BASIC_BLOCK_H) et-forest.h
-+et-forest.o : et-forest.c $(CONFIG_H) $(SYSTEM_H) et-forest.h
-+combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h function.h \
-+   insn-config.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \
-+   $(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h toplev.h $(TM_P_H)
-+regclass.o : regclass.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) hard-reg-set.h flags.h \
-+   $(BASIC_BLOCK_H) $(REGS_H) insn-config.h $(RECOG_H) reload.h real.h \
-+   toplev.h function.h output.h $(GGC_H) $(TM_P_H) $(EXPR_H)
-+local-alloc.o : local-alloc.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h \
-+   $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \
-+   output.h function.h $(INSN_ATTR_H) toplev.h  except.h $(TM_P_H)
-+bitmap.o : bitmap.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h \
-+   $(BASIC_BLOCK_H) $(REGS_H) $(GGC_H)
-+      $(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-+global.o : global.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h reload.h function.h \
-+   $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h insn-config.h output.h toplev.h \
-+   $(TM_P_H)
-+varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) varray.h $(GGC_H) errors.h
-+ra.o : ra.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H)  $(TM_P_H) insn-config.h \
-+   $(RECOG_H) integrate.h function.h $(REGS_H) $(OBSTACK_H) hard-reg-set.h \
-+   $(BASIC_BLOCK_H) df.h expr.h output.h toplev.h flags.h reload.h ra.h
-+ra-build.o : ra-build.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_P_H) \
-+   insn-config.h $(RECOG_H) function.h $(REGS_H) hard-reg-set.h \
-+   $(BASIC_BLOCK_H) df.h output.h ggc.h ra.h gt-ra-build.h reload.h
-+ra-colorize.o : ra-colorize.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_P_H) \
-+    function.h $(REGS_H) hard-reg-set.h $(BASIC_BLOCK_H) df.h output.h ra.h
-+ra-debug.o : ra-debug.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H)  insn-config.h \
-+   $(RECOG_H) function.h hard-reg-set.h $(BASIC_BLOCK_H) df.h output.h ra.h \
-+   $(TM_P_H)
-+ra-rewrite.o : ra-rewrite.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_P_H) \
-+   function.h $(REGS_H) hard-reg-set.h $(BASIC_BLOCK_H) df.h expr.h \
-+   output.h except.h ra.h reload.h insn-config.h
-+reload.o : reload.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h output.h \
-+   $(EXPR_H) $(OPTABS_H) reload.h $(RECOG_H) hard-reg-set.h insn-config.h \
-+   $(REGS_H) function.h real.h toplev.h $(TM_P_H)
-+reload1.o : reload1.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) real.h flags.h \
-+   $(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) hard-reg-set.h insn-config.h \
-+   $(BASIC_BLOCK_H) $(RECOG_H) output.h function.h toplev.h cselib.h $(TM_P_H) \
-+   except.h $(TREE_H)
-+caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h \
-+   $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) function.h \
-+   $(RECOG_H) reload.h $(EXPR_H) toplev.h $(TM_P_H)
-+reorg.o : reorg.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) conditions.h hard-reg-set.h \
-+   $(BASIC_BLOCK_H) $(REGS_H) insn-config.h $(INSN_ATTR_H) except.h \
-+   $(RECOG_H) function.h flags.h output.h $(EXPR_H) toplev.h $(PARAMS_H) $(TM_P_H)
-+alias.o : alias.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h hard-reg-set.h \
-+   $(BASIC_BLOCK_H) $(REGS_H) toplev.h output.h $(EXPR_H) \
-+   $(GGC_H) function.h cselib.h $(TREE_H) $(TM_P_H) langhooks.h $(TARGET_H) \
-+   gt-alias.h
-+regmove.o : regmove.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) insn-config.h \
-+   $(RECOG_H) output.h $(REGS_H) hard-reg-set.h flags.h function.h \
-+   $(EXPR_H) $(BASIC_BLOCK_H) toplev.h $(TM_P_H) except.h reload.h
-+haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) sched-int.h \
-+   $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
-+   $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) $(TARGET_H)
-+sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) sched-int.h \
-+   $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
-+   $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h cselib.h $(PARAMS_H) $(TM_P_H)
-+sched-rgn.o : sched-rgn.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) sched-int.h \
-+   $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
-+   $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) $(TARGET_H)
-+sched-ebb.o : sched-ebb.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) sched-int.h \
-+   $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
-+   $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H)
-+sched-vis.o : sched-vis.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) sched-int.h \
-+   hard-reg-set.h $(BASIC_BLOCK_H) $(INSN_ATTR_H) $(REGS_H) $(TM_P_H) \
-+   $(TARGET_H) real.h
-+final.o : final.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h intl.h \
-+   $(REGS_H) $(RECOG_H) conditions.h insn-config.h $(INSN_ATTR_H) function.h \
-+   real.h output.h hard-reg-set.h except.h debug.h xcoffout.h profile.h \
-+   toplev.h reload.h dwarf2out.h $(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H) $(EXPR_H)
-+recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) function.h $(BASIC_BLOCK_H) \
-+   $(REGS_H) $(RECOG_H) $(EXPR_H) hard-reg-set.h flags.h insn-config.h \
-+   $(INSN_ATTR_H) real.h toplev.h output.h reload.h $(TM_P_H)
-+reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) $(RECOG_H) \
-+   $(REGS_H) hard-reg-set.h flags.h insn-config.h toplev.h reload.h \
-+   varray.h function.h $(TM_P_H) $(GGC_H) gt-reg-stack.h
-+predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
-+   insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
-+   $(RECOG_H) function.h except.h $(EXPR_H) $(TM_P_H) $(PREDICT_H) real.h \
-+   $(PARAMS_H) $(TARGET_H)
-+lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) toplev.h $(RTL_H) $(GGC_H)
-+bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
-+   flags.h $(BASIC_BLOCK_H) hard-reg-set.h output.h cfglayout.h $(TARGET_H)
-+tracer.o : tracer.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
-+   $(BASIC_BLOCK_H) hard-reg-set.h output.h cfglayout.h flags.h \
-+   $(PARAMS_H) profile.h
-+cfglayout.o : cfglayout.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
-+   insn-config.h $(BASIC_BLOCK_H) hard-reg-set.h output.h function.h \
-+   cfglayout.h
-+timevar.o : timevar.c $(CONFIG_H) $(SYSTEM_H) $(TIMEVAR_H) flags.h intl.h
-+regrename.o : regrename.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) insn-config.h \
-+   $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h $(RECOG_H) function.h \
-+   resource.h $(OBSTACK_H) flags.h $(TM_P_H)
-+ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) toplev.h \
-+   flags.h insn-config.h function.h $(RECOG_H) $(BASIC_BLOCK_H) $(EXPR_H) \
-+   output.h except.h $(TM_P_H) real.h
-+params.o : params.c $(CONFIG_H) $(SYSTEM_H) $(PARAMS_H) toplev.h
-+hooks.o: hooks.c $(CONFIG_H) $(SYSTEM_H) $(HOOKS_H)
-+protector.o: protector.c $(CONFIG_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 \
-+   output.h $(INSN_ATTR_H) $(SYSTEM_H) toplev.h $(TARGET_H) libfuncs.h \
-+   $(TARGET_DEF_H) function.h sched-int.h $(TM_P_H) $(EXPR_H) $(OPTABS_H) \
-+   langhooks.h
-+      $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+              $(out_file) $(OUTPUT_OPTION)
-+
-+# Build auxiliary files that support ecoff format.
-+mips-tfile: mips-tfile.o version.o $(LIBDEPS)
-+      $(CC) $(CFLAGS) $(LDFLAGS) -o $@ mips-tfile.o version.o $(LIBS)
-+
-+mips-tfile.o : mips-tfile.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H) version.h
-+
-+mips-tdump: mips-tdump.o version.o $(LIBDEPS)
-+      $(CC) $(CFLAGS) $(LDFLAGS) -o $@ mips-tdump.o version.o $(LIBS)
-+
-+mips-tdump.o : mips-tdump.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H)
-+
-+#\f
-+# Generate header and source files from the machine description,
-+# and compile them.
-+
-+.PRECIOUS: insn-config.h insn-flags.h insn-codes.h insn-constants.h \
-+  insn-emit.c insn-recog.c insn-extract.c insn-output.c insn-peep.c \
-+  insn-attr.h insn-attrtab.c
-+
-+# The following pair of rules has this effect:
-+# genconfig is run only if the md has changed since genconfig was last run;
-+# but the file insn-config.h is touched only when its contents actually change.
-+
-+# Each of the other insn-* files is handled by a similar pair of rules.
-+
-+# This causes an anomaly in the results of make -n
-+# because insn-* is older than s-*
-+# and thus make -n thinks that insn-* will be updated
-+# and force recompilation of things that depend on it.
-+# We use move-if-change precisely to avoid such recompilation.
-+# But there is no way to teach make -n that it will be avoided.
-+
-+# Each of the insn-*.[ch] rules has a semicolon at the end,
-+# for otherwise the system Make on SunOS 4.1 never tries
-+# to recompile insn-*.o.  To avoid problems and extra noise from
-+# versions of make which don't like empty commands (nothing after the
-+# trailing `;'), we call true for each.
-+
-+insn-config.h: s-config ; @true
-+s-config : $(md_file) genconfig$(build_exeext) $(srcdir)/move-if-change
-+      $(RUN_GEN) ./genconfig$(build_exeext) $(md_file) > tmp-config.h
-+      $(SHELL) $(srcdir)/move-if-change tmp-config.h insn-config.h
-+      $(STAMP) s-config
-+
-+insn-conditions.c: s-conditions ; @true
-+s-conditions : $(md_file) genconditions$(build_exeext) $(srcdir)/move-if-change
-+      $(RUN_GEN) ./genconditions$(build_exeext) $(md_file) > tmp-conditions.c
-+      $(SHELL) $(srcdir)/move-if-change tmp-conditions.c insn-conditions.c
-+      $(STAMP) s-conditions
-+
-+insn-conditions.o : insn-conditions.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) \
-+  $(TM_P_H) $(REGS_H) function.h $(RECOG_H) real.h output.h flags.h \
-+  hard-reg-set.h resource.h toplev.h reload.h gensupport.h insn-constants.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) insn-conditions.c
-+
-+dummy-conditions.o : dummy-conditions.c $(HCONFIG_H) $(SYSTEM_H) gensupport.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
-+          $(srcdir)/dummy-conditions.c $(OUTPUT_OPTION)
-+
-+insn-flags.h: s-flags ; @true
-+s-flags : $(md_file) genflags$(build_exeext) $(srcdir)/move-if-change
-+      $(RUN_GEN) ./genflags$(build_exeext) $(md_file) > tmp-flags.h
-+      $(SHELL) $(srcdir)/move-if-change tmp-flags.h insn-flags.h
-+      $(STAMP) s-flags
-+
-+insn-codes.h: s-codes ; @true
-+s-codes : $(md_file) gencodes$(build_exeext) $(srcdir)/move-if-change
-+      $(RUN_GEN) ./gencodes$(build_exeext) $(md_file) > tmp-codes.h
-+      $(SHELL) $(srcdir)/move-if-change tmp-codes.h insn-codes.h
-+      $(STAMP) s-codes
-+
-+insn-constants.h: s-constants ; @true
-+s-constants : $(md_file) genconstants$(build_exeext) $(srcdir)/move-if-change
-+      $(RUN_GEN) ./genconstants$(build_exeext) $(md_file) > tmp-constants.h
-+      $(SHELL) $(srcdir)/move-if-change tmp-constants.h insn-constants.h
-+      $(STAMP) s-constants
-+
-+insn-emit.o : insn-emit.c $(CONFIG_H) $(RTL_H) $(EXPR_H) real.h output.h \
-+  insn-config.h $(OPTABS_H) $(SYSTEM_H) reload.h $(RECOG_H) toplev.h \
-+  function.h flags.h hard-reg-set.h resource.h $(TM_P_H)
-+      $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-emit.c \
-+        $(OUTPUT_OPTION)
-+
-+insn-emit.c: s-emit ; @true
-+s-emit : $(md_file) genemit$(build_exeext) $(srcdir)/move-if-change
-+      $(RUN_GEN) ./genemit$(build_exeext) $(md_file) > tmp-emit.c
-+      $(SHELL) $(srcdir)/move-if-change tmp-emit.c insn-emit.c
-+      $(STAMP) s-emit
-+
-+insn-recog.o : insn-recog.c $(CONFIG_H) $(RTL_H) insn-config.h $(RECOG_H) \
-+  real.h output.h flags.h $(SYSTEM_H) function.h hard-reg-set.h resource.h \
-+  $(TM_P_H) toplev.h reload.h
-+      $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-recog.c \
-+        $(OUTPUT_OPTION)
-+
-+insn-recog.c: s-recog ; @true
-+s-recog : $(md_file) genrecog$(build_exeext) $(srcdir)/move-if-change
-+      $(RUN_GEN) ./genrecog$(build_exeext) $(md_file) > tmp-recog.c
-+      $(SHELL) $(srcdir)/move-if-change tmp-recog.c insn-recog.c
-+      $(STAMP) s-recog
-+
-+insn-opinit.o : insn-opinit.c $(CONFIG_H) $(RTL_H) \
-+  insn-config.h flags.h $(RECOG_H) $(EXPR_H) $(OPTABS_H) reload.h $(SYSTEM_H)
-+      $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-opinit.c \
-+        $(OUTPUT_OPTION)
-+
-+insn-opinit.c: s-opinit ; @true
-+s-opinit : $(md_file) genopinit$(build_exeext) $(srcdir)/move-if-change
-+      $(RUN_GEN) ./genopinit$(build_exeext) $(md_file) > tmp-opinit.c
-+      $(SHELL) $(srcdir)/move-if-change tmp-opinit.c insn-opinit.c
-+      $(STAMP) s-opinit
-+
-+insn-extract.o : insn-extract.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H) toplev.h \
-+  insn-config.h $(RECOG_H)
-+      $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-extract.c \
-+        $(OUTPUT_OPTION)
-+
-+insn-extract.c: s-extract ; @true
-+s-extract : $(md_file) genextract$(build_exeext) $(srcdir)/move-if-change
-+      $(RUN_GEN) ./genextract$(build_exeext) $(md_file) > tmp-extract.c
-+      $(SHELL) $(srcdir)/move-if-change tmp-extract.c insn-extract.c
-+      $(STAMP) s-extract
-+
-+insn-peep.o : insn-peep.c $(CONFIG_H) $(RTL_H) $(REGS_H) output.h real.h \
-+      $(SYSTEM_H) insn-config.h $(RECOG_H) except.h function.h $(TM_P_H)
-+      $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-peep.c \
-+        $(OUTPUT_OPTION)
-+
-+insn-peep.c: s-peep ; @true
-+s-peep : $(md_file) genpeep$(build_exeext) $(srcdir)/move-if-change
-+      $(RUN_GEN) ./genpeep$(build_exeext) $(md_file) > tmp-peep.c
-+      $(SHELL) $(srcdir)/move-if-change tmp-peep.c insn-peep.c
-+      $(STAMP) s-peep
-+
-+insn-attrtab.o : insn-attrtab.c $(CONFIG_H) $(RTL_H) $(REGS_H) real.h \
-+    output.h $(INSN_ATTR_H) insn-config.h $(SYSTEM_H) toplev.h $(RECOG_H) \
-+      $(TM_P_H) flags.h
-+      $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-attrtab.c \
-+        $(OUTPUT_OPTION)
-+
-+insn-attr.h: s-attr ; @true
-+s-attr : $(md_file) genattr$(build_exeext) $(srcdir)/move-if-change
-+      $(RUN_GEN) ./genattr$(build_exeext) $(md_file) > tmp-attr.h
-+      $(SHELL) $(srcdir)/move-if-change tmp-attr.h insn-attr.h
-+      $(STAMP) s-attr
-+
-+insn-attrtab.c: s-attrtab ; @true
-+s-attrtab : $(md_file) genattrtab$(build_exeext) $(srcdir)/move-if-change
-+      $(RUN_GEN) ./genattrtab$(build_exeext) $(md_file) > tmp-attrtab.c
-+      $(SHELL) $(srcdir)/move-if-change tmp-attrtab.c insn-attrtab.c
-+      $(STAMP) s-attrtab
-+
-+insn-output.o : insn-output.c $(CONFIG_H) $(RTL_H) $(GGC_H) $(REGS_H) real.h \
-+    conditions.h hard-reg-set.h insn-config.h $(INSN_ATTR_H) $(EXPR_H) \
-+    output.h $(RECOG_H) function.h $(SYSTEM_H) toplev.h flags.h \
-+    insn-codes.h $(TM_P_H)
-+      $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-output.c \
-+        $(OUTPUT_OPTION)
-+
-+insn-output.c: s-output ; @true
-+s-output : $(md_file) genoutput$(build_exeext) $(srcdir)/move-if-change
-+      $(RUN_GEN) ./genoutput$(build_exeext) $(md_file) > tmp-output.c
-+      $(SHELL) $(srcdir)/move-if-change tmp-output.c insn-output.c
-+      $(STAMP) s-output
-+
-+genrtl.o : genrtl.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H) $(GGC_H)
-+genrtl.c genrtl.h : s-genrtl
-+      @true   # force gnu make to recheck modification times.
-+
-+s-genrtl: gengenrtl$(build_exeext) $(srcdir)/move-if-change $(RTL_BASE_H)
-+      $(RUN_GEN) ./gengenrtl$(build_exeext) -h > tmp-genrtl.h
-+      $(SHELL) $(srcdir)/move-if-change tmp-genrtl.h genrtl.h
-+      $(RUN_GEN) ./gengenrtl$(build_exeext) > tmp-genrtl.c
-+      $(SHELL) $(srcdir)/move-if-change tmp-genrtl.c genrtl.c
-+      $(STAMP) s-genrtl
-+
-+tm-preds.h: s-preds; @true
-+
-+s-preds: genpreds$(build_exeext) $(srcdir)/move-if-change
-+      $(RUN_GEN) ./genpreds$(build_exeext) > tmp-preds.h
-+      $(SHELL) $(srcdir)/move-if-change tmp-preds.h tm-preds.h
-+      $(STAMP) s-preds
-+
-+GTFILES = $(GCONFIG_H) $(srcdir)/location.h \
-+  $(HASHTAB_H) \
-+  $(srcdir)/bitmap.h $(srcdir)/function.h  $(srcdir)/rtl.h $(srcdir)/optabs.h \
-+  $(srcdir)/tree.h $(srcdir)/libfuncs.h $(srcdir)/hashtable.h $(srcdir)/real.h \
-+  $(srcdir)/varray.h $(srcdir)/ssa.h $(srcdir)/insn-addr.h $(srcdir)/cselib.h \
-+  $(srcdir)/c-common.h $(srcdir)/c-tree.h \
-+  $(srcdir)/basic-block.h \
-+  $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c \
-+  $(srcdir)/dwarf2out.c $(srcdir)/emit-rtl.c \
-+  $(srcdir)/except.c $(srcdir)/explow.c $(srcdir)/expr.c \
-+  $(srcdir)/fold-const.c $(srcdir)/function.c \
-+  $(srcdir)/gcse.c $(srcdir)/integrate.c $(srcdir)/lists.c $(srcdir)/optabs.c \
-+  $(srcdir)/profile.c $(srcdir)/ra-build.c $(srcdir)/regclass.c \
-+  $(srcdir)/reg-stack.c \
-+  $(srcdir)/sdbout.c $(srcdir)/stmt.c $(srcdir)/stor-layout.c \
-+  $(srcdir)/tree.c $(srcdir)/varasm.c \
-+  $(out_file) \
-+  @all_gtfiles@
-+
-+GTFILES_FILES_LANGS = @all_gtfiles_files_langs@
-+GTFILES_FILES_FILES = @all_gtfiles_files_files@
-+GTFILES_LANG_DIR_NAMES = @subdirs@
-+GTFILES_SRCDIR = @srcdir@
-+
-+gtype-desc.h gtype-desc.c gt-except.h gt-function.h : s-gtype; @true
-+gt-integrate.h gt-stmt.h gt-tree.h gt-varasm.h gt-emit-rtl.h : s-gtype; @true
-+gt-explow.h gt-stor-layout.h gt-regclass.h gt-lists.h : s-gtype; @true
-+gt-alias.h gt-cselib.h gt-fold-const.h gt-gcse.h gt-profile.h : s-gtype; @true
-+gt-expr.h gt-sdbout.h gt-optabs.h gt-bitmap.h gt-dwarf2out.h : s-gtype ; @true
-+gt-ra-build.h gt-reg-stack.h : s-gtype ; @true
-+gt-c-common.h gt-c-decl.h gt-c-parse.h gt-c-pragma.h : s-gtype; @true
-+gt-c-objc-common.h gtype-c.h gt-location.h : s-gtype ; @true
-+
-+gtyp-gen.h: Makefile
-+      echo "/* This file is machine generated.  Do not edit.  */" > tmp-gtyp.h
-+      echo "static const char *srcdir = "  >> tmp-gtyp.h
-+      echo "\"$(GTFILES_SRCDIR)\"" >> tmp-gtyp.h
-+      echo ";" >> tmp-gtyp.h
-+      echo "static const char *lang_files[] = {" >> tmp-gtyp.h
-+      ll="$(GTFILES_FILES_FILES)"; \
-+      for f in $$ll; do \
-+      echo "\"$$f\", "; done >> tmp-gtyp.h
-+      echo "NULL};" >> tmp-gtyp.h
-+      echo "static const char *langs_for_lang_files[] = {" >> tmp-gtyp.h
-+      ff="$(GTFILES_FILES_LANGS)"; \
-+      for f in $$ff; do \
-+      echo "\"$$f\", " ; done  >> tmp-gtyp.h
-+      echo "NULL};" >> tmp-gtyp.h
-+      echo "static const char *all_files[] = {" >> tmp-gtyp.h
-+      gf="$(GTFILES)"; \
-+      for f in $$gf; do \
-+      echo "\"$$f\", "; done >> tmp-gtyp.h
-+      echo " NULL};" >> tmp-gtyp.h
-+      echo "static const char *lang_dir_names[] = { \"c\", " >> tmp-gtyp.h
-+      gf="$(GTFILES_LANG_DIR_NAMES)"; \
-+      for l in $$gf; do \
-+      echo "\"$$l\", "; done >> tmp-gtyp.h
-+      echo "NULL};" >> tmp-gtyp.h
-+      $(SHELL) $(srcdir)/move-if-change tmp-gtyp.h gtyp-gen.h 
-+
-+s-gtype: gengtype$(build_exeext) $(GTFILES)
-+      $(RUN_GEN) ./gengtype
-+      $(STAMP) s-gtype
-+
-+#\f
-+# Compile the programs that generate insn-* from the machine description.
-+# They are compiled with $(HOST_CC), and associated libraries,
-+# since they need to run on this machine
-+# even if GCC is being compiled to run on some other machine.
-+
-+# $(CONFIG_H) is omitted from the deps of the gen*.o
-+# because these programs don't really depend on anything
-+# about the target machine.  They do depend on config.h itself,
-+# since that describes the host machine.
-+
-+read-rtl.o: read-rtl.c $(HCONFIG_H) $(SYSTEM_H) $(RTL_H) \
-+  $(OBSTACK_H) $(HASHTAB_H)
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/read-rtl.c $(OUTPUT_OPTION)
-+
-+gensupport.o: gensupport.c $(RTL_H) $(OBSTACK_H) $(SYSTEM_H) errors.h gensupport.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gensupport.c $(OUTPUT_OPTION)
-+
-+genconfig$(build_exeext) : genconfig.o $(HOST_RTL) $(HOST_SUPPORT) \
-+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+        genconfig.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
-+          $(HOST_ERRORS) $(HOST_LIBS)
-+
-+genconfig.o : genconfig.c $(RTL_H) $(HCONFIG_H) \
-+  $(SYSTEM_H) errors.h gensupport.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genconfig.c $(OUTPUT_OPTION)
-+
-+genflags$(build_exeext) : genflags.o $(HOST_RTL) $(HOST_SUPPORT) \
-+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       genflags.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
-+          $(HOST_ERRORS) $(HOST_LIBS)
-+
-+genflags.o : genflags.c $(RTL_H) $(OBSTACK_H) $(HCONFIG_H) \
-+  $(SYSTEM_H) errors.h gensupport.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genflags.c $(OUTPUT_OPTION)
-+
-+gencodes$(build_exeext) : gencodes.o $(HOST_RTL) $(HOST_SUPPORT) \
-+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       gencodes.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
-+          $(HOST_ERRORS) $(HOST_LIBS)
-+
-+gencodes.o : gencodes.c $(RTL_H) $(HCONFIG_H) \
-+  $(SYSTEM_H) errors.h gensupport.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gencodes.c $(OUTPUT_OPTION)
-+
-+genconstants$(build_exeext) : genconstants.o $(HOST_RTL) $(HOST_EARLY_SUPPORT) \
-+  $(HOST_ERRORS) $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       genconstants.o $(HOST_EARLY_SUPPORT) $(HOST_RTL) \
-+          $(HOST_ERRORS) $(HOST_LIBS)
-+
-+genconstants.o : genconstants.c $(RTL_H) $(HCONFIG_H) $(SYSTEM_H) errors.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genconstants.c $(OUTPUT_OPTION)
-+
-+genemit$(build_exeext) : genemit.o $(HOST_RTL) $(HOST_SUPPORT) \
-+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       genemit.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
-+          $(HOST_ERRORS) $(HOST_LIBS)
-+
-+genemit.o : genemit.c $(RTL_H) $(HCONFIG_H) $(SYSTEM_H) errors.h gensupport.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genemit.c $(OUTPUT_OPTION)
-+
-+genopinit$(build_exeext) : genopinit.o $(HOST_RTL) $(HOST_SUPPORT) \
-+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       genopinit.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
-+          $(HOST_ERRORS) $(HOST_LIBS)
-+
-+genopinit.o : genopinit.c $(RTL_H) $(HCONFIG_H) \
-+  $(SYSTEM_H) errors.h gensupport.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genopinit.c $(OUTPUT_OPTION)
-+
-+genrecog$(build_exeext) : genrecog.o $(HOST_RTL) $(HOST_SUPPORT) \
-+    $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       genrecog.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
-+          $(HOST_ERRORS) $(HOST_LIBS)
-+
-+genrecog.o : genrecog.c $(RTL_H) $(HCONFIG_H) \
-+  $(SYSTEM_H) errors.h gensupport.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genrecog.c $(OUTPUT_OPTION)
-+
-+genextract$(build_exeext) : genextract.o $(HOST_RTL) $(HOST_SUPPORT) \
-+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       genextract.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
-+          $(HOST_ERRORS) $(HOST_LIBS)
-+
-+genextract.o : genextract.c $(RTL_H) $(HCONFIG_H) \
-+  $(SYSTEM_H) insn-config.h errors.h gensupport.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genextract.c $(OUTPUT_OPTION)
-+
-+genpeep$(build_exeext) : genpeep.o $(HOST_RTL) $(HOST_SUPPORT) \
-+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       genpeep.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
-+          $(HOST_ERRORS) $(HOST_LIBS)
-+
-+genpeep.o : genpeep.c $(RTL_H) $(HCONFIG_H) $(SYSTEM_H) errors.h gensupport.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genpeep.c $(OUTPUT_OPTION)
-+
-+genattr$(build_exeext) : genattr.o $(HOST_RTL) $(HOST_SUPPORT) \
-+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       genattr.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
-+          $(HOST_ERRORS) $(HOST_LIBS)
-+
-+genattr.o : genattr.c $(RTL_H) $(HCONFIG_H) $(SYSTEM_H) errors.h gensupport.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genattr.c $(OUTPUT_OPTION)
-+
-+genattrtab$(build_exeext) : genattrtab.o genautomata.o \
-+  $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_VARRAY) \
-+  $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       genattrtab.o genautomata.o \
-+       $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) $(HOST_ERRORS) \
-+       $(HOST_VARRAY) $(HOST_LIBS) -lm
-+
-+genattrtab.o : genattrtab.c $(RTL_H) $(OBSTACK_H) $(HCONFIG_H) \
-+  $(SYSTEM_H) errors.h $(GGC_H) gensupport.h genattrtab.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genattrtab.c $(OUTPUT_OPTION)
-+
-+genautomata.o : genautomata.c $(RTL_H) $(OBSTACK_H) $(HCONFIG_H) \
-+  $(SYSTEM_H) errors.h varray.h genattrtab.h $(HASHTAB_H)
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genautomata.c $(OUTPUT_OPTION)
-+
-+genoutput$(build_exeext) : genoutput.o $(HOST_RTL) $(HOST_SUPPORT) \
-+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       genoutput.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
-+          $(HOST_ERRORS) $(HOST_LIBS)
-+
-+genoutput.o : genoutput.c $(RTL_H) $(HCONFIG_H) \
-+  $(SYSTEM_H) errors.h gensupport.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genoutput.c $(OUTPUT_OPTION)
-+
-+gengenrtl$(build_exeext) : gengenrtl.o $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       gengenrtl.o $(HOST_LIBS)
-+
-+gengenrtl.o : gengenrtl.c $(RTL_BASE_H) $(HCONFIG_H) $(SYSTEM_H) real.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gengenrtl.c $(OUTPUT_OPTION)
-+
-+genpreds$(build_exeext) : genpreds.o $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       genpreds.o $(HOST_LIBS)
-+
-+genpreds.o : genpreds.c $(RTL_BASE_H) $(HCONFIG_H) $(SYSTEM_H)
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genpreds.c $(OUTPUT_OPTION)
-+
-+gengtype$(build_exeext) : gengtype.o gengtype-lex.o gengtype-yacc.o \
-+  $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       gengtype.o gengtype-lex.o gengtype-yacc.o $(HOST_LIBS)
-+
-+gengtype.o : gengtype.c gengtype.h $(HCONFIG_H) $(SYSTEM_H) real.h rtl.def \
-+  gtyp-gen.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
-+        $(srcdir)/gengtype.c $(OUTPUT_OPTION)
-+
-+gengtype-lex.o : $(srcdir)/gengtype-lex.c gengtype.h $(srcdir)/gengtype-yacc.c \
-+  $(HCONFIG_H) $(SYSTEM_H)
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
-+        $(srcdir)/gengtype-lex.c $(OUTPUT_OPTION)
-+
-+gengtype-yacc.o : $(srcdir)/gengtype-yacc.c gengtype.h $(HCONFIG_H) $(SYSTEM_H)
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
-+        $(srcdir)/gengtype-yacc.c $(OUTPUT_OPTION)
-+
-+# The sed command works around a bug in flex-2.5.4.
-+$(srcdir)/gengtype-lex.c : $(srcdir)/gengtype-lex.l
-+      cd $(srcdir) && \
-+      $(FLEX) $(FLEXFLAGS) -t -o$@ gengtype-lex.l | \
-+        sed 's/^\(char msg\[\];\)/yyconst \1/' > g-$$$$ ; \
-+      if test $$? -eq 0 ; then \
-+        mv -f g-$$$$ gengtype-lex.c ; \
-+      else \
-+        rm -f g-$$$$.* ; \
-+        false ; \
-+      fi
-+
-+$(srcdir)/gengtype-yacc.c: $(srcdir)/gengtype-yacc.y
-+      (cd $(srcdir) && \
-+       $(BISON) $(BISONFLAGS) -d -o gengtype-yacc.c gengtype-yacc.y || \
-+       ( rm -f $@ && false ) )
-+
-+genconditions$(build_exeext) : genconditions.o $(HOST_EARLY_SUPPORT) \
-+  $(HOST_RTL) $(HOST_ERRORS) $(HOST_LIBDEPS)
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+       genconditions.o $(HOST_EARLY_SUPPORT) $(HOST_RTL) \
-+          $(HOST_ERRORS) $(HOST_LIBS)
-+
-+genconditions.o : genconditions.c $(RTL_H) $(HCONFIG_H) $(SYSTEM_H) errors.h
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
-+              $(srcdir)/genconditions.c $(OUTPUT_OPTION)
-+
-+#\f
-+# Compile the libraries to be used by gen*.
-+# If we are not cross-building, gen* use the same .o's that cc1 will use,
-+# and BUILD_PREFIX_1 is `loser-', just to ensure these rules don't conflict
-+# with the rules for rtl.o, etc.
-+$(BUILD_PREFIX_1)rtl.o: $(srcdir)/rtl.c $(HCONFIG_H) $(SYSTEM_H) $(RTL_H) \
-+  real.h $(GGC_H) errors.h
-+      rm -f $(BUILD_PREFIX)rtl.c
-+      sed -e 's/config[.]h/hconfig.h/' $(srcdir)/rtl.c > $(BUILD_PREFIX)rtl.c
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)rtl.c $(OUTPUT_OPTION)
-+
-+print-rtl1.o: $(srcdir)/print-rtl.c $(HCONFIG_H) \
-+  $(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H)
-+      rm -f print-rtl1.c
-+      sed -e 's/config[.]h/hconfig.h/' $(srcdir)/print-rtl.c > print-rtl1.c
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) print-rtl1.c $(OUTPUT_OPTION)
-+
-+$(BUILD_PREFIX_1)bitmap.o: $(srcdir)/bitmap.c $(HCONFIG_H) $(SYSTEM_H) \
-+  $(RTL_H) flags.h $(BASIC_BLOCK_H) $(REGS_H) $(GGC_H)
-+      rm -f $(BUILD_PREFIX)bitmap.c
-+      sed -e 's/config[.]h/hconfig.h/' $(srcdir)/bitmap.c > $(BUILD_PREFIX)bitmap.c
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)bitmap.c $(OUTPUT_OPTION)
-+
-+$(BUILD_PREFIX_1)errors.o: errors.c $(HCONFIG_H) $(SYSTEM_H) errors.h
-+      rm -f $(BUILD_PREFIX)errors.c
-+      sed -e 's/config[.]h/hconfig.h/' $(srcdir)/errors.c > $(BUILD_PREFIX)errors.c
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)errors.c $(OUTPUT_OPTION)
-+
-+$(BUILD_PREFIX_1)varray.o: varray.c $(HCONFIG_H) $(SYSTEM_H) varray.h \
-+  $(RTL_H) $(GGC_H) $(TREE_H) bitmap.h errors.h
-+      rm -f $(BUILD_PREFIX)varray.c
-+      sed -e 's/config[.]h/hconfig.h/' $(srcdir)/varray.c > \
-+              $(BUILD_PREFIX)varray.c
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
-+              $(BUILD_PREFIX)varray.c $(OUTPUT_OPTION)
-+
-+$(BUILD_PREFIX_1)ggc-none.o: ggc-none.c $(HCONFIG_H) $(SYSTEM_H) $(GGC_H)
-+      rm -f $(BUILD_PREFIX)ggc-none.c
-+      sed -e 's/config[.]h/hconfig.h/' $(srcdir)/ggc-none.c > $(BUILD_PREFIX)ggc-none.c
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)ggc-none.c $(OUTPUT_OPTION)
-+
-+#\f
-+# Remake internationalization support.
-+intl.o: intl.c $(CONFIG_H) system.h intl.h Makefile
-+      $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+        -DLOCALEDIR=\"$(localedir)\" \
-+        -c $(srcdir)/intl.c $(OUTPUT_OPTION)
-+
-+$(top_builddir)/intl/libintl.a: intl.all
-+
-+intl.all intl.install intl.uninstall \
-+  intl.mostlyclean intl.clean intl.distclean intl.maintainer-clean:
-+      @for d in $(INTL_SUBDIRS); do \
-+        target=`expr $@ : 'intl.\(.*\)'` && \
-+        echo "(cd $$d && $(MAKE) $$target)" && \
-+        (cd $$d && AWK='$(AWK)' $(MAKE) $(SUBDIR_FLAGS_TO_PASS) $$target); \
-+        if [ $$? -eq 0 ] ; then true ; else exit 1 ; fi ; \
-+      done
-+
-+# intl.all and intl.install need config.h to exist, and the files it includes.
-+# (FIXME: intl/*.c shouldn't need to see insn-foo.h!)
-+intl.all intl.install: config.h insn-flags.h insn-constants.h
-+
-+# Make-lang.in should add dependencies of po-generated on any generated
-+# files which need to be scanned by gettext (usually Yacc-generated parsers).
-+po-generated: c-parse.c
-+
-+#\f
-+# Remake cpp and protoize.
-+
-+PREPROCESSOR_DEFINES = \
-+  -DGCC_INCLUDE_DIR=\"$(libsubdir)/include\" \
-+  -DGPLUSPLUS_INCLUDE_DIR=\"$(gcc_gxx_include_dir)\" \
-+  -DGPLUSPLUS_TOOL_INCLUDE_DIR=\"$(gcc_gxx_include_dir)/$(target_alias)\" \
-+  -DGPLUSPLUS_BACKWARD_INCLUDE_DIR=\"$(gcc_gxx_include_dir)/backward\" \
-+  -DLOCAL_INCLUDE_DIR=\"$(local_includedir)\" \
-+  -DCROSS_INCLUDE_DIR=\"$(gcc_tooldir)/sys-include\" \
-+  -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\"
-+
-+LIBCPP_OBJS = cpplib.o cpplex.o cppmacro.o cppexp.o cppfiles.o cpptrad.o \
-+              cpphash.o cpperror.o cppinit.o cppdefault.o cppmain.o \
-+              hashtable.o line-map.o mkdeps.o prefix.o mbchar.o
-+
-+LIBCPP_DEPS = $(CPPLIB_H) cpphash.h line-map.h hashtable.h intl.h \
-+              $(OBSTACK_H) $(SYSTEM_H)
-+
-+# Most of the other archives built/used by this makefile are for
-+# targets.  This one is strictly for the host.
-+libcpp.a: $(LIBCPP_OBJS)
-+      -rm -rf libcpp.a
-+      $(AR) $(AR_FLAGS) libcpp.a $(LIBCPP_OBJS)
-+      -$(RANLIB) libcpp.a
-+
-+cppmain.o:  cppmain.c  $(CONFIG_H) $(LIBCPP_DEPS)
-+
-+cpperror.o: cpperror.c $(CONFIG_H) $(LIBCPP_DEPS)
-+cppexp.o:   cppexp.c   $(CONFIG_H) $(LIBCPP_DEPS)
-+cpplex.o:   cpplex.c   $(CONFIG_H) $(LIBCPP_DEPS) mbchar.h
-+cppmacro.o: cppmacro.c $(CONFIG_H) $(LIBCPP_DEPS)
-+cpplib.o:   cpplib.c   $(CONFIG_H) $(LIBCPP_DEPS)
-+cpphash.o:  cpphash.c  $(CONFIG_H) $(LIBCPP_DEPS)
-+cpptrad.o:  cpptrad.c  $(CONFIG_H) $(LIBCPP_DEPS)
-+cppfiles.o: cppfiles.c $(CONFIG_H) $(LIBCPP_DEPS) $(SPLAY_TREE_H) mkdeps.h
-+cppinit.o:  cppinit.c  $(CONFIG_H) $(LIBCPP_DEPS) cppdefault.h \
-+              mkdeps.h prefix.h
-+
-+cppdefault.o: cppdefault.c $(CONFIG_H) $(SYSTEM_H) cppdefault.h Makefile
-+      $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+        $(PREPROCESSOR_DEFINES) \
-+        -c $(srcdir)/cppdefault.c $(OUTPUT_OPTION)
-+
-+mkdeps.o: mkdeps.c $(CONFIG_H) $(SYSTEM_H) mkdeps.h
-+
-+# Note for the stamp targets, we run the program `true' instead of
-+# having an empty command (nothing following the semicolon).
-+
-+proto: config.status protoize$(exeext) unprotoize$(exeext) SYSCALLS.c.X
-+
-+PROTO_OBJS = intl.o version.o cppdefault.o
-+
-+protoize$(exeext): protoize.o $(PROTO_OBJS) $(LIBDEPS)
-+      $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ protoize.o $(PROTO_OBJS) $(LIBS)
-+
-+unprotoize$(exeext): unprotoize.o $(PROTO_OBJS) $(LIBDEPS)
-+      $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ unprotoize.o $(PROTO_OBJS) $(LIBS)
-+
-+protoize.o: protoize.c $(srcdir)/../include/getopt.h $(CONFIG_H) $(SYSTEM_H) \
-+   Makefile version.h
-+      (SHLIB_LINK='$(SHLIB_LINK)' \
-+      SHLIB_MULTILIB='$(SHLIB_MULTILIB)'; \
-+      $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+        $(DRIVER_DEFINES) \
-+        $(srcdir)/protoize.c $(OUTPUT_OPTION))
-+
-+unprotoize.o: protoize.c $(srcdir)/../include/getopt.h \
-+   $(CONFIG_H) $(SYSTEM_H) Makefile version.h
-+      (SHLIB_LINK='$(SHLIB_LINK)' \
-+      SHLIB_MULTILIB='$(SHLIB_MULTILIB)'; \
-+      $(CC) -c -DUNPROTOIZE $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+        $(DRIVER_DEFINES) \
-+        $(srcdir)/protoize.c $(OUTPUT_OPTION))
-+
-+# This info describes the target machine, so compile with GCC just built.
-+SYSCALLS.c.X: $(srcdir)/sys-types.h $(srcdir)/sys-protos.h $(GCC_PASSES) \
-+   stmp-int-hdrs
-+      -rm -f SYSCALLS.c tmp-SYSCALLS.s
-+      sed -e s/TARGET_GETGROUPS_T/$(TARGET_GETGROUPS_T)/ \
-+        $(srcdir)/sys-types.h $(srcdir)/sys-protos.h > SYSCALLS.c
-+      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+        -aux-info $@ -S -o tmp-SYSCALLS.s SYSCALLS.c
-+      -rm -f SYSCALLS.c tmp-SYSCALLS.s
-+
-+
-+test-protoize-simple: ./protoize ./unprotoize $(GCC_PASSES)
-+      -rm -f tmp-proto.[cso]
-+      cp $(srcdir)/protoize.c tmp-proto.c
-+      chmod u+w tmp-proto.c
-+      ./protoize -N -B ./ -x getopt.h -c "-B./ -Wall -Wwrite-strings \
-+        $(GCC_CFLAGS) $(INCLUDES) \
-+        -DGCC_INCLUDE_DIR=0 \
-+        -DGPLUSPLUS_INCLUDE_DIR=0 \
-+        -DCROSS_INCLUDE_DIR=0 \
-+        -DTOOL_INCLUDE_DIR=0 \
-+        -DSTANDARD_EXEC_PREFIX=0 \
-+        -DDEFAULT_TARGET_MACHINE=0 \
-+        -DDEFAULT_TARGET_VERSION=0" tmp-proto.c
-+      @echo '**********' Expect 400 lines of differences.
-+      -diff $(srcdir)/protoize.c tmp-proto.c > tmp-proto.diff
-+      -wc -l tmp-proto.diff
-+      ./unprotoize -N -x getopt.h -c "-B./ -Wall -Wwrite-strings \
-+        $(GCC_CFLAGS) $(INCLUDES) \
-+        -DGCC_INCLUDE_DIR=0 \
-+        -DGPLUSPLUS_INCLUDE_DIR=0 \
-+        -DCROSS_INCLUDE_DIR=0 \
-+        -DTOOL_INCLUDE_DIR=0 \
-+        -DSTANDARD_EXEC_PREFIX=0 \
-+        -DDEFAULT_TARGET_MACHINE=0 \
-+        -DDEFAULT_TARGET_VERSION=0" tmp-proto.c
-+      @echo Expect zero differences.
-+      diff $(srcdir)/protoize.c tmp-proto.c | cat
-+      -rm -f tmp-proto.[cs] tmp-proto$(objext)
-+
-+gcov.o: gcov.c gcov-io.h intl.h $(SYSTEM_H) $(CONFIG_H)
-+
-+# Only one of 'gcov' or 'gcov.exe' is actually built, depending
-+# upon whether $(exeext) is empty or not.
-+GCOV_OBJS = gcov.o intl.o version.o
-+gcov$(exeext): $(GCOV_OBJS) $(LIBDEPS)
-+      $(CC) $(ALL_CFLAGS) $(LDFLAGS) $(GCOV_OBJS) $(LIBS) -o $@
-+#\f
-+# Build the include directory.  The stamp files are stmp-* rather than
-+# s-* so that mostlyclean does not force the include directory to
-+# be rebuilt.
-+
-+# Build the include directory
-+stmp-int-hdrs: $(STMP_FIXINC) $(USER_H) xlimits.h
-+# Copy in the headers provided with gcc.
-+# The sed command gets just the last file name component;
-+# this is necessary because VPATH could add a dirname.
-+# 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|'`; \
-+          $(STAMP) include/$$realfile; \
-+          rm -f include/$$realfile; \
-+          cp $$file include; \
-+          chmod a+r include/$$realfile; \
-+        fi; \
-+      done
-+      rm -f include/limits.h
-+      cp xlimits.h include/limits.h
-+      chmod a+r include/limits.h
-+# Install the README
-+      rm -f include/README
-+      cp $(srcdir)/README-fixinc include/README
-+      chmod a+r include/README
-+      $(STAMP) $@
-+
-+# fixinc.sh depends on this, not on specs directly.
-+# The idea is to make sure specs gets built, but not rerun fixinc.sh
-+# after each stage just because specs' mtime has changed.
-+specs.ready: specs
-+      -if [ -f specs.ready ] ; then \
-+              true; \
-+      else \
-+              $(STAMP) specs.ready; \
-+      fi
-+
-+FIXINCSRCDIR=$(srcdir)/fixinc
-+fixinc.sh: $(FIXINCSRCDIR)/mkfixinc.sh $(FIXINCSRCDIR)/fixincl.c \
-+      $(FIXINCSRCDIR)/procopen.c $(FIXINCSRCDIR)/gnu-regex.c \
-+      $(FIXINCSRCDIR)/server.c $(FIXINCSRCDIR)/gnu-regex.h \
-+      $(FIXINCSRCDIR)/server.h $(FIXINCSRCDIR)/inclhack.def specs.ready
-+      (MAKE="$(MAKE)"; srcdir=`cd $(srcdir)/fixinc && ${PWD_COMMAND}` ; \
-+      CC="$(HOST_CC)"; CFLAGS="$(HOST_CFLAGS)"; LDFLAGS="$(HOST_LDFLAGS)"; \
-+      WARN_CFLAGS="$(WARN_CFLAGS)"; \
-+      export MAKE srcdir CC CFLAGS LDFLAGS WARN_CFLAGS; cd ./fixinc && \
-+      $(SHELL) $${srcdir}/mkfixinc.sh $(build_canonical) $(target))
-+
-+# Build fixed copies of system files.
-+stmp-fixinc: fixinc.sh gsyslimits.h
-+      rm -rf include; mkdir include
-+      -chmod a+rx include
-+      (TARGET_MACHINE='$(target)'; srcdir=`cd $(srcdir); ${PWD_COMMAND}`; \
-+      SHELL='$(SHELL)' ;\
-+      export TARGET_MACHINE srcdir SHELL ; \
-+      $(SHELL) ./fixinc.sh `${PWD_COMMAND}`/include $(SYSTEM_HEADER_DIR) $(OTHER_FIXINCLUDES_DIRS); \
-+      rm -f include/syslimits.h; \
-+      if [ -f include/limits.h ]; then \
-+        mv include/limits.h include/syslimits.h; \
-+      else \
-+        cp $(srcdir)/gsyslimits.h include/syslimits.h; \
-+      fi; \
-+      chmod a+r include/syslimits.h)
-+# If $(SYSTEM_HEADER_DIR) is $(build_tooldir)/sys-include, and
-+# that directory exists, then make sure that $(libsubdir) exists.
-+# This is because cpp is compiled to find $(gcc_tooldir)/include via
-+# $(libsubdir)/$(unlibsubdir), which will only work if $(libsubdir)
-+# exists.
-+# ??? Better would be to use -isystem $(build_tooldir)/sys-include,
-+# but fixincludes does not take such arguments.
-+      if [ "$(SYSTEM_HEADER_DIR)" = "$(build_tooldir)/sys-include" ] \
-+         && [ -d $(build_tooldir)/sys-include ]; then \
-+        if [ -d $(libdir) ] ; then true ; else mkdir $(libdir) ; fi; \
-+        if [ -d $(libdir)/gcc-lib ] ; then true ; else mkdir $(libdir)/gcc-lib; fi; \
-+        if [ -d $(libdir)/gcc-lib/$(target_alias) ] ; then true ; else mkdir $(libdir)/gcc-lib/$(target_alias) ; fi; \
-+        if [ -d $(libdir)/gcc-lib/$(target_alias)/$(version) ] ; then true ; else mkdir $(libdir)/gcc-lib/$(target_alias)/$(version) ; fi; \
-+      else true; fi
-+      $(STAMP) stmp-fixinc
-+
-+# Files related to the fixproto script.
-+# gen-protos and fix-header are compiled with HOST_CC, but they are only
-+# used in native and host-x-target builds, so it's safe to link them with
-+# libiberty.a.
-+
-+deduced.h: $(GCC_PASSES) $(srcdir)/scan-types.sh stmp-int-hdrs
-+      if [ -d $(SYSTEM_HEADER_DIR) ]; \
-+      then \
-+        CC="$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(ALL_CPPFLAGS) -I. -I$(srcdir) -isystem include -isystem ${SYSTEM_HEADER_DIR}"; \
-+        export CC; \
-+        $(SHELL) $(srcdir)/scan-types.sh "$(srcdir)" >tmp-deduced.h; \
-+        mv tmp-deduced.h deduced.h; \
-+      else \
-+        $(STAMP) deduced.h; \
-+      fi
-+
-+GEN_PROTOS_OBJS = gen-protos.o scan.o
-+gen-protos$(build_exeext): $(GEN_PROTOS_OBJS)
-+      ${HOST_CC} $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-+        $(GEN_PROTOS_OBJS) $(HOST_LIBS)
-+
-+gen-protos.o: gen-protos.c scan.h $(HCONFIG_H) $(SYSTEM_H)
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gen-protos.c $(OUTPUT_OPTION)
-+
-+scan.o: scan.c scan.h $(HCONFIG_H) $(SYSTEM_H)
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/scan.c $(OUTPUT_OPTION)
-+
-+xsys-protos.h: $(GCC_PASSES) $(srcdir)/sys-protos.h deduced.h gen-protos$(build_exeext) Makefile
-+      sed -e s/TARGET_GETGROUPS_T/$(TARGET_GETGROUPS_T)/ \
-+        deduced.h $(srcdir)/sys-protos.h > tmp-fixtmp.c
-+      mv tmp-fixtmp.c fixtmp.c
-+      $(GCC_FOR_TARGET) fixtmp.c -w -U__SIZE_TYPE__ -U__PTRDIFF_TYPE__ -U__WCHAR_TYPE__ -E \
-+        | sed -e 's/  / /g' -e 's/ *(/ (/g' -e 's/ [ ]*/ /g' -e 's/( )/()/' \
-+        | $(RUN_GEN) ./gen-protos >xsys-protos.hT
-+      mv xsys-protos.hT xsys-protos.h
-+      rm -rf fixtmp.c
-+
-+# This is nominally a 'build' program, but it's run only when host==build,
-+# so we can (indeed, must) use $(LIBDEPS) and $(LIBS).
-+fix-header$(build_exeext): fix-header.o scan-decls.o scan.o xsys-protos.h \
-+           $(LIBDEPS) libcpp.a
-+      $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ fix-header.o \
-+         scan-decls.o scan.o libcpp.a $(LIBS)
-+
-+fix-header.o: fix-header.c $(OBSTACK_H) scan.h \
-+      xsys-protos.h $(HCONFIG_H) $(SYSTEM_H) $(CPPLIB_H)
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/fix-header.c $(OUTPUT_OPTION)
-+
-+scan-decls.o: scan-decls.c scan.h $(CPPLIB_H) $(HCONFIG_H) $(SYSTEM_H)
-+      $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/scan-decls.c $(OUTPUT_OPTION)
-+
-+# stmp-fixproto depends on this, not on fix-header directly.
-+# The idea is to make sure fix-header gets built,
-+# but not rerun fixproto after each stage
-+# just because fix-header's mtime has changed.
-+fixhdr.ready: fix-header$(build_exeext)
-+      -if [ -f fixhdr.ready ] ; then \
-+              true; \
-+      else \
-+              $(STAMP) fixhdr.ready; \
-+      fi
-+
-+# stmp-int-headers is to make sure fixincludes has already finished.
-+# The if statement is so that we don't run fixproto a second time
-+# if it has already been run on the files in `include'.
-+stmp-fixproto: fixhdr.ready fixproto stmp-int-hdrs
-+      if [ -f include/fixed ] ; then true; \
-+      else \
-+        : This line works around a 'make' bug in BSDI 1.1.; \
-+        FIXPROTO_DEFINES="$(FIXPROTO_DEFINES)"; export FIXPROTO_DEFINES; \
-+        mkinstalldirs="$(SHELL) $(srcdir)/mkinstalldirs"; \
-+          export mkinstalldirs; \
-+        if [ -d $(SYSTEM_HEADER_DIR) ] ; then \
-+          $(SHELL) ${srcdir}/fixproto include include $(SYSTEM_HEADER_DIR); \
-+          if [ $$? -eq 0 ] ; then true ; else exit 1 ; fi ; \
-+        else true; fi; \
-+        $(STAMP) include/fixed; \
-+      fi
-+      $(STAMP) stmp-fixproto
-+#\f
-+# Remake the info files.
-+
-+docdir = $(srcdir)/doc
-+
-+doc: $(BUILD_INFO) $(GENERATED_MANPAGES) gccbug
-+info: $(docdir)/cpp.info $(docdir)/gcc.info $(docdir)/gccint.info $(docdir)/gccinstall.info lang.info $(docdir)/cppinternals.info
-+
-+TEXI_CPP_FILES = $(docdir)/cpp.texi $(docdir)/include/fdl.texi \
-+  $(docdir)/cppenv.texi $(docdir)/cppopts.texi
-+
-+TEXI_GCC_FILES = $(docdir)/gcc.texi $(docdir)/include/gcc-common.texi \
-+       $(docdir)/frontends.texi $(docdir)/standards.texi \
-+       $(docdir)/invoke.texi $(docdir)/extend.texi $(docdir)/md.texi \
-+       $(docdir)/objc.texi $(docdir)/gcov.texi $(docdir)/trouble.texi \
-+       $(docdir)/bugreport.texi $(docdir)/service.texi \
-+       $(docdir)/contribute.texi $(docdir)/compat.texi \
-+       $(docdir)/include/funding.texi $(docdir)/gnu.texi \
-+       $(docdir)/include/gpl.texi $(docdir)/include/fdl.texi \
-+       $(docdir)/contrib.texi $(docdir)/cppenv.texi $(docdir)/cppopts.texi
-+
-+TEXI_GCCINT_FILES = $(docdir)/gccint.texi \
-+       $(docdir)/include/gcc-common.texi $(docdir)/contribute.texi \
-+       $(docdir)/makefile.texi $(docdir)/configterms.texi \
-+       $(docdir)/portability.texi $(docdir)/interface.texi \
-+       $(docdir)/passes.texi $(docdir)/c-tree.texi \
-+       $(docdir)/rtl.texi $(docdir)/md.texi $(docdir)/tm.texi \
-+       $(docdir)/hostconfig.texi $(docdir)/fragments.texi \
-+       $(docdir)/configfiles.texi $(docdir)/collect2.texi \
-+       $(docdir)/headerdirs.texi $(docdir)/include/funding.texi \
-+       $(docdir)/gnu.texi $(docdir)/include/gpl.texi \
-+       $(docdir)/include/fdl.texi $(docdir)/contrib.texi \
-+       $(docdir)/languages.texi $(docdir)/sourcebuild.texi \
-+       $(docdir)/gty.texi
-+
-+TEXI_GCCINSTALL_FILES = $(docdir)/install.texi $(docdir)/install-old.texi \
-+       $(docdir)/include/fdl.texi
-+
-+TEXI_CPPINT_FILES = $(docdir)/cppinternals.texi
-+
-+$(docdir)/cpp.info: $(TEXI_CPP_FILES)
-+      cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/cpp.info doc/cpp.texi
-+
-+$(docdir)/gcc.info: $(TEXI_GCC_FILES)
-+      cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/gcc.info doc/gcc.texi
-+
-+$(docdir)/gccint.info: $(TEXI_GCCINT_FILES)
-+      cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/gccint.info doc/gccint.texi
-+
-+$(docdir)/gccinstall.info: $(TEXI_GCCINSTALL_FILES)
-+      cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/gccinstall.info doc/install.texi
-+
-+$(docdir)/cppinternals.info: $(TEXI_CPPINT_FILES)
-+      cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/cppinternals.info \
-+              doc/cppinternals.texi
-+
-+dvi: gcc.dvi gccint.dvi gccinstall.dvi cpp.dvi lang.dvi cppinternals.dvi
-+
-+# This works with GNU Make's default rule.
-+cpp.dvi: $(TEXI_CPP_FILES)
-+      $(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/cpp.texi
-+
-+gcc.dvi: $(TEXI_GCC_FILES)
-+      $(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/gcc.texi
-+
-+gccint.dvi: $(TEXI_GCCINT_FILES)
-+      $(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/gccint.texi
-+
-+gccinstall.dvi: $(TEXI_GCCINSTALL_FILES)
-+      s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-+      $(TEXI2DVI) -I $$s/doc -I $$s/doc/include -o $@ $$s/doc/install.texi
-+
-+cppinternals.dvi: $(TEXI_CPPINT_FILES)
-+      $(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/cppinternals.texi
-+
-+generated-manpages: $(docdir)/gcov.1 $(docdir)/cpp.1 $(docdir)/gcc.1 \
-+       $(docdir)/gfdl.7 $(docdir)/gpl.7 $(docdir)/fsf-funding.7 \
-+       lang.generated-manpages
-+
-+$(docdir)/gcov.1: $(docdir)/gcov.texi
-+      $(STAMP) $(docdir)/gcov.1
-+      -$(TEXI2POD) $(docdir)/gcov.texi > gcov.pod
-+      -($(POD2MAN) --section=1 gcov.pod > $(docdir)/gcov.1.T$$$$ && \
-+              mv -f $(docdir)/gcov.1.T$$$$ $(docdir)/gcov.1) || \
-+              (rm -f $(docdir)/gcov.1.T$$$$ && exit 1)
-+      -rm -f gcov.pod
-+
-+$(docdir)/cpp.1: $(docdir)/cpp.texi $(docdir)/cppenv.texi \
-+  $(docdir)/cppopts.texi
-+      $(STAMP) $(docdir)/cpp.1
-+      -$(TEXI2POD) $(docdir)/cpp.texi > cpp.pod
-+      -($(POD2MAN) --section=1 cpp.pod > $(docdir)/cpp.1.T$$$$ && \
-+              mv -f $(docdir)/cpp.1.T$$$$ $(docdir)/cpp.1) || \
-+              (rm -f $(docdir)/cpp.1.T$$$$ && exit 1)
-+      -rm -f cpp.pod
-+
-+$(docdir)/gcc.1: $(docdir)/invoke.texi $(docdir)/cppenv.texi \
-+  $(docdir)/cppopts.texi
-+      $(STAMP) $(docdir)/gcc.1
-+      -$(TEXI2POD) $(docdir)/invoke.texi > gcc.pod
-+      -($(POD2MAN) --section=1 gcc.pod > $(docdir)/gcc.1.T$$$$ && \
-+              mv -f $(docdir)/gcc.1.T$$$$ $(docdir)/gcc.1) || \
-+              (rm -f $(docdir)/gcc.1.T$$$$ && exit 1)
-+      -rm -f gcc.pod
-+
-+$(docdir)/gfdl.7: $(docdir)/include/fdl.texi
-+      $(STAMP) $(docdir)/gfdl.7
-+      -$(TEXI2POD) $(docdir)/include/fdl.texi > gfdl.pod
-+      -($(POD2MAN) --section=7 gfdl.pod > $(docdir)/gfdl.7.T$$$$ && \
-+              mv -f $(docdir)/gfdl.7.T$$$$ $(docdir)/gfdl.7) || \
-+              (rm -f $(docdir)/gfdl.7.T$$$$ && exit 1)
-+      -rm -f gfdl.pod
-+
-+$(docdir)/gpl.7: $(docdir)/include/gpl.texi
-+      $(STAMP) $(docdir)/gpl.7
-+      -$(TEXI2POD) $(docdir)/include/gpl.texi > gpl.pod
-+      -($(POD2MAN) --section=7 gpl.pod > $(docdir)/gpl.7.T$$$$ && \
-+              mv -f $(docdir)/gpl.7.T$$$$ $(docdir)/gpl.7) || \
-+              (rm -f $(docdir)/gpl.7.T$$$$ && exit 1)
-+      -rm -f gpl.pod
-+
-+$(docdir)/fsf-funding.7: $(docdir)/include/funding.texi
-+      $(STAMP) $(docdir)/fsf-funding.7
-+      -$(TEXI2POD) $(docdir)/include/funding.texi > fsf-funding.pod
-+      -($(POD2MAN) --section=7 fsf-funding.pod \
-+              > $(docdir)/fsf-funding.7.T$$$$ && \
-+          mv -f $(docdir)/fsf-funding.7.T$$$$ $(docdir)/fsf-funding.7) || \
-+          (rm -f $(docdir)/fsf-funding.7.T$$$$ && exit 1)
-+      -rm -f fsf-funding.pod
-+
-+#\f
-+# Deletion of files made during compilation.
-+# There are four levels of this:
-+#   `mostlyclean', `clean', `distclean' and `maintainer-clean'.
-+# `mostlyclean' is useful while working on a particular type of machine.
-+# It deletes most, but not all, of the files made by compilation.
-+# It does not delete libgcc.a or its parts, so it won't have to be recompiled.
-+# `clean' deletes everything made by running `make all'.
-+# `distclean' also deletes the files made by config.
-+# `maintainer-clean' also deletes everything that could be regenerated
-+# automatically, except for `configure'.
-+# We remove as much from the language subdirectories as we can
-+# (less duplicated code).
-+
-+INTL_MOSTLYCLEAN = intl.mostlyclean
-+mostlyclean: $(INTL_MOSTLYCLEAN) lang.mostlyclean
-+      -rm -f $(STAGESTUFF)
-+      -rm -f *$(coverageexts)
-+      -rm -rf libgcc
-+# Delete the temporary source copies for cross compilation.
-+      -rm -f $(BUILD_PREFIX_1)rtl.c $(BUILD_PREFIX_1)print-rtl.c
-+      -rm -f $(BUILD_PREFIX_1)bitmap.c $(BUILD_PREFIX_1)errors.c
-+      -rm -f $(BUILD_PREFIX_1)ggc-none.c
-+# Delete the temp files made in the course of building libgcc.a.
-+      -rm -f xlimits.h
-+# Delete other built files.
-+      -rm -f xsys-protos.hT
-+      -rm -f specs.h options.h gencheck.h
-+# Delete the stamp and temporary files.
-+      -rm -f s-* tmp-* stamp-* stmp-*
-+      -rm -f */stamp-* */tmp-*
-+# Delete debugging dump files.
-+      -rm -f *.[0-9][0-9].* */*.[0-9][0-9].*
-+# Delete some files made during installation.
-+      -rm -f specs SYSCALLS.c.X SYSCALLS.c
-+      -rm -f collect collect2 mips-tfile mips-tdump
-+# Delete files generated for fixproto
-+      -rm -rf fix-header$(build_exeext) xsys-protos.h deduced.h tmp-deduced.h \
-+        gen-protos$(build_exeext) fixproto.list fixtmp.* fixhdr.ready
-+# Delete files generated for fixincl
-+      -rm -rf fixincl fixinc.sh specs.ready
-+      (cd fixinc && $(MAKE) clean)
-+# Delete unwanted output files from TeX.
-+      -rm -f *.toc *.log *.vr *.fn *.cp *.tp *.ky *.pg
-+      -rm -f */*.toc */*.log */*.vr */*.fn */*.cp */*.tp */*.ky */*.pg
-+# Delete sorted indices we don't actually use.
-+      -rm -f gcc.vrs gcc.kys gcc.tps gcc.pgs gcc.fns
-+# Delete core dumps.
-+      -rm -f core */core
-+# Delete file generated for gengtype.c
-+      -rm -f gtyp-gen.h
-+# Delete files generated by gengtype.c
-+      -rm -f gtype-*
-+      -rm -f gt-*
-+
-+# Delete all files made by compilation
-+# that don't exist in the distribution.
-+INTL_CLEAN = intl.clean
-+clean: mostlyclean $(INTL_CLEAN) lang.clean
-+      -rm -f libgcc.a libgcc_eh.a libgcc_s$(SHLIB_EXT) libgcc_s$(SHLIB_EXT).1
-+      -rm -f config.h tconfig.h hconfig.h tm_p.h
-+      -rm -f cs-*
-+      -rm -rf libgcc
-+      -rm -f *.dvi
-+      -rm -f */*.dvi
-+# Delete the include directory.
-+      -rm -rf include
-+# Delete files used by the "multilib" facility (including libgcc subdirs).
-+      -rm -f multilib.h tmpmultilib*
-+      -if [ "x$(MULTILIB_DIRNAMES)" != x ] ; then \
-+        rm -rf $(MULTILIB_DIRNAMES); \
-+      else if [ "x$(MULTILIB_OPTIONS)" != x ] ; then \
-+        rm -rf `echo $(MULTILIB_OPTIONS) | sed -e 's/\// /g'`; \
-+      fi ; fi
-+      -rm -fr stage1 stage2 stage3 stage4
-+# Delete stamps of bootstrap stages
-+      -rm -f stage?_*
-+      -rm -f clean?_*
-+      -rm -f stage_last
-+
-+# Delete all files that users would normally create
-+# while building and installing GCC.
-+INTL_DISTCLEAN = intl.distclean
-+distclean: clean $(INTL_DISTCLEAN) lang.distclean
-+      -rm -f auto-host.h auto-build.h
-+      -rm -f cstamp-h
-+      -rm -f config.status config.run config.cache config.bak
-+      -rm -f Make-lang Make-hooks Make-host Make-target
-+      -rm -f Makefile *.oaux
-+      -rm -f gthr-default.h
-+      -rm -f */stage1 */stage2 */stage3 */stage4 */include
-+      -rm -f c-parse.output
-+      -rm -f *.asm
-+      -rm -f site.exp site.bak testsuite/site.exp testsuite/site.bak
-+      -rm -f testsuite/*.log testsuite/*.sum
-+      -cd testsuite && rm -f x *.x *.x? *.exe *.rpo *.o *.s *.S *.c
-+      -cd testsuite && rm -f *.out *.gcov *.bb *.bbg
-+      -rm -rf ${QMTEST_DIR} stamp-qmtest
-+      -rm -f intl/libintl.h libintl.h
-+      -rm -f cxxmain.c
-+      -rm -f mklibgcc mkheaders gccbug .gdbinit configargs.h
-+      -rm -f gcov.pod
-+      -rm -f fixinc/Makefile
-+# Delete po/*.gmo only if we are not building in the source directory.
-+      -if [ ! -f po/exgettext ]; then rm -f po/*.gmo; fi
-+      -rmdir ada cp f java objc fixinc intl po testsuite 2>/dev/null
-+
-+# Delete anything likely to be found in the source directory
-+# that shouldn't be in the distribution.
-+extraclean: distclean lang.extraclean
-+      -rm -rf =* ./"#"* *~* config/=* config/"#"* config/*~*
-+      -rm -f patch* *.orig *.rej config/patch* config/*.orig config/*.rej
-+      -rm -f config/*/=* config/*/"#"* config/*/*~*
-+      -rm -f config/*/*.orig config/*/*.rej
-+      -rm -f *.dvi *.ps *.oaux *.d *.[zZ] *.gz
-+      -rm -f *.tar *.xtar *diff *.diff.* *.tar.* *.xtar.* *diffs
-+      -rm -f *lose config/*lose config/*/*lose
-+      -rm -f *.s *.s[0-9] *.i config/ChangeLog
-+      -rm -f y.tab.c yacc.*
-+      -rm -f */=* */"#"* */*~*
-+      -rm -f */patch* */*.orig */*.rej
-+      -rm -f */*.dvi */*.oaux */*.d */*.[zZ] */*.gz
-+      -rm -f */*.tar */*.xtar */*diff */*.diff.* */*.tar.* */*.xtar.* */*diffs
-+      -rm -f */*lose */*.s */*.s[0-9] */*.i
-+
-+# Get rid of every file that's generated from some other file, except for `configure'.
-+# Most of these files ARE PRESENT in the GCC distribution.
-+# We define INTL_DISTCLEAN, INTL_CLEAN & INTL_MOSTLYCLEAN to be empty in the
-+# submake, so that we don't descend into intl after its makefile has been
-+# removed.
-+maintainer-clean:
-+      @echo 'This command is intended for maintainers to use; it'
-+      @echo 'deletes files that may need special tools to rebuild.'
-+      $(MAKE) INTL_DISTCLEAN= INTL_CLEAN= INTL_MOSTLYCLEAN= \
-+              intl.maintainer-clean lang.maintainer-clean distclean
-+      -rm -f c-parse.y c-parse.c c-parse.output TAGS
-+      -rm -f cpp.??s cpp.*aux
-+      -rm -f gcc.??s gcc.*aux
-+      -rm -f $(docdir)/cpp.info* $(docdir)/gcc.info* $(docdir)/gccint.info*
-+      -rm -f $(docdir)/cppinternals.info*
-+      -rm -f $(docdir)/gcov.1 $(docdir)/cpp.1 $(docdir)/gcc.1
-+      -rm -f $(docdir)/fsf-funding.7 $(docdir)/gfdl.7 $(docdir)/gpl.7
-+#\f
-+# Entry points `install' and `uninstall'.
-+# Also use `install-collect2' to install collect2 when the config files don't.
-+
-+# Copy the compiler files into directories where they will be run.
-+# Install the driver last so that the window when things are
-+# broken is small.
-+install: install-common $(INSTALL_HEADERS) $(INSTALL_LIBGCC) \
-+    install-cpp install-man install-info intl.install install-@POSUB@ \
-+    lang.install-normal install-driver
-+
-+# Handle cpp installation.
-+install-cpp: cpp$(exeext)
-+      -if [ -f gcc-cross$(exeext) ] ; then \
-+        rm -f $(DESTDIR)$(bindir)/$(CPP_CROSS_NAME)$(exeext); \
-+        $(INSTALL_PROGRAM) -m 755 cpp$(exeext) $(DESTDIR)$(bindir)/$(CPP_CROSS_NAME)$(exeext); \
-+        if [ x$(cpp_install_dir) != x ]; then \
-+          rm -f $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_CROSS_NAME)$(exeext); \
-+          $(INSTALL_PROGRAM) -m 755 cpp$(exeext) $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_CROSS_NAME)$(exeext); \
-+        else true; fi; \
-+      else \
-+        rm -f $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext); \
-+        $(INSTALL_PROGRAM) -m 755 cpp$(exeext) $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext); \
-+        if [ x$(cpp_install_dir) != x ]; then \
-+          rm -f $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_INSTALL_NAME)$(exeext); \
-+          $(INSTALL_PROGRAM) -m 755 cpp$(exeext) $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_INSTALL_NAME)$(exeext); \
-+        else true; fi; \
-+      fi
-+
-+# Create the installation directories.
-+# $(libdir)/gcc-lib/include isn't currently searched by cpp.
-+installdirs:
-+      $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(libsubdir)
-+      $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(bindir)
-+      $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(includedir)
-+      $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(infodir)
-+      $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(slibdir)
-+      $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(man1dir)
-+      $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(man7dir)
-+
-+# Install the compiler executables built during cross compilation.
-+install-common: native $(EXTRA_PARTS) lang.install-common
-+      for file in $(COMPILERS); do \
-+        if [ -f $$file ] ; then \
-+          rm -f $(DESTDIR)$(libsubdir)/$$file; \
-+          $(INSTALL_PROGRAM) $$file $(DESTDIR)$(libsubdir)/$$file; \
-+        else true; \
-+        fi; \
-+      done
-+      for file in $(EXTRA_PASSES) $(EXTRA_PROGRAMS) $(USE_COLLECT2) ..; do \
-+        if [ x"$$file" != x.. ]; then \
-+          rm -f $(DESTDIR)$(libsubdir)/$$file; \
-+          $(INSTALL_PROGRAM) $$file $(DESTDIR)$(libsubdir)/$$file; \
-+        else true; fi; \
-+      done
-+      for file in $(EXTRA_PARTS) ..; do \
-+        if [ x"$$file" != x.. ]; then \
-+          rm -f $(DESTDIR)$(libsubdir)/$$file; \
-+          $(INSTALL_DATA) $$file $(DESTDIR)$(libsubdir)/$$file; \
-+          chmod a-x $(DESTDIR)$(libsubdir)/$$file; \
-+        else true; fi; \
-+      done
-+# Don't mess with specs if it doesn't exist yet.
-+      -if [ -f specs ] ; then \
-+        rm -f $(DESTDIR)$(libsubdir)/specs; \
-+        $(INSTALL_DATA) specs $(DESTDIR)$(libsubdir)/specs; \
-+        chmod a-x $(DESTDIR)$(libsubdir)/specs; \
-+      fi
-+# Install protoize if it was compiled.
-+      -if [ -f protoize$(exeext) ]; \
-+      then \
-+          if [ -f gcc-cross$(exeext) ] ; then \
-+              rm -f $(DESTDIR)$(bindir)/$(PROTOIZE_CROSS_NAME)$(exeext); \
-+              $(INSTALL_PROGRAM) protoize$(exeext) $(DESTDIR)$(bindir)/$(PROTOIZE_CROSS_NAME)$(exeext); \
-+              rm -f $(DESTDIR)$(bindir)/$(UNPROTOIZE_CROSS_NAME)$(exeext); \
-+              $(INSTALL_PROGRAM) unprotoize$(exeext) $(DESTDIR)$(bindir)/$(UNPROTOIZE_CROSS_NAME)$(exeext); \
-+          else \
-+              rm -f $(DESTDIR)$(bindir)/$(PROTOIZE_INSTALL_NAME)$(exeext); \
-+              $(INSTALL_PROGRAM) protoize$(exeext) $(DESTDIR)$(bindir)/$(PROTOIZE_INSTALL_NAME)$(exeext); \
-+              rm -f $(DESTDIR)$(bindir)/$(UNPROTOIZE_INSTALL_NAME)$(exeext); \
-+              $(INSTALL_PROGRAM) unprotoize$(exeext) $(DESTDIR)$(bindir)/$(UNPROTOIZE_INSTALL_NAME)$(exeext); \
-+          fi ; \
-+          rm -f $(DESTDIR)$(libsubdir)/SYSCALLS.c.X; \
-+          $(INSTALL_DATA) SYSCALLS.c.X $(DESTDIR)$(libsubdir)/SYSCALLS.c.X; \
-+          chmod a-x $(DESTDIR)$(libsubdir)/SYSCALLS.c.X; \
-+      fi
-+# Install gcov if it was compiled.
-+      -if [ -f gcov$(exeext) ]; \
-+      then \
-+          rm -f $(DESTDIR)$(bindir)/gcov$(exeext); \
-+          $(INSTALL_PROGRAM) gcov$(exeext) $(DESTDIR)$(bindir)/$(GCOV_INSTALL_NAME)$(exeext); \
-+      fi
-+      $(INSTALL_SCRIPT) gccbug $(DESTDIR)$(bindir)/$(GCCBUG_INSTALL_NAME)
-+
-+# Install the driver program as $(target_alias)-gcc, 
-+# $(target-alias)-gcc-$(version)
-+# and also as either gcc (if native) or $(gcc_tooldir)/bin/gcc.
-+install-driver: installdirs xgcc$(exeext)
-+      -if [ -f gcc-cross$(exeext) ] ; then \
-+        rm -f $(DESTDIR)$(bindir)/$(GCC_CROSS_NAME)$(exeext); \
-+        $(INSTALL_PROGRAM) gcc-cross$(exeext) $(DESTDIR)$(bindir)/$(GCC_CROSS_NAME)$(exeext); \
-+        rm -f $(DESTDIR)$(bindir)/$(target_alias)-gcc-$(version); \
-+        ( cd $(DESTDIR)$(bindir) && \
-+          $(LN) $(GCC_CROSS_NAME)$(exeext) $(target_alias)-gcc-$(version) ); \
-+        if [ -d $(DESTDIR)$(gcc_tooldir)/bin/. ] ; then \
-+          rm -f $(DESTDIR)$(gcc_tooldir)/bin/gcc$(exeext); \
-+          $(INSTALL_PROGRAM) gcc-cross$(exeext) $(DESTDIR)$(gcc_tooldir)/bin/gcc$(exeext); \
-+        else true; fi; \
-+      else \
-+        rm -f $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext); \
-+        $(INSTALL_PROGRAM) xgcc$(exeext) $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext); \
-+        rm -f $(DESTDIR)$(bindir)/$(target_alias)-gcc-$(version); \
-+        ( cd $(DESTDIR)$(bindir) && \
-+          $(LN) $(GCC_INSTALL_NAME)$(exeext) $(target_alias)-gcc-$(version) ); \
-+        rm -f $(DESTDIR)$(bindir)/$(target_alias)-gcc-tmp$(exeext); \
-+        ( cd $(DESTDIR)$(bindir) && \
-+          $(LN) $(GCC_INSTALL_NAME)$(exeext) $(target_alias)-gcc-tmp$(exeext) && \
-+          mv -f $(target_alias)-gcc-tmp$(exeext) $(GCC_TARGET_INSTALL_NAME)$(exeext) ); \
-+      fi
-+
-+# Install the info files.
-+# $(INSTALL_DATA) might be a relative pathname, so we can't cd into srcdir
-+# to do the install.
-+install-info: doc installdirs lang.install-info
-+      -rm -f $(DESTDIR)$(infodir)/cpp.info* $(DESTDIR)$(infodir)/gcc.info*
-+      -rm -f $(DESTDIR)$(infodir)/cppinternals.info* $(DESTDIR)$(infodir)/gccint.info*
-+      if [ -f $(docdir)/gcc.info ]; then \
-+        for f in $(docdir)/cpp.info* $(docdir)/gcc.info* \
-+              $(docdir)/cppinternals.info* $(docdir)/gccint.info*; do \
-+          realfile=`echo $$f | sed -e 's|.*/\([^/]*\)$$|\1|'`; \
-+          $(INSTALL_DATA) $$f $(DESTDIR)$(infodir)/$$realfile; \
-+        done; \
-+      else true; fi
-+      -if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
-+        if [ -f $(DESTDIR)$(infodir)/dir ] ; then \
-+          for f in cpp.info gcc.info gccint.info cppinternals.info; do \
-+              if [ -f $(DESTDIR)$(infodir)/$$f ]; then \
-+                install-info --dir-file=$(DESTDIR)$(infodir)/dir $(DESTDIR)$(infodir)/$$f; \
-+              else true; fi; \
-+          done; \
-+        else true; fi; \
-+      else true; fi;
-+      -chmod a-x $(DESTDIR)$(infodir)/cpp.info* $(DESTDIR)$(infodir)/gcc.info*
-+      -chmod a-x $(DESTDIR)$(infodir)/cppinternals.info* $(DESTDIR)$(infodir)/gccint.info*
-+
-+# Install the man pages.
-+install-man: installdirs $(GENERATED_MANPAGES) lang.install-man
-+      -if [ -f gcc-cross$(exeext) ] ; then \
-+        rm -f $(DESTDIR)$(man1dir)/$(GCC_CROSS_NAME)$(man1ext); \
-+        $(INSTALL_DATA) $(docdir)/gcc.1 $(DESTDIR)$(man1dir)/$(GCC_CROSS_NAME)$(man1ext); \
-+        chmod a-x $(DESTDIR)$(man1dir)/$(GCC_CROSS_NAME)$(man1ext); \
-+      else \
-+        rm -f $(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext); \
-+        $(INSTALL_DATA) $(docdir)/gcc.1 $(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext); \
-+        chmod a-x $(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext); \
-+      fi
-+      -rm -f $(DESTDIR)$(man1dir)/cpp$(man1ext)
-+      -$(INSTALL_DATA) $(docdir)/cpp.1 $(DESTDIR)$(man1dir)/cpp$(man1ext)
-+      -chmod a-x $(DESTDIR)$(man1dir)/cpp$(man1ext)
-+      -rm -f $(DESTDIR)$(man1dir)/gcov$(man1ext)
-+      -$(INSTALL_DATA) $(docdir)/gcov.1 $(DESTDIR)$(man1dir)/gcov$(man1ext)
-+      -chmod a-x $(DESTDIR)$(man1dir)/gcov$(man1ext)
-+      -rm -f $(DESTDIR)$(man7dir)/fsf-funding$(man7ext)
-+      -$(INSTALL_DATA) $(docdir)/fsf-funding.7 $(DESTDIR)$(man7dir)/fsf-funding$(man7ext)
-+      -chmod a-x $(DESTDIR)$(man7dir)/fsf-funding$(man7ext)
-+      -rm -f $(DESTDIR)$(man7dir)/gfdl$(man7ext)
-+      -$(INSTALL_DATA) $(docdir)/gfdl.7 $(DESTDIR)$(man7dir)/gfdl$(man7ext)
-+      -chmod a-x $(DESTDIR)$(man7dir)/gfdl$(man7ext)
-+      -rm -f $(DESTDIR)$(man7dir)/gpl$(man7ext)
-+      -$(INSTALL_DATA) $(docdir)/gpl.7 $(DESTDIR)$(man7dir)/gpl$(man7ext)
-+      -chmod a-x $(DESTDIR)$(man7dir)/gpl$(man7ext)
-+
-+# Install the library.
-+install-libgcc: libgcc.mk libgcc.a installdirs
-+      if $(RANLIB_TEST_FOR_TARGET); then \
-+        r_f_t=$(RANLIB_FOR_TARGET); \
-+      else \
-+        r_f_t=: ; \
-+      fi; \
-+      $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
-+        BUILD_PREFIX="$(BUILD_PREFIX)" BUILD_PREFIX_1="$(BUILD_PREFIX_1)" \
-+        AR_FOR_TARGET="$(AR_FOR_TARGET)" \
-+        AR_CREATE_FOR_TARGET="$(AR_CREATE_FOR_TARGET)" \
-+        AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
-+        CFLAGS="$(CFLAGS) $(WARN_CFLAGS)" \
-+        RANLIB_TEST_FOR_TARGET="$(RANLIB_TEST_FOR_TARGET)" \
-+        NM_FOR_TARGET="$(NM_FOR_TARGET)" AWK="$(AWK)" \
-+        LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS)" \
-+        INCLUDES="$(INCLUDES)" \
-+        CONFIG_H="$(TCONFIG_H)" MACHMODE_H="$(MACHMODE_H)" \
-+        LIB1ASMSRC='$(LIB1ASMSRC)' \
-+        MAKEOVERRIDES= \
-+        INSTALL_DATA="$(INSTALL_DATA)" \
-+        RANLIB_FOR_TARGET="$$r_f_t" \
-+        DESTDIR="$(DESTDIR)" \
-+        libsubdir="$(libsubdir)" \
-+        slibdir="$(slibdir)" \
-+        -f libgcc.mk install
-+
-+# Install multiple versions of libgcc.a.
-+install-multilib: stmp-multilib installdirs
-+      if $(RANLIB_TEST_FOR_TARGET); then \
-+        r_f_t=$(RANLIB_FOR_TARGET); \
-+      else \
-+        r_f_t=: ; \
-+      fi; \
-+      $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
-+        BUILD_PREFIX="$(BUILD_PREFIX)" BUILD_PREFIX_1="$(BUILD_PREFIX_1)" \
-+        AR_FOR_TARGET="$(AR_FOR_TARGET)" \
-+        AR_CREATE_FOR_TARGET="$(AR_CREATE_FOR_TARGET)" \
-+        AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
-+        CFLAGS="$(CFLAGS) $(WARN_CFLAGS)" \
-+        RANLIB_TEST_FOR_TARGET="$(RANLIB_TEST_FOR_TARGET)" \
-+        NM_FOR_TARGET="$(NM_FOR_TARGET)" AWK="$(AWK)" \
-+        LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS)" \
-+        INCLUDES="$(INCLUDES)" \
-+        CONFIG_H="$(CONFIG_H)" MACHMODE_H="$(MACHMODE_H)" \
-+        LIB1ASMSRC='$(LIB1ASMSRC)' \
-+        MAKEOVERRIDES= \
-+        INSTALL_DATA="$(INSTALL_DATA)" \
-+        RANLIB_FOR_TARGET="$$r_f_t" \
-+        DESTDIR="$(DESTDIR)" \
-+        libsubdir="$(libsubdir)" \
-+        slibdir="$(slibdir)" \
-+        -f libgcc.mk install
-+
-+# Install all the header files built in the include subdirectory.
-+install-headers: $(INSTALL_HEADERS_DIR)
-+# Fix symlinks to absolute paths in the installed include directory to
-+# point to the installed directory, not the build directory.
-+# Don't need to use LN_S here since we really do need ln -s and no substitutes.
-+      -files=`cd $(DESTDIR)$(libsubdir)/include; find . -type l -print 2>/dev/null`; \
-+      if [ $$? -eq 0 ]; then \
-+        dir=`cd include; ${PWD_COMMAND}`; \
-+        for i in $$files; do \
-+          dest=`ls -ld $(DESTDIR)$(libsubdir)/include/$$i | sed -n 's/.*-> //p'`; \
-+          if expr "$$dest" : "$$dir.*" > /dev/null; then \
-+            rm -f $(DESTDIR)$(libsubdir)/include/$$i; \
-+            ln -s `echo $$i | sed "s|/[^/]*|/..|g" | sed 's|/..$$||'``echo "$$dest" | sed "s|$$dir||"` $(DESTDIR)$(libsubdir)/include/$$i; \
-+          fi; \
-+        done; \
-+      fi
-+
-+# Create or recreate the gcc private include file directory.
-+install-include-dir: installdirs
-+      -rm -rf $(DESTDIR)$(libsubdir)/include
-+      mkdir $(DESTDIR)$(libsubdir)/include
-+      -chmod a+rx $(DESTDIR)$(libsubdir)/include
-+
-+# Install the include directory using tar.
-+install-headers-tar: stmp-int-hdrs $(STMP_FIXPROTO) install-include-dir
-+# We use `pwd`/include instead of just include to problems with CDPATH
-+# Unless a full pathname is provided, some shells would print the new CWD,
-+# found in CDPATH, corrupting the output.  We could just redirect the
-+# output of `cd', but some shells lose on redirection within `()'s
-+      (cd `${PWD_COMMAND}`/include ; \
-+       tar -cf - .; exit 0) | (cd $(DESTDIR)$(libsubdir)/include; tar xpf - )
-+# /bin/sh on some systems returns the status of the first tar,
-+# and that can lose with GNU tar which always writes a full block.
-+# So use `exit 0' to ignore its exit status.
-+
-+# Install the include directory using cpio.
-+install-headers-cpio: stmp-int-hdrs $(STMP_FIXPROTO) install-include-dir
-+# See discussion about the use of `pwd` above
-+      cd `${PWD_COMMAND}`/include ; \
-+      find . -print | cpio -pdum $(DESTDIR)$(libsubdir)/include
-+
-+# Install the include directory using cp.
-+install-headers-cp: stmp-int-hdrs $(STMP_FIXPROTO) install-include-dir
-+      cp -p -r include $(DESTDIR)$(libsubdir)
-+
-+itoolsdir = $(libsubdir)/install-tools
-+# Don't install the headers.  Instead, install appropriate scripts
-+# and supporting files for fixincludes to be run later.
-+install-mkheaders: stmp-int-hdrs $(STMP_FIXPROTO) install-include-dir \
-+    mkheaders xlimits.h
-+      -rm -rf $(DESTDIR)$(itoolsdir)
-+      $(SHELL) $(srcdir)/mkinstalldirs $(DESTDIR)$(itoolsdir)/include
-+      for file in $(USER_H); do \
-+        realfile=`echo $$file | sed -e 's|.*/\([^/]*\)$$|\1|'`; \
-+        $(INSTALL_DATA) $$file \
-+          $(DESTDIR)$(itoolsdir)/include/$$realfile ; \
-+      done
-+      $(INSTALL_DATA) xlimits.h $(DESTDIR)$(itoolsdir)/include/limits.h
-+      if [ x$(STMP_FIXINC) != x ] ; then \
-+        $(INSTALL_DATA) $(srcdir)/README-fixinc \
-+          $(DESTDIR)$(itoolsdir)/include/README ; \
-+        $(INSTALL_PROGRAM) fixinc.sh $(DESTDIR)$(itoolsdir)/fixinc.sh ; \
-+        $(INSTALL_PROGRAM) fixinc/fixincl $(DESTDIR)$(itoolsdir)/fixincl ; \
-+        $(INSTALL_DATA) $(srcdir)/gsyslimits.h $(DESTDIR)$(itoolsdir)/gsyslimits.h ; \
-+      else :; fi
-+      if [ x$(STMP_FIXPROTO) != x ] ; then \
-+        $(INSTALL_PROGRAM) $(srcdir)/mkinstalldirs \
-+              $(DESTDIR)$(itoolsdir)/mkinstalldirs ; \
-+        $(INSTALL_PROGRAM) $(srcdir)/fixproto $(DESTDIR)$(itoolsdir)/fixproto ; \
-+        $(INSTALL_PROGRAM) fix-header$(build_exeext) \
-+              $(DESTDIR)$(itoolsdir)/fix-header$(build_exeext) ; \
-+      else :; fi
-+      $(INSTALL_PROGRAM) mkheaders $(DESTDIR)$(itoolsdir)/mkheaders
-+      echo 'SYSTEM_HEADER_DIR="$(SYSTEM_HEADER_DIR)"' \
-+              > $(DESTDIR)$(itoolsdir)/mkheaders.conf
-+      echo 'OTHER_FIXINCLUDES_DIRS="$(OTHER_FIXINCLUDES_DIRS)"' \
-+              >> $(DESTDIR)$(itoolsdir)/mkheaders.conf
-+      echo 'FIXPROTO_DEFINES="$(FIXPROTO_DEFINES)"' \
-+              >> $(DESTDIR)$(itoolsdir)/mkheaders.conf
-+      echo 'STMP_FIXPROTO="$(STMP_FIXPROTO)"' >> $(DESTDIR)$(itoolsdir)/mkheaders.conf
-+      echo 'STMP_FIXINC="$(STMP_FIXINC)"' >> $(DESTDIR)$(itoolsdir)/mkheaders.conf
-+
-+# Use this target to install the program `collect2' under the name `collect2'.
-+install-collect2: collect2 installdirs
-+      $(INSTALL_PROGRAM) collect2$(exeext) $(DESTDIR)$(libsubdir)/collect2$(exeext)
-+# Install the driver program as $(libsubdir)/gcc for collect2.
-+      $(INSTALL_PROGRAM) xgcc$(exeext) $(DESTDIR)$(libsubdir)/gcc$(exeext)
-+
-+# Cancel installation by deleting the installed files.
-+uninstall: intl.uninstall lang.uninstall
-+      -rm -rf $(DESTDIR)$(libsubdir)
-+      -rm -rf $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext)
-+      -rm -rf $(DESTDIR)$(bindir)/$(GCC_CROSS_NAME)$(exeext)
-+      -rm -f $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext)
-+      -rm -f $(DESTDIR)$(bindir)/$(CPP_CROSS_NAME)$(exeext)
-+      -if [ x$(cpp_install_dir) != x ]; then \
-+        rm -f $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_INSTALL_NAME)$(exeext); \
-+        rm -f $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_CROSS_NAME)$(exeext); \
-+      else true; fi
-+      -rm -rf $(DESTDIR)$(bindir)/$(PROTOIZE_INSTALL_NAME)$(exeext)
-+      -rm -rf $(DESTDIR)$(bindir)/$(PROTOIZE_CROSS_NAME)$(exeext)
-+      -rm -rf $(DESTDIR)$(bindir)/$(UNPROTOIZE_INSTALL_NAME)$(exeext)
-+      -rm -rf $(DESTDIR)$(bindir)/$(UNPROTOIZE_CROSS_NAME)$(exeext)
-+      -rm -rf $(DESTDIR)$(bindir)/$(GCOV_INSTALL_NAME)$(exeext)
-+      -rm -rf $(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext)
-+      -rm -rf $(DESTDIR)$(man1dir)/$(GCC_CROSS_NAME)$(man1ext)
-+      -rm -rf $(DESTDIR)$(man1dir)/cpp$(man1ext)
-+      -rm -rf $(DESTDIR)$(man1dir)/protoize$(man1ext)
-+      -rm -rf $(DESTDIR)$(man1dir)/unprotoize$(man1ext)
-+      -rm -f $(DESTDIR)$(infodir)/cpp.info* $(DESTDIR)$(infodir)/gcc.info*
-+      -rm -f $(DESTDIR)$(infodir)/cppinternals.info* $(DESTDIR)$(infodir)/gccint.info*
-+#\f
-+# These targets are for the dejagnu testsuites. The file site.exp
-+# contains global variables that all the testsuites will use.
-+
-+# Set to $(target_alias)/ for cross.
-+target_subdir = @target_subdir@
-+
-+site.exp: ./config.status Makefile
-+      @echo "Making a new config file..."
-+      -@rm -f ./tmp?
-+      @$(STAMP) site.exp
-+      -@mv site.exp site.bak
-+      @echo "## these variables are automatically generated by make ##" > ./tmp0
-+      @echo "# Do not edit here. If you wish to override these values" >> ./tmp0
-+      @echo "# add them to the last section" >> ./tmp0
-+      @echo "set rootme \"`${PWD_COMMAND}`\"" >> ./tmp0
-+      @echo "set srcdir \"`cd ${srcdir}; ${PWD_COMMAND}`\"" >> ./tmp0
-+      @echo "set host_triplet $(host_canonical)" >> ./tmp0
-+      @echo "set build_triplet $(build_canonical)" >> ./tmp0
-+      @echo "set target_triplet $(target)" >> ./tmp0
-+      @echo "set target_alias $(target_alias)" >> ./tmp0
-+# CFLAGS is set even though it's empty to show we reserve the right to set it.
-+      @echo "set CFLAGS \"\"" >> ./tmp0
-+      @echo "set CXXFLAGS \"-I$(objdir)/../$(target_subdir)libio -I\$$srcdir/../libg++/src -I\$$srcdir/../libio -I\$$srcdir/../libstdc++ -I\$$srcdir/../libstdc++/stl -L$(objdir)/../$(target_subdir)libg++ -L$(objdir)/../$(target_subdir)libstdc++\"" >> ./tmp0
-+      @echo "set TESTING_IN_BUILD_TREE 1" >> ./tmp0
-+      @echo "set HAVE_LIBSTDCXX_V3 1" >> ./tmp0
-+# If newlib has been configured, we need to pass -B to gcc so it can find
-+# newlib's crt0.o if it exists.  This will cause a "path prefix not used"
-+# message if it doesn't, but the testsuite is supposed to ignore the message -
-+# it's too difficult to tell when to and when not to pass -B (not all targets
-+# have crt0's).  We could only add the -B if ../newlib/crt0.o exists, but that
-+# seems like too selective a test.
-+# ??? Another way to solve this might be to rely on linker scripts.  Then
-+# theoretically the -B won't be needed.
-+# We also need to pass -L ../ld so that the linker can find ldscripts.
-+      @if [ -d $(objdir)/../$(target_subdir)newlib ] ; then \
-+        echo "set newlib_cflags \"-I$(objdir)/../$(target_subdir)newlib/targ-include -I\$$srcdir/../newlib/libc/include\"" >> ./tmp0; \
-+        echo "set newlib_ldflags \"-B$(objdir)/../$(target_subdir)newlib/\"" >> ./tmp0; \
-+        echo "append CFLAGS \" \$$newlib_cflags\"" >> ./tmp0; \
-+        echo "append CXXFLAGS \" \$$newlib_cflags\"" >> ./tmp0; \
-+        echo "append LDFLAGS \" \$$newlib_ldflags\"" >> ./tmp0; \
-+      else true; \
-+      fi
-+      @if [ -d $(objdir)/../ld ] ; then \
-+        echo "append LDFLAGS \" -L$(objdir)/../ld\"" >> ./tmp0; \
-+      else true; \
-+      fi
-+      echo "set tmpdir $(objdir)/testsuite" >> ./tmp0
-+      @echo "set srcdir \"\$${srcdir}/testsuite\"" >> ./tmp0
-+      @if [ "X$(ALT_CXX_UNDER_TEST)" != "X" ] ; then \
-+        echo "set ALT_CXX_UNDER_TEST $(ALT_CXX_UNDER_TEST)" >> ./tmp0; \
-+      else true; \
-+      fi
-+      @if [ "X$(COMPAT_OPTIONS)" != "X" ] ; then \
-+        echo "set COMPAT_OPTIONS $(COMPAT_OPTIONS)" >> ./tmp0; \
-+      else true; \
-+      fi
-+      @echo "## All variables above are generated by configure. Do Not Edit ##" >> ./tmp0
-+      @cat ./tmp0 > site.exp
-+      @cat site.bak | sed \
-+              -e '1,/^## All variables above are.*##/ d' >> site.exp
-+      -@rm -f ./tmp?
-+
-+CHECK_TARGETS = check-gcc @check_languages@
-+
-+check-c++ : check-g++
-+check-f77 : check-g77
-+check-java :
-+
-+check: $(CHECK_TARGETS)
-+
-+# The idea is to parallelize testing of multilibs, for example:
-+#   make -j3 check-gcc//sh-hms-sim/{-m1,-m2,-m3,-m3e,-m4}/{,-nofpu}
-+# will run 3 concurrent sessions of check-gcc, eventually testing
-+# all 10 combinations.  GNU make is required, as is a shell that expands
-+# alternations within braces.
-+check-gcc//% check-g++//% check-g77//% check-objc//%: site.exp
-+      target=`echo "$@" | sed 's,//.*,,'`; \
-+      variant=`echo "$@" | sed 's,^[^/]*//,,'`; \
-+      vardots=`echo "$$variant" | sed 's,/,.,g'`; \
-+      $(MAKE) TESTSUITEDIR="testsuite.$$vardots" \
-+        RUNTESTFLAGS="--target_board=$$variant $(RUNTESTFLAGS)" \
-+        "$$target"
-+
-+TESTSUITEDIR = testsuite
-+
-+$(TESTSUITEDIR)/site.exp: site.exp
-+      test -d $(TESTSUITEDIR) || mkdir $(TESTSUITEDIR)
-+      -rm -f $@
-+      sed '/set tmpdir/ s|testsuite|$(TESTSUITEDIR)|' < site.exp > $@
-+
-+check-g++: $(TESTSUITEDIR)/site.exp
-+      -(rootme=`${PWD_COMMAND}`; export rootme; \
-+      srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
-+      cd $(TESTSUITEDIR); \
-+      EXPECT=${EXPECT} ; export EXPECT ; \
-+      if [ -f $${rootme}/../expect/expect ] ; then  \
-+         TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
-+          export TCL_LIBRARY ; fi ; \
-+      $(RUNTEST) --tool g++ $(RUNTESTFLAGS))
-+
-+check-gcc: $(TESTSUITEDIR)/site.exp
-+      -(rootme=`${PWD_COMMAND}`; export rootme; \
-+      srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
-+      cd $(TESTSUITEDIR); \
-+      EXPECT=${EXPECT} ; export EXPECT ; \
-+      if [ -f $${rootme}/../expect/expect ] ; then  \
-+         TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
-+         export TCL_LIBRARY ; fi ; \
-+      $(RUNTEST) --tool gcc $(RUNTESTFLAGS))
-+
-+check-g77: $(TESTSUITEDIR)/site.exp
-+      -(rootme=`${PWD_COMMAND}`; export rootme; \
-+      srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
-+      cd $(TESTSUITEDIR); \
-+      EXPECT=${EXPECT} ; export EXPECT ; \
-+      if [ -f $${rootme}/../expect/expect ] ; then  \
-+         TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
-+         export TCL_LIBRARY ; fi ; \
-+      $(RUNTEST) --tool g77 $(RUNTESTFLAGS))
-+
-+check-objc: $(TESTSUITEDIR)/site.exp
-+      -(rootme=`${PWD_COMMAND}`; export rootme; \
-+      srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
-+      cd $(TESTSUITEDIR); \
-+      EXPECT=${EXPECT} ; export EXPECT ; \
-+      if [ -f $${rootme}/../expect/expect ] ; then  \
-+         TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
-+          export TCL_LIBRARY ; fi ; \
-+      $(RUNTEST) --tool objc $(RUNTESTFLAGS))
-+
-+check-consistency: testsuite/site.exp
-+      -rootme=`${PWD_COMMAND}`; export rootme; \
-+      srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
-+      cd testsuite; \
-+      EXPECT=${EXPECT} ; export EXPECT ; \
-+      if [ -f $${rootme}/../expect/expect ] ; then  \
-+         TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
-+         export TCL_LIBRARY ; fi ; \
-+      $(RUNTEST) --tool consistency $(RUNTESTFLAGS)
-+
-+# QMTest targets
-+
-+# The path to qmtest.
-+QMTEST_PATH=qmtest
-+
-+# The flags to pass to qmtest.
-+QMTESTFLAGS=
-+
-+# The flags to pass to "qmtest run".
-+QMTESTRUNFLAGS=
-+
-+# The command to use to invoke qmtest.
-+QMTEST=${QMTEST_PATH} ${QMTESTFLAGS}
-+
-+# The tests (or suites) to run.
-+QMTEST_GPP_TESTS=gpp
-+
-+# The subdirectory of the OBJDIR that will be used to store the QMTest
-+# test database configuration and that will be used for temporary
-+# scratch space during QMTest's execution.
-+QMTEST_DIR=qmtestsuite
-+
-+# Create the QMTest database configuration.
-+${QMTEST_DIR} stamp-qmtest:
-+      debug_options=""; \
-+          ${STAMP} empty.C; \
-+          for option in \
-+              -gdwarf-2 -gstabs -gstabs+ -gxcoff -gxcoff+ -gcoff; do \
-+              (./cc1plus -q $${option} empty.C 2>&1 | \
-+                   grep "unknown or unsupported -g option" > /dev/null) || \
-+              debug_options="$${debug_options}$${option} "; done; \
-+          ${QMTEST} -D ${QMTEST_DIR} create-tdb \
-+              -c gcc_database.GCCDatabase \
-+              -a GCCDatabase.testsuite_root=`cd ${srcdir}/testsuite && pwd` \
-+              -a GCCDatabase.debug_options="$${debug_options}"
-+      rm -f empty.C empty.s
-+      $(STAMP) stamp-qmtest
-+
-+# Create the QMTest context file.
-+${QMTEST_DIR}/context: stamp-qmtest
-+      echo "GCCTest.flags=-B${objdir}" >> $@
-+      echo "GCCTest.objdir=${objdir}/.." >> $@
-+      echo "GCCTest.host=${host_canonical}" >> $@
-+      echo "GCCTest.target=${target}" >> $@
-+      echo "GCCTest.gcov=${objdir}/gcov" >> $@
-+      echo "GPPTest.gpp=${objdir}/g++" >> $@
-+      echo "DGTest.demangler=${objdir}/c++filt" >> $@
-+
-+# Run the G++ testsuite using QMTest.
-+qmtest-g++: ${QMTEST_DIR}/context ${QMTEST_DIR}/gpp-expected.qmr
-+      cd ${QMTEST_DIR} && ${QMTEST} run ${QMTESTRUNFLAGS} -C context \
-+         -o gpp.qmr -O gpp-expected.qmr \
-+         ${QMTEST_GPP_TESTS}
-+
-+# Use the QMTest GUI.
-+qmtest-gui: ${QMTEST_DIR}/context
-+      cd ${QMTEST_DIR} && ${QMTEST} gui -C context
-+
-+# Build the set of expected G++ failures.
-+${QMTEST_DIR}/gpp-expected.qmr: ${QMTEST_DIR}/context
-+      echo "Determining expected results..."
-+      cd ${QMTEST_DIR} && ${QMTEST} run ${QMTESTRUNFLAGS} -C context \
-+           -c "GCCTest.generate_xfails=1" -o gpp-expected.qmr \
-+         ${QMTEST_GPP_TESTS} \
-+         > /dev/null
-+
-+.PHONY: qmtest-g++
-+
-+# Run Paranoia on real.c.
-+
-+paranoia.o: $(srcdir)/../contrib/paranoia.cc $(CONFIG_H) $(SYSTEM_H) \
-+  real.h $(TREE_H)
-+      g++ -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-+
-+paranoia: paranoia.o real.o $(LIBIBERTY)
-+      g++ -o $@ paranoia.o real.o $(LIBIBERTY)
-+
-+# These exist for maintenance purposes.
-+
-+# Update the tags table.
-+TAGS: force
-+      (cd $(srcdir);                                                  \
-+      mkdir tmp-tags;                                                 \
-+      mv -f c-parse.[ch] =*.[chy] tmp-tags;                           \
-+      etags *.y *.h *.c;                                              \
-+      mv tmp-tags/* .;                                                \
-+      rmdir tmp-tags)
-+
-+# A list of files to be destroyed during "lean" builds.
-+VOL_FILES=`echo $(BACKEND) $(OBJS) $(C_OBJS) $(LIBCPP_OBJS) *.c *.h gen*`
-+
-+# Flags to pass to stage2 and later recursive makes.  Note that the
-+# WARN_CFLAGS setting can't be to the expansion of GCC_WARN_CFLAGS in
-+# the context of the stage_x rule.
-+STAGE2_FLAGS_TO_PASS = \
-+      ADAC="\$$(CC)" \
-+      AR_FOR_TARGET="$(AR_FOR_TARGET)" \
-+      RANLIB_FOR_TARGET="$(RANLIB_FOR_TARGET)" \
-+      CFLAGS="$(BOOT_CFLAGS)" \
-+      LDFLAGS="$(BOOT_LDFLAGS)" \
-+      WARN_CFLAGS="\$$(GCC_WARN_CFLAGS)" \
-+      STRICT_WARN="$(STRICT2_WARN)" \
-+      libdir=$(libdir) \
-+      LANGUAGES="$(LANGUAGES)" \
-+      MAKEOVERRIDES= \
-+      OUTPUT_OPTION="-o \$$@"
-+
-+# Only build the C compiler for stage1, because that is the only one that
-+# we can guarantee will build with the native compiler, and also it is the
-+# only thing useful for building stage2. STAGE1_CFLAGS (via CFLAGS),
-+# MAKEINFO and MAKEINFOFLAGS are explicitly passed here to make them
-+# overrideable (for a bootstrap build stage1 also builds gcc.info).
-+stage1_build:
-+      $(MAKE) AR_FOR_TARGET="$(AR_FOR_TARGET)" \
-+              RANLIB_FOR_TARGET="$(RANLIB_FOR_TARGET)" \
-+              CC="$(CC)" libdir=$(libdir) LANGUAGES="$(BOOT_LANGUAGES)" \
-+              CFLAGS="$(STAGE1_CFLAGS)" MAKEINFO="$(MAKEINFO)" \
-+              MAKEINFOFLAGS="$(MAKEINFOFLAGS)" COVERAGE_FLAGS=
-+      $(STAMP) stage1_build
-+      echo stage1_build > stage_last
-+
-+stage1_copy: stage1_build
-+      $(MAKE) stage1
-+      $(STAMP) stage1_copy
-+      echo stage2_build > stage_last
-+
-+stage2_build: stage1_copy
-+      $(MAKE) CC="$(STAGE_CC_WRAPPER) stage1/xgcc$(exeext) -Bstage1/ -B$(build_tooldir)/bin/" \
-+               STAGE_PREFIX=stage1/ \
-+               $(STAGE2_FLAGS_TO_PASS)
-+      $(STAMP) stage2_build
-+      echo stage2_build > stage_last
-+
-+stage2_copy: stage2_build
-+      $(MAKE) stage2
-+      $(STAMP) stage2_copy
-+      echo stage3_build > stage_last
-+
-+stage3_build: stage2_copy
-+      $(MAKE) CC="$(STAGE_CC_WRAPPER) stage2/xgcc$(exeext) -Bstage2/ -B$(build_tooldir)/bin/" \
-+               STAGE_PREFIX=stage2/ \
-+               $(STAGE2_FLAGS_TO_PASS)
-+      $(STAMP) stage3_build
-+      echo stage3_build > stage_last
-+
-+# For bootstrap4:
-+stage3_copy: stage3_build
-+      $(MAKE) stage3
-+      $(STAMP) stage3_copy
-+      echo stage4_build > stage_last
-+
-+stage4_build: stage3_copy
-+      $(MAKE) CC="$(STAGE_CC_WRAPPER) stage3/xgcc$(exeext) -Bstage3/ -B$(build_tooldir)/bin/" \
-+               STAGE_PREFIX=stage3/ \
-+               $(STAGE2_FLAGS_TO_PASS)
-+      $(STAMP) stage4_build
-+      echo stage4_build > stage_last
-+
-+# Additional steps for *-lean targets:
-+clean_s1: stage1_copy
-+      -(cd stage1 && rm -f $(VOL_FILES))
-+      $(STAMP) clean_s1
-+
-+clean_s2: stage2_copy
-+      -rm -rf stage1
-+      $(STAMP) clean_s2
-+
-+# The various entry points for bootstrapping.
-+
-+bootstrap: stage3_build
-+      @echo
-+      @echo Bootstrap complete - make \"quickstrap\" to redo last build,
-+      @echo \"restage1\" through \"restage3\" to rebuild specific stages,
-+      @echo \"restrap\" to redo the bootstrap from stage1, or
-+      @echo \"cleanstrap\" to redo the bootstrap from scratch.
-+
-+bootstrap-lean : clean_s1 clean_s2 stage3_build
-+      @echo
-+      @echo Bootstrap complete - make \"quickstrap\" to redo last build,
-+      @echo or \"cleanstrap\" to redo the bootstrap from scratch.
-+
-+bootstrap2: bootstrap
-+
-+bootstrap2-lean : bootstrap-lean
-+
-+bootstrap3 bootstrap3-lean: bootstrap
-+
-+bootstrap4 bootstrap4-lean: stage4_build
-+
-+unstage1 unstage2 unstage3 unstage4:
-+      -set -vx; stage=`echo $@ | sed -e 's/un//'`; \
-+      rm -f $$stage/as$(exeext); \
-+      rm -f $$stage/ld$(exeext); \
-+      rm -f $$stage/collect-ld$(exeext); \
-+      if test -d $$stage; then \
-+        mv $$stage/* . 2>/dev/null; \
-+        for i in `cd $$stage; echo *` ; do \
-+          if test -d $$stage/$$i; then \
-+            mv $$stage/$$i/* $$i/. 2>/dev/null; \
-+          else \
-+            mv $$stage/$$i .; \
-+          fi; \
-+        done \
-+      fi ; \
-+      rm -f $${stage}_build $${stage}_copy ;\
-+      echo $${stage}_build > stage_last
-+
-+restage1: unstage1
-+      $(MAKE) stage1_build
-+
-+restage2: unstage2
-+      $(MAKE) LANGUAGES="$(LANGUAGES)" stage2_build
-+
-+restage3: unstage3
-+      $(MAKE) LANGUAGES="$(LANGUAGES)" stage3_build
-+
-+restage4: unstage4
-+      $(MAKE) LANGUAGES="$(LANGUAGES)" stage4_build
-+
-+bubblestrap:
-+      if test -f stage3_build; then true; else \
-+        echo; echo You must \"make bootstrap\" first.; \
-+        exit 1; \
-+      fi
-+      for i in stage3 \
-+              unstage1 stage1_build stage1_copy \
-+              unstage2 stage2_build stage2_copy \
-+              unstage3 stage3_build ; \
-+      do \
-+        $(MAKE) LANGUAGES="$(LANGUAGES)" $$i || exit 1 ; \
-+      done
-+
-+quickstrap:
-+      if test -f stage_last ; then \
-+        LAST=`cat stage_last`; rm $$LAST; $(MAKE) LANGUAGES="$(LANGUAGES)" $$LAST; \
-+      else \
-+        $(MAKE) stage1_build; \
-+      fi
-+
-+cleanstrap:
-+      -$(MAKE) clean
-+      $(MAKE) LANGUAGES="$(LANGUAGES)" bootstrap
-+
-+unstrap:
-+      -rm -rf stage[234]*
-+      $(MAKE) unstage1
-+
-+# Differs from cleanstrap in that it starts from the earlier stage1 build,
-+# not from scratch.
-+restrap:
-+      $(MAKE) unstrap
-+      $(MAKE) LANGUAGES="$(LANGUAGES)" bootstrap
-+
-+# Compare the object files in the current directory with those in the
-+# stage2 directory.
-+
-+# ./ avoids bug in some versions of tail.
-+compare compare3 compare4 compare-lean compare3-lean compare4-lean: force
-+      -rm -f .bad_compare
-+      case "$@" in compare | compare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^compare\([0-9][0-9]*\).*,\1,'` ;; esac; \
-+      for file in *$(objext); do \
-+        tail +16c ./$$file > tmp-foo1; \
-+        tail +16c stage$$stage/$$file > tmp-foo2 \
-+          && (cmp tmp-foo1 tmp-foo2 > /dev/null 2>&1 || echo $$file differs >> .bad_compare) || true; \
-+      done
-+      case "$@" in compare | compare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^compare\([0-9][0-9]*\).*,\1,'` ;; esac; \
-+      for dir in tmp-foo intl $(SUBDIRS); do \
-+        if [ "`echo $$dir/*$(objext)`" != "$$dir/*$(objext)" ] ; then \
-+          for file in $$dir/*$(objext); do \
-+            tail +16c ./$$file > tmp-foo1; \
-+            tail +16c stage$$stage/$$file > tmp-foo2 \
-+              && (cmp tmp-foo1 tmp-foo2 > /dev/null 2>&1 || echo $$file differs >> .bad_compare) || true; \
-+          done; \
-+        else true; fi; \
-+      done
-+      -rm -f tmp-foo*
-+      case "$@" in compare | compare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^compare\([0-9][0-9]*\).*,\1,'` ;; esac; \
-+      if [ -f .bad_compare ]; then \
-+        echo "Bootstrap comparison failure!"; \
-+        cat .bad_compare; \
-+        exit 1; \
-+      else \
-+        case "$@" in \
-+          *-lean ) rm -rf stage$$stage ;; \
-+          *) ;; \
-+        esac; true; \
-+      fi
-+
-+# Compare the object files in the current directory with those in the
-+# stage2 directory.  Use gnu cmp (diffutils v2.4 or later) to avoid
-+# running tail and the overhead of twice copying each object file.
-+# An exit status of 1 is precisely the result we're looking for (other
-+# values mean other problems).
-+gnucompare gnucompare3 gnucompare4 gnucompare-lean gnucompare3-lean gnucompare4-lean: force
-+      -rm -f .bad_compare
-+      case "$@" in gnucompare | gnucompare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^gnucompare\([0-9][0-9]*\).*,\1,'` ;; esac; \
-+      for file in *$(objext); do \
-+        cmp --ignore-initial=16 $$file stage$$stage/$$file > /dev/null 2>&1; \
-+        test $$? -eq 1 && echo $$file differs >> .bad_compare || true; \
-+      done
-+      case "$@" in gnucompare | gnucompare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^gnucompare\([0-9][0-9]*\).*,\1,'` ;; esac; \
-+      for dir in tmp-foo intl $(SUBDIRS); do \
-+        if [ "`echo $$dir/*$(objext)`" != "$$dir/*$(objext)" ] ; then \
-+          for file in $$dir/*$(objext); do \
-+            cmp --ignore-initial=16 $$file stage$$stage/$$file > /dev/null 2>&1; \
-+            test $$? -eq 1 && echo $$file differs >> .bad_compare || true; \
-+          done; \
-+        else true; fi; \
-+      done
-+      case "$@" in gnucompare | gnucompare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^gnucompare\([0-9][0-9]*\).*,\1,'` ;; esac; \
-+      if [ -f .bad_compare ]; then \
-+        echo "Bootstrap comparison failure!"; \
-+        cat .bad_compare; \
-+        exit 1; \
-+      else \
-+        case "$@" in \
-+          *-lean ) rm -rf stage$$stage ;; \
-+        esac; true; \
-+      fi
-+
-+# Copy the object files from a particular stage into a subdirectory.
-+stage1-start:
-+      -if [ -d stage1 ] ; then true ; else mkdir stage1 ; fi
-+      $(MAKE) -f libgcc.mk libgcc-stage-start stage=stage1
-+      -for dir in intl $(SUBDIRS) ; \
-+       do \
-+         if [ -d stage1/$$dir ] ; then true ; else mkdir stage1/$$dir ; fi ; \
-+       done
-+      -mv $(STAGESTUFF) stage1
-+      -mv intl/*$(objext) stage1/intl
-+# Copy as/ld if they exist to stage dir, so that running xgcc from the stage
-+# dir will work properly.
-+      -if [ -f as$(exeext) ] ; then (cd stage1 && $(LN_S) ../as$(exeext) .) ; else true ; fi
-+      -if [ -f ld$(exeext) ] ; then (cd stage1 && $(LN_S) ../ld$(exeext) .) ; else true ; fi
-+      -if [ -f collect-ld$(exeext) ] ; then (cd stage1 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
-+      -rm -f stage1/libgcc.a stage1/libgcc_eh.a
-+      -cp libgcc.a stage1
-+      -if $(RANLIB_TEST_FOR_TARGET) ; then \
-+        $(RANLIB_FOR_TARGET) stage1/libgcc.a; \
-+      else true; fi
-+      -if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage1; \
-+        if $(RANLIB_TEST_FOR_TARGET) ; then \
-+         $(RANLIB_FOR_TARGET) stage1/libgcc_eh.a; \
-+        else true; fi; fi
-+      -for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
-+        cp stage1/$${f} . ; \
-+      else true; \
-+      fi; done
-+stage1: force stage1-start lang.stage1
-+
-+stage2-start:
-+      -if [ -d stage2 ] ; then true ; else mkdir stage2 ; fi
-+      $(MAKE) -f libgcc.mk libgcc-stage-start stage=stage2
-+      -for dir in intl $(SUBDIRS) ; \
-+       do \
-+         if [ -d stage2/$$dir ] ; then true ; else mkdir stage2/$$dir ; fi ; \
-+       done
-+      -mv $(STAGESTUFF) stage2
-+      -mv intl/*$(objext) stage2/intl
-+# Copy as/ld if they exist to stage dir, so that running xgcc from the stage
-+# dir will work properly.
-+      -if [ -f as$(exeext) ] ; then (cd stage2 && $(LN_S) ../as$(exeext) .) ; else true ; fi
-+      -if [ -f ld$(exeext) ] ; then (cd stage2 && $(LN_S) ../ld$(exeext) .) ; else true ; fi
-+      -if [ -f collect-ld$(exeext) ] ; then (cd stage2 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
-+      -rm -f stage2/libgcc.a stage2/libgcc_eh.a
-+      -cp libgcc.a stage2
-+      -if $(RANLIB_TEST_FOR_TARGET) ; then \
-+        $(RANLIB_FOR_TARGET) stage2/libgcc.a; \
-+      else true; fi
-+      -if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage2; \
-+        if $(RANLIB_TEST_FOR_TARGET) ; then \
-+         $(RANLIB_FOR_TARGET) stage2/libgcc_eh.a; \
-+        else true; fi; fi
-+      -for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
-+        cp stage2/$${f} . ; \
-+      else true; \
-+      fi; done
-+stage2: force stage2-start lang.stage2
-+
-+stage3-start:
-+      -if [ -d stage3 ] ; then true ; else mkdir stage3 ; fi
-+      $(MAKE) -f libgcc.mk libgcc-stage-start stage=stage3
-+      -for dir in intl $(SUBDIRS) ; \
-+       do \
-+         if [ -d stage3/$$dir ] ; then true ; else mkdir stage3/$$dir ; fi ; \
-+       done
-+      -mv $(STAGESTUFF) stage3
-+      -mv intl/*$(objext) stage3/intl
-+# Copy as/ld if they exist to stage dir, so that running xgcc from the stage
-+# dir will work properly.
-+      -if [ -f as$(exeext) ] ; then (cd stage3 && $(LN_S) ../as$(exeext) .) ; else true ; fi
-+      -if [ -f ld$(exeext) ] ; then (cd stage3 && $(LN_S) ../ld$(exeext) .) ; else true ; fi
-+      -if [ -f collect-ld$(exeext) ] ; then (cd stage3 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
-+      -rm -f stage3/libgcc.a stage3/libgcc_eh.a
-+      -cp libgcc.a stage3
-+      -if $(RANLIB_TEST_FOR_TARGET) ; then \
-+        $(RANLIB_FOR_TARGET) stage3/libgcc.a; \
-+      else true; fi
-+      -if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage3; \
-+        if $(RANLIB_TEST_FOR_TARGET) ; then \
-+         $(RANLIB_FOR_TARGET) stage3/libgcc_eh.a; \
-+        else true; fi; fi
-+      -for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
-+        cp stage3/$${f} . ; \
-+      else true; \
-+      fi; done
-+stage3: force stage3-start lang.stage3
-+
-+stage4-start:
-+      -if [ -d stage4 ] ; then true ; else mkdir stage4 ; fi
-+      $(MAKE) -f libgcc.mk libgcc-stage-start stage=stage4
-+      -for dir in intl $(SUBDIRS) ; \
-+       do \
-+         if [ -d stage4/$$dir ] ; then true ; else mkdir stage4/$$dir ; fi ; \
-+       done
-+      -mv $(STAGESTUFF) stage4
-+      -mv intl/*$(objext) stage4/intl
-+# Copy as/ld if they exist to stage dir, so that running xgcc from the stage
-+# dir will work properly.
-+      -if [ -f as$(exeext) ] ; then (cd stage4 && $(LN_S) ../as$(exeext) .) ; else true ; fi
-+      -if [ -f ld$(exeext) ] ; then (cd stage4 && $(LN_S) ../ld$(exeext) .) ; else true ; fi
-+      -if [ -f collect-ld$(exeext) ] ; then (cd stage4 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
-+      -rm -f stage4/libgcc.a stage4/libgcc_eh.a
-+      -cp libgcc.a stage4
-+      -if $(RANLIB_TEST_FOR_TARGET) ; then \
-+        $(RANLIB_FOR_TARGET) stage4/libgcc.a; \
-+      else true; fi
-+      -if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage4; \
-+        if $(RANLIB_TEST_FOR_TARGET) ; then \
-+         $(RANLIB_FOR_TARGET) stage4/libgcc_eh.a; \
-+        else true; fi; fi
-+      -for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
-+        cp stage4/$${f} . ; \
-+      else true; \
-+      fi; done
-+stage4: force stage4-start lang.stage4
-+
-+# Copy just the executable files from a particular stage into a subdirectory,
-+# and delete the object files.  Use this if you're just verifying a version
-+# that is pretty sure to work, and you are short of disk space.
-+risky-stage1: stage1
-+      -$(MAKE) clean
-+
-+risky-stage2: stage2
-+      -$(MAKE) clean
-+
-+risky-stage3: stage3
-+      -$(MAKE) clean
-+
-+risky-stage4: stage4
-+      -$(MAKE) clean
-+
-+#In GNU Make, ignore whether `stage*' exists.
-+.PHONY: stage1 stage2 stage3 stage4 clean maintainer-clean TAGS bootstrap
-+.PHONY: risky-stage1 risky-stage2 risky-stage3 risky-stage4
-+
-+force:
-+
-+# Rules for generating translated message descriptions.
-+# Disabled by autoconf if the tools are not available.
-+
-+XGETTEXT = @XGETTEXT@
-+GMSGFMT = @GMSGFMT@
-+MSGMERGE = msgmerge
-+
-+PACKAGE = @PACKAGE@
-+CATALOGS = @CATALOGS@
-+
-+.PHONY: build- install- build-po install-po update-po
-+
-+# Dummy rules to deal with dependencies produced by use of
-+# "build-@POSUB@" and "install-@POSUB@" above, when NLS is disabled.
-+build-: ; @true
-+install-: ; @true
-+
-+build-po: $(CATALOGS)
-+
-+# This notation should be acceptable to all Make implementations used
-+# by people who are interested in updating .po files.
-+update-po: $(CATALOGS:.gmo=.pox)
-+
-+# N.B. We do not attempt to copy these into $(srcdir).  The snapshot
-+# script does that.
-+.po.gmo:
-+      -test -d po || mkdir po
-+      $(GMSGFMT) --statistics -o $@ $<
-+
-+# The new .po has to be gone over by hand, so we deposit it into
-+# build/po with a different extension.
-+# If build/po/$(PACKAGE).pot exists, use it (it was just created),
-+# else use the one in srcdir.
-+.po.pox:
-+      -test -d po || mkdir po
-+      $(MSGMERGE) $< `if test -f po/$(PACKAGE).pot; \
-+                      then echo po/$(PACKAGE).pot; \
-+                      else echo $(srcdir)/po/$(PACKAGE).pot; fi` -o $@
-+
-+# This rule has to look for .gmo modules in both srcdir and
-+# the cwd, and has to check that we actually have a catalog
-+# for each language, in case they weren't built or included
-+# with the distribution.
-+install-po:
-+      $(SHELL) $(srcdir)/mkinstalldirs $(DESTDIR)$(datadir)
-+      for cat in $(CATALOGS); do \
-+        lang=`basename $$cat | sed 's/\.gmo$$//'`; \
-+        if [ -f $$cat ]; then :; \
-+        elif [ -f $(srcdir)/$$cat ]; then cat=$(srcdir)/$$cat; \
-+        else continue; \
-+        fi; \
-+        dir=$(localedir)/$$lang/LC_MESSAGES; \
-+        echo $(SHELL) $(srcdir)/mkinstalldirs $(DESTDIR)$$dir; \
-+        $(SHELL) $(srcdir)/mkinstalldirs $(DESTDIR)$$dir || exit 1; \
-+        echo $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/$(PACKAGE).mo; \
-+        $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/$(PACKAGE).mo; \
-+      done
-+
-+# Rule for regenerating the message template (gcc.pot).
-+# Instead of forcing everyone to edit POTFILES.in, which proved impractical,
-+# this rule has no dependencies and always regenerates gcc.pot.  This is
-+# relatively harmless since the .po files do not directly depend on it.
-+# Note that exgettext has an awk script embedded in it which requires a
-+# fairly modern (POSIX-compliant) awk.
-+# The .pot file is left in the build directory.
-+$(PACKAGE).pot: po/$(PACKAGE).pot
-+po/$(PACKAGE).pot: force
-+      -test -d po || mkdir po
-+      $(MAKE) po-generated
-+      AWK=$(AWK) $(SHELL) $(srcdir)/po/exgettext \
-+              $(XGETTEXT) $(PACKAGE) $(srcdir)
-diff -ruN gcc-3.3.1/gcc/calls.c gcc-3.3.1.pp/gcc/calls.c
+diff -urN gcc-3.3.1/gcc/calls.c gcc-3.3.1-pp/gcc/calls.c
 --- gcc-3.3.1/gcc/calls.c      2003-07-18 02:58:25.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/calls.c   2003-09-05 11:58:58.000000000 +0000
++++ gcc-3.3.1-pp/gcc/calls.c   2003-09-12 13:40:28.000000000 +0000
 @@ -2327,7 +2327,7 @@
            /* For variable-sized objects, we must be called with a target
               specified.  If we were to allocate space on the stack here,
@@ -3815,33441 +57,569 @@ diff -ruN gcc-3.3.1/gcc/calls.c gcc-3.3.1.pp/gcc/calls.c
  
            mark_temp_addr_taken (d);
            structure_value_addr = XEXP (d, 0);
-diff -ruN gcc-3.3.1/gcc/calls.c.orig gcc-3.3.1.pp/gcc/calls.c.orig
---- gcc-3.3.1/gcc/calls.c.orig 1970-01-01 00:00:00.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/calls.c.orig      2003-07-18 02:58:25.000000000 +0000
-@@ -0,0 +1,4667 @@
-+/* Convert function calls to rtl insns, for GNU C compiler.
-+   Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
-+   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify it under
-+the terms of the GNU General Public License as published by the Free
-+Software Foundation; either version 2, or (at your option) any later
-+version.
-+
-+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-+WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING.  If not, write to the Free
-+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-+02111-1307, USA.  */
-+
-+#include "config.h"
-+#include "system.h"
-+#include "rtl.h"
-+#include "tree.h"
-+#include "flags.h"
-+#include "expr.h"
-+#include "libfuncs.h"
-+#include "function.h"
-+#include "regs.h"
-+#include "toplev.h"
-+#include "output.h"
-+#include "tm_p.h"
-+#include "timevar.h"
-+#include "sbitmap.h"
-+#include "langhooks.h"
-+#include "target.h"
-+#include "except.h"
-+
-+#if !defined FUNCTION_OK_FOR_SIBCALL
-+#define FUNCTION_OK_FOR_SIBCALL(DECL) 1
-+#endif
-+
-+/* Decide whether a function's arguments should be processed
-+   from first to last or from last to first.
-+
-+   They should if the stack and args grow in opposite directions, but
-+   only if we have push insns.  */
-+
-+#ifdef PUSH_ROUNDING
-+
-+#ifndef PUSH_ARGS_REVERSED
-+#if defined (STACK_GROWS_DOWNWARD) != defined (ARGS_GROW_DOWNWARD)
-+#define PUSH_ARGS_REVERSED  PUSH_ARGS
-+#endif
-+#endif
-+
-+#endif
-+
-+#ifndef PUSH_ARGS_REVERSED
-+#define PUSH_ARGS_REVERSED 0
+diff -urN gcc-3.3.1/gcc/combine.c gcc-3.3.1-pp/gcc/combine.c
+--- gcc-3.3.1/gcc/combine.c    2003-03-24 11:37:32.000000000 +0000
++++ gcc-3.3.1-pp/gcc/combine.c 2003-09-12 13:40:28.000000000 +0000
+@@ -3859,7 +3859,17 @@
+         rtx inner_op0 = XEXP (XEXP (x, 0), 1);
+         rtx inner_op1 = XEXP (x, 1);
+         rtx inner;
+-
++        
++#ifndef FRAME_GROWS_DOWNWARD
++        if (flag_propolice_protection
++            && code == PLUS
++            && other == frame_pointer_rtx
++            && GET_CODE (inner_op0) == CONST_INT
++            && GET_CODE (inner_op1) == CONST_INT
++            && INTVAL (inner_op0) > 0
++            && INTVAL (inner_op0) + INTVAL (inner_op1) <= 0)
++          return x;
 +#endif
-+
-+#ifndef STACK_POINTER_OFFSET
-+#define STACK_POINTER_OFFSET    0
+         /* Make sure we pass the constant operand if any as the second
+            one if this is a commutative operation.  */
+         if (CONSTANT_P (inner_op0) && GET_RTX_CLASS (code) == 'c')
+@@ -4272,6 +4282,11 @@
+        they are now checked elsewhere.  */
+       if (GET_CODE (XEXP (x, 0)) == PLUS
+         && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
++#ifndef FRAME_GROWS_DOWNWARD
++      if (! (flag_propolice_protection
++             && XEXP (XEXP (x, 0), 0) == frame_pointer_rtx
++             && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
 +#endif
-+
-+/* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits.  */
-+#define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
-+
-+/* Data structure and subroutines used within expand_call.  */
-+
-+struct arg_data
-+{
-+  /* Tree node for this argument.  */
-+  tree tree_value;
-+  /* Mode for value; TYPE_MODE unless promoted.  */
-+  enum machine_mode mode;
-+  /* Current RTL value for argument, or 0 if it isn't precomputed.  */
-+  rtx value;
-+  /* Initially-compute RTL value for argument; only for const functions.  */
-+  rtx initial_value;
-+  /* Register to pass this argument in, 0 if passed on stack, or an
-+     PARALLEL if the arg is to be copied into multiple non-contiguous
-+     registers.  */
-+  rtx reg;
-+  /* Register to pass this argument in when generating tail call sequence.
-+     This is not the same register as for normal calls on machines with
-+     register windows.  */
-+  rtx tail_call_reg;
-+  /* If REG was promoted from the actual mode of the argument expression,
-+     indicates whether the promotion is sign- or zero-extended.  */
-+  int unsignedp;
-+  /* Number of registers to use.  0 means put the whole arg in registers.
-+     Also 0 if not passed in registers.  */
-+  int partial;
-+  /* Nonzero if argument must be passed on stack.
-+     Note that some arguments may be passed on the stack
-+     even though pass_on_stack is zero, just because FUNCTION_ARG says so.
-+     pass_on_stack identifies arguments that *cannot* go in registers.  */
-+  int pass_on_stack;
-+  /* Offset of this argument from beginning of stack-args.  */
-+  struct args_size offset;
-+  /* Similar, but offset to the start of the stack slot.  Different from
-+     OFFSET if this arg pads downward.  */
-+  struct args_size slot_offset;
-+  /* Size of this argument on the stack, rounded up for any padding it gets,
-+     parts of the argument passed in registers do not count.
-+     If REG_PARM_STACK_SPACE is defined, then register parms
-+     are counted here as well.  */
-+  struct args_size size;
-+  /* Location on the stack at which parameter should be stored.  The store
-+     has already been done if STACK == VALUE.  */
-+  rtx stack;
-+  /* Location on the stack of the start of this argument slot.  This can
-+     differ from STACK if this arg pads downward.  This location is known
-+     to be aligned to FUNCTION_ARG_BOUNDARY.  */
-+  rtx stack_slot;
-+  /* Place that this stack area has been saved, if needed.  */
-+  rtx save_area;
-+  /* 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
-+     word-sized pseudos we made.  */
-+  rtx *aligned_regs;
-+  int n_aligned_regs;
-+  /* The amount that the stack pointer needs to be adjusted to
-+     force alignment for the next argument.  */
-+  struct args_size alignment_pad;
-+};
-+
-+/* A vector of one char per byte of stack space.  A byte if nonzero if
-+   the corresponding stack location has been used.
-+   This vector is used to prevent a function call within an argument from
-+   clobbering any stack already set up.  */
-+static char *stack_usage_map;
-+
-+/* Size of STACK_USAGE_MAP.  */
-+static int highest_outgoing_arg_in_use;
-+
-+/* A bitmap of virtual-incoming stack space.  Bit is set if the corresponding
-+   stack location's tail call argument has been already stored into the stack.
-+   This bitmap is used to prevent sibling call optimization if function tries
-+   to use parent's incoming argument slots when they have been already
-+   overwritten with tail call arguments.  */
-+static sbitmap stored_args_map;
-+
-+/* stack_arg_under_construction is nonzero when an argument may be
-+   initialized with a constructor call (including a C function that
-+   returns a BLKmode struct) and expand_call must take special action
-+   to make sure the object being constructed does not overlap the
-+   argument list for the constructor call.  */
-+int stack_arg_under_construction;
-+
-+static int calls_function     PARAMS ((tree, int));
-+static int calls_function_1   PARAMS ((tree, int));
-+
-+/* Nonzero if this is a call to a `const' function.  */
-+#define ECF_CONST             1
-+/* Nonzero if this is a call to a `volatile' function.  */
-+#define ECF_NORETURN          2
-+/* Nonzero if this is a call to malloc or a related function.  */
-+#define ECF_MALLOC            4
-+/* Nonzero if it is plausible that this is a call to alloca.  */
-+#define ECF_MAY_BE_ALLOCA     8
-+/* Nonzero if this is a call to a function that won't throw an exception.  */
-+#define ECF_NOTHROW           16
-+/* Nonzero if this is a call to setjmp or a related function.  */
-+#define ECF_RETURNS_TWICE     32
-+/* Nonzero if this is a call to `longjmp'.  */
-+#define ECF_LONGJMP           64
-+/* Nonzero if this is a syscall that makes a new process in the image of
-+   the current one.  */
-+#define ECF_FORK_OR_EXEC      128
-+#define ECF_SIBCALL           256
-+/* Nonzero if this is a call to "pure" function (like const function,
-+   but may read memory.  */
-+#define ECF_PURE              512
-+/* Nonzero if this is a call to a function that returns with the stack
-+   pointer depressed.  */
-+#define ECF_SP_DEPRESSED      1024
-+/* Nonzero if this call is known to always return.  */
-+#define ECF_ALWAYS_RETURN     2048
-+/* Create libcall block around the call.  */
-+#define ECF_LIBCALL_BLOCK     4096
-+
-+static void emit_call_1               PARAMS ((rtx, tree, tree, HOST_WIDE_INT,
-+                                       HOST_WIDE_INT, HOST_WIDE_INT, rtx,
-+                                       rtx, int, rtx, int,
-+                                       CUMULATIVE_ARGS *));
-+static void precompute_register_parameters    PARAMS ((int,
-+                                                       struct arg_data *,
-+                                                       int *));
-+static int store_one_arg      PARAMS ((struct arg_data *, rtx, int, int,
-+                                       int));
-+static void store_unaligned_arguments_into_pseudos PARAMS ((struct arg_data *,
-+                                                          int));
-+static int finalize_must_preallocate          PARAMS ((int, int,
-+                                                       struct arg_data *,
-+                                                       struct args_size *));
-+static void precompute_arguments              PARAMS ((int, int,
-+                                                       struct arg_data *));
-+static int compute_argument_block_size                PARAMS ((int,
-+                                                       struct args_size *,
-+                                                       int));
-+static void initialize_argument_information   PARAMS ((int,
-+                                                       struct arg_data *,
-+                                                       struct args_size *,
-+                                                       int, tree, tree,
-+                                                       CUMULATIVE_ARGS *,
-+                                                       int, rtx *, int *,
-+                                                       int *, int *));
-+static void compute_argument_addresses                PARAMS ((struct arg_data *,
-+                                                       rtx, int));
-+static rtx rtx_for_function_call              PARAMS ((tree, tree));
-+static void load_register_parameters          PARAMS ((struct arg_data *,
-+                                                       int, rtx *, int));
-+static rtx emit_library_call_value_1          PARAMS ((int, rtx, rtx,
-+                                                       enum libcall_type,
-+                                                       enum machine_mode,
-+                                                       int, va_list));
-+static int special_function_p                 PARAMS ((tree, int));
-+static int flags_from_decl_or_type            PARAMS ((tree));
-+static rtx try_to_integrate                   PARAMS ((tree, tree, rtx,
-+                                                       int, tree, rtx));
-+static int check_sibcall_argument_overlap_1   PARAMS ((rtx));
-+static int check_sibcall_argument_overlap     PARAMS ((rtx, struct arg_data *));
-+
-+static int combine_pending_stack_adjustment_and_call
-+                                                PARAMS ((int, struct args_size *, int));
-+static tree fix_unsafe_tree           PARAMS ((tree));
-+
-+#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));
+       return gen_binary (PLUS, mode,
+                          gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0),
+                                      XEXP (x, 1)),
+@@ -4400,7 +4415,10 @@
+       /* Canonicalize (minus A (plus B C)) to (minus (minus A B) C) for
+        integers.  */
+-      if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode))
++      if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode)
++        && (! (flag_propolice_protection
++               && XEXP (XEXP (x, 1), 0) == frame_pointer_rtx
++               && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT)))
+       return gen_binary (MINUS, mode,
+                          gen_binary (MINUS, mode, XEXP (x, 0),
+                                      XEXP (XEXP (x, 1), 0)),
+diff -urN gcc-3.3.1/gcc/config/t-linux gcc-3.3.1-pp/gcc/config/t-linux
+--- gcc-3.3.1/gcc/config/t-linux       2003-06-04 16:56:11.000000000 +0000
++++ gcc-3.3.1-pp/gcc/config/t-linux    2003-09-12 13:40:28.000000000 +0000
+@@ -4,7 +4,7 @@
+ # Compile crtbeginS.o and crtendS.o with pic.
+ CRTSTUFF_T_CFLAGS_S = $(CRTSTUFF_T_CFLAGS) -fPIC
+ # Compile libgcc2.a with pic.
+-TARGET_LIBGCC2_CFLAGS = -fPIC
++TARGET_LIBGCC2_CFLAGS = -fPIC -DHAVE_SYSLOG
+ # Override t-slibgcc-elf-ver to export some libgcc symbols with
+ # the symbol versions that glibc used.
+diff -urN gcc-3.3.1/gcc/cse.c gcc-3.3.1-pp/gcc/cse.c
+--- gcc-3.3.1/gcc/cse.c        2003-04-29 19:16:40.000000000 +0000
++++ gcc-3.3.1-pp/gcc/cse.c     2003-09-12 13:40:28.000000000 +0000
+@@ -4288,7 +4288,14 @@
+             if (new_const == 0)
+               break;
+-
++#ifndef FRAME_GROWS_DOWNWARD
++            if (flag_propolice_protection
++                && GET_CODE (y) == PLUS
++                && XEXP (y, 0) == frame_pointer_rtx
++                && INTVAL (inner_const) > 0
++                && INTVAL (new_const) <= 0)
++              break;
 +#endif
-+\f
-+/* If WHICH is 1, return 1 if EXP contains a call to the built-in function
-+   `alloca'.
-+
-+   If WHICH is 0, return 1 if EXP contains a call to any function.
-+   Actually, we only need return 1 if evaluating EXP would require pushing
-+   arguments on the stack, but that is too difficult to compute, so we just
-+   assume any function call might require the stack.  */
-+
-+static tree calls_function_save_exprs;
-+
-+static int
-+calls_function (exp, which)
-+     tree exp;
-+     int which;
-+{
-+  int val;
-+
-+  calls_function_save_exprs = 0;
-+  val = calls_function_1 (exp, which);
-+  calls_function_save_exprs = 0;
-+  return val;
-+}
-+
-+/* Recursive function to do the work of above function.  */
-+
-+static int
-+calls_function_1 (exp, which)
-+     tree exp;
-+     int which;
-+{
-+  int i;
-+  enum tree_code code = TREE_CODE (exp);
-+  int class = TREE_CODE_CLASS (code);
-+  int length = first_rtl_op (code);
-+
-+  /* If this code is language-specific, we don't know what it will do.  */
-+  if ((int) code >= NUM_TREE_CODES)
-+    return 1;
-+
-+  switch (code)
-+    {
-+    case CALL_EXPR:
-+      if (which == 0)
-+      return 1;
-+      else if ((TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))))
-+              == FUNCTION_TYPE)
-+             && (TYPE_RETURNS_STACK_DEPRESSED
-+                 (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))))))
-+      return 1;
-+      else if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
-+             && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
-+                 == FUNCTION_DECL)
-+             && (special_function_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
-+                                     0)
-+                 & ECF_MAY_BE_ALLOCA))
-+      return 1;
-+
-+      break;
-+
-+    case CONSTRUCTOR:
-+      {
-+      tree tem;
-+
-+      for (tem = CONSTRUCTOR_ELTS (exp); tem != 0; tem = TREE_CHAIN (tem))
-+        if (calls_function_1 (TREE_VALUE (tem), which))
-+          return 1;
-+      }
-+
-+      return 0;
-+
-+    case SAVE_EXPR:
-+      if (SAVE_EXPR_RTL (exp) != 0)
-+      return 0;
-+      if (value_member (exp, calls_function_save_exprs))
-+      return 0;
-+      calls_function_save_exprs = tree_cons (NULL_TREE, exp,
-+                                           calls_function_save_exprs);
-+      return (TREE_OPERAND (exp, 0) != 0
-+            && calls_function_1 (TREE_OPERAND (exp, 0), which));
-+
-+    case BLOCK:
-+      {
-+      tree local;
-+      tree subblock;
-+
-+      for (local = BLOCK_VARS (exp); local; local = TREE_CHAIN (local))
-+        if (DECL_INITIAL (local) != 0
-+            && calls_function_1 (DECL_INITIAL (local), which))
-+          return 1;
-+
-+      for (subblock = BLOCK_SUBBLOCKS (exp);
-+           subblock;
-+           subblock = TREE_CHAIN (subblock))
-+        if (calls_function_1 (subblock, which))
-+          return 1;
+             /* If we are associating shift operations, don't let this
+                produce a shift of the size of the object or larger.
+                This could occur when we follow a sign-extend by a right
+@@ -4823,6 +4830,13 @@
+       if (SET_DEST (x) == pc_rtx
+         && GET_CODE (SET_SRC (x)) == LABEL_REF)
+       ;
++      /* cut the reg propagation of stack-protected argument */
++      else if (x->volatil) {
++      rtx x1 = SET_DEST (x);
++      if (GET_CODE (x1) == SUBREG && GET_CODE (SUBREG_REG (x1)) == REG)
++        x1 = SUBREG_REG (x1);
++      make_new_qty (REGNO (x1), GET_MODE (x1));
 +      }
-+      return 0;
-+
-+    case TREE_LIST:
-+      for (; exp != 0; exp = TREE_CHAIN (exp))
-+      if (calls_function_1 (TREE_VALUE (exp), which))
-+        return 1;
-+      return 0;
-+
-+    default:
-+      break;
-+    }
-+
-+  /* Only expressions, references, and blocks can contain calls.  */
-+  if (! IS_EXPR_CODE_CLASS (class) && class != 'r' && class != 'b')
-+    return 0;
-+
-+  for (i = 0; i < length; i++)
-+    if (TREE_OPERAND (exp, i) != 0
-+      && calls_function_1 (TREE_OPERAND (exp, i), which))
-+      return 1;
-+
-+  return 0;
-+}
-+\f
-+/* Force FUNEXP into a form suitable for the address of a CALL,
-+   and return that as an rtx.  Also load the static chain register
-+   if FNDECL is a nested function.
-+
-+   CALL_FUSAGE points to a variable holding the prospective
-+   CALL_INSN_FUNCTION_USAGE information.  */
-+
-+rtx
-+prepare_call_address (funexp, fndecl, call_fusage, reg_parm_seen, sibcallp)
-+     rtx funexp;
-+     tree fndecl;
-+     rtx *call_fusage;
-+     int reg_parm_seen;
-+     int sibcallp;
-+{
-+  rtx static_chain_value = 0;
-+
-+  funexp = protect_from_queue (funexp, 0);
-+
-+  if (fndecl != 0)
-+    /* Get possible static chain value for nested function in C.  */
-+    static_chain_value = lookup_static_chain (fndecl);
-+
-+  /* Make a valid memory address and copy constants thru pseudo-regs,
-+     but not for a constant address if -fno-function-cse.  */
-+  if (GET_CODE (funexp) != SYMBOL_REF)
-+    /* If we are using registers for parameters, force the
-+       function address into a register now.  */
-+    funexp = ((SMALL_REGISTER_CLASSES && reg_parm_seen)
-+            ? force_not_mem (memory_address (FUNCTION_MODE, funexp))
-+            : memory_address (FUNCTION_MODE, funexp));
-+  else if (! sibcallp)
-+    {
-+#ifndef NO_FUNCTION_CSE
-+      if (optimize && ! flag_no_function_cse)
-+#ifdef NO_RECURSIVE_FUNCTION_CSE
-+      if (fndecl != current_function_decl)
-+#endif
-+        funexp = force_reg (Pmode, funexp);
-+#endif
-+    }
-+
-+  if (static_chain_value != 0)
-+    {
-+      emit_move_insn (static_chain_rtx, static_chain_value);
-+
-+      if (GET_CODE (static_chain_rtx) == REG)
-+      use_reg (call_fusage, static_chain_rtx);
-+    }
-+
-+  return funexp;
-+}
-+
-+/* Generate instructions to call function FUNEXP,
-+   and optionally pop the results.
-+   The CALL_INSN is the first insn generated.
-+
-+   FNDECL is the declaration node of the function.  This is given to the
-+   macro RETURN_POPS_ARGS to determine whether this function pops its own args.
-+
-+   FUNTYPE is the data type of the function.  This is given to the macro
-+   RETURN_POPS_ARGS to determine whether this function pops its own args.
-+   We used to allow an identifier for library functions, but that doesn't
-+   work when the return type is an aggregate type and the calling convention
-+   says that the pointer to this aggregate is to be popped by the callee.
-+
-+   STACK_SIZE is the number of bytes of arguments on the stack,
-+   ROUNDED_STACK_SIZE is that number rounded up to
-+   PREFERRED_STACK_BOUNDARY; zero if the size is variable.  This is
-+   both to put into the call insn and to generate explicit popping
-+   code if necessary.
-+
-+   STRUCT_VALUE_SIZE is the number of bytes wanted in a structure value.
-+   It is zero if this call doesn't want a structure value.
-+
-+   NEXT_ARG_REG is the rtx that results from executing
-+     FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1)
-+   just after all the args have had their registers assigned.
-+   This could be whatever you like, but normally it is the first
-+   arg-register beyond those used for args in this call,
-+   or 0 if all the arg-registers are used in this call.
-+   It is passed on to `gen_call' so you can put this info in the call insn.
-+
-+   VALREG is a hard register in which a value is returned,
-+   or 0 if the call does not return a value.
-+
-+   OLD_INHIBIT_DEFER_POP is the value that `inhibit_defer_pop' had before
-+   the args to this call were processed.
-+   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.  */
-+
-+static void
-+emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
-+           struct_value_size, next_arg_reg, valreg, old_inhibit_defer_pop,
-+           call_fusage, ecf_flags, args_so_far)
-+     rtx funexp;
-+     tree fndecl ATTRIBUTE_UNUSED;
-+     tree funtype ATTRIBUTE_UNUSED;
-+     HOST_WIDE_INT stack_size ATTRIBUTE_UNUSED;
-+     HOST_WIDE_INT rounded_stack_size;
-+     HOST_WIDE_INT struct_value_size ATTRIBUTE_UNUSED;
-+     rtx next_arg_reg ATTRIBUTE_UNUSED;
-+     rtx valreg;
-+     int old_inhibit_defer_pop;
-+     rtx call_fusage;
-+     int ecf_flags;
-+     CUMULATIVE_ARGS *args_so_far ATTRIBUTE_UNUSED;
-+{
-+  rtx rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
-+  rtx call_insn;
-+  int already_popped = 0;
-+  HOST_WIDE_INT n_popped = RETURN_POPS_ARGS (fndecl, funtype, stack_size);
-+#if defined (HAVE_call) && defined (HAVE_call_value)
-+  rtx struct_value_size_rtx;
-+  struct_value_size_rtx = GEN_INT (struct_value_size);
-+#endif
-+
-+#ifdef CALL_POPS_ARGS
-+  n_popped += CALL_POPS_ARGS (* args_so_far);
-+#endif
-+  
-+  /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
-+     and we don't want to load it into a register as an optimization,
-+     because prepare_call_address already did it if it should be done.  */
-+  if (GET_CODE (funexp) != SYMBOL_REF)
-+    funexp = memory_address (FUNCTION_MODE, funexp);
-+
-+#if defined (HAVE_sibcall_pop) && defined (HAVE_sibcall_value_pop)
-+  if ((ecf_flags & ECF_SIBCALL)
-+      && HAVE_sibcall_pop && HAVE_sibcall_value_pop
-+      && (n_popped > 0 || stack_size == 0))
-+    {
-+      rtx n_pop = GEN_INT (n_popped);
-+      rtx pat;
-+
-+      /* If this subroutine pops its own args, record that in the call insn
-+       if possible, for the sake of frame pointer elimination.  */
-+
-+      if (valreg)
-+      pat = GEN_SIBCALL_VALUE_POP (valreg,
-+                                   gen_rtx_MEM (FUNCTION_MODE, funexp),
-+                                   rounded_stack_size_rtx, next_arg_reg,
-+                                   n_pop);
-+      else
-+      pat = GEN_SIBCALL_POP (gen_rtx_MEM (FUNCTION_MODE, funexp),
-+                             rounded_stack_size_rtx, next_arg_reg, n_pop);
-+
-+      emit_call_insn (pat);
-+      already_popped = 1;
-+    }
-+  else
-+#endif
-+
-+#if defined (HAVE_call_pop) && defined (HAVE_call_value_pop)
-+  /* If the target has "call" or "call_value" insns, then prefer them
-+     if no arguments are actually popped.  If the target does not have
-+     "call" or "call_value" insns, then we must use the popping versions
-+     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 && ! (ecf_flags & ECF_SP_DEPRESSED))
-+#else
-+  if (HAVE_call_pop && HAVE_call_value_pop)
-+#endif
-+    {
-+      rtx n_pop = GEN_INT (n_popped);
-+      rtx pat;
-+
-+      /* If this subroutine pops its own args, record that in the call insn
-+       if possible, for the sake of frame pointer elimination.  */
-+
-+      if (valreg)
-+      pat = GEN_CALL_VALUE_POP (valreg,
-+                                gen_rtx_MEM (FUNCTION_MODE, funexp),
-+                                rounded_stack_size_rtx, next_arg_reg, n_pop);
-+      else
-+      pat = GEN_CALL_POP (gen_rtx_MEM (FUNCTION_MODE, funexp),
-+                          rounded_stack_size_rtx, next_arg_reg, n_pop);
-+
-+      emit_call_insn (pat);
-+      already_popped = 1;
-+    }
-+  else
-+#endif
-+
-+#if defined (HAVE_sibcall) && defined (HAVE_sibcall_value)
-+  if ((ecf_flags & ECF_SIBCALL)
-+      && HAVE_sibcall && HAVE_sibcall_value)
-+    {
-+      if (valreg)
-+      emit_call_insn (GEN_SIBCALL_VALUE (valreg,
-+                                         gen_rtx_MEM (FUNCTION_MODE, funexp),
-+                                         rounded_stack_size_rtx,
-+                                         next_arg_reg, NULL_RTX));
-+      else
-+      emit_call_insn (GEN_SIBCALL (gen_rtx_MEM (FUNCTION_MODE, funexp),
-+                                   rounded_stack_size_rtx, next_arg_reg,
-+                                   struct_value_size_rtx));
-+    }
-+  else
-+#endif
-+
-+#if defined (HAVE_call) && defined (HAVE_call_value)
-+  if (HAVE_call && HAVE_call_value)
-+    {
-+      if (valreg)
-+      emit_call_insn (GEN_CALL_VALUE (valreg,
-+                                      gen_rtx_MEM (FUNCTION_MODE, funexp),
-+                                      rounded_stack_size_rtx, next_arg_reg,
-+                                      NULL_RTX));
-+      else
-+      emit_call_insn (GEN_CALL (gen_rtx_MEM (FUNCTION_MODE, funexp),
-+                                rounded_stack_size_rtx, next_arg_reg,
-+                                struct_value_size_rtx));
-+    }
-+  else
-+#endif
-+    abort ();
-+
-+  /* Find the CALL insn we just emitted.  */
-+  for (call_insn = get_last_insn ();
-+       call_insn && GET_CODE (call_insn) != CALL_INSN;
-+       call_insn = PREV_INSN (call_insn))
-+    ;
-+
-+  if (! call_insn)
-+    abort ();
-+
-+  /* Mark memory as used for "pure" function call.  */
-+  if (ecf_flags & ECF_PURE)
-+    call_fusage
-+      = gen_rtx_EXPR_LIST
-+      (VOIDmode,
-+       gen_rtx_USE (VOIDmode,
-+                    gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))),
-+       call_fusage);
-+
-+  /* Put the register usage information on the CALL.  If there is already
-+     some usage information, put ours at the end.  */
-+  if (CALL_INSN_FUNCTION_USAGE (call_insn))
-+    {
-+      rtx link;
-+
-+      for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
-+         link = XEXP (link, 1))
-+      ;
-+
-+      XEXP (link, 1) = call_fusage;
-+    }
-+  else
-+    CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
-+
-+  /* If this is a const call, then set the insn's unchanging bit.  */
-+  if (ecf_flags & (ECF_CONST | ECF_PURE))
-+    CONST_OR_PURE_CALL_P (call_insn) = 1;
-+
-+  /* If this call can't throw, attach a REG_EH_REGION reg note to that
-+     effect.  */
-+  if (ecf_flags & ECF_NOTHROW)
-+    REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, const0_rtx,
-+                                             REG_NOTES (call_insn));
-+  else
-+    note_eh_region_may_contain_throw ();
-+
-+  if (ecf_flags & ECF_NORETURN)
-+    REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_NORETURN, const0_rtx,
-+                                             REG_NOTES (call_insn));
-+  if (ecf_flags & ECF_ALWAYS_RETURN)
-+    REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_ALWAYS_RETURN, const0_rtx,
-+                                             REG_NOTES (call_insn));
-+
-+  if (ecf_flags & ECF_RETURNS_TWICE)
-+    {
-+      REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_SETJMP, const0_rtx,
-+                                               REG_NOTES (call_insn));
-+      current_function_calls_setjmp = 1;
-+    }
-+
-+  SIBLING_CALL_P (call_insn) = ((ecf_flags & ECF_SIBCALL) != 0);
-+
-+  /* Restore this now, so that we do defer pops for this call's args
-+     if the context of the call as a whole permits.  */
-+  inhibit_defer_pop = old_inhibit_defer_pop;
-+
-+  if (n_popped > 0)
-+    {
-+      if (!already_popped)
-+      CALL_INSN_FUNCTION_USAGE (call_insn)
-+        = gen_rtx_EXPR_LIST (VOIDmode,
-+                             gen_rtx_CLOBBER (VOIDmode, stack_pointer_rtx),
-+                             CALL_INSN_FUNCTION_USAGE (call_insn));
-+      rounded_stack_size -= n_popped;
-+      rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
-+      stack_pointer_delta -= n_popped;
-+    }
-+
-+  if (!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.  */
-+
-+      if (rounded_stack_size != 0)
-+      {
-+        if (ecf_flags & ECF_SP_DEPRESSED)
-+          /* Just pretend we did the pop.  */
-+          stack_pointer_delta -= rounded_stack_size;
-+        else if (flag_defer_pop && inhibit_defer_pop == 0
-+            && ! (ecf_flags & (ECF_CONST | ECF_PURE)))
-+          pending_stack_adjust += rounded_stack_size;
-+        else
-+          adjust_stack (rounded_stack_size_rtx);
-+      }
-+    }
-+  /* 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
-+   special properties we wish to know about.
-+
-+   For example, if the function might return more than one time (setjmp), then
-+   set RETURNS_TWICE to a nonzero value.
-+
-+   Similarly set LONGJMP for if the function is in the longjmp family.
-+
-+   Set MALLOC for any of the standard memory allocation functions which
-+   allocate from the heap.
-+
-+   Set MAY_BE_ALLOCA for any memory allocation function that might allocate
-+   space from the stack such as alloca.  */
-+
-+static int
-+special_function_p (fndecl, flags)
-+     tree fndecl;
-+     int flags;
-+{
-+  if (! (flags & ECF_MALLOC)
-+      && fndecl && DECL_NAME (fndecl)
-+      && IDENTIFIER_LENGTH (DECL_NAME (fndecl)) <= 17
-+      /* Exclude functions not at the file scope, or not `extern',
-+       since they are not the magic functions we would otherwise
-+       think they are.  */
-+      && DECL_CONTEXT (fndecl) == NULL_TREE && TREE_PUBLIC (fndecl))
-+    {
-+      const char *name = IDENTIFIER_POINTER (DECL_NAME (fndecl));
-+      const char *tname = name;
-+
-+      /* 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.  */
-+      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] == '_')
-+      {
-+        if (name[1] == '_' && name[2] == 'x')
-+          tname += 3;
-+        else if (name[1] == '_')
-+          tname += 2;
-+        else
-+          tname += 1;
-+      }
-+
-+      if (tname[0] == 's')
-+      {
-+        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"))
-+          flags |= ECF_LONGJMP;
-+      }
-+      else if ((tname[0] == 'q' && tname[1] == 's'
-+              && ! strcmp (tname, "qsetjmp"))
-+             || (tname[0] == 'v' && tname[1] == 'f'
-+                 && ! strcmp (tname, "vfork")))
-+      flags |= ECF_RETURNS_TWICE;
-+
-+      else if (tname[0] == 'l' && tname[1] == 'o'
-+             && ! strcmp (tname, "longjmp"))
-+      flags |= ECF_LONGJMP;
-+
-+      else if ((tname[0] == 'f' && tname[1] == 'o'
-+              && ! strcmp (tname, "fork"))
-+             /* Linux specific: __clone.  check NAME to insist on the
-+                leading underscores, to avoid polluting the ISO / POSIX
-+                namespace.  */
-+             || (name[0] == '_' && name[1] == '_'
-+                 && ! strcmp (tname, "clone"))
-+             || (tname[0] == 'e' && tname[1] == 'x' && tname[2] == 'e'
-+                 && tname[3] == 'c' && (tname[4] == 'l' || tname[4] == 'v')
-+                 && (tname[5] == '\0'
-+                     || ((tname[5] == 'p' || tname[5] == 'e')
-+                         && tname[6] == '\0'))))
-+      flags |= ECF_FORK_OR_EXEC;
-+
-+      /* Do not add any more malloc-like functions to this list,
-+         instead mark them as malloc functions using the malloc attribute.
-+         Note, realloc is not suitable for attribute malloc since
-+         it may return the same address across multiple calls.
-+         C++ operator new is not suitable because it is not required
-+         to return a unique pointer; indeed, the standard placement new
-+       just returns its argument.  */
-+      else if (TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))) == Pmode
-+             && (! strcmp (tname, "malloc")
-+                 || ! strcmp (tname, "calloc")
-+                 || ! strcmp (tname, "strdup")))
-+      flags |= ECF_MALLOC;
-+    }
-+  return flags;
-+}
-+
-+/* Return nonzero when tree represent call to longjmp.  */
-+
-+int
-+setjmp_call_p (fndecl)
-+     tree fndecl;
-+{
-+  return special_function_p (fndecl, 0) & ECF_RETURNS_TWICE;
-+}
-+
-+/* Return true when exp contains alloca call.  */
-+bool
-+alloca_call_p (exp)
-+     tree exp;
-+{
-+  if (TREE_CODE (exp) == CALL_EXPR
-+      && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
-+      && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
-+        == FUNCTION_DECL)
-+      && (special_function_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
-+                            0) & ECF_MAY_BE_ALLOCA))
-+    return true;
-+  return false;
-+}
-+
-+/* Detect flags (function attributes) from the function decl or type node.  */
-+
-+static int
-+flags_from_decl_or_type (exp)
-+     tree exp;
-+{
-+  int flags = 0;
-+  tree type = exp;
-+  /* ??? We can't set IS_MALLOC for function types?  */
-+  if (DECL_P (exp))
-+    {
-+      type = TREE_TYPE (exp);
-+
-+      /* The function exp may have the `malloc' attribute.  */
-+      if (DECL_P (exp) && DECL_IS_MALLOC (exp))
-+      flags |= ECF_MALLOC;
-+
-+      /* The function exp may have the `pure' attribute.  */
-+      if (DECL_P (exp) && DECL_IS_PURE (exp))
-+      flags |= ECF_PURE | ECF_LIBCALL_BLOCK;
-+
-+      if (TREE_NOTHROW (exp))
-+      flags |= ECF_NOTHROW;
-+
-+      if (TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp))
-+      flags |= ECF_LIBCALL_BLOCK;
-+    }
-+
-+  if (TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp))
-+    flags |= ECF_CONST;
-+
-+  if (TREE_THIS_VOLATILE (exp))
-+    flags |= ECF_NORETURN;
-+
-+  /* Mark if the function returns with the stack pointer depressed.   We
-+     cannot consider it pure or constant in that case.  */
-+  if (TREE_CODE (type) == FUNCTION_TYPE && TYPE_RETURNS_STACK_DEPRESSED (type))
-+    {
-+      flags |= ECF_SP_DEPRESSED;
-+      flags &= ~(ECF_PURE | ECF_CONST | ECF_LIBCALL_BLOCK);
-+    }
-+
-+  return flags;
-+}
-+
-+/* Precompute all register parameters as described by ARGS, storing values
-+   into fields within the ARGS array.
-+
-+   NUM_ACTUALS indicates the total number elements in the ARGS array.
-+
-+   Set REG_PARM_SEEN if we encounter a register parameter.  */
-+
-+static void
-+precompute_register_parameters (num_actuals, args, reg_parm_seen)
-+     int num_actuals;
-+     struct arg_data *args;
-+     int *reg_parm_seen;
-+{
-+  int i;
-+
-+  *reg_parm_seen = 0;
-+
-+  for (i = 0; i < num_actuals; i++)
-+    if (args[i].reg != 0 && ! args[i].pass_on_stack)
-+      {
-+      *reg_parm_seen = 1;
-+
-+      if (args[i].value == 0)
-+        {
-+          push_temp_slots ();
-+          args[i].value = expand_expr (args[i].tree_value, NULL_RTX,
-+                                       VOIDmode, 0);
-+          preserve_temp_slots (args[i].value);
-+          pop_temp_slots ();
-+
-+          /* ANSI doesn't require a sequence point here,
-+             but PCC has one, so this will avoid some problems.  */
-+          emit_queue ();
-+        }
-+
-+      /* If the value is a non-legitimate constant, force it into a
-+         pseudo now.  TLS symbols sometimes need a call to resolve.  */
-+      if (CONSTANT_P (args[i].value)
-+          && !LEGITIMATE_CONSTANT_P (args[i].value))
-+        args[i].value = force_reg (args[i].mode, args[i].value);
-+
-+      /* If we are to promote the function arg to a wider mode,
-+         do it now.  */
-+
-+      if (args[i].mode != TYPE_MODE (TREE_TYPE (args[i].tree_value)))
-+        args[i].value
-+          = convert_modes (args[i].mode,
-+                           TYPE_MODE (TREE_TYPE (args[i].tree_value)),
-+                           args[i].value, args[i].unsignedp);
-+
-+      /* If the value is expensive, and we are inside an appropriately
-+         short loop, put the value into a pseudo and then put the pseudo
-+         into the hard reg.
-+
-+         For small register classes, also do this if this call uses
-+         register parameters.  This is to avoid reload conflicts while
-+         loading the parameters registers.  */
-+
-+      if ((! (GET_CODE (args[i].value) == REG
-+              || (GET_CODE (args[i].value) == SUBREG
-+                  && GET_CODE (SUBREG_REG (args[i].value)) == REG)))
-+          && args[i].mode != BLKmode
-+          && rtx_cost (args[i].value, SET) > COSTS_N_INSNS (1)
-+          && ((SMALL_REGISTER_CLASSES && *reg_parm_seen)
-+              || preserve_subexpressions_p ()))
-+        args[i].value = copy_to_mode_reg (args[i].mode, args[i].value);
-+      }
-+}
-+
-+#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
-+     parameters, we must save and restore it.  */
-+
-+static rtx
-+save_fixed_argument_area (reg_parm_stack_space, argblock,
-+                        low_to_save, high_to_save)
-+     int reg_parm_stack_space;
-+     rtx argblock;
-+     int *low_to_save;
-+     int *high_to_save;
-+{
-+  int i;
-+  rtx save_area = NULL_RTX;
-+
-+  /* Compute the boundary of the that needs to be saved, if any.  */
-+#ifdef ARGS_GROW_DOWNWARD
-+  for (i = 0; i < reg_parm_stack_space + 1; i++)
-+#else
-+  for (i = 0; i < reg_parm_stack_space; i++)
-+#endif
-+    {
-+      if (i >= highest_outgoing_arg_in_use
-+        || stack_usage_map[i] == 0)
-+      continue;
-+
-+      if (*low_to_save == -1)
-+      *low_to_save = i;
-+
-+      *high_to_save = i;
-+    }
-+
-+  if (*low_to_save >= 0)
-+    {
-+      int num_to_save = *high_to_save - *low_to_save + 1;
-+      enum machine_mode save_mode
-+      = mode_for_size (num_to_save * BITS_PER_UNIT, MODE_INT, 1);
-+      rtx stack_area;
-+
-+      /* If we don't have the required alignment, must do this in BLKmode.  */
-+      if ((*low_to_save & (MIN (GET_MODE_SIZE (save_mode),
-+                              BIGGEST_ALIGNMENT / UNITS_PER_WORD) - 1)))
-+      save_mode = BLKmode;
-+
-+#ifdef ARGS_GROW_DOWNWARD
-+      stack_area
-+      = gen_rtx_MEM (save_mode,
-+                     memory_address (save_mode,
-+                                     plus_constant (argblock,
-+                                                    - *high_to_save)));
-+#else
-+      stack_area = gen_rtx_MEM (save_mode,
-+                              memory_address (save_mode,
-+                                              plus_constant (argblock,
-+                                                             *low_to_save)));
-+#endif
-+
-+      set_mem_align (stack_area, PARM_BOUNDARY);
-+      if (save_mode == BLKmode)
-+      {
-+        save_area = assign_stack_temp (BLKmode, num_to_save, 0);
-+        emit_block_move (validize_mem (save_area), stack_area,
-+                         GEN_INT (num_to_save), BLOCK_OP_CALL_PARM);
-+      }
-+      else
-+      {
-+        save_area = gen_reg_rtx (save_mode);
-+        emit_move_insn (save_area, stack_area);
-+      }
-+    }
-+
-+  return save_area;
-+}
-+
-+static void
-+restore_fixed_argument_area (save_area, argblock, high_to_save, low_to_save)
-+     rtx save_area;
-+     rtx argblock;
-+     int high_to_save;
-+     int low_to_save;
-+{
-+  enum machine_mode save_mode = GET_MODE (save_area);
-+#ifdef ARGS_GROW_DOWNWARD
-+  rtx stack_area
-+    = gen_rtx_MEM (save_mode,
-+                 memory_address (save_mode,
-+                                 plus_constant (argblock,
-+                                                - high_to_save)));
-+#else
-+  rtx stack_area
-+    = gen_rtx_MEM (save_mode,
-+                 memory_address (save_mode,
-+                                 plus_constant (argblock,
-+                                                low_to_save)));
-+#endif
-+
-+  if (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),
-+                   BLOCK_OP_CALL_PARM);
-+}
-+#endif /* REG_PARM_STACK_SPACE */
-+
-+/* If any elements in ARGS refer to parameters that are to be passed in
-+   registers, but not in memory, and whose alignment does not permit a
-+   direct copy into registers.  Copy the values into a group of pseudos
-+   which we will later copy into the appropriate hard registers.
-+
-+   Pseudos for each unaligned argument will be stored into the array
-+   args[argnum].aligned_regs.  The caller is responsible for deallocating
-+   the aligned_regs array if it is nonzero.  */
-+
-+static void
-+store_unaligned_arguments_into_pseudos (args, num_actuals)
-+     struct arg_data *args;
-+     int num_actuals;
-+{
-+  int i, j;
-+
-+  for (i = 0; i < num_actuals; i++)
-+    if (args[i].reg != 0 && ! args[i].pass_on_stack
-+      && args[i].mode == BLKmode
-+      && (TYPE_ALIGN (TREE_TYPE (args[i].tree_value))
-+          < (unsigned int) MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD)))
-+      {
-+      int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
-+      int big_endian_correction = 0;
-+
-+      args[i].n_aligned_regs
-+        = args[i].partial ? args[i].partial
-+          : (bytes + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
-+
-+      args[i].aligned_regs = (rtx *) xmalloc (sizeof (rtx)
-+                                              * args[i].n_aligned_regs);
-+
-+      /* Structures smaller than a word are aligned to the least
-+         significant byte (to the right).  On a BYTES_BIG_ENDIAN machine,
-+         this means we must skip the empty high order bytes when
-+         calculating the bit offset.  */
-+      if (BYTES_BIG_ENDIAN
-+          && bytes < UNITS_PER_WORD)
-+        big_endian_correction = (BITS_PER_WORD  - (bytes * BITS_PER_UNIT));
-+
-+      for (j = 0; j < args[i].n_aligned_regs; j++)
-+        {
-+          rtx reg = gen_reg_rtx (word_mode);
-+          rtx word = operand_subword_force (args[i].value, j, BLKmode);
-+          int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD);
-+
-+          args[i].aligned_regs[j] = reg;
-+
-+          /* There is no need to restrict this code to loading items
-+             in TYPE_ALIGN sized hunks.  The bitfield instructions can
-+             load up entire word sized registers efficiently.
-+
-+             ??? This may not be needed anymore.
-+             We use to emit a clobber here but that doesn't let later
-+             passes optimize the instructions we emit.  By storing 0 into
-+             the register later passes know the first AND to zero out the
-+             bitfield being set in the register is unnecessary.  The store
-+             of 0 will be deleted as will at least the first AND.  */
-+
-+          emit_move_insn (reg, const0_rtx);
-+
-+          bytes -= bitsize / BITS_PER_UNIT;
-+          store_bit_field (reg, bitsize, big_endian_correction, word_mode,
-+                           extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
-+                                              word_mode, word_mode,
-+                                              BITS_PER_WORD),
-+                           BITS_PER_WORD);
-+        }
-+      }
-+}
-+
-+/* Fill in ARGS_SIZE and ARGS array based on the parameters found in
-+   ACTPARMS.
-+
-+   NUM_ACTUALS is the total number of parameters.
-+
-+   N_NAMED_ARGS is the total number of named arguments.
-+
-+   FNDECL is the tree code for the target of this call (if known)
-+
-+   ARGS_SO_FAR holds state needed by the target to know where to place
-+   the next argument.
-+
-+   REG_PARM_STACK_SPACE is the number of bytes of stack space reserved
-+   for arguments which are passed in registers.
-+
-+   OLD_STACK_LEVEL is a pointer to an rtx which olds the old stack level
-+   and may be modified by this routine.
-+
-+   OLD_PENDING_ADJ, MUST_PREALLOCATE and 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,
-+                               ecf_flags)
-+     int num_actuals ATTRIBUTE_UNUSED;
-+     struct arg_data *args;
-+     struct args_size *args_size;
-+     int n_named_args ATTRIBUTE_UNUSED;
-+     tree actparms;
-+     tree fndecl;
-+     CUMULATIVE_ARGS *args_so_far;
-+     int reg_parm_stack_space;
-+     rtx *old_stack_level;
-+     int *old_pending_adj;
-+     int *must_preallocate;
-+     int *ecf_flags;
-+{
-+  /* 1 if scanning parms front to back, -1 if scanning back to front.  */
-+  int inc;
-+
-+  /* Count arg position in order args appear.  */
-+  int argpos;
-+
-+  struct args_size alignment_pad;
-+  int i;
-+  tree p;
-+
-+  args_size->constant = 0;
-+  args_size->var = 0;
-+
-+  /* In this loop, we consider args in the order they are written.
-+     We fill up ARGS from the front or from the back if necessary
-+     so that in any case the first arg to be pushed ends up at the front.  */
-+
-+  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++)
-+    {
-+      tree type = TREE_TYPE (TREE_VALUE (p));
-+      int unsignedp;
-+      enum machine_mode mode;
-+
-+      args[i].tree_value = TREE_VALUE (p);
-+
-+      /* Replace erroneous argument with constant zero.  */
-+      if (type == error_mark_node || !COMPLETE_TYPE_P (type))
-+      args[i].tree_value = integer_zero_node, type = integer_type_node;
-+
-+      /* If TYPE is a transparent union, pass things the way we would
-+       pass the first field of the union.  We have already verified that
-+       the modes are the same.  */
-+      if (TREE_CODE (type) == UNION_TYPE && TYPE_TRANSPARENT_UNION (type))
-+      type = TREE_TYPE (TYPE_FIELDS (type));
-+
-+      /* Decide where to pass this arg.
-+
-+       args[i].reg is nonzero if all or part is passed in registers.
-+
-+       args[i].partial is nonzero if part but not all is passed in registers,
-+       and the exact value says how many words are passed in registers.
-+
-+       args[i].pass_on_stack is nonzero if the argument must at least be
-+       computed on the stack.  It may then be loaded back into registers
-+       if args[i].reg is nonzero.
-+
-+       These decisions are driven by the FUNCTION_... macros and must agree
-+       with those made by function.c.  */
-+
-+      /* See if this argument should be passed by invisible reference.  */
-+      if ((TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
-+         && contains_placeholder_p (TYPE_SIZE (type)))
-+        || TREE_ADDRESSABLE (type)
-+#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
-+        || FUNCTION_ARG_PASS_BY_REFERENCE (*args_so_far, TYPE_MODE (type),
-+                                           type, argpos < n_named_args)
-+#endif
-+        )
-+      {
-+        /* If we're compiling a thunk, pass through invisible
-+             references instead of making a copy.  */
-+        if (current_function_is_thunk
-+#ifdef FUNCTION_ARG_CALLEE_COPIES
-+            || (FUNCTION_ARG_CALLEE_COPIES (*args_so_far, TYPE_MODE (type),
-+                                           type, argpos < n_named_args)
-+                /* If it's in a register, we must make a copy of it too.  */
-+                /* ??? Is this a sufficient test?  Is there a better one? */
-+                && !(TREE_CODE (args[i].tree_value) == VAR_DECL
-+                     && REG_P (DECL_RTL (args[i].tree_value)))
-+                && ! TREE_ADDRESSABLE (type))
-+#endif
-+            )
-+          {
-+            /* C++ uses a TARGET_EXPR to indicate that we want to make a
-+               new object from the argument.  If we are passing by
-+               invisible reference, the callee will do that for us, so we
-+               can strip off the TARGET_EXPR.  This is not always safe,
-+               but it is safe in the only case where this is a useful
-+               optimization; namely, when the argument is a plain object.
-+               In that case, the frontend is just asking the backend to
-+               make a bitwise copy of the argument.  */
-+
-+            if (TREE_CODE (args[i].tree_value) == TARGET_EXPR
-+                && (DECL_P (TREE_OPERAND (args[i].tree_value, 1)))
-+                && ! REG_P (DECL_RTL (TREE_OPERAND (args[i].tree_value, 1))))
-+              args[i].tree_value = TREE_OPERAND (args[i].tree_value, 1);
-+
-+            args[i].tree_value = build1 (ADDR_EXPR,
-+                                         build_pointer_type (type),
-+                                         args[i].tree_value);
-+            type = build_pointer_type (type);
-+          }
-+        else if (TREE_CODE (args[i].tree_value) == TARGET_EXPR)
-+          {
-+            /* In the V3 C++ ABI, parameters are destroyed in the caller.
-+               We implement this by passing the address of the temporary
-+               rather than expanding it into another allocated slot.  */
-+            args[i].tree_value = build1 (ADDR_EXPR,
-+                                         build_pointer_type (type),
-+                                         args[i].tree_value);
-+            type = build_pointer_type (type);
-+          }
-+        else
-+          {
-+            /* We make a copy of the object and pass the address to the
-+               function being called.  */
-+            rtx copy;
-+
-+            if (!COMPLETE_TYPE_P (type)
-+                || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
-+                || (flag_stack_check && ! STACK_CHECK_BUILTIN
-+                    && (0 < compare_tree_int (TYPE_SIZE_UNIT (type),
-+                                              STACK_CHECK_MAX_VAR_SIZE))))
-+              {
-+                /* This is a variable-sized object.  Make space on the stack
-+                   for it.  */
-+                rtx size_rtx = expr_size (TREE_VALUE (p));
-+
-+                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;
-+                  }
-+
-+                copy = gen_rtx_MEM (BLKmode,
-+                                    allocate_dynamic_stack_space
-+                                    (size_rtx, NULL_RTX, TYPE_ALIGN (type)));
-+                set_mem_attributes (copy, type, 1);
-+              }
-+            else
-+              copy = assign_temp (type, 0, 1, 0);
-+
-+            store_expr (args[i].tree_value, copy, 0);
-+            *ecf_flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
-+
-+            args[i].tree_value = build1 (ADDR_EXPR,
-+                                         build_pointer_type (type),
-+                                         make_tree (type, copy));
-+            type = build_pointer_type (type);
-+          }
-+      }
-+
-+      mode = TYPE_MODE (type);
-+      unsignedp = TREE_UNSIGNED (type);
-+
-+#ifdef PROMOTE_FUNCTION_ARGS
-+      mode = promote_mode (type, mode, &unsignedp, 1);
-+#endif
-+
-+      args[i].unsignedp = unsignedp;
-+      args[i].mode = mode;
-+
-+      args[i].reg = FUNCTION_ARG (*args_so_far, mode, type,
-+                                argpos < n_named_args);
-+#ifdef FUNCTION_INCOMING_ARG
-+      /* 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.  */
-+      args[i].tail_call_reg = FUNCTION_INCOMING_ARG (*args_so_far, mode, type,
-+                                                   argpos < n_named_args);
-+#else
-+      args[i].tail_call_reg = args[i].reg;
-+#endif
-+
-+#ifdef FUNCTION_ARG_PARTIAL_NREGS
-+      if (args[i].reg)
-+      args[i].partial
-+        = FUNCTION_ARG_PARTIAL_NREGS (*args_so_far, mode, type,
-+                                      argpos < n_named_args);
-+#endif
-+
-+      args[i].pass_on_stack = MUST_PASS_IN_STACK (mode, type);
-+
-+      /* If FUNCTION_ARG returned a (parallel [(expr_list (nil) ...) ...]),
-+       it means that we are to pass this arg in the register(s) designated
-+       by the PARALLEL, but also to pass it in the stack.  */
-+      if (args[i].reg && GET_CODE (args[i].reg) == PARALLEL
-+        && XEXP (XVECEXP (args[i].reg, 0, 0), 0) == 0)
-+      args[i].pass_on_stack = 1;
-+
-+      /* If this is an addressable type, we must preallocate the stack
-+       since we must evaluate the object into its final location.
-+
-+       If this is to be passed in both registers and the stack, it is simpler
-+       to preallocate.  */
-+      if (TREE_ADDRESSABLE (type)
-+        || (args[i].pass_on_stack && args[i].reg != 0))
-+      *must_preallocate = 1;
-+
-+      /* If this is an addressable type, we cannot pre-evaluate it.  Thus,
-+       we cannot consider this function call constant.  */
-+      if (TREE_ADDRESSABLE (type))
-+      *ecf_flags &= ~ECF_LIBCALL_BLOCK;
-+
-+      /* Compute the stack-size of this argument.  */
-+      if (args[i].reg == 0 || args[i].partial != 0
-+        || reg_parm_stack_space > 0
-+        || args[i].pass_on_stack)
-+      locate_and_pad_parm (mode, type,
-+#ifdef STACK_PARMS_IN_REG_PARM_AREA
-+                           1,
-+#else
-+                           args[i].reg != 0,
-+#endif
-+                           fndecl, args_size, &args[i].offset,
-+                           &args[i].size, &alignment_pad);
-+
-+#ifndef ARGS_GROW_DOWNWARD
-+      args[i].slot_offset = *args_size;
-+#endif
-+
-+      args[i].alignment_pad = alignment_pad;
-+
-+      /* If a part of the arg was put into registers,
-+       don't include that part in the amount pushed.  */
-+      if (reg_parm_stack_space == 0 && ! args[i].pass_on_stack)
-+      args[i].size.constant -= ((args[i].partial * UNITS_PER_WORD)
-+                                / (PARM_BOUNDARY / BITS_PER_UNIT)
-+                                * (PARM_BOUNDARY / BITS_PER_UNIT));
-+
-+      /* Update ARGS_SIZE, the total stack space for args so far.  */
-+
-+      args_size->constant += args[i].size.constant;
-+      if (args[i].size.var)
-+      {
-+        ADD_PARM_SIZE (*args_size, args[i].size.var);
-+      }
-+
-+      /* Since the slot offset points to the bottom of the slot,
-+       we must record it after incrementing if the args grow down.  */
-+#ifdef ARGS_GROW_DOWNWARD
-+      args[i].slot_offset = *args_size;
-+
-+      args[i].slot_offset.constant = -args_size->constant;
-+      if (args_size->var)
-+      SUB_PARM_SIZE (args[i].slot_offset, args_size->var);
-+#endif
-+
-+      /* Increment ARGS_SO_FAR, which has info about which arg-registers
-+       have been used, etc.  */
-+
-+      FUNCTION_ARG_ADVANCE (*args_so_far, TYPE_MODE (type), type,
-+                          argpos < n_named_args);
-+    }
-+}
-+
-+/* Update ARGS_SIZE to contain the total size for the argument block.
-+   Return the original constant component of the argument block's size.
-+
-+   REG_PARM_STACK_SPACE holds the number of bytes of stack space reserved
-+   for arguments passed in registers.  */
-+
-+static int
-+compute_argument_block_size (reg_parm_stack_space, args_size,
-+                           preferred_stack_boundary)
-+     int reg_parm_stack_space;
-+     struct args_size *args_size;
-+     int preferred_stack_boundary ATTRIBUTE_UNUSED;
-+{
-+  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 misaligned frame sizes.  */
-+  if (ACCUMULATE_OUTGOING_ARGS && preferred_stack_boundary > STACK_BOUNDARY)
-+    preferred_stack_boundary = STACK_BOUNDARY;
-+
-+  /* Compute the actual size of the argument block required.  The variable
-+     and constant sizes must be combined, the size may have to be rounded,
-+     and there may be a minimum required size.  */
-+
-+  if (args_size->var)
-+    {
-+      args_size->var = ARGS_SIZE_TREE (*args_size);
-+      args_size->constant = 0;
-+
-+      preferred_stack_boundary /= BITS_PER_UNIT;
-+      if (preferred_stack_boundary > 1)
-+      {
-+        /* We don't handle this case yet.  To handle it correctly we have
-+           to add the delta, round and subtract 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);
-+      }
-+
-+      if (reg_parm_stack_space > 0)
-+      {
-+        args_size->var
-+          = size_binop (MAX_EXPR, args_size->var,
-+                        ssize_int (reg_parm_stack_space));
-+
-+#ifndef OUTGOING_REG_PARM_STACK_SPACE
-+        /* The area corresponding to register parameters is not to count in
-+           the size of the block we need.  So make the adjustment.  */
-+        args_size->var
-+          = size_binop (MINUS_EXPR, args_size->var,
-+                        ssize_int (reg_parm_stack_space));
-+#endif
-+      }
-+    }
-+  else
-+    {
-+      preferred_stack_boundary /= BITS_PER_UNIT;
-+      if (preferred_stack_boundary < 1)
-+      preferred_stack_boundary = 1;
-+      args_size->constant = (((args_size->constant
-+                             + stack_pointer_delta
-+                             + preferred_stack_boundary - 1)
-+                            / preferred_stack_boundary
-+                            * preferred_stack_boundary)
-+                           - stack_pointer_delta);
-+
-+      args_size->constant = MAX (args_size->constant,
-+                               reg_parm_stack_space);
-+
-+#ifdef MAYBE_REG_PARM_STACK_SPACE
-+      if (reg_parm_stack_space == 0)
-+      args_size->constant = 0;
-+#endif
-+
-+#ifndef OUTGOING_REG_PARM_STACK_SPACE
-+      args_size->constant -= reg_parm_stack_space;
-+#endif
-+    }
-+  return unadjusted_args_size;
-+}
-+
-+/* Precompute parameters as needed for a function call.
-+
-+   FLAGS is mask of ECF_* constants.
-+
-+   NUM_ACTUALS is the number of arguments.
-+
-+   ARGS is an array containing information for each argument; this
-+   routine fills in the INITIAL_VALUE and VALUE fields for each
-+   precomputed argument.  */
-+
-+static void
-+precompute_arguments (flags, num_actuals, args)
-+     int flags;
-+     int num_actuals;
-+     struct arg_data *args;
-+{
-+  int i;
-+
-+  /* If this function call is cse'able, precompute all the parameters.
-+     Note that if the parameter is constructed into a temporary, this will
-+     cause an additional copy because the parameter will be constructed
-+     into a temporary location and then copied into the outgoing arguments.
-+     If a parameter contains a call to alloca and this function uses the
-+     stack, precompute the parameter.  */
-+
-+  /* If we preallocated the stack space, and some arguments must be passed
-+     on the stack, then we must precompute any parameter which contains a
-+     function call which will store arguments on the stack.
-+     Otherwise, evaluating the parameter may clobber previous parameters
-+     which have already been stored into the stack.  (we have code to avoid
-+     such case by saving the outgoing stack arguments, but it results in
-+     worse code)  */
-+
-+  for (i = 0; i < num_actuals; i++)
-+    if ((flags & ECF_LIBCALL_BLOCK)
-+      || calls_function (args[i].tree_value, !ACCUMULATE_OUTGOING_ARGS))
-+      {
-+      enum machine_mode mode;
-+
-+      /* If this is an addressable type, we cannot pre-evaluate it.  */
-+      if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))
-+        abort ();
-+
-+      args[i].value
-+        = expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0);
-+
-+      /* ANSI doesn't require a sequence point here,
-+         but PCC has one, so this will avoid some problems.  */
-+      emit_queue ();
-+
-+      args[i].initial_value = args[i].value
-+        = protect_from_queue (args[i].value, 0);
-+
-+      mode = TYPE_MODE (TREE_TYPE (args[i].tree_value));
-+      if (mode != args[i].mode)
-+        {
-+          args[i].value
-+            = convert_modes (args[i].mode, mode,
-+                             args[i].value, args[i].unsignedp);
-+#ifdef PROMOTE_FOR_CALL_ONLY
-+          /* CSE will replace this only if it contains args[i].value
-+             pseudo, so convert it down to the declared mode using
-+             a SUBREG.  */
-+          if (GET_CODE (args[i].value) == REG
-+              && GET_MODE_CLASS (args[i].mode) == MODE_INT)
-+            {
-+              args[i].initial_value
-+                = gen_lowpart_SUBREG (mode, args[i].value);
-+              SUBREG_PROMOTED_VAR_P (args[i].initial_value) = 1;
-+              SUBREG_PROMOTED_UNSIGNED_SET (args[i].initial_value,
-+                args[i].unsignedp);
-+            }
-+#endif
-+        }
-+      }
-+}
-+
-+/* Given the current state of MUST_PREALLOCATE and information about
-+   arguments to a function call in NUM_ACTUALS, ARGS and ARGS_SIZE,
-+   compute and return the final value for MUST_PREALLOCATE.  */
-+
-+static int
-+finalize_must_preallocate (must_preallocate, num_actuals, args, args_size)
-+     int must_preallocate;
-+     int num_actuals;
-+     struct arg_data *args;
-+     struct args_size *args_size;
-+{
-+  /* See if we have or want to preallocate stack space.
-+
-+     If we would have to push a partially-in-regs parm
-+     before other stack parms, preallocate stack space instead.
-+
-+     If the size of some parm is not a multiple of the required stack
-+     alignment, we must preallocate.
-+
-+     If the total size of arguments that would otherwise create a copy in
-+     a temporary (such as a CALL) is more than half the total argument list
-+     size, preallocation is faster.
-+
-+     Another reason to preallocate is if we have a machine (like the m88k)
-+     where stack alignment is required to be maintained between every
-+     pair of insns, not just when the call is made.  However, we assume here
-+     that such machines either do not have push insns (and hence preallocation
-+     would occur anyway) or the problem is taken care of with
-+     PUSH_ROUNDING.  */
-+
-+  if (! must_preallocate)
-+    {
-+      int partial_seen = 0;
-+      int copy_to_evaluate_size = 0;
-+      int i;
-+
-+      for (i = 0; i < num_actuals && ! must_preallocate; i++)
-+      {
-+        if (args[i].partial > 0 && ! args[i].pass_on_stack)
-+          partial_seen = 1;
-+        else if (partial_seen && args[i].reg == 0)
-+          must_preallocate = 1;
-+
-+        if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode
-+            && (TREE_CODE (args[i].tree_value) == CALL_EXPR
-+                || TREE_CODE (args[i].tree_value) == TARGET_EXPR
-+                || TREE_CODE (args[i].tree_value) == COND_EXPR
-+                || TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value))))
-+          copy_to_evaluate_size
-+            += int_size_in_bytes (TREE_TYPE (args[i].tree_value));
-+      }
-+
-+      if (copy_to_evaluate_size * 2 >= args_size->constant
-+        && args_size->constant > 0)
-+      must_preallocate = 1;
-+    }
-+  return must_preallocate;
-+}
-+
-+/* If we preallocated stack space, compute the address of each argument
-+   and store it into the ARGS array.
-+
-+   We need not ensure it is a valid memory address here; it will be
-+   validized when it is used.
-+
-+   ARGBLOCK is an rtx for the address of the outgoing arguments.  */
-+
-+static void
-+compute_argument_addresses (args, argblock, num_actuals)
-+     struct arg_data *args;
-+     rtx argblock;
-+     int num_actuals;
-+{
-+  if (argblock)
-+    {
-+      rtx arg_reg = argblock;
-+      int i, arg_offset = 0;
-+
-+      if (GET_CODE (argblock) == PLUS)
-+      arg_reg = XEXP (argblock, 0), arg_offset = INTVAL (XEXP (argblock, 1));
-+
-+      for (i = 0; i < num_actuals; i++)
-+      {
-+        rtx offset = ARGS_SIZE_RTX (args[i].offset);
-+        rtx slot_offset = ARGS_SIZE_RTX (args[i].slot_offset);
-+        rtx addr;
-+
-+        /* Skip this parm if it will not be passed on the stack.  */
-+        if (! args[i].pass_on_stack && args[i].reg != 0)
-+          continue;
-+
-+        if (GET_CODE (offset) == CONST_INT)
-+          addr = plus_constant (arg_reg, INTVAL (offset));
-+        else
-+          addr = gen_rtx_PLUS (Pmode, arg_reg, offset);
-+
-+        addr = plus_constant (addr, arg_offset);
-+        args[i].stack = gen_rtx_MEM (args[i].mode, addr);
-+        set_mem_align (args[i].stack, PARM_BOUNDARY);
-+        set_mem_attributes (args[i].stack,
-+                            TREE_TYPE (args[i].tree_value), 1);
-+
-+        if (GET_CODE (slot_offset) == CONST_INT)
-+          addr = plus_constant (arg_reg, INTVAL (slot_offset));
-+        else
-+          addr = gen_rtx_PLUS (Pmode, arg_reg, slot_offset);
-+
-+        addr = plus_constant (addr, arg_offset);
-+        args[i].stack_slot = gen_rtx_MEM (args[i].mode, addr);
-+        set_mem_align (args[i].stack_slot, PARM_BOUNDARY);
-+        set_mem_attributes (args[i].stack_slot,
-+                            TREE_TYPE (args[i].tree_value), 1);
-+
-+        /* Function incoming arguments may overlap with sibling call
-+           outgoing arguments and we cannot allow reordering of reads
-+           from function arguments with stores to outgoing arguments
-+           of sibling calls.  */
-+        set_mem_alias_set (args[i].stack, 0);
-+        set_mem_alias_set (args[i].stack_slot, 0);
-+      }
-+    }
-+}
-+
-+/* Given a FNDECL and EXP, return an rtx suitable for use as a target address
-+   in a call instruction.
-+
-+   FNDECL is the tree node for the target function.  For an indirect call
-+   FNDECL will be NULL_TREE.
-+
-+   ADDR is the operand 0 of CALL_EXPR for this call.  */
-+
-+static rtx
-+rtx_for_function_call (fndecl, addr)
-+     tree fndecl;
-+     tree addr;
-+{
-+  rtx funexp;
-+
-+  /* Get the function to call, in the form of RTL.  */
-+  if (fndecl)
-+    {
-+      /* If this is the first use of the function, see if we need to
-+       make an external definition for it.  */
-+      if (! TREE_USED (fndecl))
-+      {
-+        assemble_external (fndecl);
-+        TREE_USED (fndecl) = 1;
-+      }
-+
-+      /* Get a SYMBOL_REF rtx for the function address.  */
-+      funexp = XEXP (DECL_RTL (fndecl), 0);
-+    }
-+  else
-+    /* Generate an rtx (probably a pseudo-register) for the address.  */
-+    {
-+      rtx funaddr;
-+      push_temp_slots ();
-+      funaddr = funexp
-+      = expand_expr (addr, NULL_RTX, VOIDmode, 0);
-+      pop_temp_slots ();      /* FUNEXP can't be BLKmode.  */
-+      emit_queue ();
-+    }
-+  return funexp;
-+}
-+
-+/* Do the register loads required for any wholly-register parms or any
-+   parms which are passed both on the stack and in a register.  Their
-+   expressions were already evaluated.
-+
-+   Mark all register-parms as living through the call, putting these USE
-+   insns in the CALL_INSN_FUNCTION_USAGE field.  */
-+
-+static void
-+load_register_parameters (args, num_actuals, call_fusage, flags)
-+     struct arg_data *args;
-+     int num_actuals;
-+     rtx *call_fusage;
-+     int flags;
-+{
-+  int i, j;
-+
-+#ifdef LOAD_ARGS_REVERSED
-+  for (i = num_actuals - 1; i >= 0; i--)
-+#else
-+  for (i = 0; i < num_actuals; i++)
-+#endif
-+    {
-+      rtx reg = ((flags & ECF_SIBCALL)
-+               ? args[i].tail_call_reg : args[i].reg);
-+      int partial = args[i].partial;
-+      int nregs;
-+
-+      if (reg)
-+      {
-+        /* Set to non-negative if must move a word at a time, even if just
-+           one word (e.g, partial == 1 && mode == DFmode).  Set to -1 if
-+           we just use a normal move insn.  This value can be zero if the
-+           argument is a zero size structure with no fields.  */
-+        nregs = (partial ? partial
-+                 : (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode
-+                    ? ((int_size_in_bytes (TREE_TYPE (args[i].tree_value))
-+                        + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
-+                    : -1));
-+
-+        /* Handle calls that pass values in multiple non-contiguous
-+           locations.  The Irix 6 ABI has examples of this.  */
-+
-+        if (GET_CODE (reg) == PARALLEL)
-+          emit_group_load (reg, args[i].value,
-+                           int_size_in_bytes (TREE_TYPE (args[i].tree_value)));
-+
-+        /* If simple case, just do move.  If normal partial, store_one_arg
-+           has already loaded the register for us.  In all other cases,
-+           load the register(s) from memory.  */
-+
-+        else if (nregs == -1)
-+          emit_move_insn (reg, args[i].value);
-+
-+        /* If we have pre-computed the values to put in the registers in
-+           the case of non-aligned structures, copy them in now.  */
-+
-+        else if (args[i].n_aligned_regs != 0)
-+          for (j = 0; j < args[i].n_aligned_regs; j++)
-+            emit_move_insn (gen_rtx_REG (word_mode, REGNO (reg) + j),
-+                            args[i].aligned_regs[j]);
-+
-+        else if (partial == 0 || args[i].pass_on_stack)
-+          move_block_to_reg (REGNO (reg),
-+                             validize_mem (args[i].value), nregs,
-+                             args[i].mode);
-+
-+        /* Handle calls that pass values in multiple non-contiguous
-+           locations.  The Irix 6 ABI has examples of this.  */
-+        if (GET_CODE (reg) == PARALLEL)
-+          use_group_regs (call_fusage, reg);
-+        else if (nregs == -1)
-+          use_reg (call_fusage, reg);
-+        else
-+          use_regs (call_fusage, REGNO (reg), nregs == 0 ? 1 : nregs);
-+      }
-+    }
-+}
-+
-+/* Try to integrate 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 ();
-+
-+  timevar_push (TV_INTEGRATION);
-+
-+  temp = expand_inline_function (fndecl, actparms, target,
-+                               ignore, type,
-+                               structure_value_addr);
-+
-+  timevar_pop (TV_INTEGRATION);
-+
-+  /* If inlining succeeded, return.  */
-+  if (temp != (rtx) (size_t) - 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_insn_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");
-+    }
-+  (*lang_hooks.mark_addressable) (fndecl);
-+  return (rtx) (size_t) - 1;
-+}
-+
-+/* We need to pop PENDING_STACK_ADJUST bytes.  But, if the arguments
-+   wouldn't fill up an even multiple of PREFERRED_UNIT_STACK_BOUNDARY
-+   bytes, then we would need to push some additional bytes to pad the
-+   arguments.  So, we compute an adjust to the stack pointer for an
-+   amount that will leave the stack under-aligned by UNADJUSTED_ARGS_SIZE
-+   bytes.  Then, when the arguments are pushed the stack will be perfectly
-+   aligned.  ARGS_SIZE->CONSTANT is set to the number of bytes that should
-+   be popped after the call.  Returns the adjustment.  */
-+
-+static int
-+combine_pending_stack_adjustment_and_call (unadjusted_args_size,
-+                                         args_size,
-+                                         preferred_unit_stack_boundary)
-+     int unadjusted_args_size;
-+     struct args_size *args_size;
-+     int preferred_unit_stack_boundary;
-+{
-+  /* The number of bytes to pop so that the stack will be
-+     under-aligned by UNADJUSTED_ARGS_SIZE bytes.  */
-+  HOST_WIDE_INT adjustment;
-+  /* The alignment of the stack after the arguments are pushed, if we
-+     just pushed the arguments without adjust the stack here.  */
-+  HOST_WIDE_INT unadjusted_alignment;
-+
-+  unadjusted_alignment
-+    = ((stack_pointer_delta + unadjusted_args_size)
-+       % preferred_unit_stack_boundary);
-+
-+  /* We want to get rid of as many of the PENDING_STACK_ADJUST bytes
-+     as possible -- leaving just enough left to cancel out the
-+     UNADJUSTED_ALIGNMENT.  In other words, we want to ensure that the
-+     PENDING_STACK_ADJUST is non-negative, and congruent to
-+     -UNADJUSTED_ALIGNMENT modulo the PREFERRED_UNIT_STACK_BOUNDARY.  */
-+
-+  /* Begin by trying to pop all the bytes.  */
-+  unadjusted_alignment
-+    = (unadjusted_alignment
-+       - (pending_stack_adjust % preferred_unit_stack_boundary));
-+  adjustment = pending_stack_adjust;
-+  /* Push enough additional bytes that the stack will be aligned
-+     after the arguments are pushed.  */
-+  if (preferred_unit_stack_boundary > 1)
-+    {
-+      if (unadjusted_alignment > 0)
-+      adjustment -= preferred_unit_stack_boundary - unadjusted_alignment;
-+      else
-+      adjustment += unadjusted_alignment;
-+    }
-+
-+  /* Now, sets ARGS_SIZE->CONSTANT so that we pop the right number of
-+     bytes after the call.  The right number is the entire
-+     PENDING_STACK_ADJUST less our ADJUSTMENT plus the amount required
-+     by the arguments in the first place.  */
-+  args_size->constant
-+    = pending_stack_adjust - adjustment + unadjusted_args_size;
-+
-+  return adjustment;
-+}
-+
-+/* Scan X expression if it does not dereference any argument slots
-+   we already clobbered by tail call arguments (as noted in stored_args_map
-+   bitmap).
-+   Return nonzero if X expression dereferences such argument slots,
-+   zero otherwise.  */
-+
-+static int
-+check_sibcall_argument_overlap_1 (x)
-+     rtx x;
-+{
-+  RTX_CODE code;
-+  int i, j;
-+  unsigned int k;
-+  const char *fmt;
-+
-+  if (x == NULL_RTX)
-+    return 0;
-+
-+  code = GET_CODE (x);
-+
-+  if (code == MEM)
-+    {
-+      if (XEXP (x, 0) == current_function_internal_arg_pointer)
-+      i = 0;
-+      else if (GET_CODE (XEXP (x, 0)) == PLUS
-+             && XEXP (XEXP (x, 0), 0) ==
-+                current_function_internal_arg_pointer
-+             && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
-+      i = INTVAL (XEXP (XEXP (x, 0), 1));
-+      else
-+      return 0;
-+
-+#ifdef ARGS_GROW_DOWNWARD
-+      i = -i - GET_MODE_SIZE (GET_MODE (x));
-+#endif
-+
-+      for (k = 0; k < GET_MODE_SIZE (GET_MODE (x)); k++)
-+      if (i + k < stored_args_map->n_bits
-+          && TEST_BIT (stored_args_map, i + k))
-+        return 1;
-+
-+      return 0;
-+    }
-+
-+  /* Scan all subexpressions.  */
-+  fmt = GET_RTX_FORMAT (code);
-+  for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
-+    {
-+      if (*fmt == 'e')
-+      {
-+        if (check_sibcall_argument_overlap_1 (XEXP (x, i)))
-+          return 1;
-+      }
-+      else if (*fmt == 'E')
-+      {
-+        for (j = 0; j < XVECLEN (x, i); j++)
-+          if (check_sibcall_argument_overlap_1 (XVECEXP (x, i, j)))
-+            return 1;
-+      }
-+    }
-+  return 0;
-+}
-+
-+/* Scan sequence after INSN if it does not dereference any argument slots
-+   we already clobbered by tail call arguments (as noted in stored_args_map
-+   bitmap).  Add stack slots for ARG to stored_args_map bitmap afterwards.
-+   Return nonzero if sequence after INSN dereferences such argument slots,
-+   zero otherwise.  */
-+
-+static int
-+check_sibcall_argument_overlap (insn, arg)
-+     rtx insn;
-+     struct arg_data *arg;
-+{
-+  int low, high;
-+
-+  if (insn == NULL_RTX)
-+    insn = get_insns ();
-+  else
-+    insn = NEXT_INSN (insn);
-+
-+  for (; insn; insn = NEXT_INSN (insn))
-+    if (INSN_P (insn)
-+      && check_sibcall_argument_overlap_1 (PATTERN (insn)))
-+      break;
-+
-+#ifdef ARGS_GROW_DOWNWARD
-+  low = -arg->slot_offset.constant - arg->size.constant;
-+#else
-+  low = arg->slot_offset.constant;
-+#endif
-+
-+  for (high = low + arg->size.constant; low < high; low++)
-+    SET_BIT (stored_args_map, low);
-+  return insn != NULL_RTX;
-+}
-+
-+static tree
-+fix_unsafe_tree (t)
-+     tree t;
-+{
-+  switch (unsafe_for_reeval (t))
-+    {
-+    case 0: /* Safe.  */
-+      break;
-+
-+    case 1: /* Mildly unsafe.  */
-+      t = unsave_expr (t);
-+      break;
-+
-+    case 2: /* Wildly unsafe.  */
-+      {
-+      tree var = build_decl (VAR_DECL, NULL_TREE,
-+                             TREE_TYPE (t));
-+      SET_DECL_RTL (var,
-+                    expand_expr (t, NULL_RTX, VOIDmode, EXPAND_NORMAL));
-+      t = var;
-+      }
-+      break;
-+
-+    default:
-+      abort ();
-+    }
-+  return t;
-+}
-+
-+/* Generate all the code for a function call
-+   and return an rtx for its value.
-+   Store the value in TARGET (specified as an rtx) if convenient.
-+   If the value is stored in TARGET then TARGET is returned.
-+   If IGNORE is nonzero, then we ignore the value of the function call.  */
-+
-+rtx
-+expand_call (exp, target, ignore)
-+     tree exp;
-+     rtx target;
-+     int ignore;
-+{
-+  /* Nonzero if we are currently expanding a call.  */
-+  static int currently_expanding_call = 0;
-+
-+  /* List of actual parameters.  */
-+  tree actparms = TREE_OPERAND (exp, 1);
-+  /* RTX for the function to be called.  */
-+  rtx funexp;
-+  /* Sequence of insns to perform a tail recursive "call".  */
-+  rtx tail_recursion_insns = NULL_RTX;
-+  /* Sequence of insns to perform a normal "call".  */
-+  rtx normal_call_insns = NULL_RTX;
-+  /* Sequence of insns to perform a tail recursive "call".  */
-+  rtx tail_call_insns = NULL_RTX;
-+  /* Data type of the function.  */
-+  tree funtype;
-+  /* Declaration of the function being called,
-+     or 0 if the function is computed (not known by name).  */
-+  tree fndecl = 0;
-+  rtx insn;
-+  int try_tail_call = 1;
-+  int try_tail_recursion = 1;
-+  int pass;
-+
-+  /* Register in which non-BLKmode value will be returned,
-+     or 0 if no value or if value is BLKmode.  */
-+  rtx valreg;
-+  /* Address where we should return a BLKmode value;
-+     0 if value not BLKmode.  */
-+  rtx structure_value_addr = 0;
-+  /* Nonzero if that address is being passed by treating it as
-+     an extra, implicit first parameter.  Otherwise,
-+     it is passed by being copied directly into struct_value_rtx.  */
-+  int structure_value_addr_parm = 0;
-+  /* Size of aggregate value wanted, or zero if none wanted
-+     or if we are using the non-reentrant PCC calling convention
-+     or expecting the value in registers.  */
-+  HOST_WIDE_INT struct_value_size = 0;
-+  /* Nonzero if called function returns an aggregate in memory PCC style,
-+     by returning the address of where to find it.  */
-+  int pcc_struct_value = 0;
-+
-+  /* Number of actual parameters in this call, including struct value addr.  */
-+  int num_actuals;
-+  /* Number of named args.  Args after this are anonymous ones
-+     and they must all go on the stack.  */
-+  int n_named_args;
-+
-+  /* Vector of information about each argument.
-+     Arguments are numbered in the order they will be pushed,
-+     not the order they are written.  */
-+  struct arg_data *args;
-+
-+  /* Total size in bytes of all the stack-parms scanned so far.  */
-+  struct args_size args_size;
-+  struct args_size adjusted_args_size;
-+  /* Size of arguments before any adjustments (such as rounding).  */
-+  int unadjusted_args_size;
-+  /* Data on reg parms scanned so far.  */
-+  CUMULATIVE_ARGS args_so_far;
-+  /* Nonzero if a reg parm has been scanned.  */
-+  int reg_parm_seen;
-+  /* Nonzero if this is an indirect function call.  */
-+
-+  /* Nonzero if we must avoid push-insns in the args for this call.
-+     If stack space is allocated for register parameters, but not by the
-+     caller, then it is preallocated in the fixed part of the stack frame.
-+     So the entire argument block must then be preallocated (i.e., we
-+     ignore PUSH_ROUNDING in that case).  */
-+
-+  int must_preallocate = !PUSH_ARGS;
-+
-+  /* Size of the stack reserved for parameter registers.  */
-+  int reg_parm_stack_space = 0;
-+
-+  /* Address of space preallocated for stack parms
-+     (on machines that lack push insns), or 0 if space not preallocated.  */
-+  rtx argblock = 0;
-+
-+  /* Mask of ECF_ flags.  */
-+  int flags = 0;
-+  /* Nonzero if this is a call to an inline function.  */
-+  int is_integrable = 0;
-+#ifdef REG_PARM_STACK_SPACE
-+  /* Define the boundary of the register parm stack space that needs to be
-+     save, if any.  */
-+  int low_to_save = -1, high_to_save;
-+  rtx save_area = 0;          /* Place that it is saved */
-+#endif
-+
-+  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;
-+
-+  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;
-+  tree p = TREE_OPERAND (exp, 0);
-+  tree addr = TREE_OPERAND (exp, 0);
-+  int i;
-+  /* The alignment of the stack, in bits.  */
-+  HOST_WIDE_INT preferred_stack_boundary;
-+  /* The alignment of the stack, in bytes.  */
-+  HOST_WIDE_INT preferred_unit_stack_boundary;
-+
-+  /* 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.  */
-+
-+  fndecl = get_callee_fndecl (exp);
-+  if (fndecl)
-+    {
-+      if (!flag_no_inline
-+        && fndecl != current_function_decl
-+        && DECL_INLINE (fndecl)
-+        && DECL_SAVED_INSNS (fndecl)
-+        && DECL_SAVED_INSNS (fndecl)->inlinable)
-+      is_integrable = 1;
-+      else if (! TREE_ADDRESSABLE (fndecl))
-+      {
-+        /* In case this function later becomes inlinable,
-+           record that there was already a non-inline call to it.
-+
-+           Use abstraction instead of setting TREE_ADDRESSABLE
-+           directly.  */
-+        if (DECL_INLINE (fndecl) && warn_inline && !flag_no_inline
-+            && optimize > 0)
-+          {
-+            warning_with_decl (fndecl, "can't inline call to `%s'");
-+            warning ("called from here");
-+          }
-+        (*lang_hooks.mark_addressable) (fndecl);
-+      }
-+
-+      flags |= flags_from_decl_or_type (fndecl);
-+    }
-+
-+  /* If we don't have specific function to call, see if we have a
-+     attributes set in the type.  */
-+  else
-+    flags |= flags_from_decl_or_type (TREE_TYPE (TREE_TYPE (p)));
-+
-+#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
-+
-+#ifndef OUTGOING_REG_PARM_STACK_SPACE
-+  if (reg_parm_stack_space > 0 && PUSH_ARGS)
-+    must_preallocate = 1;
-+#endif
-+
-+  /* Warn if this value is an aggregate type,
-+     regardless of which calling convention we are using for it.  */
-+  if (warn_aggregate_return && AGGREGATE_TYPE_P (TREE_TYPE (exp)))
-+    warning ("function call has aggregate value");
-+
-+  /* Set up a place to return a structure.  */
-+
-+  /* Cater to broken compilers.  */
-+  if (aggregate_value_p (exp))
-+    {
-+      /* This call returns a big structure.  */
-+      flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
-+
-+#ifdef PCC_STATIC_STRUCT_RETURN
-+      {
-+      pcc_struct_value = 1;
-+      /* Easier than making that case work right.  */
-+      if (is_integrable)
-+        {
-+          /* In case this is a static function, note that it has been
-+             used.  */
-+          if (! TREE_ADDRESSABLE (fndecl))
-+            (*lang_hooks.mark_addressable) (fndecl);
-+          is_integrable = 0;
-+        }
-+      }
-+#else /* not PCC_STATIC_STRUCT_RETURN */
-+      {
-+      struct_value_size = int_size_in_bytes (TREE_TYPE (exp));
-+
-+      if (target && GET_CODE (target) == MEM)
-+        structure_value_addr = XEXP (target, 0);
-+      else
-+        {
-+          /* For variable-sized objects, we must be called with a target
-+             specified.  If we were to allocate space on the stack here,
-+             we would have no way of knowing when to free it.  */
-+          rtx d = assign_temp (TREE_TYPE (exp), 1, 1, 1);
-+
-+          mark_temp_addr_taken (d);
-+          structure_value_addr = XEXP (d, 0);
-+          target = 0;
-+        }
-+      }
-+#endif /* not PCC_STATIC_STRUCT_RETURN */
-+    }
-+
-+  /* If called function is inline, try to integrate it.  */
-+
-+  if (is_integrable)
-+    {
-+      rtx temp = try_to_integrate (fndecl, actparms, target,
-+                                 ignore, TREE_TYPE (exp),
-+                                 structure_value_addr);
-+      if (temp != (rtx) (size_t) - 1)
-+      return temp;
-+    }
-+
-+  /* Figure out the amount to which the stack should be aligned.  */
-+  preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
-+
-+  /* Operand 0 is a pointer-to-function; get the type of the function.  */
-+  funtype = TREE_TYPE (addr);
-+  if (! POINTER_TYPE_P (funtype))
-+    abort ();
-+  funtype = TREE_TYPE (funtype);
-+
-+  /* See if this is a call to a function that can return more than once
-+     or a call to longjmp or malloc.  */
-+  flags |= special_function_p (fndecl, flags);
-+
-+  if (flags & ECF_MAY_BE_ALLOCA)
-+    current_function_calls_alloca = 1;
-+
-+  /* If struct_value_rtx is 0, it means pass the address
-+     as if it were an extra parameter.  */
-+  if (structure_value_addr && struct_value_rtx == 0)
-+    {
-+      /* If structure_value_addr is a REG other than
-+       virtual_outgoing_args_rtx, we can use always use it.  If it
-+       is not a REG, we must always copy it into a register.
-+       If it is virtual_outgoing_args_rtx, we must copy it to another
-+       register in some cases.  */
-+      rtx temp = (GET_CODE (structure_value_addr) != REG
-+                || (ACCUMULATE_OUTGOING_ARGS
-+                    && stack_arg_under_construction
-+                    && structure_value_addr == virtual_outgoing_args_rtx)
-+                ? copy_addr_to_reg (structure_value_addr)
-+                : structure_value_addr);
-+
-+      actparms
-+      = tree_cons (error_mark_node,
-+                   make_tree (build_pointer_type (TREE_TYPE (funtype)),
-+                              temp),
-+                   actparms);
-+      structure_value_addr_parm = 1;
-+    }
-+
-+  /* Count the arguments and set NUM_ACTUALS.  */
-+  for (p = actparms, num_actuals = 0; p; p = TREE_CHAIN (p))
-+    num_actuals++;
-+
-+  /* Compute number of named args.
-+     Normally, don't include the last named arg if anonymous args follow.
-+     We do include the last named arg if STRICT_ARGUMENT_NAMING is nonzero.
-+     (If no anonymous args follow, the result of list_length is actually
-+     one too large.  This is harmless.)
-+
-+     If PRETEND_OUTGOING_VARARGS_NAMED is set and STRICT_ARGUMENT_NAMING is
-+     zero, this machine will be able to place unnamed args that were
-+     passed in registers into the stack.  So treat all args as named.
-+     This allows the insns emitting for a specific argument list to be
-+     independent of the function declaration.
-+
-+     If PRETEND_OUTGOING_VARARGS_NAMED is not set, we do not have any
-+     reliable way to pass unnamed args in registers, so we must force
-+     them into memory.  */
-+
-+  if ((STRICT_ARGUMENT_NAMING
-+       || ! PRETEND_OUTGOING_VARARGS_NAMED)
-+      && TYPE_ARG_TYPES (funtype) != 0)
-+    n_named_args
-+      = (list_length (TYPE_ARG_TYPES (funtype))
-+       /* Don't include the last named arg.  */
-+       - (STRICT_ARGUMENT_NAMING ? 0 : 1)
-+       /* Count the struct value address, if it is passed as a parm.  */
-+       + structure_value_addr_parm);
-+  else
-+    /* If we know nothing, treat all args as named.  */
-+    n_named_args = num_actuals;
-+
-+  /* Start updating where the next arg would go.
-+
-+     On some machines (such as the PA) indirect calls have a different
-+     calling convention than normal calls.  The last argument in
-+     INIT_CUMULATIVE_ARGS tells the backend if this is an indirect call
-+     or not.  */
-+  INIT_CUMULATIVE_ARGS (args_so_far, funtype, NULL_RTX, (fndecl == 0));
-+
-+  /* Make a vector to hold all the information about each arg.  */
-+  args = (struct arg_data *) alloca (num_actuals * sizeof (struct arg_data));
-+  memset ((char *) args, 0, num_actuals * sizeof (struct arg_data));
-+
-+  /* Build up entries in the ARGS array, compute the size of the
-+     arguments into ARGS_SIZE, etc.  */
-+  initialize_argument_information (num_actuals, args, &args_size,
-+                                 n_named_args, actparms, fndecl,
-+                                 &args_so_far, reg_parm_stack_space,
-+                                 &old_stack_level, &old_pending_adj,
-+                                 &must_preallocate, &flags);
-+
-+  if (args_size.var)
-+    {
-+      /* If this function requires a variable-sized argument list, don't
-+       try to make a cse'able block for this call.  We may be able to
-+       do this eventually, but it is too complicated to keep track of
-+       what insns go in the cse'able block and which don't.  */
-+
-+      flags &= ~ECF_LIBCALL_BLOCK;
-+      must_preallocate = 1;
-+    }
-+
-+  /* Now make final decision about preallocating stack space.  */
-+  must_preallocate = finalize_must_preallocate (must_preallocate,
-+                                              num_actuals, args,
-+                                              &args_size);
-+
-+  /* If the structure value address will reference the stack pointer, we
-+     must stabilize it.  We don't need to do this if we know that we are
-+     not going to adjust the stack pointer in processing this call.  */
-+
-+  if (structure_value_addr
-+      && (reg_mentioned_p (virtual_stack_dynamic_rtx, structure_value_addr)
-+        || reg_mentioned_p (virtual_outgoing_args_rtx,
-+                            structure_value_addr))
-+      && (args_size.var
-+        || (!ACCUMULATE_OUTGOING_ARGS && args_size.constant)))
-+    structure_value_addr = copy_to_reg (structure_value_addr);
-+
-+  /* Tail calls can make things harder to debug, and we're traditionally
-+     pushed these optimizations into -O2.  Don't try if we're already
-+     expanding a call, as that means we're an argument.  Don't try if
-+     there's cleanups, as we know there's code to follow the call.
-+
-+     If rtx_equal_function_value_matters is false, that means we've
-+     finished with regular parsing.  Which means that some of the
-+     machinery we use to generate tail-calls is no longer in place.
-+     This is most often true of sjlj-exceptions, which we couldn't
-+     tail-call to anyway.  */
-+
-+  if (currently_expanding_call++ != 0
-+      || !flag_optimize_sibling_calls
-+      || !rtx_equal_function_value_matters
-+      || any_pending_cleanups (1)
-+      || args_size.var)
-+    try_tail_call = try_tail_recursion = 0;
-+
-+  /* Tail recursion fails, when we are not dealing with recursive calls.  */
-+  if (!try_tail_recursion
-+      || TREE_CODE (addr) != ADDR_EXPR
-+      || TREE_OPERAND (addr, 0) != current_function_decl)
-+    try_tail_recursion = 0;
-+
-+  /*  Rest of purposes for tail call optimizations to fail.  */
-+  if (
-+#ifdef HAVE_sibcall_epilogue
-+      !HAVE_sibcall_epilogue
-+#else
-+      1
-+#endif
-+      || !try_tail_call
-+      /* Doing sibling call optimization needs some work, since
-+       structure_value_addr can be allocated on the stack.
-+       It does not seem worth the effort since few optimizable
-+       sibling calls will return a structure.  */
-+      || structure_value_addr != NULL_RTX
-+      /* If the register holding the address is a callee saved
-+       register, then we lose.  We have no way to prevent that,
-+       so we only allow calls to named functions.  */
-+      /* ??? This could be done by having the insn constraints
-+       use a register class that is all call-clobbered.  Any
-+       reload insns generated to fix things up would appear
-+       before the sibcall_epilogue.  */
-+      || fndecl == NULL_TREE
-+      || (flags & (ECF_RETURNS_TWICE | ECF_LONGJMP | ECF_NORETURN))
-+      || !FUNCTION_OK_FOR_SIBCALL (fndecl)
-+      /* If this function requires more stack slots than the current
-+       function, we cannot change it into a sibling call.  */
-+      || args_size.constant > current_function_args_size
-+      /* If the callee pops its own arguments, then it must pop exactly
-+       the same number of arguments as the current function.  */
-+      || (RETURN_POPS_ARGS (fndecl, funtype, args_size.constant)
-+        != RETURN_POPS_ARGS (current_function_decl,
-+                             TREE_TYPE (current_function_decl),
-+                             current_function_args_size))
-+      || !(*lang_hooks.decls.ok_for_sibcall) (fndecl))
-+    try_tail_call = 0;
-+
-+  if (try_tail_call || try_tail_recursion)
-+    {
-+      int end, inc;
-+      actparms = NULL_TREE;
-+      /* Ok, we're going to give the tail call the old college try.
-+       This means we're going to evaluate the function arguments
-+       up to three times.  There are two degrees of badness we can
-+       encounter, those that can be unsaved and those that can't.
-+       (See unsafe_for_reeval commentary for details.)
-+
-+       Generate a new argument list.  Pass safe arguments through
-+       unchanged.  For the easy badness wrap them in UNSAVE_EXPRs.
-+       For hard badness, evaluate them now and put their resulting
-+       rtx in a temporary VAR_DECL.
-+
-+       initialize_argument_information has ordered the array for the
-+       order to be pushed, and we must remember this when reconstructing
-+       the original argument order.  */
-+
-+      if (PUSH_ARGS_REVERSED)
-+      {
-+        inc = 1;
-+        i = 0;
-+        end = num_actuals;
-+      }
-+      else
-+      {
-+        inc = -1;
-+        i = num_actuals - 1;
-+        end = -1;
-+      }
-+
-+      for (; i != end; i += inc)
-+      {
-+          args[i].tree_value = fix_unsafe_tree (args[i].tree_value);
-+        /* We need to build actparms for optimize_tail_recursion.  We can
-+           safely trash away TREE_PURPOSE, since it is unused by this
-+           function.  */
-+        if (try_tail_recursion)
-+          actparms = tree_cons (NULL_TREE, args[i].tree_value, actparms);
-+      }
-+      /* Do the same for the function address if it is an expression. */
-+      if (!fndecl)
-+        addr = fix_unsafe_tree (addr);
-+      /* Expanding one of those dangerous arguments could have added
-+       cleanups, but otherwise give it a whirl.  */
-+      if (any_pending_cleanups (1))
-+      try_tail_call = try_tail_recursion = 0;
-+    }
-+
-+  /* Generate a tail recursion sequence when calling ourselves.  */
-+
-+  if (try_tail_recursion)
-+    {
-+      /* We want to emit any pending stack adjustments before the tail
-+       recursion "call".  That way we know any adjustment after the tail
-+       recursion call can be ignored if we indeed use the tail recursion
-+       call expansion.  */
-+      int save_pending_stack_adjust = pending_stack_adjust;
-+      int save_stack_pointer_delta = stack_pointer_delta;
-+
-+      /* Emit any queued insns now; otherwise they would end up in
-+       only one of the alternates.  */
-+      emit_queue ();
-+
-+      /* 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.  */
-+      start_sequence ();
-+      /* If expanding any of the arguments creates cleanups, we can't
-+       do a tailcall.  So, we'll need to pop the pending cleanups
-+       list.  If, however, all goes well, and there are no cleanups
-+       then the call to expand_start_target_temps will have no
-+       effect.  */
-+      expand_start_target_temps ();
-+      if (optimize_tail_recursion (actparms, get_last_insn ()))
-+      {
-+        if (any_pending_cleanups (1))
-+          try_tail_call = try_tail_recursion = 0;
-+        else
-+          tail_recursion_insns = get_insns ();
-+      }
-+      expand_end_target_temps ();
-+      end_sequence ();
-+
-+      /* 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;
-+    }
-+
-+  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
-+       profile information we have gathered so far, and clear it.  */
-+      /* ??? When Linux's __clone is called with CLONE_VM set, profiling
-+       is subject to race conditions, just as with multithreaded
-+       programs.  */
-+
-+      emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__bb_fork_func"),
-+                       LCT_ALWAYS_RETURN,
-+                       VOIDmode, 0);
-+    }
-+
-+  /* Ensure current function's preferred stack boundary is at least
-+     what we need.  We don't have to increase alignment for recursive
-+     functions.  */
-+  if (cfun->preferred_stack_boundary < preferred_stack_boundary
-+      && fndecl != current_function_decl)
-+    cfun->preferred_stack_boundary = preferred_stack_boundary;
-+
-+  preferred_unit_stack_boundary = preferred_stack_boundary / BITS_PER_UNIT;
-+
-+  function_call_count++;
-+
-+  /* We want to make two insn chains; one for a sibling call, the other
-+     for a normal call.  We will select one of the two chains after
-+     initial RTL generation is complete.  */
-+  for (pass = 0; pass < 2; pass++)
-+    {
-+      int sibcall_failure = 0;
-+      /* We want to emit any pending stack adjustments before the tail
-+       recursion "call".  That way we know any adjustment after the tail
-+       recursion call can be ignored if we indeed use the tail recursion
-+       call expansion.  */
-+      int save_pending_stack_adjust = 0;
-+      int save_stack_pointer_delta = 0;
-+      rtx insns;
-+      rtx before_call, next_arg_reg;
-+
-+      if (pass == 0)
-+      {
-+        if (! try_tail_call)
-+          continue;
-+
-+        /* Emit any queued insns now; otherwise they would end up in
-+             only one of the alternates.  */
-+        emit_queue ();
-+
-+        /* 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).  */
-+      argblock = 0;
-+      call_fusage = 0;
-+
-+      /* Start a new sequence for the normal call case.
-+
-+       From this point on, if the sibling call fails, we want to set
-+       sibcall_failure instead of continuing the loop.  */
-+      start_sequence ();
-+
-+      if (pass == 0)
-+      {
-+        /* 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
-+           able to get rid of them.  */
-+        expand_start_target_temps ();
-+      }
-+
-+      /* Don't let pending stack adjusts add up to too much.
-+       Also, do all pending adjustments now if there is any chance
-+       this might be a call to alloca or if we are expanding a sibling
-+       call sequence or if we are calling a function that is to return
-+       with stack pointer depressed.  */
-+      if (pending_stack_adjust >= 32
-+        || (pending_stack_adjust > 0
-+            && (flags & (ECF_MAY_BE_ALLOCA | ECF_SP_DEPRESSED)))
-+        || pass == 0)
-+      do_pending_stack_adjust ();
-+
-+      /* 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 (pass && (flags & ECF_LIBCALL_BLOCK))
-+      NO_DEFER_POP;
-+
-+#ifdef FINAL_REG_PARM_STACK_SPACE
-+      reg_parm_stack_space = FINAL_REG_PARM_STACK_SPACE (args_size.constant,
-+                                                       args_size.var);
-+#endif
-+      /* Precompute any arguments as needed.  */
-+      if (pass)
-+      precompute_arguments (flags, num_actuals, args);
-+
-+      /* Now we are about to start emitting insns that can be deleted
-+       if a libcall is deleted.  */
-+      if (pass && (flags & (ECF_LIBCALL_BLOCK | ECF_MALLOC)))
-+      start_sequence ();
-+
-+      adjusted_args_size = args_size;
-+      /* 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.  When generating a sibcall
-+       pattern, do not round up, since we'll be re-using whatever space our
-+       caller provided.  */
-+      unadjusted_args_size
-+      = compute_argument_block_size (reg_parm_stack_space,
-+                                     &adjusted_args_size,
-+                                     (pass == 0 ? 0
-+                                      : preferred_stack_boundary));
-+
-+      old_stack_allocated = stack_pointer_delta - pending_stack_adjust;
-+
-+      /* The argument block when performing a sibling call is the
-+         incoming argument block.  */
-+      if (pass == 0)
-+      {
-+        argblock = virtual_incoming_args_rtx;
-+        argblock
-+#ifdef STACK_GROWS_DOWNWARD
-+          = plus_constant (argblock, current_function_pretend_args_size);
-+#else
-+          = plus_constant (argblock, -current_function_pretend_args_size);
-+#endif
-+        stored_args_map = sbitmap_alloc (args_size.constant);
-+        sbitmap_zero (stored_args_map);
-+      }
-+
-+      /* If we have no actual push instructions, or shouldn't use them,
-+       make space for all args right now.  */
-+      else if (adjusted_args_size.var != 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;
-+          }
-+        argblock = push_block (ARGS_SIZE_RTX (adjusted_args_size), 0, 0);
-+      }
-+      else
-+      {
-+        /* Note that we must go through the motions of allocating an argument
-+           block even if the size is zero because we may be storing args
-+           in the area reserved for register arguments, which may be part of
-+           the stack frame.  */
-+
-+        int needed = adjusted_args_size.constant;
-+
-+        /* Store the maximum argument space used.  It will be pushed by
-+           the prologue (if ACCUMULATE_OUTGOING_ARGS, or stack overflow
-+           checking).  */
-+
-+        if (needed > current_function_outgoing_args_size)
-+          current_function_outgoing_args_size = needed;
-+
-+        if (must_preallocate)
-+          {
-+            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.
-+
-+                   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;
-+#endif
-+
-+#ifdef ARGS_GROW_DOWNWARD
-+                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)
-+                  memcpy (stack_usage_map, initial_stack_usage_map,
-+                          initial_highest_arg_in_use);
-+
-+                if (initial_highest_arg_in_use != highest_outgoing_arg_in_use)
-+                  memset (&stack_usage_map[initial_highest_arg_in_use], 0,
-+                         (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 (inhibit_defer_pop == 0)
-+                  {
-+                    /* Try to reuse some or all of the pending_stack_adjust
-+                       to get this space.  */
-+                    needed
-+                      = (combine_pending_stack_adjustment_and_call
-+                         (unadjusted_args_size,
-+                          &adjusted_args_size,
-+                          preferred_unit_stack_boundary));
-+
-+                    /* combine_pending_stack_adjustment_and_call computes
-+                       an adjustment before the arguments are allocated.
-+                       Account for them and see whether or not the stack
-+                       needs to go up or down.  */
-+                    needed = unadjusted_args_size - needed;
-+
-+                    if (needed < 0)
-+                      {
-+                        /* We're releasing stack space.  */
-+                        /* ??? We can avoid any adjustment at all if we're
-+                           already aligned.  FIXME.  */
-+                        pending_stack_adjust = -needed;
-+                        do_pending_stack_adjust ();
-+                        needed = 0;
-+                      }
-+                    else
-+                      /* We need to allocate space.  We'll do that in
-+                         push_block below.  */
-+                      pending_stack_adjust = 0;
-+                  }
-+
-+                /* 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);
-+
-+                /* The save/restore code in store_one_arg handles all
-+                   cases except one: a constructor call (including a C
-+                   function returning a BLKmode struct) to initialize
-+                   an argument.  */
-+                if (stack_arg_under_construction)
-+                  {
-+#ifndef OUTGOING_REG_PARM_STACK_SPACE
-+                    rtx push_size = GEN_INT (reg_parm_stack_space
-+                                             + adjusted_args_size.constant);
-+#else
-+                    rtx push_size = GEN_INT (adjusted_args_size.constant);
-+#endif
-+                    if (old_stack_level == 0)
-+                      {
-+                        emit_stack_save (SAVE_BLOCK, &old_stack_level,
-+                                         NULL_RTX);
-+                        old_pending_adj = pending_stack_adjust;
-+                        pending_stack_adjust = 0;
-+                        /* stack_arg_under_construction says whether a stack
-+                           arg is being constructed at the old stack level.
-+                           Pushing the stack gets a clean outgoing argument
-+                           block.  */
-+                        old_stack_arg_under_construction
-+                          = stack_arg_under_construction;
-+                        stack_arg_under_construction = 0;
-+                        /* Make a new map for the new argument list.  */
-+                        stack_usage_map = (char *)
-+                          alloca (highest_outgoing_arg_in_use);
-+                        memset (stack_usage_map, 0, highest_outgoing_arg_in_use);
-+                        highest_outgoing_arg_in_use = 0;
-+                      }
-+                    allocate_dynamic_stack_space (push_size, NULL_RTX,
-+                                                  BITS_PER_UNIT);
-+                  }
-+                /* If argument evaluation might modify the stack pointer,
-+                   copy the address of the argument list to a register.  */
-+                for (i = 0; i < num_actuals; i++)
-+                  if (args[i].pass_on_stack)
-+                    {
-+                      argblock = copy_addr_to_reg (argblock);
-+                      break;
-+                    }
-+              }
-+          }
-+      }
-+
-+      compute_argument_addresses (args, argblock, num_actuals);
-+
-+      /* If we push args individually in reverse order, perform stack alignment
-+       before the first push (the last arg).  */
-+      if (PUSH_ARGS_REVERSED && argblock == 0
-+        && adjusted_args_size.constant != unadjusted_args_size)
-+      {
-+        /* When the stack adjustment is pending, we get better code
-+           by combining the adjustments.  */
-+        if (pending_stack_adjust
-+            && ! (flags & ECF_LIBCALL_BLOCK)
-+            && ! inhibit_defer_pop)
-+          {
-+            pending_stack_adjust
-+              = (combine_pending_stack_adjustment_and_call
-+                 (unadjusted_args_size,
-+                  &adjusted_args_size,
-+                  preferred_unit_stack_boundary));
-+            do_pending_stack_adjust ();
-+          }
-+        else if (argblock == 0)
-+          anti_adjust_stack (GEN_INT (adjusted_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;
-+
-+      funexp = rtx_for_function_call (fndecl, addr);
-+
-+      /* Figure out the register where the value, if any, will come back.  */
-+      valreg = 0;
-+      if (TYPE_MODE (TREE_TYPE (exp)) != VOIDmode
-+        && ! structure_value_addr)
-+      {
-+        if (pcc_struct_value)
-+          valreg = hard_function_value (build_pointer_type (TREE_TYPE (exp)),
-+                                        fndecl, (pass == 0));
-+        else
-+          valreg = hard_function_value (TREE_TYPE (exp), fndecl, (pass == 0));
-+      }
-+
-+      /* Precompute all register parameters.  It isn't safe to compute anything
-+       once we have started filling any specific hard regs.  */
-+      precompute_register_parameters (num_actuals, args, &reg_parm_seen);
-+
-+#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.  */
-+      if (ACCUMULATE_OUTGOING_ARGS && pass)
-+      save_area = save_fixed_argument_area (reg_parm_stack_space, argblock,
-+                                            &low_to_save, &high_to_save);
-+#endif
-+
-+      /* Now store (and compute if necessary) all non-register parms.
-+       These come before register parms, since they can require block-moves,
-+       which could clobber the registers used for register parms.
-+       Parms which have partial registers are not stored here,
-+       but we do preallocate space here if they want that.  */
-+
-+      for (i = 0; i < num_actuals; i++)
-+      if (args[i].reg == 0 || args[i].pass_on_stack)
-+        {
-+          rtx before_arg = get_last_insn ();
-+
-+          if (store_one_arg (&args[i], argblock, flags,
-+                             adjusted_args_size.var != 0,
-+                             reg_parm_stack_space)
-+              || (pass == 0
-+                  && check_sibcall_argument_overlap (before_arg,
-+                                                     &args[i])))
-+            sibcall_failure = 1;
-+        }
-+
-+      /* If we have a parm that is passed in registers but not in memory
-+       and whose alignment does not permit a direct copy into registers,
-+       make a group of pseudos that correspond to each register that we
-+       will later fill.  */
-+      if (STRICT_ALIGNMENT)
-+      store_unaligned_arguments_into_pseudos (args, num_actuals);
-+
-+      /* Now store any partially-in-registers parm.
-+       This is the last place a block-move can happen.  */
-+      if (reg_parm_seen)
-+      for (i = 0; i < num_actuals; i++)
-+        if (args[i].partial != 0 && ! args[i].pass_on_stack)
-+          {
-+            rtx before_arg = get_last_insn ();
-+
-+            if (store_one_arg (&args[i], argblock, flags,
-+                               adjusted_args_size.var != 0,
-+                               reg_parm_stack_space)
-+                || (pass == 0
-+                    && check_sibcall_argument_overlap (before_arg,
-+                                                       &args[i])))
-+              sibcall_failure = 1;
-+          }
-+
-+      /* If we pushed args in forward order, perform stack alignment
-+       after pushing the last arg.  */
-+      if (!PUSH_ARGS_REVERSED && argblock == 0)
-+      anti_adjust_stack (GEN_INT (adjusted_args_size.constant
-+                                  - unadjusted_args_size));
-+
-+      /* If register arguments require space on the stack and stack space
-+       was not preallocated, allocate stack space here for arguments
-+       passed in registers.  */
-+#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
-+
-+      /* Pass the function the address in which to return a
-+       structure value.  */
-+      if (pass != 0 && structure_value_addr && ! structure_value_addr_parm)
-+      {
-+        emit_move_insn (struct_value_rtx,
-+                        force_reg (Pmode,
-+                                   force_operand (structure_value_addr,
-+                                                  NULL_RTX)));
-+
-+        if (GET_CODE (struct_value_rtx) == REG)
-+          use_reg (&call_fusage, struct_value_rtx);
-+      }
-+
-+      funexp = prepare_call_address (funexp, fndecl, &call_fusage,
-+                                   reg_parm_seen, pass == 0);
-+
-+      load_register_parameters (args, num_actuals, &call_fusage, flags);
-+
-+      /* Perform postincrements before actually calling the function.  */
-+      emit_queue ();
-+
-+      /* Save a pointer to the last insn before the call, so that we can
-+       later safely search backwards to find the CALL_INSN.  */
-+      before_call = get_last_insn ();
-+
-+      /* Set up next argument register.  For sibling calls on machines
-+       with register windows this should be the incoming register.  */
-+#ifdef FUNCTION_INCOMING_ARG
-+      if (pass == 0)
-+      next_arg_reg = FUNCTION_INCOMING_ARG (args_so_far, VOIDmode,
-+                                            void_type_node, 1);
-+      else
-+#endif
-+      next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode,
-+                                   void_type_node, 1);
-+
-+      /* All arguments and registers used for the call must be set up by
-+       now!  */
-+
-+      /* Stack must be properly aligned now.  */
-+      if (pass && stack_pointer_delta % preferred_unit_stack_boundary)
-+      abort ();
-+
-+      /* Generate the actual call instruction.  */
-+      emit_call_1 (funexp, fndecl, funtype, unadjusted_args_size,
-+                 adjusted_args_size.constant, struct_value_size,
-+                 next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
-+                 flags, & args_so_far);
-+
-+      /* Verify that we've deallocated all the stack we used.  */
-+      if (pass
-+        && 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 (pass && (flags & ECF_LIBCALL_BLOCK))
-+      {
-+        rtx insns;
-+
-+        if (valreg == 0 || GET_CODE (valreg) == PARALLEL)
-+          {
-+            insns = get_insns ();
-+            end_sequence ();
-+            emit_insn (insns);
-+          }
-+        else
-+          {
-+            rtx note = 0;
-+            rtx temp = gen_reg_rtx (GET_MODE (valreg));
-+
-+            /* Mark the return value as a pointer if needed.  */
-+            if (TREE_CODE (TREE_TYPE (exp)) == POINTER_TYPE)
-+              mark_reg_pointer (temp,
-+                                TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp))));
-+
-+            /* Construct an "equal form" for the value which mentions all the
-+               arguments in order as well as the function name.  */
-+            for (i = 0; i < num_actuals; i++)
-+              note = gen_rtx_EXPR_LIST (VOIDmode,
-+                                        args[i].initial_value, note);
-+            note = gen_rtx_EXPR_LIST (VOIDmode, funexp, note);
-+
-+            insns = get_insns ();
-+            end_sequence ();
-+
-+            if (flags & ECF_PURE)
-+              note = gen_rtx_EXPR_LIST (VOIDmode,
-+                      gen_rtx_USE (VOIDmode,
-+                                   gen_rtx_MEM (BLKmode,
-+                                                gen_rtx_SCRATCH (VOIDmode))),
-+                      note);
-+
-+            emit_libcall_block (insns, temp, valreg, note);
-+
-+            valreg = temp;
-+          }
-+      }
-+      else if (pass && (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);
-+
-+        emit_move_insn (temp, valreg);
-+
-+        /* The return value from a malloc-like function can not alias
-+           anything else.  */
-+        last = get_last_insn ();
-+        REG_NOTES (last) =
-+          gen_rtx_EXPR_LIST (REG_NOALIAS, temp, REG_NOTES (last));
-+
-+        /* Write out the sequence.  */
-+        insns = get_insns ();
-+        end_sequence ();
-+        emit_insn (insns);
-+        valreg = temp;
-+      }
-+
-+      /* For calls to `setjmp', etc., inform flow.c it should complain
-+       if nonvolatile values are live.  For functions that cannot return,
-+       inform flow that control does not fall through.  */
-+
-+      if ((flags & (ECF_NORETURN | ECF_LONGJMP)) || pass == 0)
-+      {
-+        /* The barrier must be emitted
-+           immediately after the CALL_INSN.  Some ports emit more
-+           than just a CALL_INSN above, so we must search for it here.  */
-+
-+        rtx last = get_last_insn ();
-+        while (GET_CODE (last) != CALL_INSN)
-+          {
-+            last = PREV_INSN (last);
-+            /* There was no CALL_INSN?  */
-+            if (last == before_call)
-+              abort ();
-+          }
-+
-+        emit_barrier_after (last);
-+      }
-+
-+      if (flags & ECF_LONGJMP)
-+      current_function_calls_longjmp = 1;
-+
-+      /* If this function is returning into a memory location marked as
-+       readonly, it means it is initializing that location.  But we normally
-+       treat functions as not clobbering such locations, so we need to
-+       specify that this one does.  */
-+      if (target != 0 && GET_CODE (target) == MEM
-+        && structure_value_addr != 0 && RTX_UNCHANGING_P (target))
-+      emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
-+
-+      /* If value type not void, return an rtx for the value.  */
-+
-+      /* If there are cleanups to be called, don't use a hard reg as target.
-+       We need to double check this and see if it matters anymore.  */
-+      if (any_pending_cleanups (1))
-+      {
-+        if (target && REG_P (target)
-+            && REGNO (target) < FIRST_PSEUDO_REGISTER)
-+          target = 0;
-+        sibcall_failure = 1;
-+      }
-+
-+      if (TYPE_MODE (TREE_TYPE (exp)) == VOIDmode
-+        || ignore)
-+      target = const0_rtx;
-+      else if (structure_value_addr)
-+      {
-+        if (target == 0 || GET_CODE (target) != MEM)
-+          {
-+            target
-+              = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)),
-+                             memory_address (TYPE_MODE (TREE_TYPE (exp)),
-+                                             structure_value_addr));
-+            set_mem_attributes (target, exp, 1);
-+          }
-+      }
-+      else if (pcc_struct_value)
-+      {
-+        /* This is the special C++ case where we need to
-+           know what the true target was.  We take care to
-+           never use this value more than once in one expression.  */
-+        target = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)),
-+                              copy_to_reg (valreg));
-+        set_mem_attributes (target, exp, 1);
-+      }
-+      /* Handle calls that return values in multiple non-contiguous locations.
-+       The Irix 6 ABI has examples of this.  */
-+      else if (GET_CODE (valreg) == PARALLEL)
-+      {
-+        if (target == 0)
-+          {
-+            /* This will only be assigned once, so it can be readonly.  */
-+            tree nt = build_qualified_type (TREE_TYPE (exp),
-+                                            (TYPE_QUALS (TREE_TYPE (exp))
-+                                             | TYPE_QUAL_CONST));
-+
-+            target = assign_temp (nt, 0, 1, 1);
-+            preserve_temp_slots (target);
-+          }
-+
-+        if (! rtx_equal_p (target, valreg))
-+          emit_group_store (target, valreg,
-+                            int_size_in_bytes (TREE_TYPE (exp)));
-+
-+        /* We can not support sibling calls for this case.  */
-+        sibcall_failure = 1;
-+      }
-+      else if (target
-+             && GET_MODE (target) == TYPE_MODE (TREE_TYPE (exp))
-+             && GET_MODE (target) == GET_MODE (valreg))
-+      {
-+        /* TARGET and VALREG cannot be equal at this point because the
-+           latter would not have REG_FUNCTION_VALUE_P true, while the
-+           former would if it were referring to the same register.
-+
-+           If they refer to the same register, this move will be a no-op,
-+           except when function inlining is being done.  */
-+        emit_move_insn (target, valreg);
-+      }
-+      else if (TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
-+      {
-+        target = copy_blkmode_from_reg (target, valreg, TREE_TYPE (exp));
-+
-+        /* We can not support sibling calls for this case.  */
-+        sibcall_failure = 1;
-+      }
-+      else
-+      target = copy_to_reg (valreg);
-+
-+#ifdef PROMOTE_FUNCTION_RETURN
-+      /* If we promoted this return value, make the proper SUBREG.  TARGET
-+       might be const0_rtx here, so be careful.  */
-+      if (GET_CODE (target) == REG
-+        && TYPE_MODE (TREE_TYPE (exp)) != BLKmode
-+        && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
-+      {
-+        tree type = TREE_TYPE (exp);
-+        int unsignedp = TREE_UNSIGNED (type);
-+        int offset = 0;
-+
-+        /* If we don't promote as expected, something is wrong.  */
-+        if (GET_MODE (target)
-+            != promote_mode (type, TYPE_MODE (type), &unsignedp, 1))
-+          abort ();
-+
-+      if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN)
-+          && GET_MODE_SIZE (GET_MODE (target))
-+             > GET_MODE_SIZE (TYPE_MODE (type)))
-+        {
-+          offset = GET_MODE_SIZE (GET_MODE (target))
-+                   - GET_MODE_SIZE (TYPE_MODE (type));
-+          if (! BYTES_BIG_ENDIAN)
-+            offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
-+          else if (! WORDS_BIG_ENDIAN)
-+            offset %= UNITS_PER_WORD;
-+        }
-+        target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset);
-+        SUBREG_PROMOTED_VAR_P (target) = 1;
-+        SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp);
-+      }
-+#endif
-+
-+      /* If size of args is variable or this was a constructor call for a stack
-+       argument, restore saved stack-pointer value.  */
-+
-+      if (old_stack_level && ! (flags & ECF_SP_DEPRESSED))
-+      {
-+        emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
-+        pending_stack_adjust = old_pending_adj;
-+        stack_arg_under_construction = old_stack_arg_under_construction;
-+        highest_outgoing_arg_in_use = initial_highest_arg_in_use;
-+        stack_usage_map = initial_stack_usage_map;
-+        sibcall_failure = 1;
-+      }
-+      else if (ACCUMULATE_OUTGOING_ARGS && pass)
-+      {
-+#ifdef REG_PARM_STACK_SPACE
-+        if (save_area)
-+          {
-+            restore_fixed_argument_area (save_area, argblock,
-+                                         high_to_save, low_to_save);
-+          }
-+#endif
-+
-+        /* If we saved any argument areas, restore them.  */
-+        for (i = 0; i < num_actuals; i++)
-+          if (args[i].save_area)
-+            {
-+              enum machine_mode save_mode = GET_MODE (args[i].save_area);
-+              rtx stack_area
-+                = gen_rtx_MEM (save_mode,
-+                               memory_address (save_mode,
-+                                               XEXP (args[i].stack_slot, 0)));
-+
-+              if (save_mode != BLKmode)
-+                emit_move_insn (stack_area, args[i].save_area);
-+              else
-+                emit_block_move (stack_area, args[i].save_area,
-+                                 GEN_INT (args[i].size.constant),
-+                                 BLOCK_OP_CALL_PARM);
-+            }
-+
-+        highest_outgoing_arg_in_use = initial_highest_arg_in_use;
-+        stack_usage_map = initial_stack_usage_map;
-+      }
-+
-+      /* 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 ((flags & ECF_MAY_BE_ALLOCA) && nonlocal_goto_handler_slots != 0)
-+      emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX);
-+
-+      /* Free up storage we no longer need.  */
-+      for (i = 0; i < num_actuals; ++i)
-+      if (args[i].aligned_regs)
-+        free (args[i].aligned_regs);
-+
-+      if (pass == 0)
-+      {
-+        /* Undo the fake expand_start_target_temps we did earlier.  If
-+           there had been any cleanups created, we've already set
-+           sibcall_failure.  */
-+        expand_end_target_temps ();
-+      }
-+
-+      insns = get_insns ();
-+      end_sequence ();
-+
-+      if (pass == 0)
-+      {
-+        tail_call_insns = insns;
-+
-+        /* 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;
-+
-+        /* Prepare arg structure for next iteration.  */
-+        for (i = 0; i < num_actuals; i++)
-+          {
-+            args[i].value = 0;
-+            args[i].aligned_regs = 0;
-+            args[i].stack = 0;
-+          }
-+
-+        sbitmap_free (stored_args_map);
-+      }
-+      else
-+      normal_call_insns = insns;
-+
-+      /* If something prevents making this a sibling call,
-+       zero out the sequence.  */
-+      if (sibcall_failure)
-+      tail_call_insns = NULL_RTX;
-+    }
-+
-+  /* The function optimize_sibling_and_tail_recursive_calls doesn't
-+     handle CALL_PLACEHOLDERs inside other CALL_PLACEHOLDERs.  This
-+     can happen if the arguments to this function call an inline
-+     function who's expansion contains another CALL_PLACEHOLDER.
-+
-+     If there are any C_Ps in any of these sequences, replace them
-+     with their normal call.  */
-+
-+  for (insn = normal_call_insns; insn; insn = NEXT_INSN (insn))
-+    if (GET_CODE (insn) == CALL_INSN
-+      && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
-+      replace_call_placeholder (insn, sibcall_use_normal);
-+
-+  for (insn = tail_call_insns; insn; insn = NEXT_INSN (insn))
-+    if (GET_CODE (insn) == CALL_INSN
-+      && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
-+      replace_call_placeholder (insn, sibcall_use_normal);
-+
-+  for (insn = tail_recursion_insns; insn; insn = NEXT_INSN (insn))
-+    if (GET_CODE (insn) == CALL_INSN
-+      && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
-+      replace_call_placeholder (insn, sibcall_use_normal);
-+
-+  /* If this was a potential tail recursion site, then emit a
-+     CALL_PLACEHOLDER with the normal and the tail recursion streams.
-+     One of them will be selected later.  */
-+  if (tail_recursion_insns || tail_call_insns)
-+    {
-+      /* The tail recursion label must be kept around.  We could expose
-+       its use in the CALL_PLACEHOLDER, but that creates unwanted edges
-+       and makes determining true tail recursion sites difficult.
-+
-+       So we set LABEL_PRESERVE_P here, then clear it when we select
-+       one of the call sequences after rtl generation is complete.  */
-+      if (tail_recursion_insns)
-+      LABEL_PRESERVE_P (tail_recursion_label) = 1;
-+      emit_call_insn (gen_rtx_CALL_PLACEHOLDER (VOIDmode, normal_call_insns,
-+                                              tail_call_insns,
-+                                              tail_recursion_insns,
-+                                              tail_recursion_label));
-+    }
-+  else
-+    emit_insn (normal_call_insns);
-+
-+  currently_expanding_call--;
-+
-+  /* If this function returns with the stack pointer depressed, ensure
-+     this block saves and restores the stack pointer, show it was
-+     changed, and adjust for any outgoing arg space.  */
-+  if (flags & ECF_SP_DEPRESSED)
-+    {
-+      clear_pending_stack_adjust ();
-+      emit_insn (gen_rtx (CLOBBER, VOIDmode, stack_pointer_rtx));
-+      emit_move_insn (virtual_stack_dynamic_rtx, stack_pointer_rtx);
-+      save_stack_pointer ();
-+    }
-+
-+  return target;
-+}
-+\f
-+/* Output a library call to function FUN (a SYMBOL_REF rtx).
-+   The RETVAL parameter specifies whether return value needs to be saved, other
-+   parameters are documented in the emit_library_call function below.  */
-+
-+static rtx
-+emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
-+     int retval;
-+     rtx orgfun;
-+     rtx value;
-+     enum libcall_type fn_type;
-+     enum machine_mode outmode;
-+     int nargs;
-+     va_list p;
-+{
-+  /* Total size in bytes of all the stack-parms scanned so far.  */
-+  struct args_size args_size;
-+  /* Size of arguments before any adjustments (such as rounding).  */
-+  struct args_size original_args_size;
-+  int argnum;
-+  rtx fun;
-+  int inc;
-+  int count;
-+  struct args_size alignment_pad;
-+  rtx argblock = 0;
-+  CUMULATIVE_ARGS args_so_far;
-+  struct arg
-+  {
-+    rtx value;
-+    enum machine_mode mode;
-+    rtx reg;
-+    int partial;
-+    struct args_size offset;
-+    struct args_size size;
-+    rtx save_area;
-+  };
-+  struct arg *argvec;
-+  int old_inhibit_defer_pop = inhibit_defer_pop;
-+  rtx call_fusage = 0;
-+  rtx mem_value = 0;
-+  rtx valreg;
-+  int pcc_struct_value = 0;
-+  int struct_value_size = 0;
-+  int flags;
-+  int reg_parm_stack_space = 0;
-+  int needed;
-+  rtx before_call;
-+  tree tfom;                  /* type_for_mode (outmode, 0) */
-+
-+#ifdef REG_PARM_STACK_SPACE
-+  /* Define the boundary of the register parm stack space that needs to be
-+     save, if any.  */
-+  int low_to_save = -1, high_to_save = 0;
-+  rtx save_area = 0;            /* Place that it is saved.  */
-+#endif
-+
-+  /* 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;
-+
-+#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 ((tree) 0);
-+#endif
-+#endif
-+
-+  /* By default, library functions can not throw.  */
-+  flags = ECF_NOTHROW;
-+
-+  switch (fn_type)
-+    {
-+    case LCT_NORMAL:
-+      break;
-+    case LCT_CONST:
-+      flags |= ECF_CONST;
-+      break;
-+    case LCT_PURE:
-+      flags |= ECF_PURE;
-+      break;
-+    case LCT_CONST_MAKE_BLOCK:
-+      flags |= ECF_CONST | ECF_LIBCALL_BLOCK;
-+      break;
-+    case LCT_PURE_MAKE_BLOCK:
-+      flags |= ECF_PURE | ECF_LIBCALL_BLOCK;
-+      break;
-+    case LCT_NORETURN:
-+      flags |= ECF_NORETURN;
-+      break;
-+    case LCT_THROW:
-+      flags = ECF_NORETURN;
-+      break;
-+    case LCT_ALWAYS_RETURN:
-+      flags = ECF_ALWAYS_RETURN;
-+      break;
-+    case LCT_RETURNS_TWICE:
-+      flags = ECF_RETURNS_TWICE;
-+      break;
-+    }
-+  fun = orgfun;
-+
-+  /* Ensure current function's preferred stack boundary is at least
-+     what we need.  */
-+  if (cfun->preferred_stack_boundary < PREFERRED_STACK_BOUNDARY)
-+    cfun->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
-+
-+  /* If this kind of value comes back in memory,
-+     decide where in memory it should come back.  */
-+  if (outmode != VOIDmode)
-+    {
-+      tfom = (*lang_hooks.types.type_for_mode) (outmode, 0);
-+      if (aggregate_value_p (tfom))
-+      {
-+#ifdef PCC_STATIC_STRUCT_RETURN
-+        rtx pointer_reg
-+          = hard_function_value (build_pointer_type (tfom), 0, 0);
-+        mem_value = gen_rtx_MEM (outmode, pointer_reg);
-+        pcc_struct_value = 1;
-+        if (value == 0)
-+          value = gen_reg_rtx (outmode);
-+#else /* not PCC_STATIC_STRUCT_RETURN */
-+        struct_value_size = GET_MODE_SIZE (outmode);
-+        if (value != 0 && GET_CODE (value) == MEM)
-+          mem_value = value;
-+        else
-+          mem_value = assign_temp (tfom, 0, 1, 1);
-+#endif
-+        /* This call returns a big structure.  */
-+        flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
-+      }
-+    }
-+  else
-+    tfom = void_type_node;
-+
-+  /* ??? Unfinished: must pass the memory address as an argument.  */
-+
-+  /* Copy all the libcall-arguments out of the varargs data
-+     and into a vector ARGVEC.
-+
-+     Compute how to pass each argument.  We only support a very small subset
-+     of the full argument passing conventions to limit complexity here since
-+     library functions shouldn't have many args.  */
-+
-+  argvec = (struct arg *) alloca ((nargs + 1) * sizeof (struct arg));
-+  memset ((char *) argvec, 0, (nargs + 1) * sizeof (struct arg));
-+
-+#ifdef INIT_CUMULATIVE_LIBCALL_ARGS
-+  INIT_CUMULATIVE_LIBCALL_ARGS (args_so_far, outmode, fun);
-+#else
-+  INIT_CUMULATIVE_ARGS (args_so_far, NULL_TREE, fun, 0);
-+#endif
-+
-+  args_size.constant = 0;
-+  args_size.var = 0;
-+
-+  count = 0;
-+
-+  /* Now we are about to start emitting insns that can be deleted
-+     if a libcall is deleted.  */
-+  if (flags & ECF_LIBCALL_BLOCK)
-+    start_sequence ();
-+
-+  push_temp_slots ();
-+
-+  /* If there's a structure value address to be passed,
-+     either pass it in the special place, or pass it as an extra argument.  */
-+  if (mem_value && struct_value_rtx == 0 && ! pcc_struct_value)
-+    {
-+      rtx addr = XEXP (mem_value, 0);
-+      nargs++;
-+
-+      /* Make sure it is a reasonable operand for a move or push insn.  */
-+      if (GET_CODE (addr) != REG && GET_CODE (addr) != MEM
-+        && ! (CONSTANT_P (addr) && LEGITIMATE_CONSTANT_P (addr)))
-+      addr = force_operand (addr, NULL_RTX);
-+
-+      argvec[count].value = addr;
-+      argvec[count].mode = Pmode;
-+      argvec[count].partial = 0;
-+
-+      argvec[count].reg = FUNCTION_ARG (args_so_far, Pmode, NULL_TREE, 1);
-+#ifdef FUNCTION_ARG_PARTIAL_NREGS
-+      if (FUNCTION_ARG_PARTIAL_NREGS (args_so_far, Pmode, NULL_TREE, 1))
-+      abort ();
-+#endif
-+
-+      locate_and_pad_parm (Pmode, NULL_TREE,
-+#ifdef STACK_PARMS_IN_REG_PARM_AREA
-+                           1,
-+#else
-+                         argvec[count].reg != 0,
-+#endif
-+                         NULL_TREE, &args_size, &argvec[count].offset,
-+                         &argvec[count].size, &alignment_pad);
-+
-+      if (argvec[count].reg == 0 || argvec[count].partial != 0
-+        || reg_parm_stack_space > 0)
-+      args_size.constant += argvec[count].size.constant;
-+
-+      FUNCTION_ARG_ADVANCE (args_so_far, Pmode, (tree) 0, 1);
-+
-+      count++;
-+    }
-+
-+  for (; count < nargs; count++)
-+    {
-+      rtx val = va_arg (p, rtx);
-+      enum machine_mode mode = va_arg (p, enum machine_mode);
-+
-+      /* We cannot convert the arg value to the mode the library wants here;
-+       must do it earlier where we know the signedness of the arg.  */
-+      if (mode == BLKmode
-+        || (GET_MODE (val) != mode && GET_MODE (val) != VOIDmode))
-+      abort ();
-+
-+      /* On some machines, there's no way to pass a float to a library fcn.
-+       Pass it as a double instead.  */
-+#ifdef LIBGCC_NEEDS_DOUBLE
-+      if (LIBGCC_NEEDS_DOUBLE && mode == SFmode)
-+      val = convert_modes (DFmode, SFmode, val, 0), mode = DFmode;
-+#endif
-+
-+      /* There's no need to call protect_from_queue, because
-+       either emit_move_insn or emit_push_insn will do that.  */
-+
-+      /* Make sure it is a reasonable operand for a move or push insn.  */
-+      if (GET_CODE (val) != REG && GET_CODE (val) != MEM
-+        && ! (CONSTANT_P (val) && LEGITIMATE_CONSTANT_P (val)))
-+      val = force_operand (val, NULL_RTX);
-+
-+#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
-+      if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, mode, NULL_TREE, 1))
-+      {
-+        rtx slot;
-+        int must_copy = 1
-+#ifdef FUNCTION_ARG_CALLEE_COPIES       
-+          && ! FUNCTION_ARG_CALLEE_COPIES (args_so_far, mode,
-+                                           NULL_TREE, 1)
-+#endif
-+          ;
-+
-+        /* loop.c won't look at CALL_INSN_FUNCTION_USAGE of const/pure
-+           functions, so we have to pretend this isn't such a function.  */
-+        if (flags & ECF_LIBCALL_BLOCK)
-+          {
-+            rtx insns = get_insns ();
-+            end_sequence ();
-+            emit_insn (insns);
-+          }
-+        flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
-+
-+        /* If this was a CONST function, it is now PURE since
-+           it now reads memory.  */
-+        if (flags & ECF_CONST)
-+          {
-+            flags &= ~ECF_CONST;
-+            flags |= ECF_PURE;
-+          }
-+
-+        if (GET_MODE (val) == MEM && ! must_copy)
-+          slot = val;
-+        else if (must_copy)
-+          {
-+            slot = assign_temp ((*lang_hooks.types.type_for_mode) (mode, 0),
-+                                0, 1, 1);
-+            emit_move_insn (slot, val);
-+          }
-+        else
-+          {
-+            tree type = (*lang_hooks.types.type_for_mode) (mode, 0);
-+
-+            slot = gen_rtx_MEM (mode,
-+                                expand_expr (build1 (ADDR_EXPR,
-+                                                     build_pointer_type
-+                                                     (type),
-+                                                     make_tree (type, val)),
-+                                             NULL_RTX, VOIDmode, 0));
-+          }
-+
-+        call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
-+                                         gen_rtx_USE (VOIDmode, slot),
-+                                         call_fusage);
-+        if (must_copy)
-+          call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
-+                                           gen_rtx_CLOBBER (VOIDmode,
-+                                                            slot),
-+                                           call_fusage);
-+
-+        mode = Pmode;
-+        val = force_operand (XEXP (slot, 0), NULL_RTX);
-+      }
-+#endif
-+
-+      argvec[count].value = val;
-+      argvec[count].mode = mode;
-+
-+      argvec[count].reg = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1);
-+
-+#ifdef FUNCTION_ARG_PARTIAL_NREGS
-+      argvec[count].partial
-+      = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode, NULL_TREE, 1);
-+#else
-+      argvec[count].partial = 0;
-+#endif
-+
-+      locate_and_pad_parm (mode, NULL_TREE,
-+#ifdef STACK_PARMS_IN_REG_PARM_AREA
-+                         1,
-+#else
-+                         argvec[count].reg != 0,
-+#endif
-+                         NULL_TREE, &args_size, &argvec[count].offset,
-+                         &argvec[count].size, &alignment_pad);
-+
-+      if (argvec[count].size.var)
-+      abort ();
-+
-+      if (reg_parm_stack_space == 0 && argvec[count].partial)
-+      argvec[count].size.constant -= argvec[count].partial * UNITS_PER_WORD;
-+
-+      if (argvec[count].reg == 0 || argvec[count].partial != 0
-+        || reg_parm_stack_space > 0)
-+      args_size.constant += argvec[count].size.constant;
-+
-+      FUNCTION_ARG_ADVANCE (args_so_far, mode, (tree) 0, 1);
-+    }
-+
-+#ifdef FINAL_REG_PARM_STACK_SPACE
-+  reg_parm_stack_space = FINAL_REG_PARM_STACK_SPACE (args_size.constant,
-+                                                   args_size.var);
-+#endif
-+  /* If this machine requires an external definition for library
-+     functions, write one out.  */
-+  assemble_external_libcall (fun);
-+
-+  original_args_size = args_size;
-+  args_size.constant = (((args_size.constant
-+                        + stack_pointer_delta
-+                        + STACK_BYTES - 1)
-+                        / STACK_BYTES
-+                        * STACK_BYTES)
-+                       - stack_pointer_delta);
-+
-+  args_size.constant = MAX (args_size.constant,
-+                          reg_parm_stack_space);
-+
-+#ifndef OUTGOING_REG_PARM_STACK_SPACE
-+  args_size.constant -= reg_parm_stack_space;
-+#endif
-+
-+  if (args_size.constant > current_function_outgoing_args_size)
-+    current_function_outgoing_args_size = args_size.constant;
-+
-+  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.
-+
-+       Another approach might be to try to reorder the argument
-+       evaluations to avoid this conflicting stack usage.  */
-+
-+      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;
-+#endif
-+
-+#ifdef ARGS_GROW_DOWNWARD
-+      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)
-+      memcpy (stack_usage_map, initial_stack_usage_map,
-+              initial_highest_arg_in_use);
-+
-+      if (initial_highest_arg_in_use != highest_outgoing_arg_in_use)
-+      memset (&stack_usage_map[initial_highest_arg_in_use], 0,
-+             highest_outgoing_arg_in_use - initial_highest_arg_in_use);
-+      needed = 0;
-+
-+      /* We must be careful to use virtual regs before they're instantiated,
-+         and real regs afterwards.  Loop optimization, for example, can create
-+       new libcalls after we've instantiated the virtual regs, and if we
-+       use virtuals anyway, they won't match the rtl patterns.  */
-+
-+      if (virtuals_instantiated)
-+      argblock = plus_constant (stack_pointer_rtx, STACK_POINTER_OFFSET);
-+      else
-+      argblock = virtual_outgoing_args_rtx;
-+    }
-+  else
-+    {
-+      if (!PUSH_ARGS)
-+      argblock = push_block (GEN_INT (args_size.constant), 0, 0);
-+    }
-+
-+  /* If we push args individually in reverse order, perform stack alignment
-+     before the first push (the last arg).  */
-+  if (argblock == 0 && PUSH_ARGS_REVERSED)
-+    anti_adjust_stack (GEN_INT (args_size.constant
-+                              - original_args_size.constant));
-+
-+  if (PUSH_ARGS_REVERSED)
-+    {
-+      inc = -1;
-+      argnum = nargs - 1;
-+    }
-+  else
-+    {
-+      inc = 1;
-+      argnum = 0;
-+    }
-+
-+#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.  */
-+
-+#ifdef ARGS_GROW_DOWNWARD
-+      for (count = 0; count < reg_parm_stack_space + 1; count++)
-+#else
-+      for (count = 0; count < reg_parm_stack_space; count++)
-+#endif
-+      {
-+        if (count >= highest_outgoing_arg_in_use
-+            || stack_usage_map[count] == 0)
-+          continue;
-+
-+        if (low_to_save == -1)
-+          low_to_save = count;
-+
-+        high_to_save = count;
-+      }
-+
-+      if (low_to_save >= 0)
-+      {
-+        int num_to_save = high_to_save - low_to_save + 1;
-+        enum machine_mode save_mode
-+          = mode_for_size (num_to_save * BITS_PER_UNIT, MODE_INT, 1);
-+        rtx stack_area;
-+
-+        /* If we don't have the required alignment, must do this in BLKmode.  */
-+        if ((low_to_save & (MIN (GET_MODE_SIZE (save_mode),
-+                                 BIGGEST_ALIGNMENT / UNITS_PER_WORD) - 1)))
-+          save_mode = BLKmode;
-+
-+#ifdef ARGS_GROW_DOWNWARD
-+        stack_area = gen_rtx_MEM (save_mode,
-+                                  memory_address (save_mode,
-+                                                  plus_constant (argblock,
-+                                                                 -high_to_save)));
-+#else
-+        stack_area = gen_rtx_MEM (save_mode,
-+                                  memory_address (save_mode,
-+                                                  plus_constant (argblock,
-+                                                                 low_to_save)));
-+#endif
-+        if (save_mode == BLKmode)
-+          {
-+            save_area = assign_stack_temp (BLKmode, num_to_save, 0);
-+            set_mem_align (save_area, PARM_BOUNDARY);
-+            emit_block_move (save_area, stack_area, GEN_INT (num_to_save),
-+                             BLOCK_OP_CALL_PARM);
-+          }
-+        else
-+          {
-+            save_area = gen_reg_rtx (save_mode);
-+            emit_move_insn (save_area, stack_area);
-+          }
-+      }
-+    }
-+#endif
-+
-+  /* Push the args that need to be pushed.  */
-+
-+  /* ARGNUM indexes the ARGVEC array in the order in which the arguments
-+     are to be pushed.  */
-+  for (count = 0; count < nargs; count++, argnum += inc)
-+    {
-+      enum machine_mode mode = argvec[argnum].mode;
-+      rtx val = argvec[argnum].value;
-+      rtx reg = argvec[argnum].reg;
-+      int partial = argvec[argnum].partial;
-+      int lower_bound = 0, upper_bound = 0, i;
-+
-+      if (! (reg != 0 && partial == 0))
-+      {
-+        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;
-+#else
-+            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;
-+
-+            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);
-+              }
-+          }
-+
-+        emit_push_insn (val, mode, NULL_TREE, NULL_RTX, PARM_BOUNDARY,
-+                        partial, reg, 0, argblock,
-+                        GEN_INT (argvec[argnum].offset.constant),
-+                        reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
-+
-+        /* Now mark the segment we just used.  */
-+        if (ACCUMULATE_OUTGOING_ARGS)
-+          for (i = lower_bound; i < upper_bound; i++)
-+            stack_usage_map[i] = 1;
-+
-+        NO_DEFER_POP;
-+      }
-+    }
-+
-+  /* If we pushed args in forward order, perform stack alignment
-+     after pushing the last arg.  */
-+  if (argblock == 0 && !PUSH_ARGS_REVERSED)
-+    anti_adjust_stack (GEN_INT (args_size.constant
-+                              - original_args_size.constant));
-+
-+  if (PUSH_ARGS_REVERSED)
-+    argnum = nargs - 1;
-+  else
-+    argnum = 0;
-+
-+  fun = prepare_call_address (fun, NULL_TREE, &call_fusage, 0, 0);
-+
-+  /* Now load any reg parms into their regs.  */
-+
-+  /* ARGNUM indexes the ARGVEC array in the order in which the arguments
-+     are to be pushed.  */
-+  for (count = 0; count < nargs; count++, argnum += inc)
-+    {
-+      rtx val = argvec[argnum].value;
-+      rtx reg = argvec[argnum].reg;
-+      int partial = argvec[argnum].partial;
-+
-+      /* Handle calls that pass values in multiple non-contiguous
-+       locations.  The PA64 has examples of this for library calls.  */
-+      if (reg != 0 && GET_CODE (reg) == PARALLEL)
-+      emit_group_load (reg, val, GET_MODE_SIZE (GET_MODE (val)));
-+      else if (reg != 0 && partial == 0)
-+      emit_move_insn (reg, val);
-+
-+      NO_DEFER_POP;
-+    }
-+
-+  /* Any regs containing parms remain in use through the call.  */
-+  for (count = 0; count < nargs; count++)
-+    {
-+      rtx reg = argvec[count].reg;
-+      if (reg != 0 && GET_CODE (reg) == PARALLEL)
-+      use_group_regs (&call_fusage, reg);
-+      else if (reg != 0)
-+      use_reg (&call_fusage, reg);
-+    }
-+
-+  /* Pass the function the address in which to return a structure value.  */
-+  if (mem_value != 0 && struct_value_rtx != 0 && ! pcc_struct_value)
-+    {
-+      emit_move_insn (struct_value_rtx,
-+                    force_reg (Pmode,
-+                               force_operand (XEXP (mem_value, 0),
-+                                              NULL_RTX)));
-+      if (GET_CODE (struct_value_rtx) == REG)
-+      use_reg (&call_fusage, struct_value_rtx);
-+    }
-+
-+  /* Don't allow popping to be deferred, since then
-+     cse'ing of library calls could delete a call and leave the pop.  */
-+  NO_DEFER_POP;
-+  valreg = (mem_value == 0 && outmode != VOIDmode
-+          ? hard_libcall_value (outmode) : NULL_RTX);
-+
-+  /* Stack must be properly aligned now.  */
-+  if (stack_pointer_delta & (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1))
-+    abort ();
-+
-+  before_call = get_last_insn ();
-+
-+  /* We pass the old value of inhibit_defer_pop + 1 to emit_call_1, which
-+     will set inhibit_defer_pop to that value.  */
-+  /* The return type is needed to decide how many bytes the function pops.
-+     Signedness plays no role in that, so for simplicity, we pretend it's
-+     always signed.  We also assume that the list of arguments passed has
-+     no impact, so we pretend it is unknown.  */
-+
-+  emit_call_1 (fun,
-+             get_identifier (XSTR (orgfun, 0)),
-+             build_function_type (tfom, NULL_TREE),
-+             original_args_size.constant, args_size.constant,
-+             struct_value_size,
-+             FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
-+             valreg,
-+             old_inhibit_defer_pop + 1, call_fusage, flags, & args_so_far);
-+
-+  /* For calls to `setjmp', etc., inform flow.c it should complain
-+     if nonvolatile values are live.  For functions that cannot return,
-+     inform flow that control does not fall through.  */
-+
-+  if (flags & (ECF_NORETURN | ECF_LONGJMP))
-+    {
-+      /* The barrier note must be emitted
-+       immediately after the CALL_INSN.  Some ports emit more than
-+       just a CALL_INSN above, so we must search for it here.  */
-+
-+      rtx last = get_last_insn ();
-+      while (GET_CODE (last) != CALL_INSN)
-+      {
-+        last = PREV_INSN (last);
-+        /* There was no CALL_INSN?  */
-+        if (last == before_call)
-+          abort ();
-+      }
-+
-+      emit_barrier_after (last);
-+    }
-+
-+  /* Now restore inhibit_defer_pop to its actual original value.  */
-+  OK_DEFER_POP;
-+
-+  /* 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 (flags & ECF_LIBCALL_BLOCK)
-+    {
-+      rtx insns;
-+
-+      if (valreg == 0)
-+      {
-+        insns = get_insns ();
-+        end_sequence ();
-+        emit_insn (insns);
-+      }
-+      else
-+      {
-+        rtx note = 0;
-+        rtx temp;
-+        int i;
-+
-+        if (GET_CODE (valreg) == PARALLEL)
-+          {
-+            temp = gen_reg_rtx (outmode);
-+            emit_group_store (temp, valreg, outmode);
-+            valreg = temp;
-+          }
-+
-+        temp = gen_reg_rtx (GET_MODE (valreg));
-+
-+        /* Construct an "equal form" for the value which mentions all the
-+           arguments in order as well as the function name.  */
-+        for (i = 0; i < nargs; i++)
-+          note = gen_rtx_EXPR_LIST (VOIDmode, argvec[i].value, note);
-+        note = gen_rtx_EXPR_LIST (VOIDmode, fun, note);
-+
-+        insns = get_insns ();
-+        end_sequence ();
-+
-+        if (flags & ECF_PURE)
-+          note = gen_rtx_EXPR_LIST (VOIDmode,
-+                      gen_rtx_USE (VOIDmode,
-+                                   gen_rtx_MEM (BLKmode,
-+                                                gen_rtx_SCRATCH (VOIDmode))),
-+                      note);
-+
-+        emit_libcall_block (insns, temp, valreg, note);
-+
-+        valreg = temp;
-+      }
-+    }
-+  pop_temp_slots ();
-+
-+  /* Copy the value to the right place.  */
-+  if (outmode != VOIDmode && retval)
-+    {
-+      if (mem_value)
-+      {
-+        if (value == 0)
-+          value = mem_value;
-+        if (value != mem_value)
-+          emit_move_insn (value, mem_value);
-+      }
-+      else if (GET_CODE (valreg) == PARALLEL)
-+      {
-+        if (value == 0)
-+          value = gen_reg_rtx (outmode);
-+        emit_group_store (value, valreg, outmode);
-+      }
-+      else if (value != 0)
-+      emit_move_insn (value, valreg);
-+      else
-+      value = valreg;
-+    }
-+
-+  if (ACCUMULATE_OUTGOING_ARGS)
-+    {
-+#ifdef REG_PARM_STACK_SPACE
-+      if (save_area)
-+      {
-+        enum machine_mode save_mode = GET_MODE (save_area);
-+#ifdef ARGS_GROW_DOWNWARD
-+        rtx stack_area
-+          = gen_rtx_MEM (save_mode,
-+                         memory_address (save_mode,
-+                                         plus_constant (argblock,
-+                                                        - high_to_save)));
-+#else
-+        rtx stack_area
-+          = gen_rtx_MEM (save_mode,
-+                         memory_address (save_mode,
-+                                         plus_constant (argblock, low_to_save)));
-+#endif
-+
-+        set_mem_align (stack_area, PARM_BOUNDARY);
-+        if (save_mode != BLKmode)
-+          emit_move_insn (stack_area, save_area);
-+        else
-+          emit_block_move (stack_area, save_area,
-+                           GEN_INT (high_to_save - low_to_save + 1),
-+                           BLOCK_OP_CALL_PARM);
-+      }
-+#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);
-+        }
-+
-+      highest_outgoing_arg_in_use = initial_highest_arg_in_use;
-+      stack_usage_map = initial_stack_usage_map;
-+    }
-+
-+  return value;
-+
-+}
-+\f
-+/* Output a library call to function FUN (a SYMBOL_REF rtx)
-+   (emitting the queue unless NO_QUEUE is nonzero),
-+   for a value of mode OUTMODE,
-+   with NARGS different arguments, passed as alternating rtx values
-+   and machine_modes to convert them to.
-+   The rtx values should have been passed through protect_from_queue already.
-+
-+   FN_TYPE should be LCT_NORMAL for `normal' calls, LCT_CONST for `const'
-+   calls, LCT_PURE for `pure' calls, LCT_CONST_MAKE_BLOCK for `const' calls
-+   which should be enclosed in REG_LIBCALL/REG_RETVAL notes,
-+   LCT_PURE_MAKE_BLOCK for `purep' calls which should be enclosed in
-+   REG_LIBCALL/REG_RETVAL notes with extra (use (memory (scratch)),
-+   or other LCT_ value for other types of library calls.  */
-+
-+void
-+emit_library_call VPARAMS((rtx orgfun, enum libcall_type fn_type,
-+                         enum machine_mode outmode, int nargs, ...))
-+{
-+  VA_OPEN (p, nargs);
-+  VA_FIXEDARG (p, rtx, orgfun);
-+  VA_FIXEDARG (p, int, fn_type);
-+  VA_FIXEDARG (p, enum machine_mode, outmode);
-+  VA_FIXEDARG (p, int, nargs);
-+
-+  emit_library_call_value_1 (0, orgfun, NULL_RTX, fn_type, outmode, nargs, p);
-+
-+  VA_CLOSE (p);
-+}
-+\f
-+/* Like emit_library_call except that an extra argument, VALUE,
-+   comes second and says where to store the result.
-+   (If VALUE is zero, this function chooses a convenient way
-+   to return the value.
-+
-+   This function returns an rtx for where the value is to be found.
-+   If VALUE is nonzero, VALUE is returned.  */
-+
-+rtx
-+emit_library_call_value VPARAMS((rtx orgfun, rtx value,
-+                               enum libcall_type fn_type,
-+                               enum machine_mode outmode, int nargs, ...))
-+{
-+  rtx result;
-+  
-+  VA_OPEN (p, nargs);
-+  VA_FIXEDARG (p, rtx, orgfun);
-+  VA_FIXEDARG (p, rtx, value);
-+  VA_FIXEDARG (p, int, fn_type);
-+  VA_FIXEDARG (p, enum machine_mode, outmode);
-+  VA_FIXEDARG (p, int, nargs);
-+
-+  result = emit_library_call_value_1 (1, orgfun, value, fn_type, outmode,
-+                                    nargs, p);
-+
-+  VA_CLOSE (p);
-+
-+  return result;
-+}
-+\f
-+/* Store a single argument for a function call
-+   into the register or memory area where it must be passed.
-+   *ARG describes the argument value and where to pass it.
-+
-+   ARGBLOCK is the address of the stack-block for all the arguments,
-+   or 0 on a machine where arguments are pushed individually.
-+
-+   MAY_BE_ALLOCA nonzero says this could be a call to `alloca'
-+   so must be careful about how the stack is used.
-+
-+   VARIABLE_SIZE nonzero says that this was a variable-sized outgoing
-+   argument stack.  This is used if ACCUMULATE_OUTGOING_ARGS to indicate
-+   that we need not worry about saving and restoring the stack.
-+
-+   FNDECL is the declaration of the function we are calling.
-+
-+   Return nonzero if this arg should cause sibcall failure,
-+   zero otherwise.  */
-+
-+static int
-+store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
-+     struct arg_data *arg;
-+     rtx argblock;
-+     int flags;
-+     int variable_size ATTRIBUTE_UNUSED;
-+     int reg_parm_stack_space;
-+{
-+  tree pval = arg->tree_value;
-+  rtx reg = 0;
-+  int partial = 0;
-+  int used = 0;
-+  int i, lower_bound = 0, upper_bound = 0;
-+  int sibcall_failure = 0;
-+
-+  if (TREE_CODE (pval) == ERROR_MARK)
-+    return 1;
-+
-+  /* Push a new temporary level for any temporaries we make for
-+     this argument.  */
-+  push_temp_slots ();
-+
-+  if (ACCUMULATE_OUTGOING_ARGS && !(flags & ECF_SIBCALL))
-+    {
-+      /* 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;
-+
-+        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;
-+
-+        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)));
-+
-+            if (save_mode == BLKmode)
-+              {
-+                tree ot = TREE_TYPE (arg->tree_value);
-+                tree nt = build_qualified_type (ot, (TYPE_QUALS (ot)
-+                                                     | TYPE_QUAL_CONST));
-+
-+                arg->save_area = assign_temp (nt, 0, 1, 1);
-+                preserve_temp_slots (arg->save_area);
-+                emit_block_move (validize_mem (arg->save_area), stack_area,
-+                                 expr_size (arg->tree_value),
-+                                 BLOCK_OP_CALL_PARM);
-+              }
-+            else
-+              {
-+                arg->save_area = gen_reg_rtx (save_mode);
-+                emit_move_insn (arg->save_area, stack_area);
-+              }
-+          }
-+      }
-+    }
-+
-+  /* 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)
-+    {
-+      if (flags & ECF_SIBCALL)
-+      reg = arg->tail_call_reg;
-+      else
-+      reg = arg->reg;
-+      partial = arg->partial;
-+    }
-+
-+  if (reg != 0 && partial == 0)
-+    /* Being passed entirely in a register.  We shouldn't be called in
-+       this case.  */
-+    abort ();
-+
-+  /* If this arg needs special alignment, don't load the registers
-+     here.  */
-+  if (arg->n_aligned_regs != 0)
-+    reg = 0;
-+
-+  /* If this is being passed partially in a register, we can't evaluate
-+     it directly into its stack slot.  Otherwise, we can.  */
-+  if (arg->value == 0)
-+    {
-+      /* 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
-+       if it is called recursively.
-+
-+       For scalar function arguments stack_usage_map is sufficient to
-+       determine which stack slots must be saved and restored.  Scalar
-+       arguments in general have pass_on_stack == 0.
-+
-+       If this argument is initialized by a function which takes the
-+       address of the argument (a C++ constructor or a C function
-+       returning a BLKmode structure), then stack_usage_map is
-+       insufficient and expand_call must push the stack around the
-+       function call.  Such arguments have pass_on_stack == 1.
-+
-+       Note that it is always safe to set stack_arg_under_construction,
-+       but this generates suboptimal code if set when not needed.  */
-+
-+      if (arg->pass_on_stack)
-+      stack_arg_under_construction++;
-+
-+      arg->value = expand_expr (pval,
-+                              (partial
-+                               || TYPE_MODE (TREE_TYPE (pval)) != arg->mode)
-+                              ? NULL_RTX : arg->stack,
-+                              VOIDmode, EXPAND_STACK_PARM);
-+
-+      /* If we are promoting object (or for any other reason) the mode
-+       doesn't agree, convert the mode.  */
-+
-+      if (arg->mode != TYPE_MODE (TREE_TYPE (pval)))
-+      arg->value = convert_modes (arg->mode, TYPE_MODE (TREE_TYPE (pval)),
-+                                  arg->value, arg->unsignedp);
-+
-+      if (arg->pass_on_stack)
-+      stack_arg_under_construction--;
-+    }
-+
-+  /* Don't allow anything left on stack from computation
-+     of argument to alloca.  */
-+  if (flags & ECF_MAY_BE_ALLOCA)
-+    do_pending_stack_adjust ();
-+
-+  if (arg->value == arg->stack)
-+    /* If the value is already in the stack slot, we are done.  */
-+    ;
-+  else if (arg->mode != BLKmode)
-+    {
-+      int size;
-+
-+      /* Argument is a scalar, not entirely passed in registers.
-+       (If part is passed in registers, arg->partial says how much
-+       and emit_push_insn will take care of putting it there.)
-+
-+       Push it, and if its size is less than the
-+       amount of space allocated to it,
-+       also bump stack pointer by the additional space.
-+       Note that in C the default argument promotions
-+       will prevent such mismatches.  */
-+
-+      size = GET_MODE_SIZE (arg->mode);
-+      /* Compute how much space the push instruction will push.
-+       On many machines, pushing a byte will advance the stack
-+       pointer by a halfword.  */
-+#ifdef PUSH_ROUNDING
-+      size = PUSH_ROUNDING (size);
-+#endif
-+      used = size;
-+
-+      /* Compute how much space the argument should get:
-+       round up to a multiple of the alignment for arguments.  */
-+      if (none != FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)))
-+      used = (((size + PARM_BOUNDARY / BITS_PER_UNIT - 1)
-+               / (PARM_BOUNDARY / BITS_PER_UNIT))
-+              * (PARM_BOUNDARY / BITS_PER_UNIT));
-+
-+      /* This isn't already where we want it on the stack, so put it there.
-+       This can either be done with push or copy insns.  */
-+      emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX, 
-+                    PARM_BOUNDARY, partial, reg, used - size, argblock,
-+                    ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
-+                    ARGS_SIZE_RTX (arg->alignment_pad));
-+
-+      /* Unless this is a partially-in-register argument, the argument is now
-+       in the stack.  */
-+      if (partial == 0)
-+      arg->value = arg->stack;
-+    }
-+  else
-+    {
-+      /* BLKmode, at least partly to be pushed.  */
-+
-+      unsigned int parm_align;
-+      int excess;
-+      rtx size_rtx;
-+
-+      /* Pushing a nonscalar.
-+       If part is passed in registers, PARTIAL says how much
-+       and emit_push_insn will take care of putting it there.  */
-+
-+      /* Round its size up to a multiple
-+       of the allocation unit for arguments.  */
-+
-+      if (arg->size.var != 0)
-+      {
-+        excess = 0;
-+        size_rtx = ARGS_SIZE_RTX (arg->size);
-+      }
-+      else
-+      {
-+        /* PUSH_ROUNDING has no effect on us, because
-+           emit_push_insn for BLKmode is careful to avoid it.  */
-+        excess = (arg->size.constant - int_size_in_bytes (TREE_TYPE (pval))
-+                  + partial * UNITS_PER_WORD);
-+        size_rtx = expand_expr (size_in_bytes (TREE_TYPE (pval)),
-+                                NULL_RTX, TYPE_MODE (sizetype), 0);
-+      }
-+
-+      /* Some types will require stricter alignment, which will be
-+       provided for elsewhere in argument layout.  */
-+      parm_align = MAX (PARM_BOUNDARY, TYPE_ALIGN (TREE_TYPE (pval)));
-+
-+      /* When an argument is padded down, the block is aligned to
-+       PARM_BOUNDARY, but the actual argument isn't.  */
-+      if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward)
-+      {
-+        if (arg->size.var)
-+          parm_align = BITS_PER_UNIT;
-+        else if (excess)
-+          {
-+            unsigned int excess_align = (excess & -excess) * BITS_PER_UNIT;
-+            parm_align = MIN (parm_align, excess_align);
-+          }
-+      }
-+
-+      if ((flags & ECF_SIBCALL) && GET_CODE (arg->value) == MEM)
-+      {
-+        /* emit_push_insn might not work properly if arg->value and
-+           argblock + arg->offset areas overlap.  */
-+        rtx x = arg->value;
-+        int i = 0;
-+
-+        if (XEXP (x, 0) == current_function_internal_arg_pointer
-+            || (GET_CODE (XEXP (x, 0)) == PLUS
-+                && XEXP (XEXP (x, 0), 0) ==
-+                   current_function_internal_arg_pointer
-+                && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
-+          {
-+            if (XEXP (x, 0) != current_function_internal_arg_pointer)
-+              i = INTVAL (XEXP (XEXP (x, 0), 1));
-+
-+            /* expand_call should ensure this */
-+            if (arg->offset.var || GET_CODE (size_rtx) != CONST_INT)
-+              abort ();
-+
-+            if (arg->offset.constant > i)
-+              {
-+                if (arg->offset.constant < i + INTVAL (size_rtx))
-+                  sibcall_failure = 1;
-+              }
-+            else if (arg->offset.constant < i)
-+              {
-+                if (i < arg->offset.constant + INTVAL (size_rtx))
-+                  sibcall_failure = 1;
-+              }
-+          }
-+      }
-+
-+      emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
-+                    parm_align, partial, reg, excess, argblock,
-+                    ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
-+                    ARGS_SIZE_RTX (arg->alignment_pad));
-+
-+      /* Unless this is a partially-in-register argument, the argument is now
-+       in the stack.
-+
-+       ??? Unlike the case above, in which we want the actual
-+       address of the data, so that we can load it directly into a
-+       register, here we want the address of the stack slot, so that
-+       it's properly aligned for word-by-word copying or something
-+       like that.  It's not clear that this is always correct.  */
-+      if (partial == 0)
-+      arg->value = arg->stack_slot;
-+    }
-+
-+  /* Mark all slots this store used.  */
-+  if (ACCUMULATE_OUTGOING_ARGS && !(flags & ECF_SIBCALL)
-+      && argblock && ! variable_size && arg->stack)
-+    for (i = lower_bound; i < upper_bound; i++)
-+      stack_usage_map[i] = 1;
-+
-+  /* Once we have pushed something, pops can't safely
-+     be deferred during the rest of the arguments.  */
-+  NO_DEFER_POP;
-+
-+  /* ANSI doesn't require a sequence point here,
-+     but PCC has one, so this will avoid some problems.  */
-+  emit_queue ();
-+
-+  /* Free any temporary slots made in processing this argument.  Show
-+     that we might have taken the address of something and pushed that
-+     as an operand.  */
-+  preserve_temp_slots (NULL_RTX);
-+  free_temp_slots ();
-+  pop_temp_slots ();
-+
-+  return sibcall_failure;
-+}
-diff -ruN gcc-3.3.1/gcc/combine.c gcc-3.3.1.pp/gcc/combine.c
---- gcc-3.3.1/gcc/combine.c    2003-03-24 11:37:32.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/combine.c 2003-09-05 11:58:59.000000000 +0000
-@@ -3859,7 +3859,17 @@
-         rtx inner_op0 = XEXP (XEXP (x, 0), 1);
-         rtx inner_op1 = XEXP (x, 1);
-         rtx inner;
--
-+        
-+#ifndef FRAME_GROWS_DOWNWARD
-+        if (flag_propolice_protection
-+            && code == PLUS
-+            && other == frame_pointer_rtx
-+            && GET_CODE (inner_op0) == CONST_INT
-+            && GET_CODE (inner_op1) == CONST_INT
-+            && INTVAL (inner_op0) > 0
-+            && INTVAL (inner_op0) + INTVAL (inner_op1) <= 0)
-+          return x;
-+#endif
-         /* Make sure we pass the constant operand if any as the second
-            one if this is a commutative operation.  */
-         if (CONSTANT_P (inner_op0) && GET_RTX_CLASS (code) == 'c')
-@@ -4272,6 +4282,11 @@
-        they are now checked elsewhere.  */
-       if (GET_CODE (XEXP (x, 0)) == PLUS
-         && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
-+#ifndef FRAME_GROWS_DOWNWARD
-+      if (! (flag_propolice_protection
-+             && XEXP (XEXP (x, 0), 0) == frame_pointer_rtx
-+             && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
-+#endif
-       return gen_binary (PLUS, mode,
-                          gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0),
-                                      XEXP (x, 1)),
-@@ -4400,7 +4415,10 @@
-       /* Canonicalize (minus A (plus B C)) to (minus (minus A B) C) for
-        integers.  */
--      if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode))
-+      if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode)
-+        && (! (flag_propolice_protection
-+               && XEXP (XEXP (x, 1), 0) == frame_pointer_rtx
-+               && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT)))
-       return gen_binary (MINUS, mode,
-                          gen_binary (MINUS, mode, XEXP (x, 0),
-                                      XEXP (XEXP (x, 1), 0)),
-diff -ruN gcc-3.3.1/gcc/config/t-linux gcc-3.3.1.pp/gcc/config/t-linux
---- gcc-3.3.1/gcc/config/t-linux       2003-06-04 16:56:11.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/config/t-linux    2003-09-05 11:58:59.000000000 +0000
-@@ -4,7 +4,7 @@
- # Compile crtbeginS.o and crtendS.o with pic.
- CRTSTUFF_T_CFLAGS_S = $(CRTSTUFF_T_CFLAGS) -fPIC
- # Compile libgcc2.a with pic.
--TARGET_LIBGCC2_CFLAGS = -fPIC
-+TARGET_LIBGCC2_CFLAGS = -fPIC -DHAVE_SYSLOG
- # Override t-slibgcc-elf-ver to export some libgcc symbols with
- # the symbol versions that glibc used.
-diff -ruN gcc-3.3.1/gcc/cse.c gcc-3.3.1.pp/gcc/cse.c
---- gcc-3.3.1/gcc/cse.c        2003-04-29 19:16:40.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/cse.c     2003-09-05 11:58:59.000000000 +0000
-@@ -4288,7 +4288,14 @@
-             if (new_const == 0)
-               break;
--
-+#ifndef FRAME_GROWS_DOWNWARD
-+            if (flag_propolice_protection
-+                && GET_CODE (y) == PLUS
-+                && XEXP (y, 0) == frame_pointer_rtx
-+                && INTVAL (inner_const) > 0
-+                && INTVAL (new_const) <= 0)
-+              break;
-+#endif
-             /* If we are associating shift operations, don't let this
-                produce a shift of the size of the object or larger.
-                This could occur when we follow a sign-extend by a right
-@@ -4823,6 +4830,13 @@
-       if (SET_DEST (x) == pc_rtx
-         && GET_CODE (SET_SRC (x)) == LABEL_REF)
-       ;
-+      /* cut the reg propagation of stack-protected argument */
-+      else if (x->volatil) {
-+      rtx x1 = SET_DEST (x);
-+      if (GET_CODE (x1) == SUBREG && GET_CODE (SUBREG_REG (x1)) == REG)
-+        x1 = SUBREG_REG (x1);
-+      make_new_qty (REGNO (x1), GET_MODE (x1));
-+      }
-       /* Don't count call-insns, (set (reg 0) (call ...)), as a set.
-        The hard function value register is used only once, to copy to
-diff -ruN gcc-3.3.1/gcc/explow.c gcc-3.3.1.pp/gcc/explow.c
---- gcc-3.3.1/gcc/explow.c     2003-04-07 22:58:12.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/explow.c  2003-09-05 11:58:59.000000000 +0000
-@@ -86,7 +86,8 @@
-   rtx tem;
-   int all_constant = 0;
--  if (c == 0)
-+  if (c == 0
-+      && !(flag_propolice_protection && x == virtual_stack_vars_rtx))
-     return x;
-  restart:
-@@ -187,7 +188,8 @@
-       break;
-     }
--  if (c != 0)
-+  if (c != 0
-+      || (flag_propolice_protection && x == virtual_stack_vars_rtx))
-     x = gen_rtx_PLUS (mode, x, GEN_INT (c));
-   if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
-@@ -531,6 +533,21 @@
-        in certain cases.  This is not necessary since the code
-        below can handle all possible cases, but machine-dependent
-        transformations can make better code.  */
-+      if (flag_propolice_protection)
-+      {
-+#define FRAMEADDR_P(X) (GET_CODE (X) == PLUS                          \
-+                      && XEXP (X, 0) == virtual_stack_vars_rtx        \
-+                      && GET_CODE (XEXP (X, 1)) == CONST_INT)
-+        rtx y;
-+        if (FRAMEADDR_P (x)) goto win;
-+        for (y=x; y!=0 && GET_CODE (y)==PLUS; y = XEXP (y, 0))
-+          {
-+            if (FRAMEADDR_P (XEXP (y, 0)))
-+              XEXP (y, 0) = force_reg (GET_MODE (XEXP (y, 0)), XEXP (y, 0));
-+            if (FRAMEADDR_P (XEXP (y, 1)))
-+              XEXP (y, 1) = force_reg (GET_MODE (XEXP (y, 1)), XEXP (y, 1));
-+          }
-+      }
-       LEGITIMIZE_ADDRESS (x, oldx, mode, win);
-       /* PLUS and MULT can appear in special ways
-diff -ruN gcc-3.3.1/gcc/expr.c gcc-3.3.1.pp/gcc/expr.c
---- gcc-3.3.1/gcc/expr.c       2003-07-24 19:11:20.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/expr.c    2003-09-05 11:58:59.000000000 +0000
-@@ -45,6 +45,7 @@
- #include "langhooks.h"
- #include "intl.h"
- #include "tm_p.h"
-+#include "protector.h"
- /* Decide whether a function's arguments should be processed
-    from first to last or from last to first.
-@@ -1518,7 +1519,7 @@
-       if (USE_LOAD_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_from)
-       {
--        data.from_addr = copy_addr_to_reg (plus_constant (from_addr, len));
-+        data.from_addr = copy_addr_to_reg (plus_constant (from_addr, len-GET_MODE_SIZE (mode)));
-         data.autinc_from = 1;
-         data.explicit_inc_from = -1;
-       }
-@@ -1532,7 +1533,7 @@
-       data.from_addr = copy_addr_to_reg (from_addr);
-       if (USE_STORE_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_to)
-       {
--        data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len));
-+        data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len-GET_MODE_SIZE (mode)));
-         data.autinc_to = 1;
-         data.explicit_inc_to = -1;
-       }
-@@ -1649,11 +1650,13 @@
-       from1 = adjust_address (data->from, mode, data->offset);
-       if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
--      emit_insn (gen_add2_insn (data->to_addr,
--                                GEN_INT (-(HOST_WIDE_INT)size)));
-+      if (data->explicit_inc_to < -1)
-+        emit_insn (gen_add2_insn (data->to_addr,
-+                                  GEN_INT (-(HOST_WIDE_INT)size)));
-       if (HAVE_PRE_DECREMENT && data->explicit_inc_from < 0)
--      emit_insn (gen_add2_insn (data->from_addr,
--                                GEN_INT (-(HOST_WIDE_INT)size)));
-+      if (data->explicit_inc_from < -1)
-+        emit_insn (gen_add2_insn (data->from_addr,
-+                                  GEN_INT (-(HOST_WIDE_INT)size)));
-       if (data->to)
-       emit_insn ((*genfun) (to1, from1));
-@@ -2826,7 +2829,7 @@
-       if (USE_STORE_PRE_DECREMENT (mode) && data->reverse && ! data->autinc_to)
-       {
--        data->to_addr = copy_addr_to_reg (plus_constant (to_addr, data->len));
-+        data->to_addr = copy_addr_to_reg (plus_constant (to_addr, data->len-GET_MODE_SIZE (mode)));
-         data->autinc_to = 1;
-         data->explicit_inc_to = -1;
-       }
-@@ -2897,8 +2900,9 @@
-       to1 = adjust_address (data->to, mode, data->offset);
-       if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
--      emit_insn (gen_add2_insn (data->to_addr,
--                                GEN_INT (-(HOST_WIDE_INT) size)));
-+      if (data->explicit_inc_to < -1)
-+        emit_insn (gen_add2_insn (data->to_addr,
-+                                  GEN_INT (-(HOST_WIDE_INT) size)));
-       cst = (*data->constfun) (data->constfundata, data->offset, mode);
-       emit_insn ((*genfun) (to1, cst));
-@@ -5894,7 +5898,9 @@
-         && GET_CODE (XEXP (value, 0)) == PLUS
-         && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
-         && REGNO (XEXP (XEXP (value, 0), 0)) >= FIRST_VIRTUAL_REGISTER
--        && REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER)
-+        && REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER
-+        && (!flag_propolice_protection
-+            || XEXP (XEXP (value, 0), 0) != virtual_stack_vars_rtx))
-       {
-         rtx temp = expand_simple_binop (GET_MODE (value), code,
-                                         XEXP (XEXP (value, 0), 0), op2,
-@@ -8070,7 +8076,8 @@
-       /* If adding to a sum including a constant,
-        associate it to put the constant outside.  */
-       if (GET_CODE (op1) == PLUS
--        && CONSTANT_P (XEXP (op1, 1)))
-+        && CONSTANT_P (XEXP (op1, 1))
-+        && !(flag_propolice_protection && (contains_fp (op0) || contains_fp (op1))))
-       {
-         rtx constant_term = const0_rtx;
-diff -ruN gcc-3.3.1/gcc/expr.c.orig gcc-3.3.1.pp/gcc/expr.c.orig
---- gcc-3.3.1/gcc/expr.c.orig  1970-01-01 00:00:00.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/expr.c.orig       2003-07-24 19:11:20.000000000 +0000
-@@ -0,0 +1,11287 @@
-+/* Convert tree expression to rtl instructions, for GNU compiler.
-+   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-+   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify it under
-+the terms of the GNU General Public License as published by the Free
-+Software Foundation; either version 2, or (at your option) any later
-+version.
-+
-+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-+WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING.  If not, write to the Free
-+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-+02111-1307, USA.  */
-+
-+#include "config.h"
-+#include "system.h"
-+#include "machmode.h"
-+#include "real.h"
-+#include "rtl.h"
-+#include "tree.h"
-+#include "flags.h"
-+#include "regs.h"
-+#include "hard-reg-set.h"
-+#include "except.h"
-+#include "function.h"
-+#include "insn-config.h"
-+#include "insn-attr.h"
-+/* Include expr.h after insn-config.h so we get HAVE_conditional_move.  */
-+#include "expr.h"
-+#include "optabs.h"
-+#include "libfuncs.h"
-+#include "recog.h"
-+#include "reload.h"
-+#include "output.h"
-+#include "typeclass.h"
-+#include "toplev.h"
-+#include "ggc.h"
-+#include "langhooks.h"
-+#include "intl.h"
-+#include "tm_p.h"
-+
-+/* Decide whether a function's arguments should be processed
-+   from first to last or from last to first.
-+
-+   They should if the stack and args grow in opposite directions, but
-+   only if we have push insns.  */
-+
-+#ifdef PUSH_ROUNDING
-+
-+#ifndef PUSH_ARGS_REVERSED
-+#if defined (STACK_GROWS_DOWNWARD) != defined (ARGS_GROW_DOWNWARD)
-+#define PUSH_ARGS_REVERSED    /* If it's last to first.  */
-+#endif
-+#endif
-+
-+#endif
-+
-+#ifndef STACK_PUSH_CODE
-+#ifdef STACK_GROWS_DOWNWARD
-+#define STACK_PUSH_CODE PRE_DEC
-+#else
-+#define STACK_PUSH_CODE PRE_INC
-+#endif
-+#endif
-+
-+/* Assume that case vectors are not pc-relative.  */
-+#ifndef CASE_VECTOR_PC_RELATIVE
-+#define CASE_VECTOR_PC_RELATIVE 0
-+#endif
-+
-+/* Convert defined/undefined to boolean.  */
-+#ifdef TARGET_MEM_FUNCTIONS
-+#undef TARGET_MEM_FUNCTIONS
-+#define TARGET_MEM_FUNCTIONS 1
-+#else
-+#define TARGET_MEM_FUNCTIONS 0
-+#endif
-+
-+
-+/* If this is nonzero, we do not bother generating VOLATILE
-+   around volatile memory references, and we are willing to
-+   output indirect addresses.  If cse is to follow, we reject
-+   indirect addresses so a useful potential cse is generated;
-+   if it is used only once, instruction combination will produce
-+   the same indirect address eventually.  */
-+int cse_not_expected;
-+
-+/* Chain of pending expressions for PLACEHOLDER_EXPR to replace.  */
-+static tree placeholder_list = 0;
-+
-+/* This structure is used by move_by_pieces to describe the move to
-+   be performed.  */
-+struct move_by_pieces
-+{
-+  rtx to;
-+  rtx to_addr;
-+  int autinc_to;
-+  int explicit_inc_to;
-+  rtx from;
-+  rtx from_addr;
-+  int autinc_from;
-+  int explicit_inc_from;
-+  unsigned HOST_WIDE_INT len;
-+  HOST_WIDE_INT offset;
-+  int reverse;
-+};
-+
-+/* This structure is used by store_by_pieces to describe the clear to
-+   be performed.  */
-+
-+struct store_by_pieces
-+{
-+  rtx to;
-+  rtx to_addr;
-+  int autinc_to;
-+  int explicit_inc_to;
-+  unsigned HOST_WIDE_INT len;
-+  HOST_WIDE_INT offset;
-+  rtx (*constfun) PARAMS ((PTR, HOST_WIDE_INT, enum machine_mode));
-+  PTR constfundata;
-+  int reverse;
-+};
-+
-+static rtx enqueue_insn               PARAMS ((rtx, rtx));
-+static unsigned HOST_WIDE_INT move_by_pieces_ninsns
-+                              PARAMS ((unsigned HOST_WIDE_INT,
-+                                       unsigned int));
-+static void move_by_pieces_1  PARAMS ((rtx (*) (rtx, ...), enum machine_mode,
-+                                       struct move_by_pieces *));
-+static bool block_move_libcall_safe_for_call_parm PARAMS ((void));
-+static bool emit_block_move_via_movstr PARAMS ((rtx, rtx, rtx, unsigned));
-+static rtx emit_block_move_via_libcall PARAMS ((rtx, rtx, rtx));
-+static tree emit_block_move_libcall_fn PARAMS ((int));
-+static void emit_block_move_via_loop PARAMS ((rtx, rtx, rtx, unsigned));
-+static rtx clear_by_pieces_1  PARAMS ((PTR, HOST_WIDE_INT,
-+                                       enum machine_mode));
-+static void clear_by_pieces   PARAMS ((rtx, unsigned HOST_WIDE_INT,
-+                                       unsigned int));
-+static void store_by_pieces_1 PARAMS ((struct store_by_pieces *,
-+                                       unsigned int));
-+static void store_by_pieces_2 PARAMS ((rtx (*) (rtx, ...),
-+                                       enum machine_mode,
-+                                       struct store_by_pieces *));
-+static bool clear_storage_via_clrstr PARAMS ((rtx, rtx, unsigned));
-+static rtx clear_storage_via_libcall PARAMS ((rtx, rtx));
-+static tree clear_storage_libcall_fn PARAMS ((int));
-+static rtx compress_float_constant PARAMS ((rtx, rtx));
-+static rtx get_subtarget      PARAMS ((rtx));
-+static int is_zeros_p         PARAMS ((tree));
-+static int mostly_zeros_p     PARAMS ((tree));
-+static void store_constructor_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
-+                                           HOST_WIDE_INT, enum machine_mode,
-+                                           tree, tree, int, int));
-+static void store_constructor PARAMS ((tree, rtx, int, HOST_WIDE_INT));
-+static rtx store_field                PARAMS ((rtx, HOST_WIDE_INT,
-+                                       HOST_WIDE_INT, enum machine_mode,
-+                                       tree, enum machine_mode, int, tree,
-+                                       int));
-+static rtx var_rtx            PARAMS ((tree));
-+static HOST_WIDE_INT highest_pow2_factor PARAMS ((tree));
-+static HOST_WIDE_INT highest_pow2_factor_for_type PARAMS ((tree, tree));
-+static int is_aligning_offset PARAMS ((tree, tree));
-+static rtx expand_increment   PARAMS ((tree, int, int));
-+static void do_jump_by_parts_greater PARAMS ((tree, int, rtx, rtx));
-+static void do_jump_by_parts_equality PARAMS ((tree, rtx, rtx));
-+static void do_compare_and_jump       PARAMS ((tree, enum rtx_code, enum rtx_code,
-+                                       rtx, rtx));
-+static rtx do_store_flag      PARAMS ((tree, rtx, enum machine_mode, int));
-+#ifdef PUSH_ROUNDING
-+static void emit_single_push_insn PARAMS ((enum machine_mode, rtx, tree));
-+#endif
-+static void do_tablejump PARAMS ((rtx, enum machine_mode, rtx, rtx, rtx));
-+static rtx const_vector_from_tree PARAMS ((tree));
-+
-+/* Record for each mode whether we can move a register directly to or
-+   from an object of that mode in memory.  If we can't, we won't try
-+   to use that mode directly when accessing a field of that mode.  */
-+
-+static char direct_load[NUM_MACHINE_MODES];
-+static char direct_store[NUM_MACHINE_MODES];
-+
-+/* Record for each mode whether we can float-extend from memory.  */
-+
-+static bool float_extend_from_mem[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
-+
-+/* If a memory-to-memory move would take MOVE_RATIO or more simple
-+   move-instruction sequences, we will do a movstr or libcall instead.  */
-+
-+#ifndef MOVE_RATIO
-+#if defined (HAVE_movstrqi) || defined (HAVE_movstrhi) || defined (HAVE_movstrsi) || defined (HAVE_movstrdi) || defined (HAVE_movstrti)
-+#define MOVE_RATIO 2
-+#else
-+/* If we are optimizing for space (-Os), cut down the default move ratio.  */
-+#define MOVE_RATIO (optimize_size ? 3 : 15)
-+#endif
-+#endif
-+
-+/* This macro is used to determine whether move_by_pieces should be called
-+   to perform a structure copy.  */
-+#ifndef MOVE_BY_PIECES_P
-+#define MOVE_BY_PIECES_P(SIZE, ALIGN) \
-+  (move_by_pieces_ninsns (SIZE, ALIGN) < (unsigned int) MOVE_RATIO)
-+#endif
-+
-+/* If a clear memory operation would take CLEAR_RATIO or more simple
-+   move-instruction sequences, we will do a clrstr or libcall instead.  */
-+
-+#ifndef CLEAR_RATIO
-+#if defined (HAVE_clrstrqi) || defined (HAVE_clrstrhi) || defined (HAVE_clrstrsi) || defined (HAVE_clrstrdi) || defined (HAVE_clrstrti)
-+#define CLEAR_RATIO 2
-+#else
-+/* If we are optimizing for space, cut down the default clear ratio.  */
-+#define CLEAR_RATIO (optimize_size ? 3 : 15)
-+#endif
-+#endif
-+
-+/* This macro is used to determine whether clear_by_pieces should be
-+   called to clear storage.  */
-+#ifndef CLEAR_BY_PIECES_P
-+#define CLEAR_BY_PIECES_P(SIZE, ALIGN) \
-+  (move_by_pieces_ninsns (SIZE, ALIGN) < (unsigned int) CLEAR_RATIO)
-+#endif
-+
-+/* This array records the insn_code of insns to perform block moves.  */
-+enum insn_code movstr_optab[NUM_MACHINE_MODES];
-+
-+/* This array records the insn_code of insns to perform block clears.  */
-+enum insn_code clrstr_optab[NUM_MACHINE_MODES];
-+
-+/* SLOW_UNALIGNED_ACCESS is nonzero if unaligned accesses are very slow.  */
-+
-+#ifndef SLOW_UNALIGNED_ACCESS
-+#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) STRICT_ALIGNMENT
-+#endif
-+\f
-+/* This is run once per compilation to set up which modes can be used
-+   directly in memory and to initialize the block move optab.  */
-+
-+void
-+init_expr_once ()
-+{
-+  rtx insn, pat;
-+  enum machine_mode mode;
-+  int num_clobbers;
-+  rtx mem, mem1;
-+  rtx reg;
-+
-+  /* Try indexing by frame ptr and try by stack ptr.
-+     It is known that on the Convex the stack ptr isn't a valid index.
-+     With luck, one or the other is valid on any machine.  */
-+  mem = gen_rtx_MEM (VOIDmode, stack_pointer_rtx);
-+  mem1 = gen_rtx_MEM (VOIDmode, frame_pointer_rtx);
-+
-+  /* A scratch register we can modify in-place below to avoid
-+     useless RTL allocations.  */
-+  reg = gen_rtx_REG (VOIDmode, -1);
-+
-+  insn = rtx_alloc (INSN);
-+  pat = gen_rtx_SET (0, NULL_RTX, NULL_RTX);
-+  PATTERN (insn) = pat;
-+
-+  for (mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;
-+       mode = (enum machine_mode) ((int) mode + 1))
-+    {
-+      int regno;
-+
-+      direct_load[(int) mode] = direct_store[(int) mode] = 0;
-+      PUT_MODE (mem, mode);
-+      PUT_MODE (mem1, mode);
-+      PUT_MODE (reg, mode);
-+
-+      /* See if there is some register that can be used in this mode and
-+       directly loaded or stored from memory.  */
-+
-+      if (mode != VOIDmode && mode != BLKmode)
-+      for (regno = 0; regno < FIRST_PSEUDO_REGISTER
-+           && (direct_load[(int) mode] == 0 || direct_store[(int) mode] == 0);
-+           regno++)
-+        {
-+          if (! HARD_REGNO_MODE_OK (regno, mode))
-+            continue;
-+
-+          REGNO (reg) = regno;
-+
-+          SET_SRC (pat) = mem;
-+          SET_DEST (pat) = reg;
-+          if (recog (pat, insn, &num_clobbers) >= 0)
-+            direct_load[(int) mode] = 1;
-+
-+          SET_SRC (pat) = mem1;
-+          SET_DEST (pat) = reg;
-+          if (recog (pat, insn, &num_clobbers) >= 0)
-+            direct_load[(int) mode] = 1;
-+
-+          SET_SRC (pat) = reg;
-+          SET_DEST (pat) = mem;
-+          if (recog (pat, insn, &num_clobbers) >= 0)
-+            direct_store[(int) mode] = 1;
-+
-+          SET_SRC (pat) = reg;
-+          SET_DEST (pat) = mem1;
-+          if (recog (pat, insn, &num_clobbers) >= 0)
-+            direct_store[(int) mode] = 1;
-+        }
-+    }
-+
-+  mem = gen_rtx_MEM (VOIDmode, gen_rtx_raw_REG (Pmode, 10000));
-+
-+  for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
-+       mode = GET_MODE_WIDER_MODE (mode))
-+    {
-+      enum machine_mode srcmode;
-+      for (srcmode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); srcmode != mode;
-+         srcmode = GET_MODE_WIDER_MODE (srcmode))
-+      {
-+        enum insn_code ic;
-+
-+        ic = can_extend_p (mode, srcmode, 0);
-+        if (ic == CODE_FOR_nothing)
-+          continue;
-+
-+        PUT_MODE (mem, srcmode);
-+
-+        if ((*insn_data[ic].operand[1].predicate) (mem, srcmode))
-+          float_extend_from_mem[mode][srcmode] = true;
-+      }
-+    }
-+}
-+
-+/* This is run at the start of compiling a function.  */
-+
-+void
-+init_expr ()
-+{
-+  cfun->expr = (struct expr_status *) ggc_alloc (sizeof (struct expr_status));
-+
-+  pending_chain = 0;
-+  pending_stack_adjust = 0;
-+  stack_pointer_delta = 0;
-+  inhibit_defer_pop = 0;
-+  saveregs_value = 0;
-+  apply_args_value = 0;
-+  forced_labels = 0;
-+}
-+
-+/* Small sanity check that the queue is empty at the end of a function.  */
-+
-+void
-+finish_expr_for_function ()
-+{
-+  if (pending_chain)
-+    abort ();
-+}
-+\f
-+/* Manage the queue of increment instructions to be output
-+   for POSTINCREMENT_EXPR expressions, etc.  */
-+
-+/* Queue up to increment (or change) VAR later.  BODY says how:
-+   BODY should be the same thing you would pass to emit_insn
-+   to increment right away.  It will go to emit_insn later on.
-+
-+   The value is a QUEUED expression to be used in place of VAR
-+   where you want to guarantee the pre-incrementation value of VAR.  */
-+
-+static rtx
-+enqueue_insn (var, body)
-+     rtx var, body;
-+{
-+  pending_chain = gen_rtx_QUEUED (GET_MODE (var), var, NULL_RTX, NULL_RTX,
-+                                body, pending_chain);
-+  return pending_chain;
-+}
-+
-+/* Use protect_from_queue to convert a QUEUED expression
-+   into something that you can put immediately into an instruction.
-+   If the queued incrementation has not happened yet,
-+   protect_from_queue returns the variable itself.
-+   If the incrementation has happened, protect_from_queue returns a temp
-+   that contains a copy of the old value of the variable.
-+
-+   Any time an rtx which might possibly be a QUEUED is to be put
-+   into an instruction, it must be passed through protect_from_queue first.
-+   QUEUED expressions are not meaningful in instructions.
-+
-+   Do not pass a value through protect_from_queue and then hold
-+   on to it for a while before putting it in an instruction!
-+   If the queue is flushed in between, incorrect code will result.  */
-+
-+rtx
-+protect_from_queue (x, modify)
-+     rtx x;
-+     int modify;
-+{
-+  RTX_CODE code = GET_CODE (x);
-+
-+#if 0  /* A QUEUED can hang around after the queue is forced out.  */
-+  /* Shortcut for most common case.  */
-+  if (pending_chain == 0)
-+    return x;
-+#endif
-+
-+  if (code != QUEUED)
-+    {
-+      /* A special hack for read access to (MEM (QUEUED ...)) to facilitate
-+       use of autoincrement.  Make a copy of the contents of the memory
-+       location rather than a copy of the address, but not if the value is
-+       of mode BLKmode.  Don't modify X in place since it might be
-+       shared.  */
-+      if (code == MEM && GET_MODE (x) != BLKmode
-+        && GET_CODE (XEXP (x, 0)) == QUEUED && !modify)
-+      {
-+        rtx y = XEXP (x, 0);
-+        rtx new = replace_equiv_address_nv (x, QUEUED_VAR (y));
-+
-+        if (QUEUED_INSN (y))
-+          {
-+            rtx temp = gen_reg_rtx (GET_MODE (x));
-+
-+            emit_insn_before (gen_move_insn (temp, new),
-+                              QUEUED_INSN (y));
-+            return temp;
-+          }
-+
-+        /* Copy the address into a pseudo, so that the returned value
-+           remains correct across calls to emit_queue.  */
-+        return replace_equiv_address (new, copy_to_reg (XEXP (new, 0)));
-+      }
-+
-+      /* Otherwise, recursively protect the subexpressions of all
-+       the kinds of rtx's that can contain a QUEUED.  */
-+      if (code == MEM)
-+      {
-+        rtx tem = protect_from_queue (XEXP (x, 0), 0);
-+        if (tem != XEXP (x, 0))
-+          {
-+            x = copy_rtx (x);
-+            XEXP (x, 0) = tem;
-+          }
-+      }
-+      else if (code == PLUS || code == MULT)
-+      {
-+        rtx new0 = protect_from_queue (XEXP (x, 0), 0);
-+        rtx new1 = protect_from_queue (XEXP (x, 1), 0);
-+        if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
-+          {
-+            x = copy_rtx (x);
-+            XEXP (x, 0) = new0;
-+            XEXP (x, 1) = new1;
-+          }
-+      }
-+      return x;
-+    }
-+  /* If the increment has not happened, use the variable itself.  Copy it
-+     into a new pseudo so that the value remains correct across calls to
-+     emit_queue.  */
-+  if (QUEUED_INSN (x) == 0)
-+    return copy_to_reg (QUEUED_VAR (x));
-+  /* If the increment has happened and a pre-increment copy exists,
-+     use that copy.  */
-+  if (QUEUED_COPY (x) != 0)
-+    return QUEUED_COPY (x);
-+  /* The increment has happened but we haven't set up a pre-increment copy.
-+     Set one up now, and use it.  */
-+  QUEUED_COPY (x) = gen_reg_rtx (GET_MODE (QUEUED_VAR (x)));
-+  emit_insn_before (gen_move_insn (QUEUED_COPY (x), QUEUED_VAR (x)),
-+                  QUEUED_INSN (x));
-+  return QUEUED_COPY (x);
-+}
-+
-+/* Return nonzero if X contains a QUEUED expression:
-+   if it contains anything that will be altered by a queued increment.
-+   We handle only combinations of MEM, PLUS, MINUS and MULT operators
-+   since memory addresses generally contain only those.  */
-+
-+int
-+queued_subexp_p (x)
-+     rtx x;
-+{
-+  enum rtx_code code = GET_CODE (x);
-+  switch (code)
-+    {
-+    case QUEUED:
-+      return 1;
-+    case MEM:
-+      return queued_subexp_p (XEXP (x, 0));
-+    case MULT:
-+    case PLUS:
-+    case MINUS:
-+      return (queued_subexp_p (XEXP (x, 0))
-+            || queued_subexp_p (XEXP (x, 1)));
-+    default:
-+      return 0;
-+    }
-+}
-+
-+/* Perform all the pending incrementations.  */
-+
-+void
-+emit_queue ()
-+{
-+  rtx p;
-+  while ((p = pending_chain))
-+    {
-+      rtx body = QUEUED_BODY (p);
-+
-+      switch (GET_CODE (body))
-+      {
-+      case INSN:
-+      case JUMP_INSN:
-+      case CALL_INSN:
-+      case CODE_LABEL:
-+      case BARRIER:
-+      case NOTE:
-+        QUEUED_INSN (p) = body;
-+        emit_insn (body);
-+        break;
-+
-+#ifdef ENABLE_CHECKING
-+      case SEQUENCE:
-+        abort ();
-+        break;
-+#endif
-+
-+      default:
-+        QUEUED_INSN (p) = emit_insn (body);
-+        break;
-+      }
-+
-+      pending_chain = QUEUED_NEXT (p);
-+    }
-+}
-+\f
-+/* Copy data from FROM to TO, where the machine modes are not the same.
-+   Both modes may be integer, or both may be floating.
-+   UNSIGNEDP should be nonzero if FROM is an unsigned type.
-+   This causes zero-extension instead of sign-extension.  */
-+
-+void
-+convert_move (to, from, unsignedp)
-+     rtx to, from;
-+     int unsignedp;
-+{
-+  enum machine_mode to_mode = GET_MODE (to);
-+  enum machine_mode from_mode = GET_MODE (from);
-+  int to_real = GET_MODE_CLASS (to_mode) == MODE_FLOAT;
-+  int from_real = GET_MODE_CLASS (from_mode) == MODE_FLOAT;
-+  enum insn_code code;
-+  rtx libcall;
-+
-+  /* rtx code for making an equivalent value.  */
-+  enum rtx_code equiv_code = (unsignedp < 0 ? UNKNOWN
-+                            : (unsignedp ? ZERO_EXTEND : SIGN_EXTEND));
-+
-+  to = protect_from_queue (to, 1);
-+  from = protect_from_queue (from, 0);
-+
-+  if (to_real != from_real)
-+    abort ();
-+
-+  /* If FROM is a SUBREG that indicates that we have already done at least
-+     the required extension, strip it.  We don't handle such SUBREGs as
-+     TO here.  */
-+
-+  if (GET_CODE (from) == SUBREG && SUBREG_PROMOTED_VAR_P (from)
-+      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (from)))
-+        >= GET_MODE_SIZE (to_mode))
-+      && SUBREG_PROMOTED_UNSIGNED_P (from) == unsignedp)
-+    from = gen_lowpart (to_mode, from), from_mode = to_mode;
-+
-+  if (GET_CODE (to) == SUBREG && SUBREG_PROMOTED_VAR_P (to))
-+    abort ();
-+
-+  if (to_mode == from_mode
-+      || (from_mode == VOIDmode && CONSTANT_P (from)))
-+    {
-+      emit_move_insn (to, from);
-+      return;
-+    }
-+
-+  if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
-+    {
-+      if (GET_MODE_BITSIZE (from_mode) != GET_MODE_BITSIZE (to_mode))
-+      abort ();
-+
-+      if (VECTOR_MODE_P (to_mode))
-+      from = simplify_gen_subreg (to_mode, from, GET_MODE (from), 0);
-+      else
-+      to = simplify_gen_subreg (from_mode, to, GET_MODE (to), 0);
-+
-+      emit_move_insn (to, from);
-+      return;
-+    }
-+
-+  if (to_real != from_real)
-+    abort ();
-+
-+  if (to_real)
-+    {
-+      rtx value, insns;
-+
-+      if (GET_MODE_BITSIZE (from_mode) < GET_MODE_BITSIZE (to_mode))
-+      {
-+        /* Try converting directly if the insn is supported.  */
-+        if ((code = can_extend_p (to_mode, from_mode, 0))
-+            != CODE_FOR_nothing)
-+          {
-+            emit_unop_insn (code, to, from, UNKNOWN);
-+            return;
-+          }
-+      }
-+
-+#ifdef HAVE_trunchfqf2
-+      if (HAVE_trunchfqf2 && from_mode == HFmode && to_mode == QFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_trunchfqf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_trunctqfqf2
-+      if (HAVE_trunctqfqf2 && from_mode == TQFmode && to_mode == QFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_trunctqfqf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_truncsfqf2
-+      if (HAVE_truncsfqf2 && from_mode == SFmode && to_mode == QFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_truncsfqf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_truncdfqf2
-+      if (HAVE_truncdfqf2 && from_mode == DFmode && to_mode == QFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_truncdfqf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_truncxfqf2
-+      if (HAVE_truncxfqf2 && from_mode == XFmode && to_mode == QFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_truncxfqf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_trunctfqf2
-+      if (HAVE_trunctfqf2 && from_mode == TFmode && to_mode == QFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_trunctfqf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+
-+#ifdef HAVE_trunctqfhf2
-+      if (HAVE_trunctqfhf2 && from_mode == TQFmode && to_mode == HFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_trunctqfhf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_truncsfhf2
-+      if (HAVE_truncsfhf2 && from_mode == SFmode && to_mode == HFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_truncsfhf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_truncdfhf2
-+      if (HAVE_truncdfhf2 && from_mode == DFmode && to_mode == HFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_truncdfhf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_truncxfhf2
-+      if (HAVE_truncxfhf2 && from_mode == XFmode && to_mode == HFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_truncxfhf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_trunctfhf2
-+      if (HAVE_trunctfhf2 && from_mode == TFmode && to_mode == HFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_trunctfhf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+
-+#ifdef HAVE_truncsftqf2
-+      if (HAVE_truncsftqf2 && from_mode == SFmode && to_mode == TQFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_truncsftqf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_truncdftqf2
-+      if (HAVE_truncdftqf2 && from_mode == DFmode && to_mode == TQFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_truncdftqf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_truncxftqf2
-+      if (HAVE_truncxftqf2 && from_mode == XFmode && to_mode == TQFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_truncxftqf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_trunctftqf2
-+      if (HAVE_trunctftqf2 && from_mode == TFmode && to_mode == TQFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_trunctftqf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+
-+#ifdef HAVE_truncdfsf2
-+      if (HAVE_truncdfsf2 && from_mode == DFmode && to_mode == SFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_truncdfsf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_truncxfsf2
-+      if (HAVE_truncxfsf2 && from_mode == XFmode && to_mode == SFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_truncxfsf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_trunctfsf2
-+      if (HAVE_trunctfsf2 && from_mode == TFmode && to_mode == SFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_trunctfsf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_truncxfdf2
-+      if (HAVE_truncxfdf2 && from_mode == XFmode && to_mode == DFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_truncxfdf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+#ifdef HAVE_trunctfdf2
-+      if (HAVE_trunctfdf2 && from_mode == TFmode && to_mode == DFmode)
-+      {
-+        emit_unop_insn (CODE_FOR_trunctfdf2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+
-+      libcall = (rtx) 0;
-+      switch (from_mode)
-+      {
-+      case SFmode:
-+        switch (to_mode)
-+          {
-+          case DFmode:
-+            libcall = extendsfdf2_libfunc;
-+            break;
-+
-+          case XFmode:
-+            libcall = extendsfxf2_libfunc;
-+            break;
-+
-+          case TFmode:
-+            libcall = extendsftf2_libfunc;
-+            break;
-+
-+          default:
-+            break;
-+          }
-+        break;
-+
-+      case DFmode:
-+        switch (to_mode)
-+          {
-+          case SFmode:
-+            libcall = truncdfsf2_libfunc;
-+            break;
-+
-+          case XFmode:
-+            libcall = extenddfxf2_libfunc;
-+            break;
-+
-+          case TFmode:
-+            libcall = extenddftf2_libfunc;
-+            break;
-+
-+          default:
-+            break;
-+          }
-+        break;
-+
-+      case XFmode:
-+        switch (to_mode)
-+          {
-+          case SFmode:
-+            libcall = truncxfsf2_libfunc;
-+            break;
-+
-+          case DFmode:
-+            libcall = truncxfdf2_libfunc;
-+            break;
-+
-+          default:
-+            break;
-+          }
-+        break;
-+
-+      case TFmode:
-+        switch (to_mode)
-+          {
-+          case SFmode:
-+            libcall = trunctfsf2_libfunc;
-+            break;
-+
-+          case DFmode:
-+            libcall = trunctfdf2_libfunc;
-+            break;
-+
-+          default:
-+            break;
-+          }
-+        break;
-+
-+      default:
-+        break;
-+      }
-+
-+      if (libcall == (rtx) 0)
-+      /* This conversion is not implemented yet.  */
-+      abort ();
-+
-+      start_sequence ();
-+      value = emit_library_call_value (libcall, NULL_RTX, LCT_CONST, to_mode,
-+                                     1, from, from_mode);
-+      insns = get_insns ();
-+      end_sequence ();
-+      emit_libcall_block (insns, to, value, gen_rtx_FLOAT_TRUNCATE (to_mode,
-+                                                                  from));
-+      return;
-+    }
-+
-+  /* Now both modes are integers.  */
-+
-+  /* Handle expanding beyond a word.  */
-+  if (GET_MODE_BITSIZE (from_mode) < GET_MODE_BITSIZE (to_mode)
-+      && GET_MODE_BITSIZE (to_mode) > BITS_PER_WORD)
-+    {
-+      rtx insns;
-+      rtx lowpart;
-+      rtx fill_value;
-+      rtx lowfrom;
-+      int i;
-+      enum machine_mode lowpart_mode;
-+      int nwords = CEIL (GET_MODE_SIZE (to_mode), UNITS_PER_WORD);
-+
-+      /* Try converting directly if the insn is supported.  */
-+      if ((code = can_extend_p (to_mode, from_mode, unsignedp))
-+        != CODE_FOR_nothing)
-+      {
-+        /* If FROM is a SUBREG, put it into a register.  Do this
-+           so that we always generate the same set of insns for
-+           better cse'ing; if an intermediate assignment occurred,
-+           we won't be doing the operation directly on the SUBREG.  */
-+        if (optimize > 0 && GET_CODE (from) == SUBREG)
-+          from = force_reg (from_mode, from);
-+        emit_unop_insn (code, to, from, equiv_code);
-+        return;
-+      }
-+      /* Next, try converting via full word.  */
-+      else if (GET_MODE_BITSIZE (from_mode) < BITS_PER_WORD
-+             && ((code = can_extend_p (to_mode, word_mode, unsignedp))
-+                 != CODE_FOR_nothing))
-+      {
-+        if (GET_CODE (to) == REG)
-+          emit_insn (gen_rtx_CLOBBER (VOIDmode, to));
-+        convert_move (gen_lowpart (word_mode, to), from, unsignedp);
-+        emit_unop_insn (code, to,
-+                        gen_lowpart (word_mode, to), equiv_code);
-+        return;
-+      }
-+
-+      /* No special multiword conversion insn; do it by hand.  */
-+      start_sequence ();
-+
-+      /* Since we will turn this into a no conflict block, we must ensure
-+       that the source does not overlap the target.  */
-+
-+      if (reg_overlap_mentioned_p (to, from))
-+      from = force_reg (from_mode, from);
-+
-+      /* Get a copy of FROM widened to a word, if necessary.  */
-+      if (GET_MODE_BITSIZE (from_mode) < BITS_PER_WORD)
-+      lowpart_mode = word_mode;
-+      else
-+      lowpart_mode = from_mode;
-+
-+      lowfrom = convert_to_mode (lowpart_mode, from, unsignedp);
-+
-+      lowpart = gen_lowpart (lowpart_mode, to);
-+      emit_move_insn (lowpart, lowfrom);
-+
-+      /* Compute the value to put in each remaining word.  */
-+      if (unsignedp)
-+      fill_value = const0_rtx;
-+      else
-+      {
-+#ifdef HAVE_slt
-+        if (HAVE_slt
-+            && insn_data[(int) CODE_FOR_slt].operand[0].mode == word_mode
-+            && STORE_FLAG_VALUE == -1)
-+          {
-+            emit_cmp_insn (lowfrom, const0_rtx, NE, NULL_RTX,
-+                           lowpart_mode, 0);
-+            fill_value = gen_reg_rtx (word_mode);
-+            emit_insn (gen_slt (fill_value));
-+          }
-+        else
-+#endif
-+          {
-+            fill_value
-+              = expand_shift (RSHIFT_EXPR, lowpart_mode, lowfrom,
-+                              size_int (GET_MODE_BITSIZE (lowpart_mode) - 1),
-+                              NULL_RTX, 0);
-+            fill_value = convert_to_mode (word_mode, fill_value, 1);
-+          }
-+      }
-+
-+      /* Fill the remaining words.  */
-+      for (i = GET_MODE_SIZE (lowpart_mode) / UNITS_PER_WORD; i < nwords; i++)
-+      {
-+        int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
-+        rtx subword = operand_subword (to, index, 1, to_mode);
-+
-+        if (subword == 0)
-+          abort ();
-+
-+        if (fill_value != subword)
-+          emit_move_insn (subword, fill_value);
-+      }
-+
-+      insns = get_insns ();
-+      end_sequence ();
-+
-+      emit_no_conflict_block (insns, to, from, NULL_RTX,
-+                            gen_rtx_fmt_e (equiv_code, to_mode, copy_rtx (from)));
-+      return;
-+    }
-+
-+  /* Truncating multi-word to a word or less.  */
-+  if (GET_MODE_BITSIZE (from_mode) > BITS_PER_WORD
-+      && GET_MODE_BITSIZE (to_mode) <= BITS_PER_WORD)
-+    {
-+      if (!((GET_CODE (from) == MEM
-+           && ! MEM_VOLATILE_P (from)
-+           && direct_load[(int) to_mode]
-+           && ! mode_dependent_address_p (XEXP (from, 0)))
-+          || GET_CODE (from) == REG
-+          || GET_CODE (from) == SUBREG))
-+      from = force_reg (from_mode, from);
-+      convert_move (to, gen_lowpart (word_mode, from), 0);
-+      return;
-+    }
-+
-+  /* Handle pointer conversion.  */                   /* SPEE 900220.  */
-+  if (to_mode == PQImode)
-+    {
-+      if (from_mode != QImode)
-+      from = convert_to_mode (QImode, from, unsignedp);
-+
-+#ifdef HAVE_truncqipqi2
-+      if (HAVE_truncqipqi2)
-+      {
-+        emit_unop_insn (CODE_FOR_truncqipqi2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif /* HAVE_truncqipqi2 */
-+      abort ();
-+    }
-+
-+  if (from_mode == PQImode)
-+    {
-+      if (to_mode != QImode)
-+      {
-+        from = convert_to_mode (QImode, from, unsignedp);
-+        from_mode = QImode;
-+      }
-+      else
-+      {
-+#ifdef HAVE_extendpqiqi2
-+        if (HAVE_extendpqiqi2)
-+          {
-+            emit_unop_insn (CODE_FOR_extendpqiqi2, to, from, UNKNOWN);
-+            return;
-+          }
-+#endif /* HAVE_extendpqiqi2 */
-+        abort ();
-+      }
-+    }
-+
-+  if (to_mode == PSImode)
-+    {
-+      if (from_mode != SImode)
-+      from = convert_to_mode (SImode, from, unsignedp);
-+
-+#ifdef HAVE_truncsipsi2
-+      if (HAVE_truncsipsi2)
-+      {
-+        emit_unop_insn (CODE_FOR_truncsipsi2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif /* HAVE_truncsipsi2 */
-+      abort ();
-+    }
-+
-+  if (from_mode == PSImode)
-+    {
-+      if (to_mode != SImode)
-+      {
-+        from = convert_to_mode (SImode, from, unsignedp);
-+        from_mode = SImode;
-+      }
-+      else
-+      {
-+#ifdef HAVE_extendpsisi2
-+        if (! unsignedp && HAVE_extendpsisi2)
-+          {
-+            emit_unop_insn (CODE_FOR_extendpsisi2, to, from, UNKNOWN);
-+            return;
-+          }
-+#endif /* HAVE_extendpsisi2 */
-+#ifdef HAVE_zero_extendpsisi2
-+        if (unsignedp && HAVE_zero_extendpsisi2)
-+          {
-+            emit_unop_insn (CODE_FOR_zero_extendpsisi2, to, from, UNKNOWN);
-+            return;
-+          }
-+#endif /* HAVE_zero_extendpsisi2 */
-+        abort ();
-+      }
-+    }
-+
-+  if (to_mode == PDImode)
-+    {
-+      if (from_mode != DImode)
-+      from = convert_to_mode (DImode, from, unsignedp);
-+
-+#ifdef HAVE_truncdipdi2
-+      if (HAVE_truncdipdi2)
-+      {
-+        emit_unop_insn (CODE_FOR_truncdipdi2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif /* HAVE_truncdipdi2 */
-+      abort ();
-+    }
-+
-+  if (from_mode == PDImode)
-+    {
-+      if (to_mode != DImode)
-+      {
-+        from = convert_to_mode (DImode, from, unsignedp);
-+        from_mode = DImode;
-+      }
-+      else
-+      {
-+#ifdef HAVE_extendpdidi2
-+        if (HAVE_extendpdidi2)
-+          {
-+            emit_unop_insn (CODE_FOR_extendpdidi2, to, from, UNKNOWN);
-+            return;
-+          }
-+#endif /* HAVE_extendpdidi2 */
-+        abort ();
-+      }
-+    }
-+
-+  /* Now follow all the conversions between integers
-+     no more than a word long.  */
-+
-+  /* For truncation, usually we can just refer to FROM in a narrower mode.  */
-+  if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode)
-+      && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (to_mode),
-+                              GET_MODE_BITSIZE (from_mode)))
-+    {
-+      if (!((GET_CODE (from) == MEM
-+           && ! MEM_VOLATILE_P (from)
-+           && direct_load[(int) to_mode]
-+           && ! mode_dependent_address_p (XEXP (from, 0)))
-+          || GET_CODE (from) == REG
-+          || GET_CODE (from) == SUBREG))
-+      from = force_reg (from_mode, from);
-+      if (GET_CODE (from) == REG && REGNO (from) < FIRST_PSEUDO_REGISTER
-+        && ! HARD_REGNO_MODE_OK (REGNO (from), to_mode))
-+      from = copy_to_reg (from);
-+      emit_move_insn (to, gen_lowpart (to_mode, from));
-+      return;
-+    }
-+
-+  /* Handle extension.  */
-+  if (GET_MODE_BITSIZE (to_mode) > GET_MODE_BITSIZE (from_mode))
-+    {
-+      /* Convert directly if that works.  */
-+      if ((code = can_extend_p (to_mode, from_mode, unsignedp))
-+        != CODE_FOR_nothing)
-+      {
-+        if (flag_force_mem)
-+          from = force_not_mem (from);
-+
-+        emit_unop_insn (code, to, from, equiv_code);
-+        return;
-+      }
-+      else
-+      {
-+        enum machine_mode intermediate;
-+        rtx tmp;
-+        tree shift_amount;
-+
-+        /* Search for a mode to convert via.  */
-+        for (intermediate = from_mode; intermediate != VOIDmode;
-+             intermediate = GET_MODE_WIDER_MODE (intermediate))
-+          if (((can_extend_p (to_mode, intermediate, unsignedp)
-+                != CODE_FOR_nothing)
-+               || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate)
-+                   && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (to_mode),
-+                                             GET_MODE_BITSIZE (intermediate))))
-+              && (can_extend_p (intermediate, from_mode, unsignedp)
-+                  != CODE_FOR_nothing))
-+            {
-+              convert_move (to, convert_to_mode (intermediate, from,
-+                                                 unsignedp), unsignedp);
-+              return;
-+            }
-+
-+        /* No suitable intermediate mode.
-+           Generate what we need with shifts.  */
-+        shift_amount = build_int_2 (GET_MODE_BITSIZE (to_mode)
-+                                    - GET_MODE_BITSIZE (from_mode), 0);
-+        from = gen_lowpart (to_mode, force_reg (from_mode, from));
-+        tmp = expand_shift (LSHIFT_EXPR, to_mode, from, shift_amount,
-+                            to, unsignedp);
-+        tmp = expand_shift (RSHIFT_EXPR, to_mode, tmp, shift_amount,
-+                            to, unsignedp);
-+        if (tmp != to)
-+          emit_move_insn (to, tmp);
-+        return;
-+      }
-+    }
-+
-+  /* Support special truncate insns for certain modes.  */
-+
-+  if (from_mode == DImode && to_mode == SImode)
-+    {
-+#ifdef HAVE_truncdisi2
-+      if (HAVE_truncdisi2)
-+      {
-+        emit_unop_insn (CODE_FOR_truncdisi2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+      convert_move (to, force_reg (from_mode, from), unsignedp);
-+      return;
-+    }
-+
-+  if (from_mode == DImode && to_mode == HImode)
-+    {
-+#ifdef HAVE_truncdihi2
-+      if (HAVE_truncdihi2)
-+      {
-+        emit_unop_insn (CODE_FOR_truncdihi2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+      convert_move (to, force_reg (from_mode, from), unsignedp);
-+      return;
-+    }
-+
-+  if (from_mode == DImode && to_mode == QImode)
-+    {
-+#ifdef HAVE_truncdiqi2
-+      if (HAVE_truncdiqi2)
-+      {
-+        emit_unop_insn (CODE_FOR_truncdiqi2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+      convert_move (to, force_reg (from_mode, from), unsignedp);
-+      return;
-+    }
-+
-+  if (from_mode == SImode && to_mode == HImode)
-+    {
-+#ifdef HAVE_truncsihi2
-+      if (HAVE_truncsihi2)
-+      {
-+        emit_unop_insn (CODE_FOR_truncsihi2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+      convert_move (to, force_reg (from_mode, from), unsignedp);
-+      return;
-+    }
-+
-+  if (from_mode == SImode && to_mode == QImode)
-+    {
-+#ifdef HAVE_truncsiqi2
-+      if (HAVE_truncsiqi2)
-+      {
-+        emit_unop_insn (CODE_FOR_truncsiqi2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+      convert_move (to, force_reg (from_mode, from), unsignedp);
-+      return;
-+    }
-+
-+  if (from_mode == HImode && to_mode == QImode)
-+    {
-+#ifdef HAVE_trunchiqi2
-+      if (HAVE_trunchiqi2)
-+      {
-+        emit_unop_insn (CODE_FOR_trunchiqi2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+      convert_move (to, force_reg (from_mode, from), unsignedp);
-+      return;
-+    }
-+
-+  if (from_mode == TImode && to_mode == DImode)
-+    {
-+#ifdef HAVE_trunctidi2
-+      if (HAVE_trunctidi2)
-+      {
-+        emit_unop_insn (CODE_FOR_trunctidi2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+      convert_move (to, force_reg (from_mode, from), unsignedp);
-+      return;
-+    }
-+
-+  if (from_mode == TImode && to_mode == SImode)
-+    {
-+#ifdef HAVE_trunctisi2
-+      if (HAVE_trunctisi2)
-+      {
-+        emit_unop_insn (CODE_FOR_trunctisi2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+      convert_move (to, force_reg (from_mode, from), unsignedp);
-+      return;
-+    }
-+
-+  if (from_mode == TImode && to_mode == HImode)
-+    {
-+#ifdef HAVE_trunctihi2
-+      if (HAVE_trunctihi2)
-+      {
-+        emit_unop_insn (CODE_FOR_trunctihi2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+      convert_move (to, force_reg (from_mode, from), unsignedp);
-+      return;
-+    }
-+
-+  if (from_mode == TImode && to_mode == QImode)
-+    {
-+#ifdef HAVE_trunctiqi2
-+      if (HAVE_trunctiqi2)
-+      {
-+        emit_unop_insn (CODE_FOR_trunctiqi2, to, from, UNKNOWN);
-+        return;
-+      }
-+#endif
-+      convert_move (to, force_reg (from_mode, from), unsignedp);
-+      return;
-+    }
-+
-+  /* Handle truncation of volatile memrefs, and so on;
-+     the things that couldn't be truncated directly,
-+     and for which there was no special instruction.  */
-+  if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode))
-+    {
-+      rtx temp = force_reg (to_mode, gen_lowpart (to_mode, from));
-+      emit_move_insn (to, temp);
-+      return;
-+    }
-+
-+  /* Mode combination is not recognized.  */
-+  abort ();
-+}
-+
-+/* Return an rtx for a value that would result
-+   from converting X to mode MODE.
-+   Both X and MODE may be floating, or both integer.
-+   UNSIGNEDP is nonzero if X is an unsigned value.
-+   This can be done by referring to a part of X in place
-+   or by copying to a new temporary with conversion.
-+
-+   This function *must not* call protect_from_queue
-+   except when putting X into an insn (in which case convert_move does it).  */
-+
-+rtx
-+convert_to_mode (mode, x, unsignedp)
-+     enum machine_mode mode;
-+     rtx x;
-+     int unsignedp;
-+{
-+  return convert_modes (mode, VOIDmode, x, unsignedp);
-+}
-+
-+/* Return an rtx for a value that would result
-+   from converting X from mode OLDMODE to mode MODE.
-+   Both modes may be floating, or both integer.
-+   UNSIGNEDP is nonzero if X is an unsigned value.
-+
-+   This can be done by referring to a part of X in place
-+   or by copying to a new temporary with conversion.
-+
-+   You can give VOIDmode for OLDMODE, if you are sure X has a nonvoid mode.
-+
-+   This function *must not* call protect_from_queue
-+   except when putting X into an insn (in which case convert_move does it).  */
-+
-+rtx
-+convert_modes (mode, oldmode, x, unsignedp)
-+     enum machine_mode mode, oldmode;
-+     rtx x;
-+     int unsignedp;
-+{
-+  rtx temp;
-+
-+  /* If FROM is a SUBREG that indicates that we have already done at least
-+     the required extension, strip it.  */
-+
-+  if (GET_CODE (x) == SUBREG && SUBREG_PROMOTED_VAR_P (x)
-+      && GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) >= GET_MODE_SIZE (mode)
-+      && SUBREG_PROMOTED_UNSIGNED_P (x) == unsignedp)
-+    x = gen_lowpart (mode, x);
-+
-+  if (GET_MODE (x) != VOIDmode)
-+    oldmode = GET_MODE (x);
-+
-+  if (mode == oldmode)
-+    return x;
-+
-+  /* There is one case that we must handle specially: If we are converting
-+     a CONST_INT into a mode whose size is twice HOST_BITS_PER_WIDE_INT and
-+     we are to interpret the constant as unsigned, gen_lowpart will do
-+     the wrong if the constant appears negative.  What we want to do is
-+     make the high-order word of the constant zero, not all ones.  */
-+
-+  if (unsignedp && GET_MODE_CLASS (mode) == MODE_INT
-+      && GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT
-+      && GET_CODE (x) == CONST_INT && INTVAL (x) < 0)
-+    {
-+      HOST_WIDE_INT val = INTVAL (x);
-+
-+      if (oldmode != VOIDmode
-+        && HOST_BITS_PER_WIDE_INT > GET_MODE_BITSIZE (oldmode))
-+      {
-+        int width = GET_MODE_BITSIZE (oldmode);
-+
-+        /* We need to zero extend VAL.  */
-+        val &= ((HOST_WIDE_INT) 1 << width) - 1;
-+      }
-+
-+      return immed_double_const (val, (HOST_WIDE_INT) 0, mode);
-+    }
-+
-+  /* We can do this with a gen_lowpart if both desired and current modes
-+     are integer, and this is either a constant integer, a register, or a
-+     non-volatile MEM.  Except for the constant case where MODE is no
-+     wider than HOST_BITS_PER_WIDE_INT, we must be narrowing the operand.  */
-+
-+  if ((GET_CODE (x) == CONST_INT
-+       && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
-+      || (GET_MODE_CLASS (mode) == MODE_INT
-+        && GET_MODE_CLASS (oldmode) == MODE_INT
-+        && (GET_CODE (x) == CONST_DOUBLE
-+            || (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (oldmode)
-+                && ((GET_CODE (x) == MEM && ! MEM_VOLATILE_P (x)
-+                     && direct_load[(int) mode])
-+                    || (GET_CODE (x) == REG
-+                        && (! HARD_REGISTER_P (x)
-+                            || HARD_REGNO_MODE_OK (REGNO (x), mode))
-+                        && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
-+                                                  GET_MODE_BITSIZE (GET_MODE (x)))))))))
-+    {
-+      /* ?? If we don't know OLDMODE, we have to assume here that
-+       X does not need sign- or zero-extension.   This may not be
-+       the case, but it's the best we can do.  */
-+      if (GET_CODE (x) == CONST_INT && oldmode != VOIDmode
-+        && GET_MODE_SIZE (mode) > GET_MODE_SIZE (oldmode))
-+      {
-+        HOST_WIDE_INT val = INTVAL (x);
-+        int width = GET_MODE_BITSIZE (oldmode);
-+
-+        /* We must sign or zero-extend in this case.  Start by
-+           zero-extending, then sign extend if we need to.  */
-+        val &= ((HOST_WIDE_INT) 1 << width) - 1;
-+        if (! unsignedp
-+            && (val & ((HOST_WIDE_INT) 1 << (width - 1))))
-+          val |= (HOST_WIDE_INT) (-1) << width;
-+
-+        return gen_int_mode (val, mode);
-+      }
-+
-+      return gen_lowpart (mode, x);
-+    }
-+
-+  temp = gen_reg_rtx (mode);
-+  convert_move (temp, x, unsignedp);
-+  return temp;
-+}
-+\f
-+/* This macro is used to determine what the largest unit size that
-+   move_by_pieces can use is.  */
-+
-+/* MOVE_MAX_PIECES is the number of bytes at a time which we can
-+   move efficiently, as opposed to  MOVE_MAX which is the maximum
-+   number of bytes we can move with a single instruction.  */
-+
-+#ifndef MOVE_MAX_PIECES
-+#define MOVE_MAX_PIECES   MOVE_MAX
-+#endif
-+
-+/* STORE_MAX_PIECES is the number of bytes at a time that we can
-+   store efficiently.  Due to internal GCC limitations, this is
-+   MOVE_MAX_PIECES limited by the number of bytes GCC can represent
-+   for an immediate constant.  */
-+
-+#define STORE_MAX_PIECES  MIN (MOVE_MAX_PIECES, 2 * sizeof (HOST_WIDE_INT))
-+
-+/* Generate several move instructions to copy LEN bytes from block FROM to
-+   block TO.  (These are MEM rtx's with BLKmode).  The caller must pass FROM
-+   and TO through protect_from_queue before calling.
-+
-+   If PUSH_ROUNDING is defined and TO is NULL, emit_single_push_insn is
-+   used to push FROM to the stack.
-+
-+   ALIGN is maximum alignment we can assume.  */
-+
-+void
-+move_by_pieces (to, from, len, align)
-+     rtx to, from;
-+     unsigned HOST_WIDE_INT len;
-+     unsigned int align;
-+{
-+  struct move_by_pieces data;
-+  rtx to_addr, from_addr = XEXP (from, 0);
-+  unsigned int max_size = MOVE_MAX_PIECES + 1;
-+  enum machine_mode mode = VOIDmode, tmode;
-+  enum insn_code icode;
-+
-+  data.offset = 0;
-+  data.from_addr = from_addr;
-+  if (to)
-+    {
-+      to_addr = XEXP (to, 0);
-+      data.to = to;
-+      data.autinc_to
-+      = (GET_CODE (to_addr) == PRE_INC || GET_CODE (to_addr) == PRE_DEC
-+         || GET_CODE (to_addr) == POST_INC || GET_CODE (to_addr) == POST_DEC);
-+      data.reverse
-+      = (GET_CODE (to_addr) == PRE_DEC || GET_CODE (to_addr) == POST_DEC);
-+    }
-+  else
-+    {
-+      to_addr = NULL_RTX;
-+      data.to = NULL_RTX;
-+      data.autinc_to = 1;
-+#ifdef STACK_GROWS_DOWNWARD
-+      data.reverse = 1;
-+#else
-+      data.reverse = 0;
-+#endif
-+    }
-+  data.to_addr = to_addr;
-+  data.from = from;
-+  data.autinc_from
-+    = (GET_CODE (from_addr) == PRE_INC || GET_CODE (from_addr) == PRE_DEC
-+       || GET_CODE (from_addr) == POST_INC
-+       || GET_CODE (from_addr) == POST_DEC);
-+
-+  data.explicit_inc_from = 0;
-+  data.explicit_inc_to = 0;
-+  if (data.reverse) data.offset = len;
-+  data.len = len;
-+
-+  /* If copying requires more than two move insns,
-+     copy addresses to registers (to make displacements shorter)
-+     and use post-increment if available.  */
-+  if (!(data.autinc_from && data.autinc_to)
-+      && move_by_pieces_ninsns (len, align) > 2)
-+    {
-+      /* Find the mode of the largest move...  */
-+      for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
-+         tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
-+      if (GET_MODE_SIZE (tmode) < max_size)
-+        mode = tmode;
-+
-+      if (USE_LOAD_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_from)
-+      {
-+        data.from_addr = copy_addr_to_reg (plus_constant (from_addr, len));
-+        data.autinc_from = 1;
-+        data.explicit_inc_from = -1;
-+      }
-+      if (USE_LOAD_POST_INCREMENT (mode) && ! data.autinc_from)
-+      {
-+        data.from_addr = copy_addr_to_reg (from_addr);
-+        data.autinc_from = 1;
-+        data.explicit_inc_from = 1;
-+      }
-+      if (!data.autinc_from && CONSTANT_P (from_addr))
-+      data.from_addr = copy_addr_to_reg (from_addr);
-+      if (USE_STORE_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_to)
-+      {
-+        data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len));
-+        data.autinc_to = 1;
-+        data.explicit_inc_to = -1;
-+      }
-+      if (USE_STORE_POST_INCREMENT (mode) && ! data.reverse && ! data.autinc_to)
-+      {
-+        data.to_addr = copy_addr_to_reg (to_addr);
-+        data.autinc_to = 1;
-+        data.explicit_inc_to = 1;
-+      }
-+      if (!data.autinc_to && CONSTANT_P (to_addr))
-+      data.to_addr = copy_addr_to_reg (to_addr);
-+    }
-+
-+  if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
-+      || 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.  */
-+
-+  while (max_size > 1)
-+    {
-+      for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
-+         tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
-+      if (GET_MODE_SIZE (tmode) < max_size)
-+        mode = tmode;
-+
-+      if (mode == VOIDmode)
-+      break;
-+
-+      icode = mov_optab->handlers[(int) mode].insn_code;
-+      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);
-+    }
-+
-+  /* The code above should have handled everything.  */
-+  if (data.len > 0)
-+    abort ();
-+}
-+
-+/* Return number of insns required to move L bytes by pieces.
-+   ALIGN (in bits) is maximum alignment we can assume.  */
-+
-+static unsigned HOST_WIDE_INT
-+move_by_pieces_ninsns (l, align)
-+     unsigned HOST_WIDE_INT l;
-+     unsigned int align;
-+{
-+  unsigned HOST_WIDE_INT n_insns = 0;
-+  unsigned HOST_WIDE_INT max_size = MOVE_MAX + 1;
-+
-+  if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
-+      || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT)
-+    align = MOVE_MAX * BITS_PER_UNIT;
-+
-+  while (max_size > 1)
-+    {
-+      enum machine_mode mode = VOIDmode, tmode;
-+      enum insn_code icode;
-+
-+      for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
-+         tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
-+      if (GET_MODE_SIZE (tmode) < max_size)
-+        mode = tmode;
-+
-+      if (mode == VOIDmode)
-+      break;
-+
-+      icode = mov_optab->handlers[(int) mode].insn_code;
-+      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);
-+    }
-+
-+  if (l)
-+    abort ();
-+  return n_insns;
-+}
-+
-+/* Subroutine of move_by_pieces.  Move as many bytes as appropriate
-+   with move instructions for mode MODE.  GENFUN is the gen_... function
-+   to make a move insn for that mode.  DATA has all the other info.  */
-+
-+static void
-+move_by_pieces_1 (genfun, mode, data)
-+     rtx (*genfun) PARAMS ((rtx, ...));
-+     enum machine_mode mode;
-+     struct move_by_pieces *data;
-+{
-+  unsigned int size = GET_MODE_SIZE (mode);
-+  rtx to1 = NULL_RTX, from1;
-+
-+  while (data->len >= size)
-+    {
-+      if (data->reverse)
-+      data->offset -= size;
-+
-+      if (data->to)
-+      {
-+        if (data->autinc_to)
-+          to1 = adjust_automodify_address (data->to, mode, data->to_addr,
-+                                           data->offset);
-+        else
-+          to1 = adjust_address (data->to, mode, data->offset);
-+      }
-+
-+      if (data->autinc_from)
-+      from1 = adjust_automodify_address (data->from, mode, data->from_addr,
-+                                         data->offset);
-+      else
-+      from1 = adjust_address (data->from, mode, data->offset);
-+
-+      if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
-+      emit_insn (gen_add2_insn (data->to_addr,
-+                                GEN_INT (-(HOST_WIDE_INT)size)));
-+      if (HAVE_PRE_DECREMENT && data->explicit_inc_from < 0)
-+      emit_insn (gen_add2_insn (data->from_addr,
-+                                GEN_INT (-(HOST_WIDE_INT)size)));
-+
-+      if (data->to)
-+      emit_insn ((*genfun) (to1, from1));
-+      else
-+      {
-+#ifdef PUSH_ROUNDING
-+        emit_single_push_insn (mode, from1, NULL);
-+#else
-+        abort ();
-+#endif
-+      }
-+
-+      if (HAVE_POST_INCREMENT && data->explicit_inc_to > 0)
-+      emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size)));
-+      if (HAVE_POST_INCREMENT && data->explicit_inc_from > 0)
-+      emit_insn (gen_add2_insn (data->from_addr, GEN_INT (size)));
-+
-+      if (! data->reverse)
-+      data->offset += size;
-+
-+      data->len -= size;
-+    }
-+}
-+\f
-+/* Emit code to move a block Y to a block X.  This may be done with
-+   string-move instructions, with multiple scalar move instructions,
-+   or with a library call.
-+
-+   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.
-+   METHOD describes what kind of copy this is, and what mechanisms may be used.
-+
-+   Return the address of the new block, if memcpy is called and returns it,
-+   0 otherwise.  */
-+
-+rtx
-+emit_block_move (x, y, size, method)
-+     rtx x, y, size;
-+     enum block_op_methods method;
-+{
-+  bool may_use_call;
-+  rtx retval = 0;
-+  unsigned int align;
-+
-+  switch (method)
-+    {
-+    case BLOCK_OP_NORMAL:
-+      may_use_call = true;
-+      break;
-+
-+    case BLOCK_OP_CALL_PARM:
-+      may_use_call = block_move_libcall_safe_for_call_parm ();
-+
-+      /* Make inhibit_defer_pop nonzero around the library call
-+       to force it to pop the arguments right away.  */
-+      NO_DEFER_POP;
-+      break;
-+
-+    case BLOCK_OP_NO_LIBCALL:
-+      may_use_call = false;
-+      break;
-+
-+    default:
-+      abort ();
-+    }
-+
-+  align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
-+
-+  if (GET_MODE (x) != BLKmode)
-+    abort ();
-+  if (GET_MODE (y) != BLKmode)
-+    abort ();
-+
-+  x = protect_from_queue (x, 1);
-+  y = protect_from_queue (y, 0);
-+  size = protect_from_queue (size, 0);
-+
-+  if (GET_CODE (x) != MEM)
-+    abort ();
-+  if (GET_CODE (y) != MEM)
-+    abort ();
-+  if (size == 0)
-+    abort ();
-+
-+  /* Set MEM_SIZE as appropriate for this block copy.  The main place this
-+     can be incorrect is coming from __builtin_memcpy.  */
-+  if (GET_CODE (size) == CONST_INT)
-+    {
-+      x = shallow_copy_rtx (x);
-+      y = shallow_copy_rtx (y);
-+      set_mem_size (x, size);
-+      set_mem_size (y, size);
-+    }
-+
-+  if (GET_CODE (size) == CONST_INT && MOVE_BY_PIECES_P (INTVAL (size), align))
-+    move_by_pieces (x, y, INTVAL (size), align);
-+  else if (emit_block_move_via_movstr (x, y, size, align))
-+    ;
-+  else if (may_use_call)
-+    retval = emit_block_move_via_libcall (x, y, size);
-+  else
-+    emit_block_move_via_loop (x, y, size, align);
-+
-+  if (method == BLOCK_OP_CALL_PARM)
-+    OK_DEFER_POP;
-+
-+  return retval;
-+}
-+
-+/* A subroutine of emit_block_move.  Returns true if calling the 
-+   block move libcall will not clobber any parameters which may have
-+   already been placed on the stack.  */
-+
-+static bool
-+block_move_libcall_safe_for_call_parm ()
-+{
-+  if (PUSH_ARGS)
-+    return true;
-+  else
-+    {
-+      /* Check to see whether memcpy takes all register arguments.  */
-+      static enum {
-+      takes_regs_uninit, takes_regs_no, takes_regs_yes
-+      } takes_regs = takes_regs_uninit;
-+
-+      switch (takes_regs)
-+      {
-+      case takes_regs_uninit:
-+        {
-+          CUMULATIVE_ARGS args_so_far;
-+          tree fn, arg;
-+
-+          fn = emit_block_move_libcall_fn (false);
-+          INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (fn), NULL_RTX, 0);
-+
-+          arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
-+          for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
-+            {
-+              enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
-+              rtx tmp = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1);
-+              if (!tmp || !REG_P (tmp))
-+                goto fail_takes_regs;
-+#ifdef FUNCTION_ARG_PARTIAL_NREGS
-+              if (FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode,
-+                                              NULL_TREE, 1))
-+                goto fail_takes_regs;
-+#endif
-+              FUNCTION_ARG_ADVANCE (args_so_far, mode, NULL_TREE, 1);
-+            }
-+        }
-+        takes_regs = takes_regs_yes;
-+        /* FALLTHRU */
-+
-+      case takes_regs_yes:
-+        return true;
-+
-+      fail_takes_regs:
-+        takes_regs = takes_regs_no;
-+        /* FALLTHRU */
-+      case takes_regs_no:
-+        return false;
-+
-+      default:
-+        abort ();
-+      }
-+    }
-+}
-+
-+/* A subroutine of emit_block_move.  Expand a movstr pattern; 
-+   return true if successful.  */
-+
-+static bool
-+emit_block_move_via_movstr (x, y, size, align)
-+     rtx x, y, size;
-+     unsigned int align;
-+{
-+  /* Try the most limited insn first, because there's no point
-+     including more than one in the machine description unless
-+     the more limited one has some advantage.  */
-+
-+  rtx opalign = GEN_INT (align / BITS_PER_UNIT);
-+  enum machine_mode mode;
-+
-+  /* Since this is a move insn, we don't care about volatility.  */
-+  volatile_ok = 1;
-+
-+  for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
-+       mode = GET_MODE_WIDER_MODE (mode))
-+    {
-+      enum insn_code code = movstr_optab[(int) mode];
-+      insn_operand_predicate_fn pred;
-+
-+      if (code != CODE_FOR_nothing
-+        /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
-+           here because if SIZE is less than the mode mask, as it is
-+           returned by the macro, it will definitely be less than the
-+           actual mode mask.  */
-+        && ((GET_CODE (size) == CONST_INT
-+             && ((unsigned HOST_WIDE_INT) INTVAL (size)
-+                 <= (GET_MODE_MASK (mode) >> 1)))
-+            || GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)
-+        && ((pred = insn_data[(int) code].operand[0].predicate) == 0
-+            || (*pred) (x, BLKmode))
-+        && ((pred = insn_data[(int) code].operand[1].predicate) == 0
-+            || (*pred) (y, BLKmode))
-+        && ((pred = insn_data[(int) code].operand[3].predicate) == 0
-+            || (*pred) (opalign, VOIDmode)))
-+      {
-+        rtx op2;
-+        rtx last = get_last_insn ();
-+        rtx pat;
-+
-+        op2 = convert_to_mode (mode, size, 1);
-+        pred = insn_data[(int) code].operand[2].predicate;
-+        if (pred != 0 && ! (*pred) (op2, mode))
-+          op2 = copy_to_mode_reg (mode, op2);
-+
-+        /* ??? When called via emit_block_move_for_call, it'd be
-+           nice if there were some way to inform the backend, so
-+           that it doesn't fail the expansion because it thinks
-+           emitting the libcall would be more efficient.  */
-+
-+        pat = GEN_FCN ((int) code) (x, y, op2, opalign);
-+        if (pat)
-+          {
-+            emit_insn (pat);
-+            volatile_ok = 0;
-+            return true;
-+          }
-+        else
-+          delete_insns_since (last);
-+      }
-+    }
-+
-+  volatile_ok = 0;
-+  return false;
-+}
-+
-+/* A subroutine of emit_block_move.  Expand a call to memcpy or bcopy.
-+   Return the return value from memcpy, 0 otherwise.  */
-+
-+static rtx
-+emit_block_move_via_libcall (dst, src, size)
-+     rtx dst, src, size;
-+{
-+  tree call_expr, arg_list, fn, src_tree, dst_tree, size_tree;
-+  enum machine_mode size_mode;
-+  rtx retval;
-+
-+  /* DST, SRC, or SIZE may have been passed through protect_from_queue.
-+
-+     It is unsafe to save the value generated by protect_from_queue
-+     and reuse it later.  Consider what happens if emit_queue is
-+     called before the return value from protect_from_queue is used.
-+
-+     Expansion of the CALL_EXPR below will call emit_queue before
-+     we are finished emitting RTL for argument setup.  So if we are
-+     not careful we could get the wrong value for an argument.
-+
-+     To avoid this problem we go ahead and emit code to copy X, Y &
-+     SIZE into new pseudos.  We can then place those new pseudos
-+     into an RTL_EXPR and use them later, even after a call to
-+     emit_queue.
-+
-+     Note this is not strictly needed for library calls since they
-+     do not call emit_queue before loading their arguments.  However,
-+     we may need to have library calls call emit_queue in the future
-+     since failing to do so could cause problems for targets which
-+     define SMALL_REGISTER_CLASSES and pass arguments in registers.  */
-+
-+  dst = copy_to_mode_reg (Pmode, XEXP (dst, 0));
-+  src = copy_to_mode_reg (Pmode, XEXP (src, 0));
-+
-+  if (TARGET_MEM_FUNCTIONS)
-+    size_mode = TYPE_MODE (sizetype);
-+  else
-+    size_mode = TYPE_MODE (unsigned_type_node);
-+  size = convert_to_mode (size_mode, size, 1);
-+  size = copy_to_mode_reg (size_mode, size);
-+
-+  /* It is incorrect to use the libcall calling conventions to call
-+     memcpy in this context.  This could be a user call to memcpy and
-+     the user may wish to examine the return value from memcpy.  For
-+     targets where libcalls and normal calls have different conventions
-+     for returning pointers, we could end up generating incorrect code.
-+
-+     For convenience, we generate the call to bcopy this way as well.  */
-+
-+  dst_tree = make_tree (ptr_type_node, dst);
-+  src_tree = make_tree (ptr_type_node, src);
-+  if (TARGET_MEM_FUNCTIONS)
-+    size_tree = make_tree (sizetype, size);
-+  else
-+    size_tree = make_tree (unsigned_type_node, size);
-+
-+  fn = emit_block_move_libcall_fn (true);
-+  arg_list = tree_cons (NULL_TREE, size_tree, NULL_TREE);
-+  if (TARGET_MEM_FUNCTIONS)
-+    {
-+      arg_list = tree_cons (NULL_TREE, src_tree, arg_list);
-+      arg_list = tree_cons (NULL_TREE, dst_tree, arg_list);
-+    }
-+  else
-+    {
-+      arg_list = tree_cons (NULL_TREE, dst_tree, arg_list);
-+      arg_list = tree_cons (NULL_TREE, src_tree, arg_list);
-+    }
-+
-+  /* Now we have to build up the CALL_EXPR itself.  */
-+  call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
-+  call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
-+                   call_expr, arg_list, NULL_TREE);
-+  TREE_SIDE_EFFECTS (call_expr) = 1;
-+
-+  retval = expand_expr (call_expr, NULL_RTX, VOIDmode, 0);
-+
-+  /* If we are initializing a readonly value, show the above call
-+     clobbered it.  Otherwise, a load from it may erroneously be
-+     hoisted from a loop.  */
-+  if (RTX_UNCHANGING_P (dst))
-+    emit_insn (gen_rtx_CLOBBER (VOIDmode, dst));
-+
-+  return (TARGET_MEM_FUNCTIONS ? retval : NULL_RTX);
-+}
-+
-+/* A subroutine of emit_block_move_via_libcall.  Create the tree node
-+   for the function we use for block copies.  The first time FOR_CALL
-+   is true, we call assemble_external.  */
-+
-+static GTY(()) tree block_move_fn;
-+
-+static tree
-+emit_block_move_libcall_fn (for_call)
-+      int for_call;
-+{
-+  static bool emitted_extern;
-+  tree fn = block_move_fn, args;
-+
-+  if (!fn)
-+    {
-+      if (TARGET_MEM_FUNCTIONS)
-+      {
-+        fn = get_identifier ("memcpy");
-+        args = build_function_type_list (ptr_type_node, ptr_type_node,
-+                                         const_ptr_type_node, sizetype,
-+                                         NULL_TREE);
-+      }
-+      else
-+      {
-+        fn = get_identifier ("bcopy");
-+        args = build_function_type_list (void_type_node, const_ptr_type_node,
-+                                         ptr_type_node, unsigned_type_node,
-+                                         NULL_TREE);
-+      }
-+
-+      fn = build_decl (FUNCTION_DECL, fn, args);
-+      DECL_EXTERNAL (fn) = 1;
-+      TREE_PUBLIC (fn) = 1;
-+      DECL_ARTIFICIAL (fn) = 1;
-+      TREE_NOTHROW (fn) = 1;
-+
-+      block_move_fn = fn;
-+    }
-+
-+  if (for_call && !emitted_extern)
-+    {
-+      emitted_extern = true;
-+      make_decl_rtl (fn, NULL);
-+      assemble_external (fn);
-+    }
-+
-+  return fn;
-+}
-+
-+/* A subroutine of emit_block_move.  Copy the data via an explicit
-+   loop.  This is used only when libcalls are forbidden.  */
-+/* ??? It'd be nice to copy in hunks larger than QImode.  */
-+
-+static void
-+emit_block_move_via_loop (x, y, size, align)
-+     rtx x, y, size;
-+     unsigned int align ATTRIBUTE_UNUSED;
-+{
-+  rtx cmp_label, top_label, iter, x_addr, y_addr, tmp;
-+  enum machine_mode iter_mode;
-+
-+  iter_mode = GET_MODE (size);
-+  if (iter_mode == VOIDmode)
-+    iter_mode = word_mode;
-+
-+  top_label = gen_label_rtx ();
-+  cmp_label = gen_label_rtx ();
-+  iter = gen_reg_rtx (iter_mode);
-+
-+  emit_move_insn (iter, const0_rtx);
-+
-+  x_addr = force_operand (XEXP (x, 0), NULL_RTX);
-+  y_addr = force_operand (XEXP (y, 0), NULL_RTX);
-+  do_pending_stack_adjust ();
-+
-+  emit_note (NULL, NOTE_INSN_LOOP_BEG);
-+
-+  emit_jump (cmp_label);
-+  emit_label (top_label);
-+
-+  tmp = convert_modes (Pmode, iter_mode, iter, true);
-+  x_addr = gen_rtx_PLUS (Pmode, x_addr, tmp);
-+  y_addr = gen_rtx_PLUS (Pmode, y_addr, tmp);
-+  x = change_address (x, QImode, x_addr);
-+  y = change_address (y, QImode, y_addr);
-+
-+  emit_move_insn (x, y);
-+
-+  tmp = expand_simple_binop (iter_mode, PLUS, iter, const1_rtx, iter,
-+                           true, OPTAB_LIB_WIDEN);
-+  if (tmp != iter)
-+    emit_move_insn (iter, tmp);
-+
-+  emit_note (NULL, NOTE_INSN_LOOP_CONT);
-+  emit_label (cmp_label);
-+
-+  emit_cmp_and_jump_insns (iter, size, LT, NULL_RTX, iter_mode,
-+                         true, top_label);
-+
-+  emit_note (NULL, NOTE_INSN_LOOP_END);
-+}
-+\f
-+/* Copy all or part of a value X into registers starting at REGNO.
-+   The number of registers to be filled is NREGS.  */
-+
-+void
-+move_block_to_reg (regno, x, nregs, mode)
-+     int regno;
-+     rtx x;
-+     int nregs;
-+     enum machine_mode mode;
-+{
-+  int i;
-+#ifdef HAVE_load_multiple
-+  rtx pat;
-+  rtx last;
-+#endif
-+
-+  if (nregs == 0)
-+    return;
-+
-+  if (CONSTANT_P (x) && ! LEGITIMATE_CONSTANT_P (x))
-+    x = validize_mem (force_const_mem (mode, x));
-+
-+  /* See if the machine can do this with a load multiple insn.  */
-+#ifdef HAVE_load_multiple
-+  if (HAVE_load_multiple)
-+    {
-+      last = get_last_insn ();
-+      pat = gen_load_multiple (gen_rtx_REG (word_mode, regno), x,
-+                             GEN_INT (nregs));
-+      if (pat)
-+      {
-+        emit_insn (pat);
-+        return;
-+      }
-+      else
-+      delete_insns_since (last);
-+    }
-+#endif
-+
-+  for (i = 0; i < nregs; i++)
-+    emit_move_insn (gen_rtx_REG (word_mode, regno + i),
-+                  operand_subword_force (x, i, mode));
-+}
-+
-+/* Copy all or part of a BLKmode value X out of registers starting at REGNO.
-+   The number of registers to be filled is NREGS.  SIZE indicates the number
-+   of bytes in the object X.  */
-+
-+void
-+move_block_from_reg (regno, x, nregs, size)
-+     int regno;
-+     rtx x;
-+     int nregs;
-+     int size;
-+{
-+  int i;
-+#ifdef HAVE_store_multiple
-+  rtx pat;
-+  rtx last;
-+#endif
-+  enum machine_mode mode;
-+
-+  if (nregs == 0)
-+    return;
-+
-+  /* If SIZE is that of a mode no bigger than a word, just use that
-+     mode's store operation.  */
-+  if (size <= UNITS_PER_WORD
-+      && (mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0)) != BLKmode)
-+    {
-+      emit_move_insn (adjust_address (x, mode, 0), gen_rtx_REG (mode, regno));
-+      return;
-+    }
-+
-+  /* Blocks smaller than a word on a BYTES_BIG_ENDIAN machine must be aligned
-+     to the left before storing to memory.  Note that the previous test
-+     doesn't handle all cases (e.g. SIZE == 3).  */
-+  if (size < UNITS_PER_WORD && BYTES_BIG_ENDIAN)
-+    {
-+      rtx tem = operand_subword (x, 0, 1, BLKmode);
-+      rtx shift;
-+
-+      if (tem == 0)
-+      abort ();
-+
-+      shift = expand_shift (LSHIFT_EXPR, word_mode,
-+                          gen_rtx_REG (word_mode, regno),
-+                          build_int_2 ((UNITS_PER_WORD - size)
-+                                       * BITS_PER_UNIT, 0), NULL_RTX, 0);
-+      emit_move_insn (tem, shift);
-+      return;
-+    }
-+
-+  /* See if the machine can do this with a store multiple insn.  */
-+#ifdef HAVE_store_multiple
-+  if (HAVE_store_multiple)
-+    {
-+      last = get_last_insn ();
-+      pat = gen_store_multiple (x, gen_rtx_REG (word_mode, regno),
-+                              GEN_INT (nregs));
-+      if (pat)
-+      {
-+        emit_insn (pat);
-+        return;
-+      }
-+      else
-+      delete_insns_since (last);
-+    }
-+#endif
-+
-+  for (i = 0; i < nregs; i++)
-+    {
-+      rtx tem = operand_subword (x, i, 1, BLKmode);
-+
-+      if (tem == 0)
-+      abort ();
-+
-+      emit_move_insn (tem, gen_rtx_REG (word_mode, regno + i));
-+    }
-+}
-+
-+/* Generate a PARALLEL rtx for a new non-consecutive group of registers from
-+   ORIG, where ORIG is a non-consecutive group of registers represented by
-+   a PARALLEL.  The clone is identical to the original except in that the
-+   original set of registers is replaced by a new set of pseudo registers.
-+   The new set has the same modes as the original set.  */
-+
-+rtx
-+gen_group_rtx (orig)
-+     rtx orig;
-+{
-+  int i, length;
-+  rtx *tmps;
-+
-+  if (GET_CODE (orig) != PARALLEL)
-+    abort ();
-+
-+  length = XVECLEN (orig, 0);
-+  tmps = (rtx *) alloca (sizeof (rtx) * length);
-+
-+  /* Skip a NULL entry in first slot.  */
-+  i = XEXP (XVECEXP (orig, 0, 0), 0) ? 0 : 1;
-+
-+  if (i)
-+    tmps[0] = 0;
-+
-+  for (; i < length; i++)
-+    {
-+      enum machine_mode mode = GET_MODE (XEXP (XVECEXP (orig, 0, i), 0));
-+      rtx offset = XEXP (XVECEXP (orig, 0, i), 1);
-+
-+      tmps[i] = gen_rtx_EXPR_LIST (VOIDmode, gen_reg_rtx (mode), offset);
-+    }
-+
-+  return gen_rtx_PARALLEL (GET_MODE (orig), gen_rtvec_v (length, tmps));
-+}
-+
-+/* Emit code to move a block SRC to a block DST, where DST is non-consecutive
-+   registers represented by a PARALLEL.  SSIZE represents the total size of
-+   block SRC in bytes, or -1 if not known.  */
-+/* ??? If SSIZE % UNITS_PER_WORD != 0, we make the blatant assumption that
-+   the balance will be in what would be the low-order memory addresses, i.e.
-+   left justified for big endian, right justified for little endian.  This
-+   happens to be true for the targets currently using this support.  If this
-+   ever changes, a new target macro along the lines of FUNCTION_ARG_PADDING
-+   would be needed.  */
-+
-+void
-+emit_group_load (dst, orig_src, ssize)
-+     rtx dst, orig_src;
-+     int ssize;
-+{
-+  rtx *tmps, src;
-+  int start, i;
-+
-+  if (GET_CODE (dst) != PARALLEL)
-+    abort ();
-+
-+  /* Check for a NULL entry, used to indicate that the parameter goes
-+     both on the stack and in registers.  */
-+  if (XEXP (XVECEXP (dst, 0, 0), 0))
-+    start = 0;
-+  else
-+    start = 1;
-+
-+  tmps = (rtx *) alloca (sizeof (rtx) * XVECLEN (dst, 0));
-+
-+  /* Process the pieces.  */
-+  for (i = start; i < XVECLEN (dst, 0); i++)
-+    {
-+      enum machine_mode mode = GET_MODE (XEXP (XVECEXP (dst, 0, i), 0));
-+      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.  */
-+      if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
-+      {
-+        shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
-+        bytelen = ssize - bytepos;
-+        if (bytelen <= 0)
-+          abort ();
-+      }
-+
-+      /* If we won't be loading directly from memory, protect the real source
-+       from strange tricks we might play; but make sure that the source can
-+       be loaded directly into the destination.  */
-+      src = orig_src;
-+      if (GET_CODE (orig_src) != MEM
-+        && (!CONSTANT_P (orig_src)
-+            || (GET_MODE (orig_src) != mode
-+                && GET_MODE (orig_src) != VOIDmode)))
-+      {
-+        if (GET_MODE (orig_src) == VOIDmode)
-+          src = gen_reg_rtx (mode);
-+        else
-+          src = gen_reg_rtx (GET_MODE (orig_src));
-+
-+        emit_move_insn (src, orig_src);
-+      }
-+
-+      /* Optimize the access just a bit.  */
-+      if (GET_CODE (src) == MEM
-+        && MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode)
-+        && bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
-+        && bytelen == GET_MODE_SIZE (mode))
-+      {
-+        tmps[i] = gen_reg_rtx (mode);
-+        emit_move_insn (tmps[i], adjust_address (src, mode, bytepos));
-+      }
-+      else if (GET_CODE (src) == CONCAT)
-+      {
-+        unsigned int slen = GET_MODE_SIZE (GET_MODE (src));
-+        unsigned int slen0 = GET_MODE_SIZE (GET_MODE (XEXP (src, 0)));
-+
-+        if ((bytepos == 0 && bytelen == slen0)
-+            || (bytepos != 0 && bytepos + bytelen <= slen))
-+          {
-+            /* The following assumes that the concatenated objects all
-+               have the same size.  In this case, a simple calculation
-+               can be used to determine the object and the bit field
-+               to be extracted.  */
-+            tmps[i] = XEXP (src, bytepos / slen0);
-+            if (! CONSTANT_P (tmps[i])
-+                && (GET_CODE (tmps[i]) != REG || GET_MODE (tmps[i]) != mode))
-+              tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT,
-+                                           (bytepos % slen0) * BITS_PER_UNIT,
-+                                           1, NULL_RTX, mode, mode, ssize);
-+          }
-+        else if (bytepos == 0)
-+          {
-+            rtx mem = assign_stack_temp (GET_MODE (src), slen, 0);
-+            emit_move_insn (mem, src);
-+            tmps[i] = adjust_address (mem, mode, 0);
-+          }
-+        else
-+          abort ();
-+      }
-+      else if (CONSTANT_P (src)
-+             || (GET_CODE (src) == REG && GET_MODE (src) == mode))
-+      tmps[i] = src;
-+      else
-+      tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
-+                                   bytepos * BITS_PER_UNIT, 1, NULL_RTX,
-+                                   mode, mode, ssize);
-+
-+      if (BYTES_BIG_ENDIAN && shift)
-+      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.  */
-+  for (i = start; i < XVECLEN (dst, 0); i++)
-+    emit_move_insn (XEXP (XVECEXP (dst, 0, i), 0), tmps[i]);
-+}
-+
-+/* Emit code to move a block SRC to block DST, where SRC and DST are
-+   non-consecutive groups of registers, each represented by a PARALLEL.  */
-+
-+void
-+emit_group_move (dst, src)
-+     rtx dst, src;
-+{
-+  int i;
-+
-+  if (GET_CODE (src) != PARALLEL
-+      || GET_CODE (dst) != PARALLEL
-+      || XVECLEN (src, 0) != XVECLEN (dst, 0))
-+    abort ();
-+
-+  /* Skip first entry if NULL.  */
-+  for (i = XEXP (XVECEXP (src, 0, 0), 0) ? 0 : 1; i < XVECLEN (src, 0); i++)
-+    emit_move_insn (XEXP (XVECEXP (dst, 0, i), 0),
-+                  XEXP (XVECEXP (src, 0, i), 0));
-+}
-+
-+/* Emit code to move a block SRC to a block DST, where SRC is non-consecutive
-+   registers represented by a PARALLEL.  SSIZE represents the total size of
-+   block DST, or -1 if not known.  */
-+
-+void
-+emit_group_store (orig_dst, src, ssize)
-+     rtx orig_dst, src;
-+     int ssize;
-+{
-+  rtx *tmps, dst;
-+  int start, i;
-+
-+  if (GET_CODE (src) != PARALLEL)
-+    abort ();
-+
-+  /* Check for a NULL entry, used to indicate that the parameter goes
-+     both on the stack and in registers.  */
-+  if (XEXP (XVECEXP (src, 0, 0), 0))
-+    start = 0;
-+  else
-+    start = 1;
-+
-+  tmps = (rtx *) alloca (sizeof (rtx) * XVECLEN (src, 0));
-+
-+  /* Copy the (probable) hard regs into pseudos.  */
-+  for (i = start; i < XVECLEN (src, 0); i++)
-+    {
-+      rtx reg = XEXP (XVECEXP (src, 0, i), 0);
-+      tmps[i] = gen_reg_rtx (GET_MODE (reg));
-+      emit_move_insn (tmps[i], reg);
-+    }
-+  emit_queue ();
-+
-+  /* If we won't be storing directly into memory, protect the real destination
-+     from strange tricks we might play.  */
-+  dst = orig_dst;
-+  if (GET_CODE (dst) == PARALLEL)
-+    {
-+      rtx temp;
-+
-+      /* We can get a PARALLEL dst if there is a conditional expression in
-+       a return statement.  In that case, the dst and src are the same,
-+       so no action is necessary.  */
-+      if (rtx_equal_p (dst, src))
-+      return;
-+
-+      /* It is unclear if we can ever reach here, but we may as well handle
-+       it.  Allocate a temporary, and split this into a store/load to/from
-+       the temporary.  */
-+
-+      temp = assign_stack_temp (GET_MODE (dst), ssize, 0);
-+      emit_group_store (temp, src, ssize);
-+      emit_group_load (dst, temp, ssize);
-+      return;
-+    }
-+  else if (GET_CODE (dst) != MEM && GET_CODE (dst) != CONCAT)
-+    {
-+      dst = gen_reg_rtx (GET_MODE (orig_dst));
-+      /* Make life a bit easier for combine.  */
-+      emit_move_insn (dst, CONST0_RTX (GET_MODE (orig_dst)));
-+    }
-+
-+  /* Process the pieces.  */
-+  for (i = start; i < XVECLEN (src, 0); i++)
-+    {
-+      HOST_WIDE_INT bytepos = INTVAL (XEXP (XVECEXP (src, 0, i), 1));
-+      enum machine_mode mode = GET_MODE (tmps[i]);
-+      unsigned int bytelen = GET_MODE_SIZE (mode);
-+      rtx dest = dst;
-+
-+      /* Handle trailing fragments that run over the size of the struct.  */
-+      if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
-+      {
-+        if (BYTES_BIG_ENDIAN)
-+          {
-+            int shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
-+            expand_binop (mode, ashr_optab, tmps[i], GEN_INT (shift),
-+                          tmps[i], 0, OPTAB_WIDEN);
-+          }
-+        bytelen = ssize - bytepos;
-+      }
-+
-+      if (GET_CODE (dst) == CONCAT)
-+      {
-+        if (bytepos + bytelen <= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0))))
-+          dest = XEXP (dst, 0);
-+        else if (bytepos >= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0))))
-+          {
-+            bytepos -= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)));
-+            dest = XEXP (dst, 1);
-+          }
-+        else if (bytepos == 0 && XVECLEN (src, 0))
-+          {
-+            dest = assign_stack_temp (GET_MODE (dest),
-+                                      GET_MODE_SIZE (GET_MODE (dest)), 0);
-+            emit_move_insn (adjust_address (dest, GET_MODE (tmps[i]), bytepos),
-+                            tmps[i]);
-+            dst = dest;
-+            break;
-+          }
-+        else
-+          abort ();
-+      }
-+
-+      /* Optimize the access just a bit.  */
-+      if (GET_CODE (dest) == MEM
-+        && MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode)
-+        && bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
-+        && bytelen == GET_MODE_SIZE (mode))
-+      emit_move_insn (adjust_address (dest, mode, bytepos), tmps[i]);
-+      else
-+      store_bit_field (dest, bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
-+                       mode, tmps[i], ssize);
-+    }
-+
-+  emit_queue ();
-+
-+  /* Copy from the pseudo into the (probable) hard reg.  */
-+  if (orig_dst != dst)
-+    emit_move_insn (orig_dst, dst);
-+}
-+
-+/* Generate code to copy a BLKmode object of TYPE out of a
-+   set of registers starting with SRCREG into TGTBLK.  If TGTBLK
-+   is null, a stack temporary is created.  TGTBLK is returned.
-+
-+   The primary purpose of this routine is to handle functions
-+   that return BLKmode structures in registers.  Some machines
-+   (the PA for example) want to return all small structures
-+   in registers regardless of the structure's alignment.  */
-+
-+rtx
-+copy_blkmode_from_reg (tgtblk, srcreg, type)
-+     rtx tgtblk;
-+     rtx srcreg;
-+     tree type;
-+{
-+  unsigned HOST_WIDE_INT bytes = int_size_in_bytes (type);
-+  rtx src = NULL, dst = NULL;
-+  unsigned HOST_WIDE_INT bitsize = MIN (TYPE_ALIGN (type), BITS_PER_WORD);
-+  unsigned HOST_WIDE_INT bitpos, xbitpos, big_endian_correction = 0;
-+
-+  if (tgtblk == 0)
-+    {
-+      tgtblk = assign_temp (build_qualified_type (type,
-+                                                (TYPE_QUALS (type)
-+                                                 | TYPE_QUAL_CONST)),
-+                          0, 1, 1);
-+      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,
-+                                   GET_MODE (srcreg));
-+
-+      /* 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,
-+                                        BITS_PER_WORD),
-+                     BITS_PER_WORD);
-+    }
-+
-+  return tgtblk;
-+}
-+
-+/* Add a USE expression for REG to the (possibly empty) list pointed
-+   to by CALL_FUSAGE.  REG must denote a hard register.  */
-+
-+void
-+use_reg (call_fusage, reg)
-+     rtx *call_fusage, reg;
-+{
-+  if (GET_CODE (reg) != REG
-+      || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
-+    abort ();
-+
-+  *call_fusage
-+    = gen_rtx_EXPR_LIST (VOIDmode,
-+                       gen_rtx_USE (VOIDmode, reg), *call_fusage);
-+}
-+
-+/* Add USE expressions to *CALL_FUSAGE for each of NREGS consecutive regs,
-+   starting at REGNO.  All of these registers must be hard registers.  */
-+
-+void
-+use_regs (call_fusage, regno, nregs)
-+     rtx *call_fusage;
-+     int regno;
-+     int nregs;
-+{
-+  int i;
-+
-+  if (regno + nregs > FIRST_PSEUDO_REGISTER)
-+    abort ();
-+
-+  for (i = 0; i < nregs; i++)
-+    use_reg (call_fusage, regno_reg_rtx[regno + i]);
-+}
-+
-+/* Add USE expressions to *CALL_FUSAGE for each REG contained in the
-+   PARALLEL REGS.  This is for calls that pass values in multiple
-+   non-contiguous locations.  The Irix 6 ABI has examples of this.  */
-+
-+void
-+use_group_regs (call_fusage, regs)
-+     rtx *call_fusage;
-+     rtx regs;
-+{
-+  int i;
-+
-+  for (i = 0; i < XVECLEN (regs, 0); i++)
-+    {
-+      rtx reg = XEXP (XVECEXP (regs, 0, i), 0);
-+
-+      /* A NULL entry means the parameter goes both on the stack and in
-+       registers.  This can also be a MEM for targets that pass values
-+       partially on the stack and partially in registers.  */
-+      if (reg != 0 && GET_CODE (reg) == REG)
-+      use_reg (call_fusage, reg);
-+    }
-+}
-+\f
-+
-+/* Determine whether the LEN bytes generated by CONSTFUN can be
-+   stored to memory using several move instructions.  CONSTFUNDATA is
-+   a pointer which will be passed as argument in every CONSTFUN call.
-+   ALIGN is maximum alignment we can assume.  Return nonzero if a
-+   call to store_by_pieces should succeed.  */
-+
-+int
-+can_store_by_pieces (len, constfun, constfundata, align)
-+     unsigned HOST_WIDE_INT len;
-+     rtx (*constfun) PARAMS ((PTR, HOST_WIDE_INT, enum machine_mode));
-+     PTR constfundata;
-+     unsigned int align;
-+{
-+  unsigned HOST_WIDE_INT max_size, l;
-+  HOST_WIDE_INT offset = 0;
-+  enum machine_mode mode, tmode;
-+  enum insn_code icode;
-+  int reverse;
-+  rtx cst;
-+
-+  if (len == 0)
-+    return 1;
-+
-+  if (! MOVE_BY_PIECES_P (len, align))
-+    return 0;
-+
-+  if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
-+      || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT)
-+    align = MOVE_MAX * BITS_PER_UNIT;
-+
-+  /* We would first store what we can in the largest integer mode, then go to
-+     successively smaller modes.  */
-+
-+  for (reverse = 0;
-+       reverse <= (HAVE_PRE_DECREMENT || HAVE_POST_DECREMENT);
-+       reverse++)
-+    {
-+      l = len;
-+      mode = VOIDmode;
-+      max_size = STORE_MAX_PIECES + 1;
-+      while (max_size > 1)
-+      {
-+        for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
-+             tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
-+          if (GET_MODE_SIZE (tmode) < max_size)
-+            mode = tmode;
-+
-+        if (mode == VOIDmode)
-+          break;
-+
-+        icode = mov_optab->handlers[(int) mode].insn_code;
-+        if (icode != CODE_FOR_nothing
-+            && align >= GET_MODE_ALIGNMENT (mode))
-+          {
-+            unsigned int size = GET_MODE_SIZE (mode);
-+
-+            while (l >= size)
-+              {
-+                if (reverse)
-+                  offset -= size;
-+
-+                cst = (*constfun) (constfundata, offset, mode);
-+                if (!LEGITIMATE_CONSTANT_P (cst))
-+                  return 0;
-+
-+                if (!reverse)
-+                  offset += size;
-+
-+                l -= size;
-+              }
-+          }
-+
-+        max_size = GET_MODE_SIZE (mode);
-+      }
-+
-+      /* The code above should have handled everything.  */
-+      if (l != 0)
-+      abort ();
-+    }
-+
-+  return 1;
-+}
-+
-+/* Generate several move instructions to store LEN bytes generated by
-+   CONSTFUN to block TO.  (A MEM rtx with BLKmode).  CONSTFUNDATA is a
-+   pointer which will be passed as argument in every CONSTFUN call.
-+   ALIGN is maximum alignment we can assume.  */
-+
-+void
-+store_by_pieces (to, len, constfun, constfundata, align)
-+     rtx to;
-+     unsigned HOST_WIDE_INT len;
-+     rtx (*constfun) PARAMS ((PTR, HOST_WIDE_INT, enum machine_mode));
-+     PTR constfundata;
-+     unsigned int align;
-+{
-+  struct store_by_pieces data;
-+
-+  if (len == 0)
-+    return;
-+
-+  if (! MOVE_BY_PIECES_P (len, align))
-+    abort ();
-+  to = protect_from_queue (to, 1);
-+  data.constfun = constfun;
-+  data.constfundata = constfundata;
-+  data.len = len;
-+  data.to = to;
-+  store_by_pieces_1 (&data, align);
-+}
-+
-+/* 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)
-+     rtx to;
-+     unsigned HOST_WIDE_INT len;
-+     unsigned int align;
-+{
-+  struct store_by_pieces data;
-+
-+  if (len == 0)
-+    return;
-+
-+  data.constfun = clear_by_pieces_1;
-+  data.constfundata = NULL;
-+  data.len = len;
-+  data.to = to;
-+  store_by_pieces_1 (&data, align);
-+}
-+
-+/* Callback routine for clear_by_pieces.
-+   Return const0_rtx unconditionally.  */
-+
-+static rtx
-+clear_by_pieces_1 (data, offset, mode)
-+     PTR data ATTRIBUTE_UNUSED;
-+     HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
-+     enum machine_mode mode ATTRIBUTE_UNUSED;
-+{
-+  return const0_rtx;
-+}
-+
-+/* Subroutine of clear_by_pieces and store_by_pieces.
-+   Generate several move instructions to store 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
-+store_by_pieces_1 (data, align)
-+     struct store_by_pieces *data;
-+     unsigned int align;
-+{
-+  rtx to_addr = XEXP (data->to, 0);
-+  unsigned HOST_WIDE_INT max_size = STORE_MAX_PIECES + 1;
-+  enum machine_mode mode = VOIDmode, tmode;
-+  enum insn_code icode;
-+
-+  data->offset = 0;
-+  data->to_addr = to_addr;
-+  data->autinc_to
-+    = (GET_CODE (to_addr) == PRE_INC || GET_CODE (to_addr) == PRE_DEC
-+       || GET_CODE (to_addr) == POST_INC || GET_CODE (to_addr) == POST_DEC);
-+
-+  data->explicit_inc_to = 0;
-+  data->reverse
-+    = (GET_CODE (to_addr) == PRE_DEC || GET_CODE (to_addr) == POST_DEC);
-+  if (data->reverse)
-+    data->offset = data->len;
-+
-+  /* If storing requires more than two move insns,
-+     copy addresses to registers (to make displacements shorter)
-+     and use post-increment if available.  */
-+  if (!data->autinc_to
-+      && move_by_pieces_ninsns (data->len, align) > 2)
-+    {
-+      /* Determine the main mode we'll be using.  */
-+      for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
-+         tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
-+      if (GET_MODE_SIZE (tmode) < max_size)
-+        mode = tmode;
-+
-+      if (USE_STORE_PRE_DECREMENT (mode) && data->reverse && ! data->autinc_to)
-+      {
-+        data->to_addr = copy_addr_to_reg (plus_constant (to_addr, data->len));
-+        data->autinc_to = 1;
-+        data->explicit_inc_to = -1;
-+      }
-+
-+      if (USE_STORE_POST_INCREMENT (mode) && ! data->reverse
-+        && ! data->autinc_to)
-+      {
-+        data->to_addr = copy_addr_to_reg (to_addr);
-+        data->autinc_to = 1;
-+        data->explicit_inc_to = 1;
-+      }
-+
-+      if ( !data->autinc_to && CONSTANT_P (to_addr))
-+      data->to_addr = copy_addr_to_reg (to_addr);
-+    }
-+
-+  if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
-+      || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT)
-+    align = MOVE_MAX * BITS_PER_UNIT;
-+
-+  /* First store what we can in the largest integer mode, then go to
-+     successively smaller modes.  */
-+
-+  while (max_size > 1)
-+    {
-+      for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
-+         tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
-+      if (GET_MODE_SIZE (tmode) < max_size)
-+        mode = tmode;
-+
-+      if (mode == VOIDmode)
-+      break;
-+
-+      icode = mov_optab->handlers[(int) mode].insn_code;
-+      if (icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode))
-+      store_by_pieces_2 (GEN_FCN (icode), mode, data);
-+
-+      max_size = GET_MODE_SIZE (mode);
-+    }
-+
-+  /* The code above should have handled everything.  */
-+  if (data->len != 0)
-+    abort ();
-+}
-+
-+/* Subroutine of store_by_pieces_1.  Store as many bytes as appropriate
-+   with move instructions for mode MODE.  GENFUN is the gen_... function
-+   to make a move insn for that mode.  DATA has all the other info.  */
-+
-+static void
-+store_by_pieces_2 (genfun, mode, data)
-+     rtx (*genfun) PARAMS ((rtx, ...));
-+     enum machine_mode mode;
-+     struct store_by_pieces *data;
-+{
-+  unsigned int size = GET_MODE_SIZE (mode);
-+  rtx to1, cst;
-+
-+  while (data->len >= size)
-+    {
-+      if (data->reverse)
-+      data->offset -= size;
-+
-+      if (data->autinc_to)
-+      to1 = adjust_automodify_address (data->to, mode, data->to_addr,
-+                                       data->offset);
-+      else
-+      to1 = adjust_address (data->to, mode, data->offset);
-+
-+      if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
-+      emit_insn (gen_add2_insn (data->to_addr,
-+                                GEN_INT (-(HOST_WIDE_INT) size)));
-+
-+      cst = (*data->constfun) (data->constfundata, data->offset, mode);
-+      emit_insn ((*genfun) (to1, cst));
-+
-+      if (HAVE_POST_INCREMENT && data->explicit_inc_to > 0)
-+      emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size)));
-+
-+      if (! data->reverse)
-+      data->offset += size;
-+
-+      data->len -= size;
-+    }
-+}
-+\f
-+/* Write zeros through the storage of OBJECT.  If OBJECT has BLKmode, SIZE is
-+   its length in bytes.  */
-+
-+rtx
-+clear_storage (object, size)
-+     rtx object;
-+     rtx size;
-+{
-+  rtx retval = 0;
-+  unsigned int align = (GET_CODE (object) == MEM ? MEM_ALIGN (object)
-+                      : GET_MODE_ALIGNMENT (GET_MODE (object)));
-+
-+  /* If OBJECT is not BLKmode and SIZE is the same size as its mode,
-+     just move a zero.  Otherwise, do this a piece at a time.  */
-+  if (GET_MODE (object) != BLKmode
-+      && GET_CODE (size) == CONST_INT
-+      && INTVAL (size) == (HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (object)))
-+    emit_move_insn (object, CONST0_RTX (GET_MODE (object)));
-+  else
-+    {
-+      object = protect_from_queue (object, 1);
-+      size = protect_from_queue (size, 0);
-+
-+      if (GET_CODE (size) == CONST_INT && INTVAL (size) == 0)
-+      ;
-+      else if (GET_CODE (size) == CONST_INT
-+        && CLEAR_BY_PIECES_P (INTVAL (size), align))
-+      clear_by_pieces (object, INTVAL (size), align);
-+      else if (clear_storage_via_clrstr (object, size, align))
-+      ;
-+      else
-+      retval = clear_storage_via_libcall (object, size);
-+    }
-+
-+  return retval;
-+}
-+
-+/* A subroutine of clear_storage.  Expand a clrstr pattern;
-+   return true if successful.  */
-+
-+static bool
-+clear_storage_via_clrstr (object, size, align)
-+     rtx object, size;
-+     unsigned int align;
-+{
-+  /* Try the most limited insn first, because there's no point
-+     including more than one in the machine description unless
-+     the more limited one has some advantage.  */
-+
-+  rtx opalign = GEN_INT (align / BITS_PER_UNIT);
-+  enum machine_mode mode;
-+
-+  for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
-+       mode = GET_MODE_WIDER_MODE (mode))
-+    {
-+      enum insn_code code = clrstr_optab[(int) mode];
-+      insn_operand_predicate_fn pred;
-+
-+      if (code != CODE_FOR_nothing
-+        /* We don't need MODE to be narrower than
-+           BITS_PER_HOST_WIDE_INT here because if SIZE is less than
-+           the mode mask, as it is returned by the macro, it will
-+           definitely be less than the actual mode mask.  */
-+        && ((GET_CODE (size) == CONST_INT
-+             && ((unsigned HOST_WIDE_INT) INTVAL (size)
-+                 <= (GET_MODE_MASK (mode) >> 1)))
-+            || GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)
-+        && ((pred = insn_data[(int) code].operand[0].predicate) == 0
-+            || (*pred) (object, BLKmode))
-+        && ((pred = insn_data[(int) code].operand[2].predicate) == 0
-+            || (*pred) (opalign, VOIDmode)))
-+      {
-+        rtx op1;
-+        rtx last = get_last_insn ();
-+        rtx pat;
-+
-+        op1 = convert_to_mode (mode, size, 1);
-+        pred = insn_data[(int) code].operand[1].predicate;
-+        if (pred != 0 && ! (*pred) (op1, mode))
-+          op1 = copy_to_mode_reg (mode, op1);
-+
-+        pat = GEN_FCN ((int) code) (object, op1, opalign);
-+        if (pat)
-+          {
-+            emit_insn (pat);
-+            return true;
-+          }
-+        else
-+          delete_insns_since (last);
-+      }
-+    }
-+
-+  return false;
-+}
-+
-+/* A subroutine of clear_storage.  Expand a call to memset or bzero.
-+   Return the return value of memset, 0 otherwise.  */
-+
-+static rtx
-+clear_storage_via_libcall (object, size)
-+     rtx object, size;
-+{
-+  tree call_expr, arg_list, fn, object_tree, size_tree;
-+  enum machine_mode size_mode;
-+  rtx retval;
-+
-+  /* OBJECT or SIZE may have been passed through protect_from_queue.
-+
-+     It is unsafe to save the value generated by protect_from_queue
-+     and reuse it later.  Consider what happens if emit_queue is
-+     called before the return value from protect_from_queue is used.
-+
-+     Expansion of the CALL_EXPR below will call emit_queue before
-+     we are finished emitting RTL for argument setup.  So if we are
-+     not careful we could get the wrong value for an argument.
-+
-+     To avoid this problem we go ahead and emit code to copy OBJECT
-+     and SIZE into new pseudos.  We can then place those new pseudos
-+     into an RTL_EXPR and use them later, even after a call to
-+     emit_queue.
-+
-+     Note this is not strictly needed for library calls since they
-+     do not call emit_queue before loading their arguments.  However,
-+     we may need to have library calls call emit_queue in the future
-+     since failing to do so could cause problems for targets which
-+     define SMALL_REGISTER_CLASSES and pass arguments in registers.  */
-+
-+  object = copy_to_mode_reg (Pmode, XEXP (object, 0));
-+
-+  if (TARGET_MEM_FUNCTIONS)
-+    size_mode = TYPE_MODE (sizetype);
-+  else
-+    size_mode = TYPE_MODE (unsigned_type_node);
-+  size = convert_to_mode (size_mode, size, 1);
-+  size = copy_to_mode_reg (size_mode, size);
-+
-+  /* It is incorrect to use the libcall calling conventions to call
-+     memset in this context.  This could be a user call to memset and
-+     the user may wish to examine the return value from memset.  For
-+     targets where libcalls and normal calls have different conventions
-+     for returning pointers, we could end up generating incorrect code.
-+
-+     For convenience, we generate the call to bzero this way as well.  */
-+
-+  object_tree = make_tree (ptr_type_node, object);
-+  if (TARGET_MEM_FUNCTIONS)
-+    size_tree = make_tree (sizetype, size);
-+  else
-+    size_tree = make_tree (unsigned_type_node, size);
-+
-+  fn = clear_storage_libcall_fn (true);
-+  arg_list = tree_cons (NULL_TREE, size_tree, NULL_TREE);
-+  if (TARGET_MEM_FUNCTIONS)
-+    arg_list = tree_cons (NULL_TREE, integer_zero_node, arg_list);
-+  arg_list = tree_cons (NULL_TREE, object_tree, arg_list);
-+
-+  /* Now we have to build up the CALL_EXPR itself.  */
-+  call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
-+  call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
-+                   call_expr, arg_list, NULL_TREE);
-+  TREE_SIDE_EFFECTS (call_expr) = 1;
-+
-+  retval = expand_expr (call_expr, NULL_RTX, VOIDmode, 0);
-+
-+  /* If we are initializing a readonly value, show the above call
-+     clobbered it.  Otherwise, a load from it may erroneously be
-+     hoisted from a loop.  */
-+  if (RTX_UNCHANGING_P (object))
-+    emit_insn (gen_rtx_CLOBBER (VOIDmode, object));
-+
-+  return (TARGET_MEM_FUNCTIONS ? retval : NULL_RTX);
-+}
-+
-+/* A subroutine of clear_storage_via_libcall.  Create the tree node
-+   for the function we use for block clears.  The first time FOR_CALL
-+   is true, we call assemble_external.  */
-+
-+static GTY(()) tree block_clear_fn;
-+
-+static tree
-+clear_storage_libcall_fn (for_call)
-+     int for_call;
-+{
-+  static bool emitted_extern;
-+  tree fn = block_clear_fn, args;
-+
-+  if (!fn)
-+    {
-+      if (TARGET_MEM_FUNCTIONS)
-+      {
-+        fn = get_identifier ("memset");
-+        args = build_function_type_list (ptr_type_node, ptr_type_node,
-+                                         integer_type_node, sizetype,
-+                                         NULL_TREE);
-+      }
-+      else
-+      {
-+        fn = get_identifier ("bzero");
-+        args = build_function_type_list (void_type_node, ptr_type_node,
-+                                         unsigned_type_node, NULL_TREE);
-+      }
-+
-+      fn = build_decl (FUNCTION_DECL, fn, args);
-+      DECL_EXTERNAL (fn) = 1;
-+      TREE_PUBLIC (fn) = 1;
-+      DECL_ARTIFICIAL (fn) = 1;
-+      TREE_NOTHROW (fn) = 1;
-+
-+      block_clear_fn = fn;
-+    }
-+
-+  if (for_call && !emitted_extern)
-+    {
-+      emitted_extern = true;
-+      make_decl_rtl (fn, NULL);
-+      assemble_external (fn);
-+    }
-+
-+  return fn;
-+}
-+\f
-+/* Generate code to copy Y into X.
-+   Both Y and X must have the same mode, except that
-+   Y can be a constant with VOIDmode.
-+   This mode cannot be BLKmode; use emit_block_move for that.
-+
-+   Return the last instruction emitted.  */
-+
-+rtx
-+emit_move_insn (x, y)
-+     rtx x, y;
-+{
-+  enum machine_mode mode = GET_MODE (x);
-+  rtx y_cst = NULL_RTX;
-+  rtx last_insn;
-+
-+  x = protect_from_queue (x, 1);
-+  y = protect_from_queue (y, 0);
-+
-+  if (mode == BLKmode || (GET_MODE (y) != mode && GET_MODE (y) != VOIDmode))
-+    abort ();
-+
-+  /* Never force constant_p_rtx to memory.  */
-+  if (GET_CODE (y) == CONSTANT_P_RTX)
-+    ;
-+  else if (CONSTANT_P (y))
-+    {
-+      if (optimize
-+        && SCALAR_FLOAT_MODE_P (GET_MODE (x))
-+        && (last_insn = compress_float_constant (x, y)))
-+      return last_insn;
-+
-+      if (!LEGITIMATE_CONSTANT_P (y))
-+      {
-+        y_cst = y;
-+        y = force_const_mem (mode, y);
-+
-+        /* If the target's cannot_force_const_mem prevented the spill,
-+           assume that the target's move expanders will also take care
-+           of the non-legitimate constant.  */
-+        if (!y)
-+          y = y_cst;
-+      }
-+    }
-+
-+  /* If X or Y are memory references, verify that their addresses are valid
-+     for the machine.  */
-+  if (GET_CODE (x) == MEM
-+      && ((! memory_address_p (GET_MODE (x), XEXP (x, 0))
-+         && ! push_operand (x, GET_MODE (x)))
-+        || (flag_force_addr
-+            && CONSTANT_ADDRESS_P (XEXP (x, 0)))))
-+    x = validize_mem (x);
-+
-+  if (GET_CODE (y) == MEM
-+      && (! memory_address_p (GET_MODE (y), XEXP (y, 0))
-+        || (flag_force_addr
-+            && CONSTANT_ADDRESS_P (XEXP (y, 0)))))
-+    y = validize_mem (y);
-+
-+  if (mode == BLKmode)
-+    abort ();
-+
-+  last_insn = emit_move_insn_1 (x, y);
-+
-+  if (y_cst && GET_CODE (x) == REG)
-+    set_unique_reg_note (last_insn, REG_EQUAL, y_cst);
-+
-+  return last_insn;
-+}
-+
-+/* Low level part of emit_move_insn.
-+   Called just like emit_move_insn, but assumes X and Y
-+   are basically valid.  */
-+
-+rtx
-+emit_move_insn_1 (x, y)
-+     rtx x, y;
-+{
-+  enum machine_mode mode = GET_MODE (x);
-+  enum machine_mode submode;
-+  enum mode_class class = GET_MODE_CLASS (mode);
-+
-+  if ((unsigned int) mode >= (unsigned int) MAX_MACHINE_MODE)
-+    abort ();
-+
-+  if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
-+    return
-+      emit_insn (GEN_FCN (mov_optab->handlers[(int) mode].insn_code) (x, y));
-+
-+  /* Expand complex moves by moving real part and imag part, if possible.  */
-+  else if ((class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
-+         && BLKmode != (submode = GET_MODE_INNER (mode))
-+         && (mov_optab->handlers[(int) submode].insn_code
-+             != CODE_FOR_nothing))
-+    {
-+      /* Don't split destination if it is a stack push.  */
-+      int stack = push_operand (x, GET_MODE (x));
-+
-+#ifdef PUSH_ROUNDING
-+      /* In case we output to the stack, but the size is smaller machine can
-+       push exactly, we need to use move instructions.  */
-+      if (stack
-+        && (PUSH_ROUNDING (GET_MODE_SIZE (submode))
-+            != GET_MODE_SIZE (submode)))
-+      {
-+        rtx temp;
-+        HOST_WIDE_INT offset1, offset2;
-+
-+        /* Do not use anti_adjust_stack, since we don't want to update
-+           stack_pointer_delta.  */
-+        temp = expand_binop (Pmode,
-+#ifdef STACK_GROWS_DOWNWARD
-+                             sub_optab,
-+#else
-+                             add_optab,
-+#endif
-+                             stack_pointer_rtx,
-+                             GEN_INT
-+                               (PUSH_ROUNDING
-+                                (GET_MODE_SIZE (GET_MODE (x)))),
-+                             stack_pointer_rtx, 0, OPTAB_LIB_WIDEN);
-+
-+        if (temp != stack_pointer_rtx)
-+          emit_move_insn (stack_pointer_rtx, temp);
-+
-+#ifdef STACK_GROWS_DOWNWARD
-+        offset1 = 0;
-+        offset2 = GET_MODE_SIZE (submode);
-+#else
-+        offset1 = -PUSH_ROUNDING (GET_MODE_SIZE (GET_MODE (x)));
-+        offset2 = (-PUSH_ROUNDING (GET_MODE_SIZE (GET_MODE (x)))
-+                   + GET_MODE_SIZE (submode));
-+#endif
-+
-+        emit_move_insn (change_address (x, submode,
-+                                        gen_rtx_PLUS (Pmode,
-+                                                      stack_pointer_rtx,
-+                                                      GEN_INT (offset1))),
-+                        gen_realpart (submode, y));
-+        emit_move_insn (change_address (x, submode,
-+                                        gen_rtx_PLUS (Pmode,
-+                                                      stack_pointer_rtx,
-+                                                      GEN_INT (offset2))),
-+                        gen_imagpart (submode, y));
-+      }
-+      else
-+#endif
-+      /* If this is a stack, push the highpart first, so it
-+       will be in the argument order.
-+
-+       In that case, change_address is used only to convert
-+       the mode, not to change the address.  */
-+      if (stack)
-+      {
-+        /* Note that the real part always precedes the imag part in memory
-+           regardless of machine's endianness.  */
-+#ifdef STACK_GROWS_DOWNWARD
-+        emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
-+                   (gen_rtx_MEM (submode, XEXP (x, 0)),
-+                    gen_imagpart (submode, y)));
-+        emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
-+                   (gen_rtx_MEM (submode, XEXP (x, 0)),
-+                    gen_realpart (submode, y)));
-+#else
-+        emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
-+                   (gen_rtx_MEM (submode, XEXP (x, 0)),
-+                    gen_realpart (submode, y)));
-+        emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
-+                   (gen_rtx_MEM (submode, XEXP (x, 0)),
-+                    gen_imagpart (submode, y)));
-+#endif
-+      }
-+      else
-+      {
-+        rtx realpart_x, realpart_y;
-+        rtx imagpart_x, imagpart_y;
-+
-+        /* If this is a complex value with each part being smaller than a
-+           word, the usual calling sequence will likely pack the pieces into
-+           a single register.  Unfortunately, SUBREG of hard registers only
-+           deals in terms of words, so we have a problem converting input
-+           arguments to the CONCAT of two registers that is used elsewhere
-+           for complex values.  If this is before reload, we can copy it into
-+           memory and reload.  FIXME, we should see about using extract and
-+           insert on integer registers, but complex short and complex char
-+           variables should be rarely used.  */
-+        if (GET_MODE_BITSIZE (mode) < 2 * BITS_PER_WORD
-+            && (reload_in_progress | reload_completed) == 0)
-+          {
-+            int packed_dest_p
-+              = (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER);
-+            int packed_src_p
-+              = (REG_P (y) && REGNO (y) < FIRST_PSEUDO_REGISTER);
-+
-+            if (packed_dest_p || packed_src_p)
-+              {
-+                enum mode_class reg_class = ((class == MODE_COMPLEX_FLOAT)
-+                                             ? MODE_FLOAT : MODE_INT);
-+
-+                enum machine_mode reg_mode
-+                  = mode_for_size (GET_MODE_BITSIZE (mode), reg_class, 1);
-+
-+                if (reg_mode != BLKmode)
-+                  {
-+                    rtx mem = assign_stack_temp (reg_mode,
-+                                                 GET_MODE_SIZE (mode), 0);
-+                    rtx cmem = adjust_address (mem, mode, 0);
-+
-+                    cfun->cannot_inline
-+                      = N_("function using short complex types cannot be inline");
-+
-+                    if (packed_dest_p)
-+                      {
-+                        rtx sreg = gen_rtx_SUBREG (reg_mode, x, 0);
-+
-+                        emit_move_insn_1 (cmem, y);
-+                        return emit_move_insn_1 (sreg, mem);
-+                      }
-+                    else
-+                      {
-+                        rtx sreg = gen_rtx_SUBREG (reg_mode, y, 0);
-+
-+                        emit_move_insn_1 (mem, sreg);
-+                        return emit_move_insn_1 (x, cmem);
-+                      }
-+                  }
-+              }
-+          }
-+
-+        realpart_x = gen_realpart (submode, x);
-+        realpart_y = gen_realpart (submode, y);
-+        imagpart_x = gen_imagpart (submode, x);
-+        imagpart_y = gen_imagpart (submode, y);
-+
-+        /* Show the output dies here.  This is necessary for SUBREGs
-+           of pseudos since we cannot track their lifetimes correctly;
-+           hard regs shouldn't appear here except as return values.
-+           We never want to emit such a clobber after reload.  */
-+        if (x != y
-+            && ! (reload_in_progress || reload_completed)
-+            && (GET_CODE (realpart_x) == SUBREG
-+                || GET_CODE (imagpart_x) == SUBREG))
-+          emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
-+
-+        emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
-+                   (realpart_x, realpart_y));
-+        emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
-+                   (imagpart_x, imagpart_y));
-+      }
-+
-+      return get_last_insn ();
-+    }
-+
-+  /* This will handle any multi-word or full-word mode that lacks a move_insn
-+     pattern.  However, you will get better code if you define such patterns,
-+     even if they must turn into multiple assembler instructions.  */
-+  else if (GET_MODE_SIZE (mode) >= UNITS_PER_WORD)
-+    {
-+      rtx last_insn = 0;
-+      rtx seq, inner;
-+      int need_clobber;
-+      int i;
-+
-+#ifdef PUSH_ROUNDING
-+
-+      /* If X is a push on the stack, do the push now and replace
-+       X with a reference to the stack pointer.  */
-+      if (push_operand (x, GET_MODE (x)))
-+      {
-+        rtx temp;
-+        enum rtx_code code;
-+
-+        /* Do not use anti_adjust_stack, since we don't want to update
-+           stack_pointer_delta.  */
-+        temp = expand_binop (Pmode,
-+#ifdef STACK_GROWS_DOWNWARD
-+                             sub_optab,
-+#else
-+                             add_optab,
-+#endif
-+                             stack_pointer_rtx,
-+                             GEN_INT
-+                               (PUSH_ROUNDING
-+                                (GET_MODE_SIZE (GET_MODE (x)))),
-+                             stack_pointer_rtx, 0, OPTAB_LIB_WIDEN);
-+
-+        if (temp != stack_pointer_rtx)
-+          emit_move_insn (stack_pointer_rtx, temp);
-+
-+        code = GET_CODE (XEXP (x, 0));
-+
-+        /* Just hope that small offsets off SP are OK.  */
-+        if (code == POST_INC)
-+          temp = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-+                              GEN_INT (-((HOST_WIDE_INT)
-+                                         GET_MODE_SIZE (GET_MODE (x)))));
-+        else if (code == POST_DEC)
-+          temp = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-+                              GEN_INT (GET_MODE_SIZE (GET_MODE (x))));
-+        else
-+          temp = stack_pointer_rtx;
-+
-+        x = change_address (x, VOIDmode, temp);
-+      }
-+#endif
-+
-+      /* If we are in reload, see if either operand is a MEM whose address
-+       is scheduled for replacement.  */
-+      if (reload_in_progress && GET_CODE (x) == MEM
-+        && (inner = find_replacement (&XEXP (x, 0))) != XEXP (x, 0))
-+      x = replace_equiv_address_nv (x, inner);
-+      if (reload_in_progress && GET_CODE (y) == MEM
-+        && (inner = find_replacement (&XEXP (y, 0))) != XEXP (y, 0))
-+      y = replace_equiv_address_nv (y, inner);
-+
-+      start_sequence ();
-+
-+      need_clobber = 0;
-+      for (i = 0;
-+         i < (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
-+         i++)
-+      {
-+        rtx xpart = operand_subword (x, i, 1, mode);
-+        rtx ypart = operand_subword (y, i, 1, mode);
-+
-+        /* If we can't get a part of Y, put Y into memory if it is a
-+           constant.  Otherwise, force it into a register.  If we still
-+           can't get a part of Y, abort.  */
-+        if (ypart == 0 && CONSTANT_P (y))
-+          {
-+            y = force_const_mem (mode, y);
-+            ypart = operand_subword (y, i, 1, mode);
-+          }
-+        else if (ypart == 0)
-+          ypart = operand_subword_force (y, i, mode);
-+
-+        if (xpart == 0 || ypart == 0)
-+          abort ();
-+
-+        need_clobber |= (GET_CODE (xpart) == SUBREG);
-+
-+        last_insn = emit_move_insn (xpart, ypart);
-+      }
-+
-+      seq = get_insns ();
-+      end_sequence ();
-+
-+      /* Show the output dies here.  This is necessary for SUBREGs
-+       of pseudos since we cannot track their lifetimes correctly;
-+       hard regs shouldn't appear here except as return values.
-+       We never want to emit such a clobber after reload.  */
-+      if (x != y
-+        && ! (reload_in_progress || reload_completed)
-+        && need_clobber != 0)
-+      emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
-+
-+      emit_insn (seq);
-+
-+      return last_insn;
-+    }
-+  else
-+    abort ();
-+}
-+
-+/* If Y is representable exactly in a narrower mode, and the target can
-+   perform the extension directly from constant or memory, then emit the
-+   move as an extension.  */
-+
-+static rtx
-+compress_float_constant (x, y)
-+     rtx x, y;
-+{
-+  enum machine_mode dstmode = GET_MODE (x);
-+  enum machine_mode orig_srcmode = GET_MODE (y);
-+  enum machine_mode srcmode;
-+  REAL_VALUE_TYPE r;
-+
-+  REAL_VALUE_FROM_CONST_DOUBLE (r, y);
-+
-+  for (srcmode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (orig_srcmode));
-+       srcmode != orig_srcmode;
-+       srcmode = GET_MODE_WIDER_MODE (srcmode))
-+    {
-+      enum insn_code ic;
-+      rtx trunc_y, last_insn;
-+
-+      /* Skip if the target can't extend this way.  */
-+      ic = can_extend_p (dstmode, srcmode, 0);
-+      if (ic == CODE_FOR_nothing)
-+      continue;
-+
-+      /* Skip if the narrowed value isn't exact.  */
-+      if (! exact_real_truncate (srcmode, &r))
-+      continue;
-+
-+      trunc_y = CONST_DOUBLE_FROM_REAL_VALUE (r, srcmode);
-+
-+      if (LEGITIMATE_CONSTANT_P (trunc_y))
-+      {
-+        /* Skip if the target needs extra instructions to perform
-+           the extension.  */
-+        if (! (*insn_data[ic].operand[1].predicate) (trunc_y, srcmode))
-+          continue;
-+      }
-+      else if (float_extend_from_mem[dstmode][srcmode])
-+      trunc_y = validize_mem (force_const_mem (srcmode, trunc_y));
-+      else
-+      continue;
-+
-+      emit_unop_insn (ic, x, trunc_y, UNKNOWN);
-+      last_insn = get_last_insn ();
-+
-+      if (GET_CODE (x) == REG)
-+      REG_NOTES (last_insn)
-+        = gen_rtx_EXPR_LIST (REG_EQUAL, y, REG_NOTES (last_insn));
-+
-+      return last_insn;
-+    }
-+
-+  return NULL_RTX;
-+}
-+\f
-+/* Pushing data onto the stack.  */
-+
-+/* Push a block of length SIZE (perhaps variable)
-+   and return an rtx to address the beginning of the block.
-+   Note that it is not possible for the value returned to be a QUEUED.
-+   The value may be virtual_outgoing_args_rtx.
-+
-+   EXTRA is the number of bytes of padding to push in addition to SIZE.
-+   BELOW nonzero means this padding comes at low addresses;
-+   otherwise, the padding comes at high addresses.  */
-+
-+rtx
-+push_block (size, extra, below)
-+     rtx size;
-+     int extra, below;
-+{
-+  rtx temp;
-+
-+  size = convert_modes (Pmode, ptr_mode, size, 1);
-+  if (CONSTANT_P (size))
-+    anti_adjust_stack (plus_constant (size, extra));
-+  else if (GET_CODE (size) == REG && extra == 0)
-+    anti_adjust_stack (size);
-+  else
-+    {
-+      temp = copy_to_mode_reg (Pmode, size);
-+      if (extra != 0)
-+      temp = expand_binop (Pmode, add_optab, temp, GEN_INT (extra),
-+                           temp, 0, OPTAB_LIB_WIDEN);
-+      anti_adjust_stack (temp);
-+    }
-+
-+#ifndef STACK_GROWS_DOWNWARD
-+  if (0)
-+#else
-+  if (1)
-+#endif
-+    {
-+      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);
-+}
-+
-+#ifdef PUSH_ROUNDING
-+
-+/* Emit single push insn.  */
-+
-+static void
-+emit_single_push_insn (mode, x, type)
-+     rtx x;
-+     enum machine_mode mode;
-+     tree type;
-+{
-+  rtx dest_addr;
-+  unsigned rounded_size = PUSH_ROUNDING (GET_MODE_SIZE (mode));
-+  rtx dest;
-+  enum insn_code icode;
-+  insn_operand_predicate_fn pred;
-+
-+  stack_pointer_delta += PUSH_ROUNDING (GET_MODE_SIZE (mode));
-+  /* If there is push pattern, use it.  Otherwise try old way of throwing
-+     MEM representing push operation to move expander.  */
-+  icode = push_optab->handlers[(int) mode].insn_code;
-+  if (icode != CODE_FOR_nothing)
-+    {
-+      if (((pred = insn_data[(int) icode].operand[0].predicate)
-+         && !((*pred) (x, mode))))
-+      x = force_reg (mode, x);
-+      emit_insn (GEN_FCN (icode) (x));
-+      return;
-+    }
-+  if (GET_MODE_SIZE (mode) == rounded_size)
-+    dest_addr = gen_rtx_fmt_e (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
-+  else
-+    {
-+#ifdef STACK_GROWS_DOWNWARD
-+      dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-+                              GEN_INT (-(HOST_WIDE_INT) rounded_size));
-+#else
-+      dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-+                              GEN_INT (rounded_size));
-+#endif
-+      dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr);
-+    }
-+
-+  dest = gen_rtx_MEM (mode, dest_addr);
-+
-+  if (type != 0)
-+    {
-+      set_mem_attributes (dest, type, 1);
-+
-+      if (flag_optimize_sibling_calls)
-+      /* Function incoming arguments may overlap with sibling call
-+         outgoing arguments and we cannot allow reordering of reads
-+         from function arguments with stores to outgoing arguments
-+         of sibling calls.  */
-+      set_mem_alias_set (dest, 0);
-+    }
-+  emit_move_insn (dest, x);
-+}
-+#endif
-+
-+/* Generate code to push X onto the stack, assuming it has mode MODE and
-+   type TYPE.
-+   MODE is redundant except when X is a CONST_INT (since they don't
-+   carry mode info).
-+   SIZE is an rtx for the size of data to be copied (in bytes),
-+   needed only if X is BLKmode.
-+
-+   ALIGN (in bits) 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.
-+   The amount of space pushed is decreased by PARTIAL words,
-+   rounded *down* to a multiple of PARM_BOUNDARY.
-+   REG must be a hard register in this case.
-+   If REG is zero but PARTIAL is not, take any all others actions for an
-+   argument partially in registers, but do not actually load any
-+   registers.
-+
-+   EXTRA is the amount in bytes of extra space to leave next to this arg.
-+   This is ignored if an argument block has already been allocated.
-+
-+   On a machine that lacks real push insns, ARGS_ADDR is the address of
-+   the bottom of the argument block for this call.  We use indexing off there
-+   to store the arg.  On machines with push insns, ARGS_ADDR is 0 when a
-+   argument block has not been preallocated.
-+
-+   ARGS_SO_FAR is the size of args previously pushed for this call.
-+
-+   REG_PARM_STACK_SPACE is nonzero if functions require stack space
-+   for arguments passed in registers.  If nonzero, it will be the number
-+   of bytes required.  */
-+
-+void
-+emit_push_insn (x, mode, type, size, align, partial, reg, extra,
-+              args_addr, args_so_far, reg_parm_stack_space,
-+              alignment_pad)
-+     rtx x;
-+     enum machine_mode mode;
-+     tree type;
-+     rtx size;
-+     unsigned int align;
-+     int partial;
-+     rtx reg;
-+     int extra;
-+     rtx args_addr;
-+     rtx args_so_far;
-+     int reg_parm_stack_space;
-+     rtx alignment_pad;
-+{
-+  rtx xinner;
-+  enum direction stack_direction
-+#ifdef STACK_GROWS_DOWNWARD
-+    = downward;
-+#else
-+    = upward;
-+#endif
-+
-+  /* Decide where to pad the argument: `downward' for below,
-+     `upward' for above, or `none' for don't pad it.
-+     Default is below for small data on big-endian machines; else above.  */
-+  enum direction where_pad = FUNCTION_ARG_PADDING (mode, type);
-+
-+  /* Invert direction if stack is post-decrement.
-+     FIXME: why?  */
-+  if (STACK_PUSH_CODE == POST_DEC)
-+    if (where_pad != none)
-+      where_pad = (where_pad == downward ? upward : downward);
-+
-+  xinner = x = protect_from_queue (x, 0);
-+
-+  if (mode == BLKmode)
-+    {
-+      /* Copy a block into the stack, entirely or partially.  */
-+
-+      rtx temp;
-+      int used = partial * UNITS_PER_WORD;
-+      int offset = used % (PARM_BOUNDARY / BITS_PER_UNIT);
-+      int skip;
-+
-+      if (size == 0)
-+      abort ();
-+
-+      used -= offset;
-+
-+      /* USED is now the # of bytes we need not copy to the stack
-+       because registers will take care of them.  */
-+
-+      if (partial != 0)
-+      xinner = adjust_address (xinner, BLKmode, used);
-+
-+      /* If the partial register-part of the arg counts in its stack size,
-+       skip the part of stack space corresponding to the registers.
-+       Otherwise, start copying to the beginning of the stack space,
-+       by setting SKIP to 0.  */
-+      skip = (reg_parm_stack_space == 0) ? 0 : used;
-+
-+#ifdef PUSH_ROUNDING
-+      /* Do it with several push insns if that doesn't take lots of insns
-+       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))
-+        /* Here we avoid the case of a structure whose weak alignment
-+           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
-+            || (PUSH_ROUNDING (align / BITS_PER_UNIT)
-+                == (align / BITS_PER_UNIT)))
-+        && PUSH_ROUNDING (INTVAL (size)) == INTVAL (size))
-+      {
-+        /* Push padding now if padding above and stack grows down,
-+           or if padding below and stack grows up.
-+           But if space already allocated, this has already been done.  */
-+        if (extra && args_addr == 0
-+            && where_pad != none && where_pad != stack_direction)
-+          anti_adjust_stack (GEN_INT (extra));
-+
-+        move_by_pieces (NULL, xinner, INTVAL (size) - used, align);
-+      }
-+      else
-+#endif /* PUSH_ROUNDING  */
-+      {
-+        rtx target;
-+
-+        /* Otherwise make space on the stack and copy the data
-+           to the address of that space.  */
-+
-+        /* Deduct words put into registers from the size we must copy.  */
-+        if (partial != 0)
-+          {
-+            if (GET_CODE (size) == CONST_INT)
-+              size = GEN_INT (INTVAL (size) - used);
-+            else
-+              size = expand_binop (GET_MODE (size), sub_optab, size,
-+                                   GEN_INT (used), NULL_RTX, 0,
-+                                   OPTAB_LIB_WIDEN);
-+          }
-+
-+        /* Get the address of the stack space.
-+           In this case, we do not deal with EXTRA separately.
-+           A single stack adjust will do.  */
-+        if (! args_addr)
-+          {
-+            temp = push_block (size, extra, where_pad == downward);
-+            extra = 0;
-+          }
-+        else if (GET_CODE (args_so_far) == CONST_INT)
-+          temp = memory_address (BLKmode,
-+                                 plus_constant (args_addr,
-+                                                skip + INTVAL (args_so_far)));
-+        else
-+          temp = memory_address (BLKmode,
-+                                 plus_constant (gen_rtx_PLUS (Pmode,
-+                                                              args_addr,
-+                                                              args_so_far),
-+                                                skip));
-+
-+        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);
-+          }
-+
-+        target = gen_rtx_MEM (BLKmode, temp);
-+
-+        if (type != 0)
-+          {
-+            set_mem_attributes (target, type, 1);
-+            /* Function incoming arguments may overlap with sibling call
-+               outgoing arguments and we cannot allow reordering of reads
-+               from function arguments with stores to outgoing arguments
-+               of sibling calls.  */
-+            set_mem_alias_set (target, 0);
-+          }
-+
-+        /* ALIGN may well be better aligned than TYPE, e.g. due to
-+           PARM_BOUNDARY.  Assume the caller isn't lying.  */
-+        set_mem_align (target, align);
-+
-+        emit_block_move (target, xinner, size, BLOCK_OP_CALL_PARM);
-+      }
-+    }
-+  else if (partial > 0)
-+    {
-+      /* Scalar partly in registers.  */
-+
-+      int size = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
-+      int i;
-+      int not_stack;
-+      /* # words of start of argument
-+       that we must make space for but need not store.  */
-+      int offset = partial % (PARM_BOUNDARY / BITS_PER_WORD);
-+      int args_offset = INTVAL (args_so_far);
-+      int skip;
-+
-+      /* Push padding now if padding above and stack grows down,
-+       or if padding below and stack grows up.
-+       But if space already allocated, this has already been done.  */
-+      if (extra && args_addr == 0
-+        && where_pad != none && where_pad != stack_direction)
-+      anti_adjust_stack (GEN_INT (extra));
-+
-+      /* If we make space by pushing it, we might as well push
-+       the real data.  Otherwise, we can leave OFFSET nonzero
-+       and leave the space uninitialized.  */
-+      if (args_addr == 0)
-+      offset = 0;
-+
-+      /* Now NOT_STACK gets the number of words that we don't need to
-+       allocate on the stack.  */
-+      not_stack = partial - offset;
-+
-+      /* If the partial register-part of the arg counts in its stack size,
-+       skip the part of stack space corresponding to the registers.
-+       Otherwise, start copying to the beginning of the stack space,
-+       by setting SKIP to 0.  */
-+      skip = (reg_parm_stack_space == 0) ? 0 : not_stack;
-+
-+      if (CONSTANT_P (x) && ! LEGITIMATE_CONSTANT_P (x))
-+      x = validize_mem (force_const_mem (mode, x));
-+
-+      /* If X is a hard register in a non-integer mode, copy it into a pseudo;
-+       SUBREGs of such registers are not allowed.  */
-+      if ((GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER
-+         && GET_MODE_CLASS (GET_MODE (x)) != MODE_INT))
-+      x = copy_to_reg (x);
-+
-+      /* Loop over all the words allocated on the stack for this arg.  */
-+      /* We can do it by words, because any scalar bigger than a word
-+       has a size a multiple of a word.  */
-+#ifndef PUSH_ARGS_REVERSED
-+      for (i = not_stack; i < size; i++)
-+#else
-+      for (i = size - 1; i >= not_stack; i--)
-+#endif
-+      if (i >= not_stack + offset)
-+        emit_push_insn (operand_subword_force (x, i, mode),
-+                        word_mode, NULL_TREE, NULL_RTX, align, 0, NULL_RTX,
-+                        0, args_addr,
-+                        GEN_INT (args_offset + ((i - not_stack + skip)
-+                                                * UNITS_PER_WORD)),
-+                        reg_parm_stack_space, alignment_pad);
-+    }
-+  else
-+    {
-+      rtx addr;
-+      rtx target = NULL_RTX;
-+      rtx dest;
-+
-+      /* Push padding now if padding above and stack grows down,
-+       or if padding below and stack grows up.
-+       But if space already allocated, this has already been done.  */
-+      if (extra && args_addr == 0
-+        && where_pad != none && where_pad != stack_direction)
-+      anti_adjust_stack (GEN_INT (extra));
-+
-+#ifdef PUSH_ROUNDING
-+      if (args_addr == 0 && PUSH_ARGS)
-+      emit_single_push_insn (mode, x, type);
-+      else
-+#endif
-+      {
-+        if (GET_CODE (args_so_far) == CONST_INT)
-+          addr
-+            = memory_address (mode,
-+                              plus_constant (args_addr,
-+                                             INTVAL (args_so_far)));
-+        else
-+          addr = memory_address (mode, gen_rtx_PLUS (Pmode, args_addr,
-+                                                     args_so_far));
-+        target = addr;
-+        dest = gen_rtx_MEM (mode, addr);
-+        if (type != 0)
-+          {
-+            set_mem_attributes (dest, type, 1);
-+            /* Function incoming arguments may overlap with sibling call
-+               outgoing arguments and we cannot allow reordering of reads
-+               from function arguments with stores to outgoing arguments
-+               of sibling calls.  */
-+            set_mem_alias_set (dest, 0);
-+          }
-+
-+        emit_move_insn (dest, x);
-+      }
-+    }
-+
-+  /* If part should go in registers, copy that part
-+     into the appropriate registers.  Do this now, at the end,
-+     since mem-to-mem copies above may do function calls.  */
-+  if (partial > 0 && reg != 0)
-+    {
-+      /* Handle calls that pass values in multiple non-contiguous locations.
-+       The Irix 6 ABI has examples of this.  */
-+      if (GET_CODE (reg) == PARALLEL)
-+      emit_group_load (reg, x, -1);  /* ??? size? */
-+      else
-+      move_block_to_reg (REGNO (reg), x, partial, mode);
-+    }
-+
-+  if (extra && args_addr == 0 && where_pad == stack_direction)
-+    anti_adjust_stack (GEN_INT (extra));
-+
-+  if (alignment_pad && args_addr == 0)
-+    anti_adjust_stack (alignment_pad);
-+}
-+\f
-+/* Return X if X can be used as a subtarget in a sequence of arithmetic
-+   operations.  */
-+
-+static rtx
-+get_subtarget (x)
-+     rtx x;
-+{
-+  return ((x == 0
-+         /* Only registers can be subtargets.  */
-+         || GET_CODE (x) != REG
-+         /* If the register is readonly, it can't be set more than once.  */
-+         || RTX_UNCHANGING_P (x)
-+         /* Don't use hard regs to avoid extending their life.  */
-+         || REGNO (x) < FIRST_PSEUDO_REGISTER
-+         /* Avoid subtargets inside loops,
-+            since they hide some invariant expressions.  */
-+         || preserve_subexpressions_p ())
-+        ? 0 : x);
-+}
-+
-+/* Expand an assignment that stores the value of FROM into TO.
-+   If WANT_VALUE is nonzero, return an rtx for the value of TO.
-+   (This may contain a QUEUED rtx;
-+   if the value is constant, this rtx is a constant.)
-+   Otherwise, the returned value is NULL_RTX.
-+
-+   SUGGEST_REG is no longer actually used.
-+   It used to mean, copy the value through a register
-+   and return that register, if that is possible.
-+   We now use WANT_VALUE to decide whether to do this.  */
-+
-+rtx
-+expand_assignment (to, from, want_value, suggest_reg)
-+     tree to, from;
-+     int want_value;
-+     int suggest_reg ATTRIBUTE_UNUSED;
-+{
-+  rtx to_rtx = 0;
-+  rtx result;
-+
-+  /* Don't crash if the lhs of the assignment was erroneous.  */
-+
-+  if (TREE_CODE (to) == ERROR_MARK)
-+    {
-+      result = expand_expr (from, NULL_RTX, VOIDmode, 0);
-+      return want_value ? result : NULL_RTX;
-+    }
-+
-+  /* Assignment of a structure component needs special treatment
-+     if the structure component's rtx is not simply a MEM.
-+     Assignment of an array element at a constant index, and assignment of
-+     an array element in an unaligned packed structure field, has the same
-+     problem.  */
-+
-+  if (TREE_CODE (to) == COMPONENT_REF || TREE_CODE (to) == BIT_FIELD_REF
-+      || TREE_CODE (to) == ARRAY_REF || TREE_CODE (to) == ARRAY_RANGE_REF
-+      || TREE_CODE (TREE_TYPE (to)) == ARRAY_TYPE)
-+    {
-+      enum machine_mode mode1;
-+      HOST_WIDE_INT bitsize, bitpos;
-+      rtx orig_to_rtx;
-+      tree offset;
-+      int unsignedp;
-+      int volatilep = 0;
-+      tree tem;
-+
-+      push_temp_slots ();
-+      tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
-+                               &unsignedp, &volatilep);
-+
-+      /* If we are going to use store_bit_field and extract_bit_field,
-+       make sure to_rtx will be safe for multiple use.  */
-+
-+      if (mode1 == VOIDmode && want_value)
-+      tem = stabilize_reference (tem);
-+
-+      orig_to_rtx = to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, 0);
-+
-+      if (offset != 0)
-+      {
-+        rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
-+
-+        if (GET_CODE (to_rtx) != MEM)
-+          abort ();
-+
-+#ifdef POINTERS_EXTEND_UNSIGNED
-+        if (GET_MODE (offset_rtx) != Pmode)
-+          offset_rtx = convert_to_mode (Pmode, offset_rtx, 0);
-+#else
-+        if (GET_MODE (offset_rtx) != ptr_mode)
-+          offset_rtx = convert_to_mode (ptr_mode, offset_rtx, 0);
-+#endif
-+
-+        /* A constant address in TO_RTX can have VOIDmode, we must not try
-+           to call force_reg for that case.  Avoid that case.  */
-+        if (GET_CODE (to_rtx) == MEM
-+            && GET_MODE (to_rtx) == BLKmode
-+            && GET_MODE (XEXP (to_rtx, 0)) != VOIDmode
-+            && bitsize > 0
-+            && (bitpos % bitsize) == 0
-+            && (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0
-+            && MEM_ALIGN (to_rtx) == GET_MODE_ALIGNMENT (mode1))
-+          {
-+            to_rtx = adjust_address (to_rtx, mode1, bitpos / BITS_PER_UNIT);
-+            bitpos = 0;
-+          }
-+
-+        to_rtx = offset_address (to_rtx, offset_rtx,
-+                                 highest_pow2_factor_for_type (TREE_TYPE (to),
-+                                                               offset));
-+      }
-+
-+      if (GET_CODE (to_rtx) == MEM)
-+      {
-+        /* If the field is at offset zero, we could have been given the
-+           DECL_RTX of the parent struct.  Don't munge it.  */
-+        to_rtx = shallow_copy_rtx (to_rtx);
-+
-+        set_mem_attributes_minus_bitpos (to_rtx, to, 0, bitpos);
-+      }
-+
-+      /* Deal with volatile and readonly fields.  The former is only done
-+       for MEM.  Also set MEM_KEEP_ALIAS_SET_P if needed.  */
-+      if (volatilep && GET_CODE (to_rtx) == MEM)
-+      {
-+        if (to_rtx == orig_to_rtx)
-+          to_rtx = copy_rtx (to_rtx);
-+        MEM_VOLATILE_P (to_rtx) = 1;
-+      }
-+
-+      if (TREE_CODE (to) == COMPONENT_REF
-+        && TREE_READONLY (TREE_OPERAND (to, 1)))
-+      {
-+        if (to_rtx == orig_to_rtx)
-+          to_rtx = copy_rtx (to_rtx);
-+        RTX_UNCHANGING_P (to_rtx) = 1;
-+      }
-+
-+      if (GET_CODE (to_rtx) == MEM && ! can_address_p (to))
-+      {
-+        if (to_rtx == orig_to_rtx)
-+          to_rtx = copy_rtx (to_rtx);
-+        MEM_KEEP_ALIAS_SET_P (to_rtx) = 1;
-+      }
-+
-+      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, 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,
-+     call the function before we start to compute the lhs.
-+     This is needed for correct code for cases such as
-+     val = setjmp (buf) on machines where reference to val
-+     requires loading up part of an address in a separate insn.
-+
-+     Don't do this if TO is a VAR_DECL or PARM_DECL whose DECL_RTL is REG
-+     since it might be a promoted variable where the zero- or sign- extension
-+     needs to be done.  Handling this in the normal way is safe because no
-+     computation is done before the call.  */
-+  if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from)
-+      && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
-+      && ! ((TREE_CODE (to) == VAR_DECL || TREE_CODE (to) == PARM_DECL)
-+          && GET_CODE (DECL_RTL (to)) == REG))
-+    {
-+      rtx value;
-+
-+      push_temp_slots ();
-+      value = expand_expr (from, NULL_RTX, VOIDmode, 0);
-+      if (to_rtx == 0)
-+      to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
-+
-+      /* Handle calls that return values in multiple non-contiguous locations.
-+       The Irix 6 ABI has examples of this.  */
-+      if (GET_CODE (to_rtx) == PARALLEL)
-+      emit_group_load (to_rtx, value, int_size_in_bytes (TREE_TYPE (from)));
-+      else if (GET_MODE (to_rtx) == BLKmode)
-+      emit_block_move (to_rtx, value, expr_size (from), BLOCK_OP_NORMAL);
-+      else
-+      {
-+#ifdef POINTERS_EXTEND_UNSIGNED
-+        if (POINTER_TYPE_P (TREE_TYPE (to))
-+            && GET_MODE (to_rtx) != GET_MODE (value))
-+          value = convert_memory_address (GET_MODE (to_rtx), value);
-+#endif
-+        emit_move_insn (to_rtx, value);
-+      }
-+      preserve_temp_slots (to_rtx);
-+      free_temp_slots ();
-+      pop_temp_slots ();
-+      return want_value ? to_rtx : NULL_RTX;
-+    }
-+
-+  /* Ordinary treatment.  Expand TO to get a REG or MEM rtx.
-+     Don't re-expand if it was expanded already (in COMPONENT_REF case).  */
-+
-+  if (to_rtx == 0)
-+    to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
-+
-+  /* Don't move directly into a return register.  */
-+  if (TREE_CODE (to) == RESULT_DECL
-+      && (GET_CODE (to_rtx) == REG || GET_CODE (to_rtx) == PARALLEL))
-+    {
-+      rtx temp;
-+
-+      push_temp_slots ();
-+      temp = expand_expr (from, 0, GET_MODE (to_rtx), 0);
-+
-+      if (GET_CODE (to_rtx) == PARALLEL)
-+      emit_group_load (to_rtx, temp, int_size_in_bytes (TREE_TYPE (from)));
-+      else
-+      emit_move_insn (to_rtx, temp);
-+
-+      preserve_temp_slots (to_rtx);
-+      free_temp_slots ();
-+      pop_temp_slots ();
-+      return want_value ? to_rtx : NULL_RTX;
-+    }
-+
-+  /* In case we are returning the contents of an object which overlaps
-+     the place the value is being stored, use a safe function when copying
-+     a value through a pointer into a structure value return block.  */
-+  if (TREE_CODE (to) == RESULT_DECL && TREE_CODE (from) == INDIRECT_REF
-+      && current_function_returns_struct
-+      && !current_function_returns_pcc_struct)
-+    {
-+      rtx from_rtx, size;
-+
-+      push_temp_slots ();
-+      size = expr_size (from);
-+      from_rtx = expand_expr (from, NULL_RTX, VOIDmode, 0);
-+
-+      if (TARGET_MEM_FUNCTIONS)
-+      emit_library_call (memmove_libfunc, LCT_NORMAL,
-+                         VOIDmode, 3, XEXP (to_rtx, 0), Pmode,
-+                         XEXP (from_rtx, 0), Pmode,
-+                         convert_to_mode (TYPE_MODE (sizetype),
-+                                          size, TREE_UNSIGNED (sizetype)),
-+                         TYPE_MODE (sizetype));
-+      else
-+        emit_library_call (bcopy_libfunc, LCT_NORMAL,
-+                         VOIDmode, 3, XEXP (from_rtx, 0), Pmode,
-+                         XEXP (to_rtx, 0), Pmode,
-+                         convert_to_mode (TYPE_MODE (integer_type_node),
-+                                          size,
-+                                          TREE_UNSIGNED (integer_type_node)),
-+                         TYPE_MODE (integer_type_node));
-+
-+      preserve_temp_slots (to_rtx);
-+      free_temp_slots ();
-+      pop_temp_slots ();
-+      return want_value ? to_rtx : NULL_RTX;
-+    }
-+
-+  /* Compute FROM and store the value in the rtx we got.  */
-+
-+  push_temp_slots ();
-+  result = store_expr (from, to_rtx, want_value);
-+  preserve_temp_slots (result);
-+  free_temp_slots ();
-+  pop_temp_slots ();
-+  return want_value ? result : NULL_RTX;
-+}
-+
-+/* Generate code for computing expression EXP,
-+   and storing the value into TARGET.
-+   TARGET may contain a QUEUED rtx.
-+
-+   If WANT_VALUE & 1 is nonzero, return a copy of the value
-+   not in TARGET, so that we can be sure to use the proper
-+   value in a containing expression even if TARGET has something
-+   else stored in it.  If possible, we copy the value through a pseudo
-+   and return that pseudo.  Or, if the value is constant, we try to
-+   return the constant.  In some cases, we return a pseudo
-+   copied *from* TARGET.
-+
-+   If the mode is BLKmode then we may return TARGET itself.
-+   It turns out that in BLKmode it doesn't cause a problem.
-+   because C has no operators that could combine two different
-+   assignments into the same BLKmode object with different values
-+   with no sequence point.  Will other languages need this to
-+   be more thorough?
-+
-+   If WANT_VALUE & 1 is 0, we return NULL, to make sure
-+   to catch quickly any cases where the caller uses the value
-+   and fails to set WANT_VALUE.
-+
-+   If WANT_VALUE & 2 is set, this is a store into a call param on the
-+   stack, and block moves may need to be treated specially.  */
-+
-+rtx
-+store_expr (exp, target, want_value)
-+     tree exp;
-+     rtx target;
-+     int want_value;
-+{
-+  rtx temp;
-+  int dont_return_target = 0;
-+  int dont_store_target = 0;
-+
-+  if (VOID_TYPE_P (TREE_TYPE (exp)))
-+    {
-+      /* C++ can generate ?: expressions with a throw expression in one
-+       branch and an rvalue in the other. Here, we resolve attempts to
-+       store the throw expression's nonexistant result. */
-+      if (want_value)
-+      abort ();
-+      expand_expr (exp, const0_rtx, VOIDmode, 0);
-+      return NULL_RTX;
-+    }
-+  if (TREE_CODE (exp) == COMPOUND_EXPR)
-+    {
-+      /* Perform first part of compound expression, then assign from second
-+       part.  */
-+      expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
-+                 want_value & 2 ? EXPAND_STACK_PARM : EXPAND_NORMAL);
-+      emit_queue ();
-+      return store_expr (TREE_OPERAND (exp, 1), target, want_value);
-+    }
-+  else if (TREE_CODE (exp) == COND_EXPR && GET_MODE (target) == BLKmode)
-+    {
-+      /* For conditional expression, get safe form of the target.  Then
-+       test the condition, doing the appropriate assignment on either
-+       side.  This avoids the creation of unnecessary temporaries.
-+       For non-BLKmode, it is more efficient not to do this.  */
-+
-+      rtx lab1 = gen_label_rtx (), lab2 = gen_label_rtx ();
-+
-+      emit_queue ();
-+      target = protect_from_queue (target, 1);
-+
-+      do_pending_stack_adjust ();
-+      NO_DEFER_POP;
-+      jumpifnot (TREE_OPERAND (exp, 0), lab1);
-+      start_cleanup_deferral ();
-+      store_expr (TREE_OPERAND (exp, 1), target, want_value & 2);
-+      end_cleanup_deferral ();
-+      emit_queue ();
-+      emit_jump_insn (gen_jump (lab2));
-+      emit_barrier ();
-+      emit_label (lab1);
-+      start_cleanup_deferral ();
-+      store_expr (TREE_OPERAND (exp, 2), target, want_value & 2);
-+      end_cleanup_deferral ();
-+      emit_queue ();
-+      emit_label (lab2);
-+      OK_DEFER_POP;
-+
-+      return want_value & 1 ? target : NULL_RTX;
-+    }
-+  else if (queued_subexp_p (target))
-+    /* If target contains a postincrement, let's not risk
-+       using it as the place to generate the rhs.  */
-+    {
-+      if (GET_MODE (target) != BLKmode && GET_MODE (target) != VOIDmode)
-+      {
-+        /* Expand EXP into a new pseudo.  */
-+        temp = gen_reg_rtx (GET_MODE (target));
-+        temp = expand_expr (exp, temp, GET_MODE (target),
-+                            (want_value & 2
-+                             ? EXPAND_STACK_PARM : EXPAND_NORMAL));
-+      }
-+      else
-+      temp = expand_expr (exp, NULL_RTX, GET_MODE (target),
-+                          (want_value & 2
-+                           ? EXPAND_STACK_PARM : EXPAND_NORMAL));
-+
-+      /* If target is volatile, ANSI requires accessing the value
-+       *from* the target, if it is accessed.  So make that happen.
-+       In no case return the target itself.  */
-+      if (! MEM_VOLATILE_P (target) && (want_value & 1) != 0)
-+      dont_return_target = 1;
-+    }
-+  else if ((want_value & 1) != 0
-+         && GET_CODE (target) == MEM
-+         && ! MEM_VOLATILE_P (target)
-+         && GET_MODE (target) != BLKmode)
-+    /* If target is in memory and caller wants value in a register instead,
-+       arrange that.  Pass TARGET as target for expand_expr so that,
-+       if EXP is another assignment, WANT_VALUE will be nonzero for it.
-+       We know expand_expr will not use the target in that case.
-+       Don't do this if TARGET is volatile because we are supposed
-+       to write it and then read it.  */
-+    {
-+      temp = expand_expr (exp, target, GET_MODE (target),
-+                        want_value & 2 ? EXPAND_STACK_PARM : EXPAND_NORMAL);
-+      if (GET_MODE (temp) != BLKmode && GET_MODE (temp) != VOIDmode)
-+      {
-+        /* If TEMP is already in the desired TARGET, only copy it from
-+           memory and don't store it there again.  */
-+        if (temp == target
-+            || (rtx_equal_p (temp, target)
-+                && ! side_effects_p (temp) && ! side_effects_p (target)))
-+          dont_store_target = 1;
-+        temp = copy_to_reg (temp);
-+      }
-+      dont_return_target = 1;
-+    }
-+  else if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
-+    /* If this is a scalar in a register that is stored in a wider mode
-+       than the declared mode, compute the result into its declared mode
-+       and then convert to the wider mode.  Our value is the computed
-+       expression.  */
-+    {
-+      rtx inner_target = 0;
-+
-+      /* If we don't want a value, we can do the conversion inside EXP,
-+       which will often result in some optimizations.  Do the conversion
-+       in two steps: first change the signedness, if needed, then
-+       the extend.  But don't do this if the type of EXP is a subtype
-+       of something else since then the conversion might involve
-+       more than just converting modes.  */
-+      if ((want_value & 1) == 0
-+        && INTEGRAL_TYPE_P (TREE_TYPE (exp))
-+        && TREE_TYPE (TREE_TYPE (exp)) == 0)
-+      {
-+        if (TREE_UNSIGNED (TREE_TYPE (exp))
-+            != SUBREG_PROMOTED_UNSIGNED_P (target))
-+          exp = convert
-+            ((*lang_hooks.types.signed_or_unsigned_type)
-+             (SUBREG_PROMOTED_UNSIGNED_P (target), TREE_TYPE (exp)), exp);
-+
-+        exp = convert ((*lang_hooks.types.type_for_mode)
-+                       (GET_MODE (SUBREG_REG (target)),
-+                        SUBREG_PROMOTED_UNSIGNED_P (target)),
-+                       exp);
-+
-+        inner_target = SUBREG_REG (target);
-+      }
-+
-+      temp = expand_expr (exp, inner_target, VOIDmode,
-+                        want_value & 2 ? EXPAND_STACK_PARM : EXPAND_NORMAL);
-+
-+      /* If TEMP is a volatile MEM and we want a result value, make
-+       the access now so it gets done only once.  Likewise if
-+       it contains TARGET.  */
-+      if (GET_CODE (temp) == MEM && (want_value & 1) != 0
-+        && (MEM_VOLATILE_P (temp)
-+            || reg_mentioned_p (SUBREG_REG (target), XEXP (temp, 0))))
-+      temp = copy_to_reg (temp);
-+
-+      /* If TEMP is a VOIDmode constant, use convert_modes to make
-+       sure that we properly convert it.  */
-+      if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode)
-+      {
-+        temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
-+                              temp, SUBREG_PROMOTED_UNSIGNED_P (target));
-+        temp = convert_modes (GET_MODE (SUBREG_REG (target)),
-+                              GET_MODE (target), temp,
-+                              SUBREG_PROMOTED_UNSIGNED_P (target));
-+      }
-+
-+      convert_move (SUBREG_REG (target), temp,
-+                  SUBREG_PROMOTED_UNSIGNED_P (target));
-+
-+      /* If we promoted a constant, change the mode back down to match
-+       target.  Otherwise, the caller might get confused by a result whose
-+       mode is larger than expected.  */
-+
-+      if ((want_value & 1) != 0 && GET_MODE (temp) != GET_MODE (target))
-+      {
-+        if (GET_MODE (temp) != VOIDmode)
-+          {
-+            temp = gen_lowpart_SUBREG (GET_MODE (target), temp);
-+            SUBREG_PROMOTED_VAR_P (temp) = 1;
-+            SUBREG_PROMOTED_UNSIGNED_SET (temp,
-+              SUBREG_PROMOTED_UNSIGNED_P (target));
-+          }
-+        else
-+          temp = convert_modes (GET_MODE (target),
-+                                GET_MODE (SUBREG_REG (target)),
-+                                temp, SUBREG_PROMOTED_UNSIGNED_P (target));
-+      }
-+
-+      return want_value & 1 ? temp : NULL_RTX;
-+    }
-+  else
-+    {
-+      temp = expand_expr (exp, target, GET_MODE (target),
-+                        want_value & 2 ? EXPAND_STACK_PARM : EXPAND_NORMAL);
-+      /* Return TARGET if it's a specified hardware register.
-+       If TARGET is a volatile mem ref, either return TARGET
-+       or return a reg copied *from* TARGET; ANSI requires this.
-+
-+       Otherwise, if TEMP is not TARGET, return TEMP
-+       if it is constant (for efficiency),
-+       or if we really want the correct value.  */
-+      if (!(target && GET_CODE (target) == REG
-+          && REGNO (target) < FIRST_PSEUDO_REGISTER)
-+        && !(GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
-+        && ! rtx_equal_p (temp, target)
-+        && (CONSTANT_P (temp) || (want_value & 1) != 0))
-+      dont_return_target = 1;
-+    }
-+
-+  /* If TEMP is a VOIDmode constant and the mode of the type of EXP is not
-+     the same as that of TARGET, adjust the constant.  This is needed, for
-+     example, in case it is a CONST_DOUBLE and we want only a word-sized
-+     value.  */
-+  if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode
-+      && TREE_CODE (exp) != ERROR_MARK
-+      && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
-+    temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
-+                        temp, TREE_UNSIGNED (TREE_TYPE (exp)));
-+
-+  /* If value was not generated in the target, store it there.
-+     Convert the value to TARGET's type first if necessary.
-+     If TEMP and TARGET compare equal according to rtx_equal_p, but
-+     one or both of them are volatile memory refs, we have to distinguish
-+     two cases:
-+     - expand_expr has used TARGET.  In this case, we must not generate
-+       another copy.  This can be detected by TARGET being equal according
-+       to == .
-+     - expand_expr has not used TARGET - that means that the source just
-+       happens to have the same RTX form.  Since temp will have been created
-+       by expand_expr, it will compare unequal according to == .
-+       We must generate a copy in this case, to reach the correct number
-+       of volatile memory references.  */
-+
-+  if ((! rtx_equal_p (temp, target)
-+       || (temp != target && (side_effects_p (temp)
-+                            || side_effects_p (target))))
-+      && TREE_CODE (exp) != ERROR_MARK
-+      && ! dont_store_target
-+       /* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET,
-+          but TARGET is not valid memory reference, TEMP will differ
-+          from TARGET although it is really the same location.  */
-+      && (TREE_CODE_CLASS (TREE_CODE (exp)) != 'd'
-+        || target != DECL_RTL_IF_SET (exp))
-+      /* If there's nothing to copy, don't bother.  Don't call expr_size
-+       unless necessary, because some front-ends (C++) expr_size-hook
-+       aborts on objects that are not supposed to be bit-copied or
-+       bit-initialized.  */
-+      && expr_size (exp) != const0_rtx)
-+    {
-+      target = protect_from_queue (target, 1);
-+      if (GET_MODE (temp) != GET_MODE (target)
-+        && GET_MODE (temp) != VOIDmode)
-+      {
-+        int unsignedp = TREE_UNSIGNED (TREE_TYPE (exp));
-+        if (dont_return_target)
-+          {
-+            /* In this case, we will return TEMP,
-+               so make sure it has the proper mode.
-+               But don't forget to store the value into TARGET.  */
-+            temp = convert_to_mode (GET_MODE (target), temp, unsignedp);
-+            emit_move_insn (target, temp);
-+          }
-+        else
-+          convert_move (target, temp, unsignedp);
-+      }
-+
-+      else if (GET_MODE (temp) == BLKmode && TREE_CODE (exp) == STRING_CST)
-+      {
-+        /* Handle copying a string constant into an array.  The string
-+           constant may be shorter than the array.  So copy just the string's
-+           actual length, and clear the rest.  First get the size of the data
-+           type of the string, which is actually the size of the target.  */
-+        rtx size = expr_size (exp);
-+
-+        if (GET_CODE (size) == CONST_INT
-+            && INTVAL (size) < TREE_STRING_LENGTH (exp))
-+          emit_block_move (target, temp, size,
-+                           (want_value & 2
-+                            ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
-+        else
-+          {
-+            /* Compute the size of the data to copy from the string.  */
-+            tree copy_size
-+              = size_binop (MIN_EXPR,
-+                            make_tree (sizetype, size),
-+                            size_int (TREE_STRING_LENGTH (exp)));
-+            rtx copy_size_rtx
-+              = expand_expr (copy_size, NULL_RTX, VOIDmode,
-+                             (want_value & 2
-+                              ? EXPAND_STACK_PARM : EXPAND_NORMAL));
-+            rtx label = 0;
-+
-+            /* Copy that much.  */
-+            copy_size_rtx = convert_to_mode (ptr_mode, copy_size_rtx,
-+                                             TREE_UNSIGNED (sizetype));
-+            emit_block_move (target, temp, copy_size_rtx,
-+                             (want_value & 2
-+                              ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
-+
-+            /* Figure out how much is left in TARGET that we have to clear.
-+               Do all calculations in ptr_mode.  */
-+            if (GET_CODE (copy_size_rtx) == CONST_INT)
-+              {
-+                size = plus_constant (size, -INTVAL (copy_size_rtx));
-+                target = adjust_address (target, BLKmode,
-+                                         INTVAL (copy_size_rtx));
-+              }
-+            else
-+              {
-+                size = expand_binop (TYPE_MODE (sizetype), sub_optab, size,
-+                                     copy_size_rtx, NULL_RTX, 0,
-+                                     OPTAB_LIB_WIDEN);
-+
-+#ifdef POINTERS_EXTEND_UNSIGNED
-+                if (GET_MODE (copy_size_rtx) != Pmode)
-+                  copy_size_rtx = convert_to_mode (Pmode, copy_size_rtx,
-+                                                   TREE_UNSIGNED (sizetype));
-+#endif
-+
-+                target = offset_address (target, copy_size_rtx,
-+                                         highest_pow2_factor (copy_size));
-+                label = gen_label_rtx ();
-+                emit_cmp_and_jump_insns (size, const0_rtx, LT, NULL_RTX,
-+                                         GET_MODE (size), 0, label);
-+              }
-+
-+            if (size != const0_rtx)
-+              clear_storage (target, size);
-+
-+            if (label)
-+              emit_label (label);
-+          }
-+      }
-+      /* Handle calls that return values in multiple non-contiguous locations.
-+       The Irix 6 ABI has examples of this.  */
-+      else if (GET_CODE (target) == PARALLEL)
-+      emit_group_load (target, temp, int_size_in_bytes (TREE_TYPE (exp)));
-+      else if (GET_MODE (temp) == BLKmode)
-+      emit_block_move (target, temp, expr_size (exp),
-+                       (want_value & 2
-+                        ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
-+      else
-+      emit_move_insn (target, temp);
-+    }
-+
-+  /* If we don't want a value, return NULL_RTX.  */
-+  if ((want_value & 1) == 0)
-+    return NULL_RTX;
-+
-+  /* If we are supposed to return TEMP, do so as long as it isn't a MEM.
-+     ??? The latter test doesn't seem to make sense.  */
-+  else if (dont_return_target && GET_CODE (temp) != MEM)
-+    return temp;
-+
-+  /* Return TARGET itself if it is a hard register.  */
-+  else if ((want_value & 1) != 0
-+         && GET_MODE (target) != BLKmode
-+         && ! (GET_CODE (target) == REG
-+               && REGNO (target) < FIRST_PSEUDO_REGISTER))
-+    return copy_to_reg (target);
-+
-+  else
-+    return target;
-+}
-+\f
-+/* Return 1 if EXP just contains zeros.  */
-+
-+static int
-+is_zeros_p (exp)
-+     tree exp;
-+{
-+  tree elt;
-+
-+  switch (TREE_CODE (exp))
-+    {
-+    case CONVERT_EXPR:
-+    case NOP_EXPR:
-+    case NON_LVALUE_EXPR:
-+    case VIEW_CONVERT_EXPR:
-+      return is_zeros_p (TREE_OPERAND (exp, 0));
-+
-+    case INTEGER_CST:
-+      return integer_zerop (exp);
-+
-+    case COMPLEX_CST:
-+      return
-+      is_zeros_p (TREE_REALPART (exp)) && is_zeros_p (TREE_IMAGPART (exp));
-+
-+    case REAL_CST:
-+      return REAL_VALUES_IDENTICAL (TREE_REAL_CST (exp), dconst0);
-+
-+    case VECTOR_CST:
-+      for (elt = TREE_VECTOR_CST_ELTS (exp); elt;
-+         elt = TREE_CHAIN (elt))
-+      if (!is_zeros_p (TREE_VALUE (elt)))
-+        return 0;
-+
-+      return 1;
-+
-+    case CONSTRUCTOR:
-+      if (TREE_TYPE (exp) && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
-+      return CONSTRUCTOR_ELTS (exp) == NULL_TREE;
-+      for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
-+      if (! is_zeros_p (TREE_VALUE (elt)))
-+        return 0;
-+
-+      return 1;
-+
-+    default:
-+      return 0;
-+    }
-+}
-+
-+/* Return 1 if EXP contains mostly (3/4)  zeros.  */
-+
-+static int
-+mostly_zeros_p (exp)
-+     tree exp;
-+{
-+  if (TREE_CODE (exp) == CONSTRUCTOR)
-+    {
-+      int elts = 0, zeros = 0;
-+      tree elt = CONSTRUCTOR_ELTS (exp);
-+      if (TREE_TYPE (exp) && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
-+      {
-+        /* If there are no ranges of true bits, it is all zero.  */
-+        return elt == NULL_TREE;
-+      }
-+      for (; elt; elt = TREE_CHAIN (elt))
-+      {
-+        /* We do not handle the case where the index is a RANGE_EXPR,
-+           so the statistic will be somewhat inaccurate.
-+           We do make a more accurate count in store_constructor itself,
-+           so since this function is only used for nested array elements,
-+           this should be close enough.  */
-+        if (mostly_zeros_p (TREE_VALUE (elt)))
-+          zeros++;
-+        elts++;
-+      }
-+
-+      return 4 * zeros >= 3 * elts;
-+    }
-+
-+  return is_zeros_p (exp);
-+}
-+\f
-+/* Helper function for store_constructor.
-+   TARGET, BITSIZE, BITPOS, MODE, EXP are as for store_field.
-+   TYPE is the type of the CONSTRUCTOR, not the element type.
-+   CLEARED is as for store_constructor.
-+   ALIAS_SET is the alias set to use for any stores.
-+
-+   This provides a recursive shortcut back to store_constructor when it isn't
-+   necessary to go through store_field.  This is so that we can pass through
-+   the cleared field to let store_constructor know that we may not have to
-+   clear a substructure if the outer structure has already been cleared.  */
-+
-+static void
-+store_constructor_field (target, bitsize, bitpos, mode, exp, type, cleared,
-+                       alias_set)
-+     rtx target;
-+     unsigned HOST_WIDE_INT bitsize;
-+     HOST_WIDE_INT bitpos;
-+     enum machine_mode mode;
-+     tree exp, type;
-+     int cleared;
-+     int alias_set;
-+{
-+  if (TREE_CODE (exp) == CONSTRUCTOR
-+      && bitpos % BITS_PER_UNIT == 0
-+      /* If we have a nonzero bitpos for a register target, then we just
-+       let store_field do the bitfield handling.  This is unlikely to
-+       generate unnecessary clear instructions anyways.  */
-+      && (bitpos == 0 || GET_CODE (target) == MEM))
-+    {
-+      if (GET_CODE (target) == MEM)
-+      target
-+        = adjust_address (target,
-+                          GET_MODE (target) == BLKmode
-+                          || 0 != (bitpos
-+                                   % GET_MODE_ALIGNMENT (GET_MODE (target)))
-+                          ? BLKmode : VOIDmode, bitpos / BITS_PER_UNIT);
-+
-+
-+      /* Update the alias set, if required.  */
-+      if (GET_CODE (target) == MEM && ! MEM_KEEP_ALIAS_SET_P (target)
-+        && MEM_ALIAS_SET (target) != 0)
-+      {
-+        target = copy_rtx (target);
-+        set_mem_alias_set (target, alias_set);
-+      }
-+
-+      store_constructor (exp, target, cleared, bitsize / BITS_PER_UNIT);
-+    }
-+  else
-+    store_field (target, bitsize, bitpos, mode, exp, VOIDmode, 0, type,
-+               alias_set);
-+}
-+
-+/* Store the value of constructor EXP into the rtx TARGET.
-+   TARGET is either a REG or a MEM; we know it cannot conflict, since
-+   safe_from_p has been called.
-+   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
-+   which has been packed to exclude padding bits.  */
-+
-+static void
-+store_constructor (exp, target, cleared, size)
-+     tree exp;
-+     rtx target;
-+     int cleared;
-+     HOST_WIDE_INT size;
-+{
-+  tree type = TREE_TYPE (exp);
-+#ifdef WORD_REGISTER_OPERATIONS
-+  HOST_WIDE_INT exp_size = int_size_in_bytes (type);
-+#endif
-+
-+  if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
-+      || TREE_CODE (type) == QUAL_UNION_TYPE)
-+    {
-+      tree elt;
-+
-+      /* If size is zero or the target is already cleared, do nothing.  */
-+      if (size == 0 || cleared)
-+      cleared = 1;
-+      /* We either clear the aggregate or indicate the value is dead.  */
-+      else if ((TREE_CODE (type) == UNION_TYPE
-+              || TREE_CODE (type) == QUAL_UNION_TYPE)
-+             && ! CONSTRUCTOR_ELTS (exp))
-+      /* If the constructor is empty, clear the union.  */
-+      {
-+        clear_storage (target, expr_size (exp));
-+        cleared = 1;
-+      }
-+
-+      /* If we are building a static constructor into a register,
-+       set the initial value as zero so we can fold the value into
-+       a constant.  But if more than one register is involved,
-+       this probably loses.  */
-+      else if (GET_CODE (target) == REG && TREE_STATIC (exp)
-+             && GET_MODE_SIZE (GET_MODE (target)) <= UNITS_PER_WORD)
-+      {
-+        emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
-+        cleared = 1;
-+      }
-+
-+      /* If the constructor has fewer fields than the structure
-+       or if we are initializing the structure to mostly zeros,
-+       clear the whole structure first.  Don't do this if TARGET is a
-+       register whose mode size isn't equal to SIZE since clear_storage
-+       can't handle this case.  */
-+      else if (((list_length (CONSTRUCTOR_ELTS (exp)) != fields_length (type))
-+              || mostly_zeros_p (exp))
-+             && (GET_CODE (target) != REG
-+                 || ((HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (target))
-+                     == size)))
-+      {
-+        clear_storage (target, GEN_INT (size));
-+        cleared = 1;
-+      }
-+
-+      if (! cleared)
-+      emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
-+
-+      /* Store each element of the constructor into
-+       the corresponding field of TARGET.  */
-+
-+      for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
-+      {
-+        tree field = TREE_PURPOSE (elt);
-+        tree value = TREE_VALUE (elt);
-+        enum machine_mode mode;
-+        HOST_WIDE_INT bitsize;
-+        HOST_WIDE_INT bitpos = 0;
-+        int unsignedp;
-+        tree offset;
-+        rtx to_rtx = target;
-+
-+        /* Just ignore missing fields.
-+           We cleared the whole structure, above,
-+           if any fields are missing.  */
-+        if (field == 0)
-+          continue;
-+
-+        if (cleared && is_zeros_p (value))
-+          continue;
-+
-+        if (host_integerp (DECL_SIZE (field), 1))
-+          bitsize = tree_low_cst (DECL_SIZE (field), 1);
-+        else
-+          bitsize = -1;
-+
-+        unsignedp = TREE_UNSIGNED (field);
-+        mode = DECL_MODE (field);
-+        if (DECL_BIT_FIELD (field))
-+          mode = VOIDmode;
-+
-+        offset = DECL_FIELD_OFFSET (field);
-+        if (host_integerp (offset, 0)
-+            && host_integerp (bit_position (field), 0))
-+          {
-+            bitpos = int_bit_position (field);
-+            offset = 0;
-+          }
-+        else
-+          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, sizetype,
-+                              offset, make_tree (TREE_TYPE (exp), target));
-+
-+            offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
-+            if (GET_CODE (to_rtx) != MEM)
-+              abort ();
-+
-+#ifdef POINTERS_EXTEND_UNSIGNED
-+            if (GET_MODE (offset_rtx) != Pmode)
-+              offset_rtx = convert_to_mode (Pmode, offset_rtx, 0);
-+#else
-+            if (GET_MODE (offset_rtx) != ptr_mode)
-+              offset_rtx = convert_to_mode (ptr_mode, offset_rtx, 0);
-+#endif
-+
-+            to_rtx = offset_address (to_rtx, offset_rtx,
-+                                     highest_pow2_factor (offset));
-+          }
-+
-+        if (TREE_READONLY (field))
-+          {
-+            if (GET_CODE (to_rtx) == MEM)
-+              to_rtx = copy_rtx (to_rtx);
-+
-+            RTX_UNCHANGING_P (to_rtx) = 1;
-+          }
-+
-+#ifdef WORD_REGISTER_OPERATIONS
-+        /* If this initializes a field that is smaller than a word, at the
-+           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 (GET_CODE (target) == REG
-+            && bitsize < BITS_PER_WORD
-+            && bitpos % BITS_PER_WORD == 0
-+            && GET_MODE_CLASS (mode) == MODE_INT
-+            && TREE_CODE (value) == INTEGER_CST
-+            && exp_size >= 0
-+            && bitpos + BITS_PER_WORD <= exp_size * BITS_PER_UNIT)
-+          {
-+            tree type = TREE_TYPE (value);
-+
-+            if (TYPE_PRECISION (type) < BITS_PER_WORD)
-+              {
-+                type = (*lang_hooks.types.type_for_size)
-+                  (BITS_PER_WORD, TREE_UNSIGNED (type));
-+                value = convert (type, value);
-+              }
-+
-+            if (BYTES_BIG_ENDIAN)
-+              value
-+                = fold (build (LSHIFT_EXPR, type, value,
-+                               build_int_2 (BITS_PER_WORD - bitsize, 0)));
-+            bitsize = BITS_PER_WORD;
-+            mode = word_mode;
-+          }
-+#endif
-+
-+        if (GET_CODE (to_rtx) == MEM && !MEM_KEEP_ALIAS_SET_P (to_rtx)
-+            && DECL_NONADDRESSABLE_P (field))
-+          {
-+            to_rtx = copy_rtx (to_rtx);
-+            MEM_KEEP_ALIAS_SET_P (to_rtx) = 1;
-+          }
-+
-+        store_constructor_field (to_rtx, bitsize, bitpos, mode,
-+                                 value, type, cleared,
-+                                 get_alias_set (TREE_TYPE (field)));
-+      }
-+    }
-+  else if (TREE_CODE (type) == ARRAY_TYPE
-+         || TREE_CODE (type) == VECTOR_TYPE)
-+    {
-+      tree elt;
-+      int i;
-+      int need_to_clear;
-+      tree domain = TYPE_DOMAIN (type);
-+      tree elttype = TREE_TYPE (type);
-+      int const_bounds_p;
-+      HOST_WIDE_INT minelt = 0;
-+      HOST_WIDE_INT maxelt = 0;
-+
-+      /* Vectors are like arrays, but the domain is stored via an array
-+       type indirectly.  */
-+      if (TREE_CODE (type) == VECTOR_TYPE)
-+      {
-+        /* Note that although TYPE_DEBUG_REPRESENTATION_TYPE uses
-+           the same field as TYPE_DOMAIN, we are not guaranteed that
-+           it always will.  */
-+        domain = TYPE_DEBUG_REPRESENTATION_TYPE (type);
-+        domain = TYPE_DOMAIN (TREE_TYPE (TYPE_FIELDS (domain)));
-+      }
-+
-+      const_bounds_p = (TYPE_MIN_VALUE (domain)
-+                      && TYPE_MAX_VALUE (domain)
-+                      && host_integerp (TYPE_MIN_VALUE (domain), 0)
-+                      && host_integerp (TYPE_MAX_VALUE (domain), 0));
-+
-+      /* If we have constant bounds for the range of the type, get them.  */
-+      if (const_bounds_p)
-+      {
-+        minelt = tree_low_cst (TYPE_MIN_VALUE (domain), 0);
-+        maxelt = tree_low_cst (TYPE_MAX_VALUE (domain), 0);
-+      }
-+
-+      /* If the constructor has fewer elements than the array,
-+         clear the whole array first.  Similarly if this is
-+         static constructor of a non-BLKmode object.  */
-+      if (cleared || (GET_CODE (target) == REG && TREE_STATIC (exp)))
-+      need_to_clear = 1;
-+      else
-+      {
-+        HOST_WIDE_INT count = 0, zero_count = 0;
-+        need_to_clear = ! const_bounds_p;
-+
-+        /* This loop is a more accurate version of the loop in
-+           mostly_zeros_p (it handles RANGE_EXPR in an index).
-+           It is also needed to check for missing elements.  */
-+        for (elt = CONSTRUCTOR_ELTS (exp);
-+             elt != NULL_TREE && ! need_to_clear;
-+             elt = TREE_CHAIN (elt))
-+          {
-+            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 (! host_integerp (lo_index, 1)
-+                    || ! host_integerp (hi_index, 1))
-+                  {
-+                    need_to_clear = 1;
-+                    break;
-+                  }
-+
-+                this_node_count = (tree_low_cst (hi_index, 1)
-+                                   - tree_low_cst (lo_index, 1) + 1);
-+              }
-+            else
-+              this_node_count = 1;
-+
-+            count += this_node_count;
-+            if (mostly_zeros_p (TREE_VALUE (elt)))
-+              zero_count += this_node_count;
-+          }
-+
-+        /* Clear the entire array first if there are any missing elements,
-+           or if the incidence of zero elements is >= 75%.  */
-+        if (! need_to_clear
-+            && (count < maxelt - minelt + 1 || 4 * zero_count >= 3 * count))
-+          need_to_clear = 1;
-+      }
-+
-+      if (need_to_clear && size > 0)
-+      {
-+        if (! cleared)
-+          {
-+            if (REG_P (target))
-+              emit_move_insn (target,  CONST0_RTX (GET_MODE (target)));
-+            else
-+              clear_storage (target, GEN_INT (size));
-+          }
-+        cleared = 1;
-+      }
-+      else if (REG_P (target))
-+      /* Inform later passes that the old value is dead.  */
-+      emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
-+
-+      /* Store each element of the constructor into
-+       the corresponding element of TARGET, determined
-+       by counting the elements.  */
-+      for (elt = CONSTRUCTOR_ELTS (exp), i = 0;
-+         elt;
-+         elt = TREE_CHAIN (elt), i++)
-+      {
-+        enum machine_mode mode;
-+        HOST_WIDE_INT bitsize;
-+        HOST_WIDE_INT bitpos;
-+        int unsignedp;
-+        tree value = TREE_VALUE (elt);
-+        tree index = TREE_PURPOSE (elt);
-+        rtx xtarget = target;
-+
-+        if (cleared && is_zeros_p (value))
-+          continue;
-+
-+        unsignedp = TREE_UNSIGNED (elttype);
-+        mode = TYPE_MODE (elttype);
-+        if (mode == BLKmode)
-+          bitsize = (host_integerp (TYPE_SIZE (elttype), 1)
-+                     ? tree_low_cst (TYPE_SIZE (elttype), 1)
-+                     : -1);
-+        else
-+          bitsize = GET_MODE_BITSIZE (mode);
-+
-+        if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
-+          {
-+            tree lo_index = TREE_OPERAND (index, 0);
-+            tree hi_index = TREE_OPERAND (index, 1);
-+            rtx index_r, pos_rtx, hi_r, loop_top, loop_end;
-+            struct nesting *loop;
-+            HOST_WIDE_INT lo, hi, count;
-+            tree position;
-+
-+            /* If the range is constant and "small", unroll the loop.  */
-+            if (const_bounds_p
-+                && 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
-+                     || (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_low_cst (TYPE_SIZE (elttype), 0);
-+
-+                    if (GET_CODE (target) == MEM
-+                        && !MEM_KEEP_ALIAS_SET_P (target)
-+                        && TREE_CODE (type) == ARRAY_TYPE
-+                        && TYPE_NONALIASED_COMPONENT (type))
-+                      {
-+                        target = copy_rtx (target);
-+                        MEM_KEEP_ALIAS_SET_P (target) = 1;
-+                      }
-+
-+                    store_constructor_field
-+                      (target, bitsize, bitpos, mode, value, type, cleared,
-+                       get_alias_set (elttype));
-+                  }
-+              }
-+            else
-+              {
-+                hi_r = expand_expr (hi_index, NULL_RTX, VOIDmode, 0);
-+                loop_top = gen_label_rtx ();
-+                loop_end = gen_label_rtx ();
-+
-+                unsignedp = TREE_UNSIGNED (domain);
-+
-+                index = build_decl (VAR_DECL, NULL_TREE, domain);
-+
-+                index_r
-+                  = gen_reg_rtx (promote_mode (domain, DECL_MODE (index),
-+                                               &unsignedp, 0));
-+                SET_DECL_RTL (index, index_r);
-+                if (TREE_CODE (value) == SAVE_EXPR
-+                    && SAVE_EXPR_RTL (value) == 0)
-+                  {
-+                    /* Make sure value gets expanded once before the
-+                         loop.  */
-+                    expand_expr (value, const0_rtx, VOIDmode, 0);
-+                    emit_queue ();
-+                  }
-+                store_expr (lo_index, index_r, 0);
-+                loop = expand_start_loop (0);
-+
-+                /* Assign value to element index.  */
-+                position
-+                  = convert (ssizetype,
-+                             fold (build (MINUS_EXPR, TREE_TYPE (index),
-+                                          index, TYPE_MIN_VALUE (domain))));
-+                position = size_binop (MULT_EXPR, position,
-+                                       convert (ssizetype,
-+                                                TYPE_SIZE_UNIT (elttype)));
-+
-+                pos_rtx = expand_expr (position, 0, VOIDmode, 0);
-+                xtarget = offset_address (target, pos_rtx,
-+                                          highest_pow2_factor (position));
-+                xtarget = adjust_address (xtarget, mode, 0);
-+                if (TREE_CODE (value) == CONSTRUCTOR)
-+                  store_constructor (value, xtarget, cleared,
-+                                     bitsize / BITS_PER_UNIT);
-+                else
-+                  store_expr (value, xtarget, 0);
-+
-+                expand_exit_loop_if_false (loop,
-+                                           build (LT_EXPR, integer_type_node,
-+                                                  index, hi_index));
-+
-+                expand_increment (build (PREINCREMENT_EXPR,
-+                                         TREE_TYPE (index),
-+                                         index, integer_one_node), 0, 0);
-+                expand_end_loop ();
-+                emit_label (loop_end);
-+              }
-+          }
-+        else if ((index != 0 && ! host_integerp (index, 0))
-+                 || ! host_integerp (TYPE_SIZE (elttype), 1))
-+          {
-+            tree position;
-+
-+            if (index == 0)
-+              index = ssize_int (1);
-+
-+            if (minelt)
-+              index = convert (ssizetype,
-+                               fold (build (MINUS_EXPR, index,
-+                                            TYPE_MIN_VALUE (domain))));
-+
-+            position = size_binop (MULT_EXPR, index,
-+                                   convert (ssizetype,
-+                                            TYPE_SIZE_UNIT (elttype)));
-+            xtarget = offset_address (target,
-+                                      expand_expr (position, 0, VOIDmode, 0),
-+                                      highest_pow2_factor (position));
-+            xtarget = adjust_address (xtarget, mode, 0);
-+            store_expr (value, xtarget, 0);
-+          }
-+        else
-+          {
-+            if (index != 0)
-+              bitpos = ((tree_low_cst (index, 0) - minelt)
-+                        * tree_low_cst (TYPE_SIZE (elttype), 1));
-+            else
-+              bitpos = (i * tree_low_cst (TYPE_SIZE (elttype), 1));
-+
-+            if (GET_CODE (target) == MEM && !MEM_KEEP_ALIAS_SET_P (target)
-+                && TREE_CODE (type) == ARRAY_TYPE
-+                && TYPE_NONALIASED_COMPONENT (type))
-+              {
-+                target = copy_rtx (target);
-+                MEM_KEEP_ALIAS_SET_P (target) = 1;
-+              }
-+
-+            store_constructor_field (target, bitsize, bitpos, mode, value,
-+                                     type, cleared, get_alias_set (elttype));
-+
-+          }
-+      }
-+    }
-+
-+  /* Set constructor assignments.  */
-+  else if (TREE_CODE (type) == SET_TYPE)
-+    {
-+      tree elt = CONSTRUCTOR_ELTS (exp);
-+      unsigned HOST_WIDE_INT nbytes = int_size_in_bytes (type), nbits;
-+      tree domain = TYPE_DOMAIN (type);
-+      tree domain_min, domain_max, bitlength;
-+
-+      /* The default implementation strategy is to extract the constant
-+       parts of the constructor, use that to initialize the target,
-+       and then "or" in whatever non-constant ranges we need in addition.
-+
-+       If a large set is all zero or all ones, it is
-+       probably better to set it using memset (if available) or bzero.
-+       Also, if a large set has just a single range, it may also be
-+       better to first clear all the first clear the set (using
-+       bzero/memset), and set the bits we want.  */
-+
-+      /* Check for all zeros.  */
-+      if (elt == NULL_TREE && size > 0)
-+      {
-+        if (!cleared)
-+          clear_storage (target, GEN_INT (size));
-+        return;
-+      }
-+
-+      domain_min = convert (sizetype, TYPE_MIN_VALUE (domain));
-+      domain_max = convert (sizetype, TYPE_MAX_VALUE (domain));
-+      bitlength = size_binop (PLUS_EXPR,
-+                            size_diffop (domain_max, domain_min),
-+                            ssize_int (1));
-+
-+      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
-+       constant parts) by copying from a constant.  */
-+      if (GET_MODE (target) != BLKmode || nbits <= 2 * BITS_PER_WORD
-+        || (nbytes <= 32 && TREE_CHAIN (elt) != NULL_TREE))
-+      {
-+        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;
-+        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 (;;)
-+          {
-+            if (bit_buffer[ibit])
-+              {
-+                if (BYTES_BIG_ENDIAN)
-+                  word |= (1 << (set_word_size - 1 - bit_pos));
-+                else
-+                  word |= 1 << bit_pos;
-+              }
-+
-+            bit_pos++;  ibit++;
-+            if (bit_pos >= set_word_size || ibit == nbits)
-+              {
-+                if (word != 0 || ! cleared)
-+                  {
-+                    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.  */
-+                    if (GET_CODE (target) == MEM)
-+                      to_rtx = adjust_address (target, mode, offset);
-+                    else if (offset == 0)
-+                      to_rtx = target;
-+                    else
-+                      abort ();
-+                    emit_move_insn (to_rtx, datum);
-+                  }
-+
-+                if (ibit == nbits)
-+                  break;
-+                word = 0;
-+                bit_pos = 0;
-+                offset += set_word_size / BITS_PER_UNIT;
-+              }
-+          }
-+      }
-+      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
-+              : ( ! 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));
-+
-+      for (; elt != NULL_TREE; elt = TREE_CHAIN (elt))
-+      {
-+        /* Start of range of element or NULL.  */
-+        tree startbit = TREE_PURPOSE (elt);
-+        /* End of range of element, or element value.  */
-+        tree endbit   = TREE_VALUE (elt);
-+        HOST_WIDE_INT startb, endb;
-+        rtx bitlength_rtx, startbit_rtx, endbit_rtx, targetx;
-+
-+        bitlength_rtx = expand_expr (bitlength,
-+                                     NULL_RTX, MEM, EXPAND_CONST_ADDRESS);
-+
-+        /* Handle non-range tuple element like [ expr ].  */
-+        if (startbit == NULL_TREE)
-+          {
-+            startbit = save_expr (endbit);
-+            endbit = startbit;
-+          }
-+
-+        startbit = convert (sizetype, startbit);
-+        endbit = convert (sizetype, endbit);
-+        if (! integer_zerop (domain_min))
-+          {
-+            startbit = size_binop (MINUS_EXPR, startbit, domain_min);
-+            endbit = size_binop (MINUS_EXPR, endbit, domain_min);
-+          }
-+        startbit_rtx = expand_expr (startbit, NULL_RTX, MEM,
-+                                    EXPAND_CONST_ADDRESS);
-+        endbit_rtx = expand_expr (endbit, NULL_RTX, MEM,
-+                                  EXPAND_CONST_ADDRESS);
-+
-+        if (REG_P (target))
-+          {
-+            targetx
-+              = assign_temp
-+                ((build_qualified_type ((*lang_hooks.types.type_for_mode)
-+                                        (GET_MODE (target), 0),
-+                                        TYPE_QUAL_CONST)),
-+                 0, 1, 1);
-+            emit_move_insn (targetx, target);
-+          }
-+
-+        else if (GET_CODE (target) == MEM)
-+          targetx = target;
-+        else
-+          abort ();
-+
-+        /* Optimization:  If startbit and endbit are constants divisible
-+           by BITS_PER_UNIT, call memset instead.  */
-+        if (TARGET_MEM_FUNCTIONS
-+            && TREE_CODE (startbit) == INTEGER_CST
-+            && TREE_CODE (endbit) == INTEGER_CST
-+            && (startb = TREE_INT_CST_LOW (startbit)) % BITS_PER_UNIT == 0
-+            && (endb = TREE_INT_CST_LOW (endbit) + 1) % BITS_PER_UNIT == 0)
-+          {
-+            emit_library_call (memset_libfunc, LCT_NORMAL,
-+                               VOIDmode, 3,
-+                               plus_constant (XEXP (targetx, 0),
-+                                              startb / BITS_PER_UNIT),
-+                               Pmode,
-+                               constm1_rtx, TYPE_MODE (integer_type_node),
-+                               GEN_INT ((endb - startb) / BITS_PER_UNIT),
-+                               TYPE_MODE (sizetype));
-+          }
-+        else
-+          emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__setbits"),
-+                             LCT_NORMAL, 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);
-+      }
-+    }
-+
-+  else
-+    abort ();
-+}
-+
-+/* Store the value of EXP (an expression tree)
-+   into a subfield of TARGET which has mode MODE and occupies
-+   BITSIZE bits, starting BITPOS bits from the start of TARGET.
-+   If MODE is VOIDmode, it means that we are storing into a bit-field.
-+
-+   If VALUE_MODE is VOIDmode, return nothing in particular.
-+   UNSIGNEDP is not used in this case.
-+
-+   Otherwise, return an rtx for the value stored.  This rtx
-+   has mode VALUE_MODE if that is convenient to do.
-+   In this case, UNSIGNEDP must be nonzero if the value is an unsigned type.
-+
-+   TYPE is the type of the underlying object,
-+
-+   ALIAS_SET is the alias set for the destination.  This value will
-+   (in general) be different from that for TARGET, since TARGET is a
-+   reference to the containing structure.  */
-+
-+static rtx
-+store_field (target, bitsize, bitpos, mode, exp, value_mode, unsignedp, type,
-+           alias_set)
-+     rtx target;
-+     HOST_WIDE_INT bitsize;
-+     HOST_WIDE_INT bitpos;
-+     enum machine_mode mode;
-+     tree exp;
-+     enum machine_mode value_mode;
-+     int unsignedp;
-+     tree type;
-+     int alias_set;
-+{
-+  HOST_WIDE_INT width_mask = 0;
-+
-+  if (TREE_CODE (exp) == ERROR_MARK)
-+    return const0_rtx;
-+
-+  /* If we have nothing to store, do nothing unless the expression has
-+     side-effects.  */
-+  if (bitsize == 0)
-+    return expand_expr (exp, const0_rtx, VOIDmode, 0);
-+  else if (bitsize >=0 && bitsize < HOST_BITS_PER_WIDE_INT)
-+    width_mask = ((HOST_WIDE_INT) 1 << bitsize) - 1;
-+
-+  /* If we are storing into an unaligned field of an aligned union that is
-+     in a register, we may have the mode of TARGET being an integer mode but
-+     MODE == BLKmode.  In that case, get an aligned object whose size and
-+     alignment are the same as TARGET and store TARGET into it (we can avoid
-+     the store if the field being stored is the entire width of TARGET).  Then
-+     call ourselves recursively to store the field into a BLKmode version of
-+     that object.  Finally, load from the object into TARGET.  This is not
-+     very efficient in general, but should only be slightly more expensive
-+     than the otherwise-required unaligned accesses.  Perhaps this can be
-+     cleaned up later.  */
-+
-+  if (mode == BLKmode
-+      && (GET_CODE (target) == REG || GET_CODE (target) == SUBREG))
-+    {
-+      rtx object
-+      = assign_temp
-+        (build_qualified_type (type, TYPE_QUALS (type) | TYPE_QUAL_CONST),
-+         0, 1, 1);
-+      rtx blk_object = adjust_address (object, BLKmode, 0);
-+
-+      if (bitsize != (HOST_WIDE_INT) GET_MODE_BITSIZE (GET_MODE (target)))
-+      emit_move_insn (object, target);
-+
-+      store_field (blk_object, bitsize, bitpos, mode, exp, VOIDmode, 0, type,
-+                 alias_set);
-+
-+      emit_move_insn (target, object);
-+
-+      /* We want to return the BLKmode version of the data.  */
-+      return blk_object;
-+    }
-+
-+  if (GET_CODE (target) == CONCAT)
-+    {
-+      /* We're storing into a struct containing a single __complex.  */
-+
-+      if (bitpos != 0)
-+      abort ();
-+      return store_expr (exp, target, 0);
-+    }
-+
-+  /* If the structure is in a register or if the component
-+     is a bit field, we cannot use addressing to access it.
-+     Use bit-field techniques or SUBREG to store in it.  */
-+
-+  if (mode == VOIDmode
-+      || (mode != BLKmode && ! direct_store[(int) mode]
-+        && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
-+        && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
-+      || GET_CODE (target) == REG
-+      || GET_CODE (target) == SUBREG
-+      /* If the field isn't aligned enough to store as an ordinary memref,
-+       store it as a bit field.  */
-+      || (mode != BLKmode && SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (target))
-+        && (MEM_ALIGN (target) < GET_MODE_ALIGNMENT (mode)
-+            || bitpos % GET_MODE_ALIGNMENT (mode)))
-+      /* If the RHS and field are a constant size and the size of the
-+       RHS isn't the same size as the bitfield, we must use bitfield
-+       operations.  */
-+      || (bitsize >= 0
-+        && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) == INTEGER_CST
-+        && compare_tree_int (TYPE_SIZE (TREE_TYPE (exp)), bitsize) != 0))
-+    {
-+      rtx temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
-+
-+      /* If BITSIZE is narrower than the size of the type of EXP
-+       we will be narrowing TEMP.  Normally, what's wanted are the
-+       low-order bits.  However, if EXP's type is a record and this is
-+       big-endian machine, we want the upper BITSIZE bits.  */
-+      if (BYTES_BIG_ENDIAN && GET_MODE_CLASS (GET_MODE (temp)) == MODE_INT
-+        && bitsize < (HOST_WIDE_INT) GET_MODE_BITSIZE (GET_MODE (temp))
-+        && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
-+      temp = expand_shift (RSHIFT_EXPR, GET_MODE (temp), temp,
-+                           size_int (GET_MODE_BITSIZE (GET_MODE (temp))
-+                                     - bitsize),
-+                           temp, 1);
-+
-+      /* Unless MODE is VOIDmode or BLKmode, convert TEMP to
-+       MODE.  */
-+      if (mode != VOIDmode && mode != BLKmode
-+        && mode != TYPE_MODE (TREE_TYPE (exp)))
-+      temp = convert_modes (mode, TYPE_MODE (TREE_TYPE (exp)), temp, 1);
-+
-+      /* If the modes of TARGET and TEMP are both BLKmode, both
-+       must be in memory and BITPOS must be aligned on a byte
-+       boundary.  If so, we simply do a block copy.  */
-+      if (GET_MODE (target) == BLKmode && GET_MODE (temp) == BLKmode)
-+      {
-+        if (GET_CODE (target) != MEM || GET_CODE (temp) != MEM
-+            || bitpos % BITS_PER_UNIT != 0)
-+          abort ();
-+
-+        target = adjust_address (target, VOIDmode, bitpos / BITS_PER_UNIT);
-+        emit_block_move (target, temp,
-+                         GEN_INT ((bitsize + BITS_PER_UNIT - 1)
-+                                  / BITS_PER_UNIT),
-+                         BLOCK_OP_NORMAL);
-+
-+        return value_mode == VOIDmode ? const0_rtx : target;
-+      }
-+
-+      /* Store the value in the bitfield.  */
-+      store_bit_field (target, bitsize, bitpos, mode, temp,
-+                     int_size_in_bytes (type));
-+
-+      if (value_mode != VOIDmode)
-+      {
-+        /* The caller wants an rtx for the value.
-+           If possible, avoid refetching from the bitfield itself.  */
-+        if (width_mask != 0
-+            && ! (GET_CODE (target) == MEM && MEM_VOLATILE_P (target)))
-+          {
-+            tree count;
-+            enum machine_mode tmode;
-+
-+            tmode = GET_MODE (temp);
-+            if (tmode == VOIDmode)
-+              tmode = value_mode;
-+
-+            if (unsignedp)
-+              return expand_and (tmode, temp,
-+                                 gen_int_mode (width_mask, tmode),
-+                                 NULL_RTX);
-+
-+            count = build_int_2 (GET_MODE_BITSIZE (tmode) - bitsize, 0);
-+            temp = expand_shift (LSHIFT_EXPR, tmode, temp, count, 0, 0);
-+            return expand_shift (RSHIFT_EXPR, tmode, temp, count, 0, 0);
-+          }
-+
-+        return extract_bit_field (target, bitsize, bitpos, unsignedp,
-+                                  NULL_RTX, value_mode, VOIDmode,
-+                                  int_size_in_bytes (type));
-+      }
-+      return const0_rtx;
-+    }
-+  else
-+    {
-+      rtx addr = XEXP (target, 0);
-+      rtx to_rtx = target;
-+
-+      /* If a value is wanted, it must be the lhs;
-+       so make the address stable for multiple use.  */
-+
-+      if (value_mode != VOIDmode && GET_CODE (addr) != REG
-+        && ! CONSTANT_ADDRESS_P (addr)
-+        /* A frame-pointer reference is already stable.  */
-+        && ! (GET_CODE (addr) == PLUS
-+              && GET_CODE (XEXP (addr, 1)) == CONST_INT
-+              && (XEXP (addr, 0) == virtual_incoming_args_rtx
-+                  || XEXP (addr, 0) == virtual_stack_vars_rtx)))
-+      to_rtx = replace_equiv_address (to_rtx, copy_to_reg (addr));
-+
-+      /* Now build a reference to just the desired component.  */
-+
-+      to_rtx = adjust_address (target, mode, bitpos / BITS_PER_UNIT);
-+
-+      if (to_rtx == target)
-+      to_rtx = copy_rtx (to_rtx);
-+
-+      MEM_SET_IN_STRUCT_P (to_rtx, 1);
-+      if (!MEM_KEEP_ALIAS_SET_P (to_rtx) && MEM_ALIAS_SET (to_rtx) != 0)
-+      set_mem_alias_set (to_rtx, alias_set);
-+
-+      return store_expr (exp, to_rtx, value_mode != VOIDmode);
-+    }
-+}
-+\f
-+/* Given an expression EXP that may be a COMPONENT_REF, a BIT_FIELD_REF,
-+   an ARRAY_REF, or an ARRAY_RANGE_REF, look for nested operations of these
-+   codes and find the ultimate containing object, which we return.
-+
-+   We set *PBITSIZE to the size in bits that we want, *PBITPOS to the
-+   bit position, and *PUNSIGNEDP to the signedness of the field.
-+   If the position of the field is variable, we store a tree
-+   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.
-+
-+   If any of the extraction expressions is volatile,
-+   we store 1 in *PVOLATILEP.  Otherwise we don't change that.
-+
-+   If the field is a bit-field, *PMODE is set to VOIDmode.  Otherwise, it
-+   is a mode that can be used to access the field.  In that case, *PBITSIZE
-+   is redundant.
-+
-+   If the field describes a variable-sized object, *PMODE is set to
-+   VOIDmode and *PBITSIZE is set to -1.  An access cannot be made in
-+   this case, but the address of the object can be found.  */
-+
-+tree
-+get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
-+                   punsignedp, pvolatilep)
-+     tree exp;
-+     HOST_WIDE_INT *pbitsize;
-+     HOST_WIDE_INT *pbitpos;
-+     tree *poffset;
-+     enum machine_mode *pmode;
-+     int *punsignedp;
-+     int *pvolatilep;
-+{
-+  tree size_tree = 0;
-+  enum machine_mode mode = VOIDmode;
-+  tree offset = size_zero_node;
-+  tree bit_offset = bitsize_zero_node;
-+  tree placeholder_ptr = 0;
-+  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)
-+    {
-+      size_tree = TREE_OPERAND (exp, 1);
-+      *punsignedp = TREE_UNSIGNED (exp);
-+    }
-+  else
-+    {
-+      mode = TYPE_MODE (TREE_TYPE (exp));
-+      *punsignedp = TREE_UNSIGNED (TREE_TYPE (exp));
-+
-+      if (mode == BLKmode)
-+      size_tree = TYPE_SIZE (TREE_TYPE (exp));
-+      else
-+      *pbitsize = GET_MODE_BITSIZE (mode);
-+    }
-+
-+  if (size_tree != 0)
-+    {
-+      if (! host_integerp (size_tree, 1))
-+      mode = BLKmode, *pbitsize = -1;
-+      else
-+      *pbitsize = tree_low_cst (size_tree, 1);
-+    }
-+
-+  /* Compute cumulative bit-offset for nested component-refs and array-refs,
-+     and find the ultimate containing object.  */
-+  while (1)
-+    {
-+      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 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 (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);
-+
-+        offset = size_binop (PLUS_EXPR, offset, this_offset);
-+        bit_offset = size_binop (PLUS_EXPR, bit_offset,
-+                                 DECL_FIELD_BIT_OFFSET (field));
-+
-+        /* ??? Right now we don't do anything with DECL_OFFSET_ALIGN.  */
-+      }
-+
-+      else if (TREE_CODE (exp) == ARRAY_REF
-+             || TREE_CODE (exp) == ARRAY_RANGE_REF)
-+      {
-+        tree index = TREE_OPERAND (exp, 1);
-+        tree array = TREE_OPERAND (exp, 0);
-+        tree domain = TYPE_DOMAIN (TREE_TYPE (array));
-+        tree low_bound = (domain ? TYPE_MIN_VALUE (domain) : 0);
-+        tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (array)));
-+
-+        /* 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));
-+
-+        /* If the index has a self-referential type, pass it to a
-+           WITH_RECORD_EXPR; if the component size is, pass our
-+           component to one.  */
-+        if (! TREE_CONSTANT (index)
-+            && contains_placeholder_p (index))
-+          index = build (WITH_RECORD_EXPR, TREE_TYPE (index), index, exp);
-+        if (! TREE_CONSTANT (unit_size)
-+            && contains_placeholder_p (unit_size))
-+          unit_size = build (WITH_RECORD_EXPR, sizetype, unit_size, array);
-+
-+        offset = size_binop (PLUS_EXPR, offset,
-+                             size_binop (MULT_EXPR,
-+                                         convert (sizetype, index),
-+                                         unit_size));
-+      }
-+
-+      else if (TREE_CODE (exp) == PLACEHOLDER_EXPR)
-+      {
-+        tree new = find_placeholder (exp, &placeholder_ptr);
-+
-+        /* If we couldn't find the replacement, return the PLACEHOLDER_EXPR.
-+           We might have been called from tree optimization where we
-+           haven't set up an object yet.  */
-+        if (new == 0)
-+          break;
-+        else
-+          exp = new;
-+
-+        continue;
-+      }
-+      else if (TREE_CODE (exp) != NON_LVALUE_EXPR
-+             && TREE_CODE (exp) != VIEW_CONVERT_EXPR
-+             && ! ((TREE_CODE (exp) == NOP_EXPR
-+                    || TREE_CODE (exp) == CONVERT_EXPR)
-+                   && (TYPE_MODE (TREE_TYPE (exp))
-+                       == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))))
-+      break;
-+
-+      /* If any reference in the chain is volatile, the effect is volatile.  */
-+      if (TREE_THIS_VOLATILE (exp))
-+      *pvolatilep = 1;
-+
-+      exp = TREE_OPERAND (exp, 0);
-+    }
-+
-+  /* 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;
-+  return exp;
-+}
-+
-+/* Return 1 if T is an expression that get_inner_reference handles.  */
-+
-+int
-+handled_component_p (t)
-+     tree t;
-+{
-+  switch (TREE_CODE (t))
-+    {
-+    case BIT_FIELD_REF:
-+    case COMPONENT_REF:
-+    case ARRAY_REF:
-+    case ARRAY_RANGE_REF:
-+    case NON_LVALUE_EXPR:
-+    case VIEW_CONVERT_EXPR:
-+      return 1;
-+
-+    case NOP_EXPR:
-+    case CONVERT_EXPR:
-+      return (TYPE_MODE (TREE_TYPE (t))
-+            == TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 0))));
-+
-+    default:
-+      return 0;
-+    }
-+}
-+\f
-+/* Given an rtx VALUE that may contain additions and multiplications, return
-+   an equivalent value that just refers to a register, memory, or constant.
-+   This is done by generating instructions to perform the arithmetic and
-+   returning a pseudo-register containing the value.
-+
-+   The returned value may be a REG, SUBREG, MEM or constant.  */
-+
-+rtx
-+force_operand (value, target)
-+     rtx value, target;
-+{
-+  rtx op1, op2;
-+  /* Use subtarget as the target for operand 0 of a binary operation.  */
-+  rtx subtarget = get_subtarget (target);
-+  enum rtx_code code = GET_CODE (value);
-+
-+  /* Check for a PIC address load.  */
-+  if ((code == PLUS || code == MINUS)
-+      && XEXP (value, 0) == pic_offset_table_rtx
-+      && (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
-+        || GET_CODE (XEXP (value, 1)) == LABEL_REF
-+        || GET_CODE (XEXP (value, 1)) == CONST))
-+    {
-+      if (!subtarget)
-+      subtarget = gen_reg_rtx (GET_MODE (value));
-+      emit_move_insn (subtarget, value);
-+      return subtarget;
-+    }
-+
-+  if (code == ZERO_EXTEND || code == SIGN_EXTEND)
-+    {
-+      if (!target)
-+      target = gen_reg_rtx (GET_MODE (value));
-+      convert_move (target, force_operand (XEXP (value, 0), NULL),
-+                  code == ZERO_EXTEND);
-+      return target;
-+    }
-+
-+  if (GET_RTX_CLASS (code) == '2' || GET_RTX_CLASS (code) == 'c')
-+    {
-+      op2 = XEXP (value, 1);
-+      if (!CONSTANT_P (op2) && !(GET_CODE (op2) == REG && op2 != subtarget))
-+      subtarget = 0;
-+      if (code == MINUS && GET_CODE (op2) == CONST_INT)
-+      {
-+        code = PLUS;
-+        op2 = negate_rtx (GET_MODE (value), op2);
-+      }
-+
-+      /* Check for an addition with OP2 a constant integer and our first
-+         operand a PLUS of a virtual register and something else.  In that
-+         case, we want to emit the sum of the virtual register and the
-+         constant first and then add the other value.  This allows virtual
-+         register instantiation to simply modify the constant rather than
-+         creating another one around this addition.  */
-+      if (code == PLUS && GET_CODE (op2) == CONST_INT
-+        && GET_CODE (XEXP (value, 0)) == PLUS
-+        && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
-+        && REGNO (XEXP (XEXP (value, 0), 0)) >= FIRST_VIRTUAL_REGISTER
-+        && REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER)
-+      {
-+        rtx temp = expand_simple_binop (GET_MODE (value), code,
-+                                        XEXP (XEXP (value, 0), 0), op2,
-+                                        subtarget, 0, OPTAB_LIB_WIDEN);
-+        return expand_simple_binop (GET_MODE (value), code, temp,
-+                                    force_operand (XEXP (XEXP (value,
-+                                                               0), 1), 0),
-+                                    target, 0, OPTAB_LIB_WIDEN);
-+      }
-+
-+      op1 = force_operand (XEXP (value, 0), subtarget);
-+      op2 = force_operand (op2, NULL_RTX);
-+      switch (code)
-+      {
-+      case MULT:
-+        return expand_mult (GET_MODE (value), op1, op2, target, 1);
-+      case DIV:
-+        if (!INTEGRAL_MODE_P (GET_MODE (value)))
-+          return expand_simple_binop (GET_MODE (value), code, op1, op2,
-+                                      target, 1, OPTAB_LIB_WIDEN);
-+        else
-+          return expand_divmod (0,
-+                                FLOAT_MODE_P (GET_MODE (value))
-+                                ? RDIV_EXPR : TRUNC_DIV_EXPR,
-+                                GET_MODE (value), op1, op2, target, 0);
-+        break;
-+      case MOD:
-+        return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
-+                              target, 0);
-+        break;
-+      case UDIV:
-+        return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), op1, op2,
-+                              target, 1);
-+        break;
-+      case UMOD:
-+        return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
-+                              target, 1);
-+        break;
-+      case ASHIFTRT:
-+        return expand_simple_binop (GET_MODE (value), code, op1, op2,
-+                                    target, 0, OPTAB_LIB_WIDEN);
-+        break;
-+      default:
-+        return expand_simple_binop (GET_MODE (value), code, op1, op2,
-+                                    target, 1, OPTAB_LIB_WIDEN);
-+      }
-+    }
-+  if (GET_RTX_CLASS (code) == '1')
-+    {
-+      op1 = force_operand (XEXP (value, 0), NULL_RTX);
-+      return expand_simple_unop (GET_MODE (value), code, op1, target, 0);
-+    }
-+
-+#ifdef INSN_SCHEDULING
-+  /* On machines that have insn scheduling, we want all memory reference to be
-+     explicit, so we need to deal with such paradoxical SUBREGs.  */
-+  if (GET_CODE (value) == SUBREG && GET_CODE (SUBREG_REG (value)) == MEM
-+      && (GET_MODE_SIZE (GET_MODE (value))
-+        > GET_MODE_SIZE (GET_MODE (SUBREG_REG (value)))))
-+    value
-+      = simplify_gen_subreg (GET_MODE (value),
-+                           force_reg (GET_MODE (SUBREG_REG (value)),
-+                                      force_operand (SUBREG_REG (value),
-+                                                     NULL_RTX)),
-+                           GET_MODE (SUBREG_REG (value)),
-+                           SUBREG_BYTE (value));
-+#endif
-+
-+  return value;
-+}
-+\f
-+/* Subroutine of expand_expr: return nonzero iff there is no way that
-+   EXP can reference X, which is being modified.  TOP_P is nonzero if this
-+   call is going to be used to determine whether we need a temporary
-+   for EXP, as opposed to a recursive call to this function.
-+
-+   It is always safe for this routine to return zero since it merely
-+   searches for optimization opportunities.  */
-+
-+int
-+safe_from_p (x, exp, top_p)
-+     rtx x;
-+     tree exp;
-+     int top_p;
-+{
-+  rtx exp_rtl = 0;
-+  int i, nops;
-+  static tree save_expr_list;
-+
-+  if (x == 0
-+      /* If EXP has varying size, we MUST use a target since we currently
-+       have no way of allocating temporaries of variable size
-+       (except for arrays that have TYPE_ARRAY_MAX_SIZE set).
-+       So we assume here that something at a higher level has prevented a
-+       clash.  This is somewhat bogus, but the best we can do.  Only
-+       do this when X is BLKmode and when we are at the top level.  */
-+      || (top_p && TREE_TYPE (exp) != 0 && COMPLETE_TYPE_P (TREE_TYPE (exp))
-+        && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST
-+        && (TREE_CODE (TREE_TYPE (exp)) != ARRAY_TYPE
-+            || TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)) == NULL_TREE
-+            || TREE_CODE (TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)))
-+            != INTEGER_CST)
-+        && GET_MODE (x) == BLKmode)
-+      /* If X is in the outgoing argument area, it is always safe.  */
-+      || (GET_CODE (x) == MEM
-+        && (XEXP (x, 0) == virtual_outgoing_args_rtx
-+            || (GET_CODE (XEXP (x, 0)) == PLUS
-+                && XEXP (XEXP (x, 0), 0) == virtual_outgoing_args_rtx))))
-+    return 1;
-+
-+  /* If this is a subreg of a hard register, declare it unsafe, otherwise,
-+     find the underlying pseudo.  */
-+  if (GET_CODE (x) == SUBREG)
-+    {
-+      x = SUBREG_REG (x);
-+      if (GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
-+      return 0;
-+    }
-+
-+  /* A SAVE_EXPR might appear many times in the expression passed to the
-+     top-level safe_from_p call, and if it has a complex subexpression,
-+     examining it multiple times could result in a combinatorial explosion.
-+     E.g. on an Alpha running at least 200MHz, a Fortran test case compiled
-+     with optimization took about 28 minutes to compile -- even though it was
-+     only a few lines long.  So we mark each SAVE_EXPR we see with TREE_PRIVATE
-+     and turn that off when we are done.  We keep a list of the SAVE_EXPRs
-+     we have processed.  Note that the only test of top_p was above.  */
-+
-+  if (top_p)
-+    {
-+      int rtn;
-+      tree t;
-+
-+      save_expr_list = 0;
-+
-+      rtn = safe_from_p (x, exp, 0);
-+
-+      for (t = save_expr_list; t != 0; t = TREE_CHAIN (t))
-+      TREE_PRIVATE (TREE_PURPOSE (t)) = 0;
-+
-+      return rtn;
-+    }
-+
-+  /* Now look at our tree code and possibly recurse.  */
-+  switch (TREE_CODE_CLASS (TREE_CODE (exp)))
-+    {
-+    case 'd':
-+      exp_rtl = DECL_RTL_IF_SET (exp);
-+      break;
-+
-+    case 'c':
-+      return 1;
-+
-+    case 'x':
-+      if (TREE_CODE (exp) == TREE_LIST)
-+      {
-+        while (1)
-+          {
-+            if (TREE_VALUE (exp) && !safe_from_p (x, TREE_VALUE (exp), 0))
-+              return 0;
-+            exp = TREE_CHAIN (exp);
-+            if (!exp)
-+              return 1;
-+            if (TREE_CODE (exp) != TREE_LIST)
-+              return safe_from_p (x, exp, 0);
-+          }
-+      }
-+      else if (TREE_CODE (exp) == ERROR_MARK)
-+      return 1;       /* An already-visited SAVE_EXPR? */
-+      else
-+      return 0;
-+
-+    case '2':
-+    case '<':
-+      if (!safe_from_p (x, TREE_OPERAND (exp, 1), 0))
-+      return 0;
-+      /* FALLTHRU */
-+
-+    case '1':
-+      return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
-+
-+    case 'e':
-+    case 'r':
-+      /* Now do code-specific tests.  EXP_RTL is set to any rtx we find in
-+       the expression.  If it is set, we conflict iff we are that rtx or
-+       both are in memory.  Otherwise, we check all operands of the
-+       expression recursively.  */
-+
-+      switch (TREE_CODE (exp))
-+      {
-+      case ADDR_EXPR:
-+        /* If the operand is static or we are static, we can't conflict.
-+           Likewise if we don't conflict with the operand at all.  */
-+        if (staticp (TREE_OPERAND (exp, 0))
-+            || TREE_STATIC (exp)
-+            || safe_from_p (x, TREE_OPERAND (exp, 0), 0))
-+          return 1;
-+
-+        /* Otherwise, the only way this can conflict is if we are taking
-+           the address of a DECL a that address if part of X, which is
-+           very rare.  */
-+        exp = TREE_OPERAND (exp, 0);
-+        if (DECL_P (exp))
-+          {
-+            if (!DECL_RTL_SET_P (exp)
-+                || GET_CODE (DECL_RTL (exp)) != MEM)
-+              return 0;
-+            else
-+              exp_rtl = XEXP (DECL_RTL (exp), 0);
-+          }
-+        break;
-+
-+      case INDIRECT_REF:
-+        if (GET_CODE (x) == MEM
-+            && alias_sets_conflict_p (MEM_ALIAS_SET (x),
-+                                      get_alias_set (exp)))
-+          return 0;
-+        break;
-+
-+      case CALL_EXPR:
-+        /* Assume that the call will clobber all hard registers and
-+           all of memory.  */
-+        if ((GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
-+            || GET_CODE (x) == MEM)
-+          return 0;
-+        break;
-+
-+      case RTL_EXPR:
-+        /* If a sequence exists, we would have to scan every instruction
-+           in the sequence to see if it was safe.  This is probably not
-+           worthwhile.  */
-+        if (RTL_EXPR_SEQUENCE (exp))
-+          return 0;
-+
-+        exp_rtl = RTL_EXPR_RTL (exp);
-+        break;
-+
-+      case WITH_CLEANUP_EXPR:
-+        exp_rtl = WITH_CLEANUP_EXPR_RTL (exp);
-+        break;
-+
-+      case CLEANUP_POINT_EXPR:
-+        return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
-+
-+      case SAVE_EXPR:
-+        exp_rtl = SAVE_EXPR_RTL (exp);
-+        if (exp_rtl)
-+          break;
-+
-+        /* If we've already scanned this, don't do it again.  Otherwise,
-+           show we've scanned it and record for clearing the flag if we're
-+           going on.  */
-+        if (TREE_PRIVATE (exp))
-+          return 1;
-+
-+        TREE_PRIVATE (exp) = 1;
-+        if (! safe_from_p (x, TREE_OPERAND (exp, 0), 0))
-+          {
-+            TREE_PRIVATE (exp) = 0;
-+            return 0;
-+          }
-+
-+        save_expr_list = tree_cons (exp, NULL_TREE, save_expr_list);
-+        return 1;
-+
-+      case BIND_EXPR:
-+        /* The only operand we look at is operand 1.  The rest aren't
-+           part of the expression.  */
-+        return safe_from_p (x, TREE_OPERAND (exp, 1), 0);
-+
-+      case METHOD_CALL_EXPR:
-+        /* This takes an rtx argument, but shouldn't appear here.  */
-+        abort ();
-+
-+      default:
-+        break;
-+      }
-+
-+      /* If we have an rtx, we do not need to scan our operands.  */
-+      if (exp_rtl)
-+      break;
-+
-+      nops = first_rtl_op (TREE_CODE (exp));
-+      for (i = 0; i < nops; i++)
-+      if (TREE_OPERAND (exp, i) != 0
-+          && ! safe_from_p (x, TREE_OPERAND (exp, i), 0))
-+        return 0;
-+
-+      /* If this is a language-specific tree code, it may require
-+       special handling.  */
-+      if ((unsigned int) TREE_CODE (exp)
-+        >= (unsigned int) LAST_AND_UNUSED_TREE_CODE
-+        && !(*lang_hooks.safe_from_p) (x, exp))
-+      return 0;
-+    }
-+
-+  /* If we have an rtl, find any enclosed object.  Then see if we conflict
-+     with it.  */
-+  if (exp_rtl)
-+    {
-+      if (GET_CODE (exp_rtl) == SUBREG)
-+      {
-+        exp_rtl = SUBREG_REG (exp_rtl);
-+        if (GET_CODE (exp_rtl) == REG
-+            && REGNO (exp_rtl) < FIRST_PSEUDO_REGISTER)
-+          return 0;
-+      }
-+
-+      /* If the rtl is X, then it is not safe.  Otherwise, it is unless both
-+       are memory and they conflict.  */
-+      return ! (rtx_equal_p (x, exp_rtl)
-+              || (GET_CODE (x) == MEM && GET_CODE (exp_rtl) == MEM
-+                  && true_dependence (exp_rtl, VOIDmode, x,
-+                                      rtx_addr_varies_p)));
-+    }
-+
-+  /* If we reach here, it is safe.  */
-+  return 1;
-+}
-+
-+/* Subroutine of expand_expr: return rtx if EXP is a
-+   variable or parameter; else return 0.  */
-+
-+static rtx
-+var_rtx (exp)
-+     tree exp;
-+{
-+  STRIP_NOPS (exp);
-+  switch (TREE_CODE (exp))
-+    {
-+    case PARM_DECL:
-+    case VAR_DECL:
-+      return DECL_RTL (exp);
-+    default:
-+      return 0;
-+    }
-+}
-+
-+#ifdef MAX_INTEGER_COMPUTATION_MODE
-+
-+void
-+check_max_integer_computation_mode (exp)
-+     tree exp;
-+{
-+  enum tree_code code;
-+  enum machine_mode mode;
-+
-+  /* Strip any NOPs that don't change the mode.  */
-+  STRIP_NOPS (exp);
-+  code = TREE_CODE (exp);
-+
-+  /* We must allow conversions of constants to MAX_INTEGER_COMPUTATION_MODE.  */
-+  if (code == NOP_EXPR
-+      && TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST)
-+    return;
-+
-+  /* First check the type of the overall operation.   We need only look at
-+     unary, binary and relational operations.  */
-+  if (TREE_CODE_CLASS (code) == '1'
-+      || TREE_CODE_CLASS (code) == '2'
-+      || TREE_CODE_CLASS (code) == '<')
-+    {
-+      mode = TYPE_MODE (TREE_TYPE (exp));
-+      if (GET_MODE_CLASS (mode) == MODE_INT
-+        && mode > MAX_INTEGER_COMPUTATION_MODE)
-+      internal_error ("unsupported wide integer operation");
-+    }
-+
-+  /* Check operand of a unary op.  */
-+  if (TREE_CODE_CLASS (code) == '1')
-+    {
-+      mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
-+      if (GET_MODE_CLASS (mode) == MODE_INT
-+        && mode > MAX_INTEGER_COMPUTATION_MODE)
-+      internal_error ("unsupported wide integer operation");
-+    }
-+
-+  /* Check operands of a binary/comparison op.  */
-+  if (TREE_CODE_CLASS (code) == '2' || TREE_CODE_CLASS (code) == '<')
-+    {
-+      mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
-+      if (GET_MODE_CLASS (mode) == MODE_INT
-+        && mode > MAX_INTEGER_COMPUTATION_MODE)
-+      internal_error ("unsupported wide integer operation");
-+
-+      mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 1)));
-+      if (GET_MODE_CLASS (mode) == MODE_INT
-+        && mode > MAX_INTEGER_COMPUTATION_MODE)
-+      internal_error ("unsupported wide integer operation");
-+    }
-+}
-+#endif
-+\f
-+/* Return the highest power of two that EXP is known to be a multiple of.
-+   This is used in updating alignment of MEMs in array references.  */
-+
-+static HOST_WIDE_INT
-+highest_pow2_factor (exp)
-+     tree exp;
-+{
-+  HOST_WIDE_INT c0, c1;
-+
-+  switch (TREE_CODE (exp))
-+    {
-+    case INTEGER_CST:
-+      /* We can find the lowest bit that's a one.  If the low
-+       HOST_BITS_PER_WIDE_INT bits are zero, return BIGGEST_ALIGNMENT.
-+       We need to handle this case since we can find it in a COND_EXPR,
-+       a MIN_EXPR, or a MAX_EXPR.  If the constant overlows, we have an
-+       erroneous program, so return BIGGEST_ALIGNMENT to avoid any
-+       later ICE.  */
-+      if (TREE_CONSTANT_OVERFLOW (exp))
-+      return BIGGEST_ALIGNMENT;
-+      else
-+      {
-+        /* Note: tree_low_cst is intentionally not used here,
-+           we don't care about the upper bits.  */
-+        c0 = TREE_INT_CST_LOW (exp);
-+        c0 &= -c0;
-+        return c0 ? c0 : BIGGEST_ALIGNMENT;
-+      }
-+      break;
-+
-+    case PLUS_EXPR:  case MINUS_EXPR:  case MIN_EXPR:  case MAX_EXPR:
-+      c0 = highest_pow2_factor (TREE_OPERAND (exp, 0));
-+      c1 = highest_pow2_factor (TREE_OPERAND (exp, 1));
-+      return MIN (c0, c1);
-+
-+    case MULT_EXPR:
-+      c0 = highest_pow2_factor (TREE_OPERAND (exp, 0));
-+      c1 = highest_pow2_factor (TREE_OPERAND (exp, 1));
-+      return c0 * c1;
-+
-+    case ROUND_DIV_EXPR:  case TRUNC_DIV_EXPR:  case FLOOR_DIV_EXPR:
-+    case CEIL_DIV_EXPR:
-+      if (integer_pow2p (TREE_OPERAND (exp, 1))
-+        && host_integerp (TREE_OPERAND (exp, 1), 1))
-+      {
-+        c0 = highest_pow2_factor (TREE_OPERAND (exp, 0));
-+        c1 = tree_low_cst (TREE_OPERAND (exp, 1), 1);
-+        return MAX (1, c0 / c1);
-+      }
-+      break;
-+
-+    case NON_LVALUE_EXPR:  case NOP_EXPR:  case CONVERT_EXPR:
-+    case SAVE_EXPR: case WITH_RECORD_EXPR:
-+      return highest_pow2_factor (TREE_OPERAND (exp, 0));
-+
-+    case COMPOUND_EXPR:
-+      return highest_pow2_factor (TREE_OPERAND (exp, 1));
-+
-+    case COND_EXPR:
-+      c0 = highest_pow2_factor (TREE_OPERAND (exp, 1));
-+      c1 = highest_pow2_factor (TREE_OPERAND (exp, 2));
-+      return MIN (c0, c1);
-+
-+    default:
-+      break;
-+    }
-+
-+  return 1;
-+}
-+
-+/* Similar, except that it is known that the expression must be a multiple
-+   of the alignment of TYPE.  */
-+
-+static HOST_WIDE_INT
-+highest_pow2_factor_for_type (type, exp)
-+     tree type;
-+     tree exp;
-+{
-+  HOST_WIDE_INT type_align, factor;
-+
-+  factor = highest_pow2_factor (exp);
-+  type_align = TYPE_ALIGN (type) / BITS_PER_UNIT;
-+  return MAX (factor, type_align);
-+}
-+\f
-+/* Return an object on the placeholder list that matches EXP, a
-+   PLACEHOLDER_EXPR.  An object "matches" if it is of the type of the
-+   PLACEHOLDER_EXPR or a pointer type to it.  For further information, see
-+   tree.def.  If no such object is found, return 0.  If PLIST is nonzero, it
-+   is a location which initially points to a starting location in the
-+   placeholder list (zero means start of the list) and where a pointer into
-+   the placeholder list at which the object is found is placed.  */
-+
-+tree
-+find_placeholder (exp, plist)
-+     tree exp;
-+     tree *plist;
-+{
-+  tree type = TREE_TYPE (exp);
-+  tree placeholder_expr;
-+
-+  for (placeholder_expr
-+       = plist && *plist ? TREE_CHAIN (*plist) : placeholder_list;
-+       placeholder_expr != 0;
-+       placeholder_expr = TREE_CHAIN (placeholder_expr))
-+    {
-+      tree need_type = TYPE_MAIN_VARIANT (type);
-+      tree elt;
-+
-+      /* Find the outermost reference that is of the type we want.  If none,
-+       see if any object has a type that is a pointer to the type we
-+       want.  */
-+      for (elt = TREE_PURPOSE (placeholder_expr); elt != 0;
-+         elt = ((TREE_CODE (elt) == COMPOUND_EXPR
-+                 || TREE_CODE (elt) == COND_EXPR)
-+                ? TREE_OPERAND (elt, 1)
-+                : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
-+                   || TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
-+                   || TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
-+                   || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
-+                ? TREE_OPERAND (elt, 0) : 0))
-+      if (TYPE_MAIN_VARIANT (TREE_TYPE (elt)) == need_type)
-+        {
-+          if (plist)
-+            *plist = placeholder_expr;
-+          return elt;
-+        }
-+
-+      for (elt = TREE_PURPOSE (placeholder_expr); elt != 0;
-+         elt
-+         = ((TREE_CODE (elt) == COMPOUND_EXPR
-+             || TREE_CODE (elt) == COND_EXPR)
-+            ? TREE_OPERAND (elt, 1)
-+            : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
-+               || TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
-+               || TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
-+               || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
-+            ? TREE_OPERAND (elt, 0) : 0))
-+      if (POINTER_TYPE_P (TREE_TYPE (elt))
-+          && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (elt)))
-+              == need_type))
-+        {
-+          if (plist)
-+            *plist = placeholder_expr;
-+          return build1 (INDIRECT_REF, need_type, elt);
-+        }
-+    }
-+
-+  return 0;
-+}
-+\f
-+/* expand_expr: generate code for computing expression EXP.
-+   An rtx for the computed value is returned.  The value is never null.
-+   In the case of a void EXP, const0_rtx is returned.
-+
-+   The value may be stored in TARGET if TARGET is nonzero.
-+   TARGET is just a suggestion; callers must assume that
-+   the rtx returned may not be the same as TARGET.
-+
-+   If TARGET is CONST0_RTX, it means that the value will be ignored.
-+
-+   If TMODE is not VOIDmode, it suggests generating the
-+   result in mode TMODE.  But this is done only when convenient.
-+   Otherwise, TMODE is ignored and the value generated in its natural mode.
-+   TMODE is just a suggestion; callers must assume that
-+   the rtx returned may not have mode TMODE.
-+
-+   Note that TARGET may have neither TMODE nor MODE.  In that case, it
-+   probably will not be used.
-+
-+   If MODIFIER is EXPAND_SUM then when EXP is an addition
-+   we can return an rtx of the form (MULT (REG ...) (CONST_INT ...))
-+   or a nest of (PLUS ...) and (MINUS ...) where the terms are
-+   products as above, or REG or MEM, or constant.
-+   Ordinarily in such cases we would output mul or add instructions
-+   and then return a pseudo reg containing the sum.
-+
-+   EXPAND_INITIALIZER is much like EXPAND_SUM except that
-+   it also marks a label as absolutely required (it can't be dead).
-+   It also makes a ZERO_EXTEND or SIGN_EXTEND instead of emitting extend insns.
-+   This is used for outputting expressions used in initializers.
-+
-+   EXPAND_CONST_ADDRESS says that it is okay to return a MEM
-+   with a constant address even if that address is not normally legitimate.
-+   EXPAND_INITIALIZER and EXPAND_SUM also have this effect.
-+
-+   EXPAND_STACK_PARM is used when expanding to a TARGET on the stack for
-+   a call parameter.  Such targets require special care as we haven't yet
-+   marked TARGET so that it's safe from being trashed by libcalls.  We
-+   don't want to use TARGET for anything but the final result;
-+   Intermediate values must go elsewhere.   Additionally, calls to
-+   emit_block_move will be flagged with BLOCK_OP_CALL_PARM.  */
-+
-+rtx
-+expand_expr (exp, target, tmode, modifier)
-+     tree exp;
-+     rtx target;
-+     enum machine_mode tmode;
-+     enum expand_modifier modifier;
-+{
-+  rtx op0, op1, temp;
-+  tree type = TREE_TYPE (exp);
-+  int unsignedp = TREE_UNSIGNED (type);
-+  enum machine_mode mode;
-+  enum tree_code code = TREE_CODE (exp);
-+  optab this_optab;
-+  rtx subtarget, original_target;
-+  int ignore;
-+  tree context;
-+
-+  /* Handle ERROR_MARK before anybody tries to access its type.  */
-+  if (TREE_CODE (exp) == ERROR_MARK || TREE_CODE (type) == ERROR_MARK)
-+    {
-+      op0 = CONST0_RTX (tmode);
-+      if (op0 != 0)
-+      return op0;
-+      return const0_rtx;
-+    }
-+
-+  mode = TYPE_MODE (type);
-+  /* Use subtarget as the target for operand 0 of a binary operation.  */
-+  subtarget = get_subtarget (target);
-+  original_target = target;
-+  ignore = (target == const0_rtx
-+          || ((code == NON_LVALUE_EXPR || code == NOP_EXPR
-+               || code == CONVERT_EXPR || code == REFERENCE_EXPR
-+               || code == COND_EXPR || code == VIEW_CONVERT_EXPR)
-+              && TREE_CODE (type) == VOID_TYPE));
-+
-+  /* If we are going to ignore this result, we need only do something
-+     if there is a side-effect somewhere in the expression.  If there
-+     is, short-circuit the most common cases here.  Note that we must
-+     not call expand_expr with anything but const0_rtx in case this
-+     is an initial expansion of a size that contains a PLACEHOLDER_EXPR.  */
-+
-+  if (ignore)
-+    {
-+      if (! TREE_SIDE_EFFECTS (exp))
-+      return const0_rtx;
-+
-+      /* Ensure we reference a volatile object even if value is ignored, but
-+       don't do this if all we are doing is taking its address.  */
-+      if (TREE_THIS_VOLATILE (exp)
-+        && TREE_CODE (exp) != FUNCTION_DECL
-+        && mode != VOIDmode && mode != BLKmode
-+        && modifier != EXPAND_CONST_ADDRESS)
-+      {
-+        temp = expand_expr (exp, NULL_RTX, VOIDmode, modifier);
-+        if (GET_CODE (temp) == MEM)
-+          temp = copy_to_reg (temp);
-+        return const0_rtx;
-+      }
-+
-+      if (TREE_CODE_CLASS (code) == '1' || code == COMPONENT_REF
-+        || code == INDIRECT_REF || code == BUFFER_REF)
-+      return expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
-+                          modifier);
-+
-+      else if (TREE_CODE_CLASS (code) == '2' || TREE_CODE_CLASS (code) == '<'
-+             || code == ARRAY_REF || code == ARRAY_RANGE_REF)
-+      {
-+        expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, modifier);
-+        expand_expr (TREE_OPERAND (exp, 1), const0_rtx, VOIDmode, modifier);
-+        return const0_rtx;
-+      }
-+      else if ((code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
-+             && ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
-+      /* If the second operand has no side effects, just evaluate
-+         the first.  */
-+      return expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
-+                          modifier);
-+      else if (code == BIT_FIELD_REF)
-+      {
-+        expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, modifier);
-+        expand_expr (TREE_OPERAND (exp, 1), const0_rtx, VOIDmode, modifier);
-+        expand_expr (TREE_OPERAND (exp, 2), const0_rtx, VOIDmode, modifier);
-+        return const0_rtx;
-+      }
-+
-+      target = 0;
-+    }
-+
-+#ifdef MAX_INTEGER_COMPUTATION_MODE
-+  /* Only check stuff here if the mode we want is different from the mode
-+     of the expression; if it's the same, check_max_integer_computiation_mode
-+     will handle it.  Do we really need to check this stuff at all?  */
-+
-+  if (target
-+      && GET_MODE (target) != mode
-+      && TREE_CODE (exp) != INTEGER_CST
-+      && TREE_CODE (exp) != PARM_DECL
-+      && TREE_CODE (exp) != ARRAY_REF
-+      && TREE_CODE (exp) != ARRAY_RANGE_REF
-+      && TREE_CODE (exp) != COMPONENT_REF
-+      && TREE_CODE (exp) != BIT_FIELD_REF
-+      && TREE_CODE (exp) != INDIRECT_REF
-+      && TREE_CODE (exp) != CALL_EXPR
-+      && TREE_CODE (exp) != VAR_DECL
-+      && TREE_CODE (exp) != RTL_EXPR)
-+    {
-+      enum machine_mode mode = GET_MODE (target);
-+
-+      if (GET_MODE_CLASS (mode) == MODE_INT
-+        && mode > MAX_INTEGER_COMPUTATION_MODE)
-+      internal_error ("unsupported wide integer operation");
-+    }
-+
-+  if (tmode != mode
-+      && TREE_CODE (exp) != INTEGER_CST
-+      && TREE_CODE (exp) != PARM_DECL
-+      && TREE_CODE (exp) != ARRAY_REF
-+      && TREE_CODE (exp) != ARRAY_RANGE_REF
-+      && TREE_CODE (exp) != COMPONENT_REF
-+      && TREE_CODE (exp) != BIT_FIELD_REF
-+      && TREE_CODE (exp) != INDIRECT_REF
-+      && TREE_CODE (exp) != VAR_DECL
-+      && TREE_CODE (exp) != CALL_EXPR
-+      && TREE_CODE (exp) != RTL_EXPR
-+      && GET_MODE_CLASS (tmode) == MODE_INT
-+      && tmode > MAX_INTEGER_COMPUTATION_MODE)
-+    internal_error ("unsupported wide integer operation");
-+
-+  check_max_integer_computation_mode (exp);
-+#endif
-+
-+  /* If will do cse, generate all results into pseudo registers
-+     since 1) that allows cse to find more things
-+     and 2) otherwise cse could produce an insn the machine
-+     cannot support.  And exception is a CONSTRUCTOR into a multi-word
-+     MEM: that's much more likely to be most efficient into the MEM.  */
-+
-+  if (! cse_not_expected && mode != BLKmode && target
-+      && (GET_CODE (target) != REG || REGNO (target) < FIRST_PSEUDO_REGISTER)
-+      && ! (code == CONSTRUCTOR && GET_MODE_SIZE (mode) > UNITS_PER_WORD))
-+    target = 0;
-+
-+  switch (code)
-+    {
-+    case LABEL_DECL:
-+      {
-+      tree function = decl_function_context (exp);
-+      /* Handle using a label in a containing function.  */
-+      if (function != current_function_decl
-+          && function != inline_function_decl && function != 0)
-+        {
-+          struct function *p = find_function_data (function);
-+          p->expr->x_forced_labels
-+            = gen_rtx_EXPR_LIST (VOIDmode, label_rtx (exp),
-+                                 p->expr->x_forced_labels);
-+        }
-+      else
-+        {
-+          if (modifier == EXPAND_INITIALIZER)
-+            forced_labels = gen_rtx_EXPR_LIST (VOIDmode,
-+                                               label_rtx (exp),
-+                                               forced_labels);
-+        }
-+
-+      temp = gen_rtx_MEM (FUNCTION_MODE,
-+                          gen_rtx_LABEL_REF (Pmode, label_rtx (exp)));
-+      if (function != current_function_decl
-+          && function != inline_function_decl && function != 0)
-+        LABEL_REF_NONLOCAL_P (XEXP (temp, 0)) = 1;
-+      return temp;
-+      }
-+
-+    case PARM_DECL:
-+      if (!DECL_RTL_SET_P (exp))
-+      {
-+        error_with_decl (exp, "prior parameter's size depends on `%s'");
-+        return CONST0_RTX (mode);
-+      }
-+
-+      /* ... fall through ...  */
-+
-+    case VAR_DECL:
-+      /* If a static var's type was incomplete when the decl was written,
-+       but the type is complete now, lay out the decl now.  */
-+      if (DECL_SIZE (exp) == 0
-+        && COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (TREE_TYPE (exp))
-+        && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
-+      layout_decl (exp, 0);
-+
-+      /* ... fall through ...  */
-+
-+    case FUNCTION_DECL:
-+    case RESULT_DECL:
-+      if (DECL_RTL (exp) == 0)
-+      abort ();
-+
-+      /* Ensure variable marked as used even if it doesn't go through
-+       a parser.  If it hasn't be used yet, write out an external
-+       definition.  */
-+      if (! TREE_USED (exp))
-+      {
-+        assemble_external (exp);
-+        TREE_USED (exp) = 1;
-+      }
-+
-+      /* Show we haven't gotten RTL for this yet.  */
-+      temp = 0;
-+
-+      /* Handle variables inherited from containing functions.  */
-+      context = decl_function_context (exp);
-+
-+      /* We treat inline_function_decl as an alias for the current function
-+       because that is the inline function whose vars, types, etc.
-+       are being merged into the current function.
-+       See expand_inline_function.  */
-+
-+      if (context != 0 && context != current_function_decl
-+        && context != inline_function_decl
-+        /* If var is static, we don't need a static chain to access it.  */
-+        && ! (GET_CODE (DECL_RTL (exp)) == MEM
-+              && CONSTANT_P (XEXP (DECL_RTL (exp), 0))))
-+      {
-+        rtx addr;
-+
-+        /* Mark as non-local and addressable.  */
-+        DECL_NONLOCAL (exp) = 1;
-+        if (DECL_NO_STATIC_CHAIN (current_function_decl))
-+          abort ();
-+        (*lang_hooks.mark_addressable) (exp);
-+        if (GET_CODE (DECL_RTL (exp)) != MEM)
-+          abort ();
-+        addr = XEXP (DECL_RTL (exp), 0);
-+        if (GET_CODE (addr) == MEM)
-+          addr
-+            = replace_equiv_address (addr,
-+                                     fix_lexical_addr (XEXP (addr, 0), exp));
-+        else
-+          addr = fix_lexical_addr (addr, exp);
-+
-+        temp = replace_equiv_address (DECL_RTL (exp), addr);
-+      }
-+
-+      /* This is the case of an array whose size is to be determined
-+       from its initializer, while the initializer is still being parsed.
-+       See expand_decl.  */
-+
-+      else if (GET_CODE (DECL_RTL (exp)) == MEM
-+             && GET_CODE (XEXP (DECL_RTL (exp), 0)) == REG)
-+      temp = validize_mem (DECL_RTL (exp));
-+
-+      /* If DECL_RTL is memory, we are in the normal case and either
-+       the address is not valid or it is not a register and -fforce-addr
-+       is specified, get the address into a register.  */
-+
-+      else if (GET_CODE (DECL_RTL (exp)) == MEM
-+             && modifier != EXPAND_CONST_ADDRESS
-+             && modifier != EXPAND_SUM
-+             && modifier != EXPAND_INITIALIZER
-+             && (! memory_address_p (DECL_MODE (exp),
-+                                     XEXP (DECL_RTL (exp), 0))
-+                 || (flag_force_addr
-+                     && GET_CODE (XEXP (DECL_RTL (exp), 0)) != REG)))
-+      temp = replace_equiv_address (DECL_RTL (exp),
-+                                    copy_rtx (XEXP (DECL_RTL (exp), 0)));
-+
-+      /* If we got something, return it.  But first, set the alignment
-+       if the address is a register.  */
-+      if (temp != 0)
-+      {
-+        if (GET_CODE (temp) == MEM && GET_CODE (XEXP (temp, 0)) == REG)
-+          mark_reg_pointer (XEXP (temp, 0), DECL_ALIGN (exp));
-+
-+        return temp;
-+      }
-+
-+      /* If the mode of DECL_RTL does not match that of the decl, it
-+       must be a promoted value.  We return a SUBREG of the wanted mode,
-+       but mark it so that we know that it was already extended.  */
-+
-+      if (GET_CODE (DECL_RTL (exp)) == REG
-+        && GET_MODE (DECL_RTL (exp)) != DECL_MODE (exp))
-+      {
-+        /* Get the signedness used for this variable.  Ensure we get the
-+           same mode we got when the variable was declared.  */
-+        if (GET_MODE (DECL_RTL (exp))
-+            != promote_mode (type, DECL_MODE (exp), &unsignedp,
-+                             (TREE_CODE (exp) == RESULT_DECL ? 1 : 0)))
-+          abort ();
-+
-+        temp = gen_lowpart_SUBREG (mode, DECL_RTL (exp));
-+        SUBREG_PROMOTED_VAR_P (temp) = 1;
-+        SUBREG_PROMOTED_UNSIGNED_SET (temp, unsignedp);
-+        return temp;
-+      }
-+
-+      return DECL_RTL (exp);
-+
-+    case INTEGER_CST:
-+      temp = immed_double_const (TREE_INT_CST_LOW (exp),
-+                               TREE_INT_CST_HIGH (exp), mode);
-+
-+      /* ??? If overflow is set, fold will have done an incomplete job,
-+       which can result in (plus xx (const_int 0)), which can get
-+       simplified by validate_replace_rtx during virtual register
-+       instantiation, which can result in unrecognizable insns.
-+       Avoid this by forcing all overflows into registers.  */
-+      if (TREE_CONSTANT_OVERFLOW (exp)
-+        && modifier != EXPAND_INITIALIZER)
-+      temp = force_reg (mode, temp);
-+
-+      return temp;
-+
-+    case VECTOR_CST:
-+      return const_vector_from_tree (exp);
-+
-+    case CONST_DECL:
-+      return expand_expr (DECL_INITIAL (exp), target, VOIDmode, modifier);
-+
-+    case REAL_CST:
-+      /* If optimized, generate immediate CONST_DOUBLE
-+       which will be turned into memory by reload if necessary.
-+
-+       We used to force a register so that loop.c could see it.  But
-+       this does not allow gen_* patterns to perform optimizations with
-+       the constants.  It also produces two insns in cases like "x = 1.0;".
-+       On most machines, floating-point constants are not permitted in
-+       many insns, so we'd end up copying it to a register in any case.
-+
-+       Now, we do the copying in expand_binop, if appropriate.  */
-+      return CONST_DOUBLE_FROM_REAL_VALUE (TREE_REAL_CST (exp),
-+                                         TYPE_MODE (TREE_TYPE (exp)));
-+
-+    case COMPLEX_CST:
-+    case STRING_CST:
-+      if (! TREE_CST_RTL (exp))
-+      output_constant_def (exp, 1);
-+
-+      /* TREE_CST_RTL probably contains a constant address.
-+       On RISC machines where a constant address isn't valid,
-+       make some insns to get that address into a register.  */
-+      if (GET_CODE (TREE_CST_RTL (exp)) == MEM
-+        && modifier != EXPAND_CONST_ADDRESS
-+        && modifier != EXPAND_INITIALIZER
-+        && modifier != EXPAND_SUM
-+        && (! memory_address_p (mode, XEXP (TREE_CST_RTL (exp), 0))
-+            || (flag_force_addr
-+                && GET_CODE (XEXP (TREE_CST_RTL (exp), 0)) != REG)))
-+      return replace_equiv_address (TREE_CST_RTL (exp),
-+                                    copy_rtx (XEXP (TREE_CST_RTL (exp), 0)));
-+      return TREE_CST_RTL (exp);
-+
-+    case EXPR_WITH_FILE_LOCATION:
-+      {
-+      rtx to_return;
-+      const char *saved_input_filename = input_filename;
-+      int saved_lineno = lineno;
-+      input_filename = EXPR_WFL_FILENAME (exp);
-+      lineno = EXPR_WFL_LINENO (exp);
-+      if (EXPR_WFL_EMIT_LINE_NOTE (exp))
-+        emit_line_note (input_filename, lineno);
-+      /* Possibly avoid switching back and forth here.  */
-+      to_return = expand_expr (EXPR_WFL_NODE (exp), target, tmode, modifier);
-+      input_filename = saved_input_filename;
-+      lineno = saved_lineno;
-+      return to_return;
-+      }
-+
-+    case SAVE_EXPR:
-+      context = decl_function_context (exp);
-+
-+      /* If this SAVE_EXPR was at global context, assume we are an
-+       initialization function and move it into our context.  */
-+      if (context == 0)
-+      SAVE_EXPR_CONTEXT (exp) = current_function_decl;
-+
-+      /* We treat inline_function_decl as an alias for the current function
-+       because that is the inline function whose vars, types, etc.
-+       are being merged into the current function.
-+       See expand_inline_function.  */
-+      if (context == current_function_decl || context == inline_function_decl)
-+      context = 0;
-+
-+      /* If this is non-local, handle it.  */
-+      if (context)
-+      {
-+        /* The following call just exists to abort if the context is
-+           not of a containing function.  */
-+        find_function_data (context);
-+
-+        temp = SAVE_EXPR_RTL (exp);
-+        if (temp && GET_CODE (temp) == REG)
-+          {
-+            put_var_into_stack (exp, /*rescan=*/true);
-+            temp = SAVE_EXPR_RTL (exp);
-+          }
-+        if (temp == 0 || GET_CODE (temp) != MEM)
-+          abort ();
-+        return
-+          replace_equiv_address (temp,
-+                                 fix_lexical_addr (XEXP (temp, 0), exp));
-+      }
-+      if (SAVE_EXPR_RTL (exp) == 0)
-+      {
-+        if (mode == VOIDmode)
-+          temp = const0_rtx;
-+        else
-+          temp = assign_temp (build_qualified_type (type,
-+                                                    (TYPE_QUALS (type)
-+                                                     | TYPE_QUAL_CONST)),
-+                              3, 0, 0);
-+
-+        SAVE_EXPR_RTL (exp) = temp;
-+        if (!optimize && GET_CODE (temp) == REG)
-+          save_expr_regs = gen_rtx_EXPR_LIST (VOIDmode, temp,
-+                                              save_expr_regs);
-+
-+        /* If the mode of TEMP does not match that of the expression, it
-+           must be a promoted value.  We pass store_expr a SUBREG of the
-+           wanted mode but mark it so that we know that it was already
-+           extended.  */
-+
-+        if (GET_CODE (temp) == REG && GET_MODE (temp) != mode)
-+          {
-+            temp = gen_lowpart_SUBREG (mode, SAVE_EXPR_RTL (exp));
-+            promote_mode (type, mode, &unsignedp, 0);
-+            SUBREG_PROMOTED_VAR_P (temp) = 1;
-+            SUBREG_PROMOTED_UNSIGNED_SET (temp, unsignedp);
-+          }
-+
-+        if (temp == const0_rtx)
-+          expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
-+        else
-+          store_expr (TREE_OPERAND (exp, 0), temp,
-+                      modifier == EXPAND_STACK_PARM ? 2 : 0);
-+
-+        TREE_USED (exp) = 1;
-+      }
-+
-+      /* If the mode of SAVE_EXPR_RTL does not match that of the expression, it
-+       must be a promoted value.  We return a SUBREG of the wanted mode,
-+       but mark it so that we know that it was already extended.  */
-+
-+      if (GET_CODE (SAVE_EXPR_RTL (exp)) == REG
-+        && GET_MODE (SAVE_EXPR_RTL (exp)) != mode)
-+      {
-+        /* Compute the signedness and make the proper SUBREG.  */
-+        promote_mode (type, mode, &unsignedp, 0);
-+        temp = gen_lowpart_SUBREG (mode, SAVE_EXPR_RTL (exp));
-+        SUBREG_PROMOTED_VAR_P (temp) = 1;
-+        SUBREG_PROMOTED_UNSIGNED_SET (temp, unsignedp);
-+        return temp;
-+      }
-+
-+      return SAVE_EXPR_RTL (exp);
-+
-+    case UNSAVE_EXPR:
-+      {
-+      rtx temp;
-+      temp = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
-+      TREE_OPERAND (exp, 0)
-+        = (*lang_hooks.unsave_expr_now) (TREE_OPERAND (exp, 0));
-+      return temp;
-+      }
-+
-+    case PLACEHOLDER_EXPR:
-+      {
-+      tree old_list = placeholder_list;
-+      tree placeholder_expr = 0;
-+
-+      exp = find_placeholder (exp, &placeholder_expr);
-+      if (exp == 0)
-+        abort ();
-+
-+      placeholder_list = TREE_CHAIN (placeholder_expr);
-+      temp = expand_expr (exp, original_target, tmode, modifier);
-+      placeholder_list = old_list;
-+      return temp;
-+      }
-+
-+    case WITH_RECORD_EXPR:
-+      /* Put the object on the placeholder list, expand our first operand,
-+       and pop the list.  */
-+      placeholder_list = tree_cons (TREE_OPERAND (exp, 1), NULL_TREE,
-+                                  placeholder_list);
-+      target = expand_expr (TREE_OPERAND (exp, 0), original_target, tmode,
-+                          modifier);
-+      placeholder_list = TREE_CHAIN (placeholder_list);
-+      return target;
-+
-+    case GOTO_EXPR:
-+      if (TREE_CODE (TREE_OPERAND (exp, 0)) == LABEL_DECL)
-+      expand_goto (TREE_OPERAND (exp, 0));
-+      else
-+      expand_computed_goto (TREE_OPERAND (exp, 0));
-+      return const0_rtx;
-+
-+    case EXIT_EXPR:
-+      expand_exit_loop_if_false (NULL,
-+                               invert_truthvalue (TREE_OPERAND (exp, 0)));
-+      return const0_rtx;
-+
-+    case LABELED_BLOCK_EXPR:
-+      if (LABELED_BLOCK_BODY (exp))
-+      expand_expr_stmt_value (LABELED_BLOCK_BODY (exp), 0, 1);
-+      /* Should perhaps use expand_label, but this is simpler and safer.  */
-+      do_pending_stack_adjust ();
-+      emit_label (label_rtx (LABELED_BLOCK_LABEL (exp)));
-+      return const0_rtx;
-+
-+    case EXIT_BLOCK_EXPR:
-+      if (EXIT_BLOCK_RETURN (exp))
-+      sorry ("returned value in block_exit_expr");
-+      expand_goto (LABELED_BLOCK_LABEL (EXIT_BLOCK_LABELED_BLOCK (exp)));
-+      return const0_rtx;
-+
-+    case LOOP_EXPR:
-+      push_temp_slots ();
-+      expand_start_loop (1);
-+      expand_expr_stmt_value (TREE_OPERAND (exp, 0), 0, 1);
-+      expand_end_loop ();
-+      pop_temp_slots ();
-+
-+      return const0_rtx;
-+
-+    case BIND_EXPR:
-+      {
-+      tree vars = TREE_OPERAND (exp, 0);
-+      int vars_need_expansion = 0;
-+
-+      /* Need to open a binding contour here because
-+         if there are any cleanups they must be contained here.  */
-+      expand_start_bindings (2);
-+
-+      /* Mark the corresponding BLOCK for output in its proper place.  */
-+      if (TREE_OPERAND (exp, 2) != 0
-+          && ! TREE_USED (TREE_OPERAND (exp, 2)))
-+        (*lang_hooks.decls.insert_block) (TREE_OPERAND (exp, 2));
-+
-+      /* If VARS have not yet been expanded, expand them now.  */
-+      while (vars)
-+        {
-+          if (!DECL_RTL_SET_P (vars))
-+            {
-+              vars_need_expansion = 1;
-+              expand_decl (vars);
-+            }
-+          expand_decl_init (vars);
-+          vars = TREE_CHAIN (vars);
-+        }
-+
-+      temp = expand_expr (TREE_OPERAND (exp, 1), target, tmode, modifier);
-+
-+      expand_end_bindings (TREE_OPERAND (exp, 0), 0, 0);
-+
-+      return temp;
-+      }
-+
-+    case RTL_EXPR:
-+      if (RTL_EXPR_SEQUENCE (exp))
-+      {
-+        if (RTL_EXPR_SEQUENCE (exp) == const0_rtx)
-+          abort ();
-+        emit_insn (RTL_EXPR_SEQUENCE (exp));
-+        RTL_EXPR_SEQUENCE (exp) = const0_rtx;
-+      }
-+      preserve_rtl_expr_result (RTL_EXPR_RTL (exp));
-+      free_temps_for_rtl_expr (exp);
-+      return RTL_EXPR_RTL (exp);
-+
-+    case CONSTRUCTOR:
-+      /* If we don't need the result, just ensure we evaluate any
-+       subexpressions.  */
-+      if (ignore)
-+      {
-+        tree elt;
-+
-+        for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
-+          expand_expr (TREE_VALUE (elt), const0_rtx, VOIDmode, 0);
-+
-+        return const0_rtx;
-+      }
-+
-+      /* All elts simple constants => refer to a constant in memory.  But
-+       if this is a non-BLKmode mode, let it store a field at a time
-+       since that should make a CONST_INT or CONST_DOUBLE when we
-+       fold.  Likewise, if we have a target we can use, it is best to
-+       store directly into the target unless the type is large enough
-+       that memcpy will be used.  If we are making an initializer and
-+       all operands are constant, put it in memory as well.
-+
-+      FIXME: Avoid trying to fill vector constructors piece-meal.
-+      Output them with output_constant_def below unless we're sure
-+      they're zeros.  This should go away when vector initializers
-+      are treated like VECTOR_CST instead of arrays.
-+      */
-+      else if ((TREE_STATIC (exp)
-+              && ((mode == BLKmode
-+                   && ! (target != 0 && safe_from_p (target, exp, 1)))
-+                  || TREE_ADDRESSABLE (exp)
-+                  || (host_integerp (TYPE_SIZE_UNIT (type), 1)
-+                      && (! MOVE_BY_PIECES_P
-+                          (tree_low_cst (TYPE_SIZE_UNIT (type), 1),
-+                           TYPE_ALIGN (type)))
-+                      && ((TREE_CODE (type) == VECTOR_TYPE
-+                           && !is_zeros_p (exp))
-+                          || ! mostly_zeros_p (exp)))))
-+             || (modifier == EXPAND_INITIALIZER && TREE_CONSTANT (exp)))
-+      {
-+        rtx constructor = output_constant_def (exp, 1);
-+
-+        if (modifier != EXPAND_CONST_ADDRESS
-+            && modifier != EXPAND_INITIALIZER
-+            && modifier != EXPAND_SUM)
-+          constructor = validize_mem (constructor);
-+
-+        return constructor;
-+      }
-+      else
-+      {
-+        /* Handle calls that pass values in multiple non-contiguous
-+           locations.  The Irix 6 ABI has examples of this.  */
-+        if (target == 0 || ! safe_from_p (target, exp, 1)
-+            || GET_CODE (target) == PARALLEL
-+            || modifier == EXPAND_STACK_PARM)
-+          target
-+            = assign_temp (build_qualified_type (type,
-+                                                 (TYPE_QUALS (type)
-+                                                  | (TREE_READONLY (exp)
-+                                                     * TYPE_QUAL_CONST))),
-+                           0, TREE_ADDRESSABLE (exp), 1);
-+
-+        store_constructor (exp, target, 0, int_expr_size (exp));
-+        return target;
-+      }
-+
-+    case INDIRECT_REF:
-+      {
-+      tree exp1 = TREE_OPERAND (exp, 0);
-+      tree index;
-+      tree string = string_constant (exp1, &index);
-+
-+      /* Try to optimize reads from const strings.  */
-+      if (string
-+          && TREE_CODE (string) == STRING_CST
-+          && TREE_CODE (index) == INTEGER_CST
-+          && compare_tree_int (index, TREE_STRING_LENGTH (string)) < 0
-+          && GET_MODE_CLASS (mode) == MODE_INT
-+          && GET_MODE_SIZE (mode) == 1
-+          && modifier != EXPAND_WRITE)
-+        return gen_int_mode (TREE_STRING_POINTER (string)
-+                             [TREE_INT_CST_LOW (index)], mode);
-+
-+      op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
-+      op0 = memory_address (mode, op0);
-+      temp = gen_rtx_MEM (mode, op0);
-+      set_mem_attributes (temp, exp, 0);
-+
-+      /* If we are writing to this object and its type is a record with
-+         readonly fields, we must mark it as readonly so it will
-+         conflict with readonly references to those fields.  */
-+      if (modifier == EXPAND_WRITE && readonly_fields_p (type))
-+        RTX_UNCHANGING_P (temp) = 1;
-+
-+      return temp;
-+      }
-+
-+    case ARRAY_REF:
-+      if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) != ARRAY_TYPE)
-+      abort ();
-+
-+      {
-+      tree array = TREE_OPERAND (exp, 0);
-+      tree domain = TYPE_DOMAIN (TREE_TYPE (array));
-+      tree low_bound = domain ? TYPE_MIN_VALUE (domain) : integer_zero_node;
-+      tree index = convert (sizetype, TREE_OPERAND (exp, 1));
-+      HOST_WIDE_INT i;
-+
-+      /* 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!)  */
-+
-+      if (! integer_zerop (low_bound))
-+        index = size_diffop (index, convert (sizetype, low_bound));
-+
-+      /* Fold an expression like: "foo"[2].
-+         This is not done in fold so it won't happen inside &.
-+         Don't fold if this is for wide characters since it's too
-+         difficult to do correctly and this is a very rare case.  */
-+
-+      if (modifier != EXPAND_CONST_ADDRESS
-+          && modifier != EXPAND_INITIALIZER
-+          && modifier != EXPAND_MEMORY
-+          && TREE_CODE (array) == STRING_CST
-+          && TREE_CODE (index) == INTEGER_CST
-+          && compare_tree_int (index, TREE_STRING_LENGTH (array)) < 0
-+          && GET_MODE_CLASS (mode) == MODE_INT
-+          && GET_MODE_SIZE (mode) == 1)
-+        return gen_int_mode (TREE_STRING_POINTER (array)
-+                             [TREE_INT_CST_LOW (index)], mode);
-+
-+      /* If this is a constant index into a constant array,
-+         just get the value from the array.  Handle both the cases when
-+         we have an explicit constructor and when our operand is a variable
-+         that was declared const.  */
-+
-+      if (modifier != EXPAND_CONST_ADDRESS
-+          && modifier != EXPAND_INITIALIZER
-+          && modifier != EXPAND_MEMORY
-+          && TREE_CODE (array) == CONSTRUCTOR
-+          && ! TREE_SIDE_EFFECTS (array)
-+          && TREE_CODE (index) == INTEGER_CST
-+          && 0 > compare_tree_int (index,
-+                                   list_length (CONSTRUCTOR_ELTS
-+                                                (TREE_OPERAND (exp, 0)))))
-+        {
-+          tree elem;
-+
-+          for (elem = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0)),
-+               i = TREE_INT_CST_LOW (index);
-+               elem != 0 && i != 0; i--, elem = TREE_CHAIN (elem))
-+            ;
-+
-+          if (elem)
-+            return expand_expr (fold (TREE_VALUE (elem)), target, tmode,
-+                                modifier);
-+        }
-+
-+      else if (optimize >= 1
-+               && modifier != EXPAND_CONST_ADDRESS
-+               && modifier != EXPAND_INITIALIZER
-+               && modifier != EXPAND_MEMORY
-+               && TREE_READONLY (array) && ! TREE_SIDE_EFFECTS (array)
-+               && TREE_CODE (array) == VAR_DECL && DECL_INITIAL (array)
-+               && TREE_CODE (DECL_INITIAL (array)) != ERROR_MARK)
-+        {
-+          if (TREE_CODE (index) == INTEGER_CST)
-+            {
-+              tree init = DECL_INITIAL (array);
-+
-+              if (TREE_CODE (init) == CONSTRUCTOR)
-+                {
-+                  tree elem;
-+
-+                  for (elem = CONSTRUCTOR_ELTS (init);
-+                       (elem
-+                        && !tree_int_cst_equal (TREE_PURPOSE (elem), index));
-+                       elem = TREE_CHAIN (elem))
-+                    ;
-+
-+                  if (elem && !TREE_SIDE_EFFECTS (TREE_VALUE (elem)))
-+                    return expand_expr (fold (TREE_VALUE (elem)), target,
-+                                        tmode, modifier);
-+                }
-+              else if (TREE_CODE (init) == STRING_CST
-+                       && 0 > compare_tree_int (index,
-+                                                TREE_STRING_LENGTH (init)))
-+                {
-+                  tree type = TREE_TYPE (TREE_TYPE (init));
-+                  enum machine_mode mode = TYPE_MODE (type);
-+
-+                  if (GET_MODE_CLASS (mode) == MODE_INT
-+                      && GET_MODE_SIZE (mode) == 1)
-+                    return gen_int_mode (TREE_STRING_POINTER (init)
-+                                         [TREE_INT_CST_LOW (index)], mode);
-+                }
-+            }
-+        }
-+      }
-+      /* Fall through.  */
-+
-+    case COMPONENT_REF:
-+    case BIT_FIELD_REF:
-+    case ARRAY_RANGE_REF:
-+      /* If the operand is a CONSTRUCTOR, we can just extract the
-+       appropriate field if it is present.  Don't do this if we have
-+       already written the data since we want to refer to that copy
-+       and varasm.c assumes that's what we'll do.  */
-+      if (code == COMPONENT_REF
-+        && TREE_CODE (TREE_OPERAND (exp, 0)) == CONSTRUCTOR
-+        && TREE_CST_RTL (TREE_OPERAND (exp, 0)) == 0)
-+      {
-+        tree elt;
-+
-+        for (elt = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0)); elt;
-+             elt = TREE_CHAIN (elt))
-+          if (TREE_PURPOSE (elt) == TREE_OPERAND (exp, 1)
-+              /* We can normally use the value of the field in the
-+                 CONSTRUCTOR.  However, if this is a bitfield in
-+                 an integral mode that we can fit in a HOST_WIDE_INT,
-+                 we must mask only the number of bits in the bitfield,
-+                 since this is done implicitly by the constructor.  If
-+                 the bitfield does not meet either of those conditions,
-+                 we can't do this optimization.  */
-+              && (! DECL_BIT_FIELD (TREE_PURPOSE (elt))
-+                  || ((GET_MODE_CLASS (DECL_MODE (TREE_PURPOSE (elt)))
-+                       == MODE_INT)
-+                      && (GET_MODE_BITSIZE (DECL_MODE (TREE_PURPOSE (elt)))
-+                          <= HOST_BITS_PER_WIDE_INT))))
-+            {
-+              if (DECL_BIT_FIELD (TREE_PURPOSE (elt))
-+                  && modifier == EXPAND_STACK_PARM)
-+                target = 0;
-+              op0 = expand_expr (TREE_VALUE (elt), target, tmode, modifier);
-+              if (DECL_BIT_FIELD (TREE_PURPOSE (elt)))
-+                {
-+                  HOST_WIDE_INT bitsize
-+                    = TREE_INT_CST_LOW (DECL_SIZE (TREE_PURPOSE (elt)));
-+                  enum machine_mode imode
-+                    = TYPE_MODE (TREE_TYPE (TREE_PURPOSE (elt)));
-+
-+                  if (TREE_UNSIGNED (TREE_TYPE (TREE_PURPOSE (elt))))
-+                    {
-+                      op1 = GEN_INT (((HOST_WIDE_INT) 1 << bitsize) - 1);
-+                      op0 = expand_and (imode, op0, op1, target);
-+                    }
-+                  else
-+                    {
-+                      tree count
-+                        = build_int_2 (GET_MODE_BITSIZE (imode) - bitsize,
-+                                       0);
-+
-+                      op0 = expand_shift (LSHIFT_EXPR, imode, op0, count,
-+                                          target, 0);
-+                      op0 = expand_shift (RSHIFT_EXPR, imode, op0, count,
-+                                          target, 0);
-+                    }
-+                }
-+
-+              return op0;
-+            }
-+      }
-+
-+      {
-+      enum machine_mode mode1;
-+      HOST_WIDE_INT bitsize, bitpos;
-+      tree offset;
-+      int volatilep = 0;
-+      tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset,
-+                                      &mode1, &unsignedp, &volatilep);
-+      rtx orig_op0;
-+
-+      /* If we got back the original object, something is wrong.  Perhaps
-+         we are evaluating an expression too early.  In any event, don't
-+         infinitely recurse.  */
-+      if (tem == exp)
-+        abort ();
-+
-+      /* If TEM's type is a union of variable size, pass TARGET to the inner
-+         computation, since it will need a temporary and TARGET is known
-+         to have to do.  This occurs in unchecked conversion in Ada.  */
-+
-+      orig_op0 = op0
-+        = expand_expr (tem,
-+                       (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
-+                        && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
-+                            != INTEGER_CST)
-+                        && modifier != EXPAND_STACK_PARM
-+                        ? target : NULL_RTX),
-+                       VOIDmode,
-+                       (modifier == EXPAND_INITIALIZER
-+                        || modifier == EXPAND_CONST_ADDRESS
-+                        || modifier == EXPAND_STACK_PARM)
-+                       ? modifier : EXPAND_NORMAL);
-+
-+      /* If this is a constant, put it into a register if it is a
-+         legitimate constant and OFFSET is 0 and memory if it isn't.  */
-+      if (CONSTANT_P (op0))
-+        {
-+          enum machine_mode mode = TYPE_MODE (TREE_TYPE (tem));
-+          if (mode != BLKmode && LEGITIMATE_CONSTANT_P (op0)
-+              && offset == 0)
-+            op0 = force_reg (mode, op0);
-+          else
-+            op0 = validize_mem (force_const_mem (mode, op0));
-+        }
-+
-+      if (offset != 0)
-+        {
-+          rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode,
-+                                        EXPAND_SUM);
-+
-+          /* If this object is in a register, put it into memory.
-+             This case can't occur in C, but can in Ada if we have
-+             unchecked conversion of an expression from a scalar type to
-+             an array or record type.  */
-+          if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG
-+              || GET_CODE (op0) == CONCAT || GET_CODE (op0) == ADDRESSOF)
-+            {
-+              /* If the operand is a SAVE_EXPR, we can deal with this by
-+                 forcing the SAVE_EXPR into memory.  */
-+              if (TREE_CODE (TREE_OPERAND (exp, 0)) == SAVE_EXPR)
-+                {
-+                  put_var_into_stack (TREE_OPERAND (exp, 0), 
-+                                      /*rescan=*/true);
-+                  op0 = SAVE_EXPR_RTL (TREE_OPERAND (exp, 0));
-+                }
-+              else
-+                {
-+                  tree nt
-+                    = build_qualified_type (TREE_TYPE (tem),
-+                                            (TYPE_QUALS (TREE_TYPE (tem))
-+                                             | TYPE_QUAL_CONST));
-+                  rtx memloc = assign_temp (nt, 1, 1, 1);
-+
-+                  emit_move_insn (memloc, op0);
-+                  op0 = memloc;
-+                }
-+            }
-+
-+          if (GET_CODE (op0) != MEM)
-+            abort ();
-+
-+#ifdef POINTERS_EXTEND_UNSIGNED
-+          if (GET_MODE (offset_rtx) != Pmode)
-+            offset_rtx = convert_to_mode (Pmode, offset_rtx, 0);
-+#else
-+          if (GET_MODE (offset_rtx) != ptr_mode)
-+            offset_rtx = convert_to_mode (ptr_mode, offset_rtx, 0);
-+#endif
-+
-+          /* A constant address in OP0 can have VOIDmode, we must not try
-+             to call force_reg for that case.  Avoid that case.  */
-+          if (GET_CODE (op0) == MEM
-+              && GET_MODE (op0) == BLKmode
-+              && GET_MODE (XEXP (op0, 0)) != VOIDmode
-+              && bitsize != 0
-+              && (bitpos % bitsize) == 0
-+              && (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0
-+              && MEM_ALIGN (op0) == GET_MODE_ALIGNMENT (mode1))
-+            {
-+              op0 = adjust_address (op0, mode1, bitpos / BITS_PER_UNIT);
-+              bitpos = 0;
-+            }
-+
-+          op0 = offset_address (op0, offset_rtx,
-+                                highest_pow2_factor (offset));
-+        }
-+
-+      /* If OFFSET is making OP0 more aligned than BIGGEST_ALIGNMENT,
-+         record its alignment as BIGGEST_ALIGNMENT.  */
-+      if (GET_CODE (op0) == MEM && bitpos == 0 && offset != 0
-+          && is_aligning_offset (offset, tem))
-+        set_mem_align (op0, BIGGEST_ALIGNMENT);
-+
-+      /* Don't forget about volatility even if this is a bitfield.  */
-+      if (GET_CODE (op0) == MEM && volatilep && ! MEM_VOLATILE_P (op0))
-+        {
-+          if (op0 == orig_op0)
-+            op0 = copy_rtx (op0);
-+
-+          MEM_VOLATILE_P (op0) = 1;
-+        }
-+
-+      /* The following code doesn't handle CONCAT.
-+         Assume only bitpos == 0 can be used for CONCAT, due to
-+         one element arrays having the same mode as its element.  */
-+      if (GET_CODE (op0) == CONCAT)
-+        {
-+          if (bitpos != 0 || bitsize != GET_MODE_BITSIZE (GET_MODE (op0)))
-+            abort ();
-+          return op0;
-+        }
-+
-+      /* In cases where an aligned union has an unaligned object
-+         as a field, we might be extracting a BLKmode value from
-+         an integer-mode (e.g., SImode) object.  Handle this case
-+         by doing the extract into an object as wide as the field
-+         (which we know to be the width of a basic mode), then
-+         storing into memory, and changing the mode to BLKmode.  */
-+      if (mode1 == VOIDmode
-+          || GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG
-+          || (mode1 != BLKmode && ! direct_load[(int) mode1]
-+              && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
-+              && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT
-+              && modifier != EXPAND_CONST_ADDRESS
-+              && modifier != EXPAND_INITIALIZER)
-+          /* If the field isn't aligned enough to fetch as a memref,
-+             fetch it as a bit field.  */
-+          || (mode1 != BLKmode
-+              && SLOW_UNALIGNED_ACCESS (mode1, MEM_ALIGN (op0))
-+              && ((TYPE_ALIGN (TREE_TYPE (tem))
-+                   < GET_MODE_ALIGNMENT (mode))
-+                  || (bitpos % GET_MODE_ALIGNMENT (mode) != 0)))
-+          /* If the type and the field are a constant size and the
-+             size of the type isn't the same size as the bitfield,
-+             we must use bitfield operations.  */
-+          || (bitsize >= 0
-+              && (TREE_CODE (TYPE_SIZE (TREE_TYPE (exp)))
-+                  == INTEGER_CST)
-+              && 0 != compare_tree_int (TYPE_SIZE (TREE_TYPE (exp)),
-+                                        bitsize)))
-+        {
-+          enum machine_mode ext_mode = mode;
-+
-+          if (ext_mode == BLKmode
-+              && ! (target != 0 && GET_CODE (op0) == MEM
-+                    && GET_CODE (target) == MEM
-+                    && bitpos % BITS_PER_UNIT == 0))
-+            ext_mode = mode_for_size (bitsize, MODE_INT, 1);
-+
-+          if (ext_mode == BLKmode)
-+            {
-+              /* In this case, BITPOS must start at a byte boundary and
-+                 TARGET, if specified, must be a MEM.  */
-+              if (GET_CODE (op0) != MEM
-+                  || (target != 0 && GET_CODE (target) != MEM)
-+                  || bitpos % BITS_PER_UNIT != 0)
-+                abort ();
-+
-+              op0 = adjust_address (op0, VOIDmode, bitpos / BITS_PER_UNIT);
-+              if (target == 0)
-+                target = assign_temp (type, 0, 1, 1);
-+
-+              emit_block_move (target, op0,
-+                               GEN_INT ((bitsize + BITS_PER_UNIT - 1)
-+                                        / BITS_PER_UNIT),
-+                               (modifier == EXPAND_STACK_PARM
-+                                ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
-+
-+              return target;
-+            }
-+
-+          op0 = validize_mem (op0);
-+
-+          if (GET_CODE (op0) == MEM && GET_CODE (XEXP (op0, 0)) == REG)
-+            mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
-+
-+          op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp,
-+                                   (modifier == EXPAND_STACK_PARM
-+                                    ? NULL_RTX : target),
-+                                   ext_mode, ext_mode,
-+                                   int_size_in_bytes (TREE_TYPE (tem)));
-+
-+          /* If the result is a record type and BITSIZE is narrower than
-+             the mode of OP0, an integral mode, and this is a big endian
-+             machine, we must put the field into the high-order bits.  */
-+          if (TREE_CODE (type) == RECORD_TYPE && BYTES_BIG_ENDIAN
-+              && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
-+              && bitsize < (HOST_WIDE_INT) GET_MODE_BITSIZE (GET_MODE (op0)))
-+            op0 = expand_shift (LSHIFT_EXPR, GET_MODE (op0), op0,
-+                                size_int (GET_MODE_BITSIZE (GET_MODE (op0))
-+                                          - bitsize),
-+                                op0, 1);
-+
-+          if (mode == BLKmode)
-+            {
-+              rtx new = assign_temp (build_qualified_type
-+                                     ((*lang_hooks.types.type_for_mode)
-+                                      (ext_mode, 0),
-+                                      TYPE_QUAL_CONST), 0, 1, 1);
-+
-+              emit_move_insn (new, op0);
-+              op0 = copy_rtx (new);
-+              PUT_MODE (op0, BLKmode);
-+              set_mem_attributes (op0, exp, 1);
-+            }
-+
-+          return op0;
-+        }
-+
-+      /* If the result is BLKmode, use that to access the object
-+         now as well.  */
-+      if (mode == BLKmode)
-+        mode1 = BLKmode;
-+
-+      /* Get a reference to just this component.  */
-+      if (modifier == EXPAND_CONST_ADDRESS
-+          || modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
-+        op0 = adjust_address_nv (op0, mode1, bitpos / BITS_PER_UNIT);
-+      else
-+        op0 = adjust_address (op0, mode1, bitpos / BITS_PER_UNIT);
-+
-+      if (op0 == orig_op0)
-+        op0 = copy_rtx (op0);
-+
-+      set_mem_attributes (op0, exp, 0);
-+      if (GET_CODE (XEXP (op0, 0)) == REG)
-+        mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
-+
-+      MEM_VOLATILE_P (op0) |= volatilep;
-+      if (mode == mode1 || mode1 == BLKmode || mode1 == tmode
-+          || modifier == EXPAND_CONST_ADDRESS
-+          || modifier == EXPAND_INITIALIZER)
-+        return op0;
-+      else if (target == 0)
-+        target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
-+
-+      convert_move (target, op0, unsignedp);
-+      return target;
-+      }
-+
-+    case VTABLE_REF:
-+      {
-+      rtx insn, before = get_last_insn (), vtbl_ref;
-+
-+      /* Evaluate the interior expression.  */
-+      subtarget = expand_expr (TREE_OPERAND (exp, 0), target,
-+                               tmode, modifier);
-+
-+      /* Get or create an instruction off which to hang a note.  */
-+      if (REG_P (subtarget))
-+        {
-+          target = subtarget;
-+          insn = get_last_insn ();
-+          if (insn == before)
-+            abort ();
-+          if (! INSN_P (insn))
-+            insn = prev_nonnote_insn (insn);
-+        }
-+      else
-+        {
-+          target = gen_reg_rtx (GET_MODE (subtarget));
-+          insn = emit_move_insn (target, subtarget);
-+        }
-+
-+      /* Collect the data for the note.  */
-+      vtbl_ref = XEXP (DECL_RTL (TREE_OPERAND (exp, 1)), 0);
-+      vtbl_ref = plus_constant (vtbl_ref,
-+                                tree_low_cst (TREE_OPERAND (exp, 2), 0));
-+      /* Discard the initial CONST that was added.  */
-+      vtbl_ref = XEXP (vtbl_ref, 0);
-+
-+      REG_NOTES (insn)
-+        = gen_rtx_EXPR_LIST (REG_VTABLE_REF, vtbl_ref, REG_NOTES (insn));
-+
-+      return target;
-+      }
-+
-+      /* Intended for a reference to a buffer of a file-object in Pascal.
-+       But it's not certain that a special tree code will really be
-+       necessary for these.  INDIRECT_REF might work for them.  */
-+    case BUFFER_REF:
-+      abort ();
-+
-+    case IN_EXPR:
-+      {
-+      /* Pascal set IN expression.
-+
-+         Algorithm:
-+             rlo       = set_low - (set_low%bits_per_word);
-+             the_word  = set [ (index - rlo)/bits_per_word ];
-+             bit_index = index % bits_per_word;
-+             bitmask   = 1 << bit_index;
-+             return !!(the_word & bitmask);  */
-+
-+      tree set = TREE_OPERAND (exp, 0);
-+      tree index = TREE_OPERAND (exp, 1);
-+      int iunsignedp = TREE_UNSIGNED (TREE_TYPE (index));
-+      tree set_type = TREE_TYPE (set);
-+      tree set_low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (set_type));
-+      tree set_high_bound = TYPE_MAX_VALUE (TYPE_DOMAIN (set_type));
-+      rtx index_val = expand_expr (index, 0, VOIDmode, 0);
-+      rtx lo_r = expand_expr (set_low_bound, 0, VOIDmode, 0);
-+      rtx hi_r = expand_expr (set_high_bound, 0, VOIDmode, 0);
-+      rtx setval = expand_expr (set, 0, VOIDmode, 0);
-+      rtx setaddr = XEXP (setval, 0);
-+      enum machine_mode index_mode = TYPE_MODE (TREE_TYPE (index));
-+      rtx rlow;
-+      rtx diff, quo, rem, addr, bit, result;
-+
-+      /* If domain is empty, answer is no.  Likewise if index is constant
-+         and out of bounds.  */
-+      if (((TREE_CODE (set_high_bound) == INTEGER_CST
-+           && TREE_CODE (set_low_bound) == INTEGER_CST
-+           && tree_int_cst_lt (set_high_bound, set_low_bound))
-+           || (TREE_CODE (index) == INTEGER_CST
-+               && TREE_CODE (set_low_bound) == INTEGER_CST
-+               && tree_int_cst_lt (index, set_low_bound))
-+           || (TREE_CODE (set_high_bound) == INTEGER_CST
-+               && TREE_CODE (index) == INTEGER_CST
-+               && tree_int_cst_lt (set_high_bound, index))))
-+        return const0_rtx;
-+
-+      if (target == 0)
-+        target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
-+
-+      /* If we get here, we have to generate the code for both cases
-+         (in range and out of range).  */
-+
-+      op0 = gen_label_rtx ();
-+      op1 = gen_label_rtx ();
-+
-+      if (! (GET_CODE (index_val) == CONST_INT
-+             && GET_CODE (lo_r) == CONST_INT))
-+        emit_cmp_and_jump_insns (index_val, lo_r, LT, NULL_RTX,
-+                                 GET_MODE (index_val), iunsignedp, op1);
-+
-+      if (! (GET_CODE (index_val) == CONST_INT
-+             && GET_CODE (hi_r) == CONST_INT))
-+        emit_cmp_and_jump_insns (index_val, hi_r, GT, NULL_RTX,
-+                                 GET_MODE (index_val), iunsignedp, op1);
-+
-+      /* Calculate the element number of bit zero in the first word
-+         of the set.  */
-+      if (GET_CODE (lo_r) == CONST_INT)
-+        rlow = GEN_INT (INTVAL (lo_r)
-+                        & ~((HOST_WIDE_INT) 1 << BITS_PER_UNIT));
-+      else
-+        rlow = expand_binop (index_mode, and_optab, lo_r,
-+                             GEN_INT (~((HOST_WIDE_INT) 1 << BITS_PER_UNIT)),
-+                             NULL_RTX, iunsignedp, OPTAB_LIB_WIDEN);
-+
-+      diff = expand_binop (index_mode, sub_optab, index_val, rlow,
-+                           NULL_RTX, iunsignedp, OPTAB_LIB_WIDEN);
-+
-+      quo = expand_divmod (0, TRUNC_DIV_EXPR, index_mode, diff,
-+                           GEN_INT (BITS_PER_UNIT), NULL_RTX, iunsignedp);
-+      rem = expand_divmod (1, TRUNC_MOD_EXPR, index_mode, index_val,
-+                           GEN_INT (BITS_PER_UNIT), NULL_RTX, iunsignedp);
-+
-+      addr = memory_address (byte_mode,
-+                             expand_binop (index_mode, add_optab, diff,
-+                                           setaddr, NULL_RTX, iunsignedp,
-+                                           OPTAB_LIB_WIDEN));
-+
-+      /* Extract the bit we want to examine.  */
-+      bit = expand_shift (RSHIFT_EXPR, byte_mode,
-+                          gen_rtx_MEM (byte_mode, addr),
-+                          make_tree (TREE_TYPE (index), rem),
-+                          NULL_RTX, 1);
-+      result = expand_binop (byte_mode, and_optab, bit, const1_rtx,
-+                             GET_MODE (target) == byte_mode ? target : 0,
-+                             1, OPTAB_LIB_WIDEN);
-+
-+      if (result != target)
-+        convert_move (target, result, 1);
-+
-+      /* Output the code to handle the out-of-range case.  */
-+      emit_jump (op0);
-+      emit_label (op1);
-+      emit_move_insn (target, const0_rtx);
-+      emit_label (op0);
-+      return target;
-+      }
-+
-+    case WITH_CLEANUP_EXPR:
-+      if (WITH_CLEANUP_EXPR_RTL (exp) == 0)
-+      {
-+        WITH_CLEANUP_EXPR_RTL (exp)
-+          = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
-+        expand_decl_cleanup_eh (NULL_TREE, TREE_OPERAND (exp, 1),
-+                                CLEANUP_EH_ONLY (exp));
-+
-+        /* That's it for this cleanup.  */
-+        TREE_OPERAND (exp, 1) = 0;
-+      }
-+      return WITH_CLEANUP_EXPR_RTL (exp);
-+
-+    case CLEANUP_POINT_EXPR:
-+      {
-+      /* Start a new binding layer that will keep track of all cleanup
-+         actions to be performed.  */
-+      expand_start_bindings (2);
-+
-+      target_temp_slot_level = temp_slot_level;
-+
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
-+      /* If we're going to use this value, load it up now.  */
-+      if (! ignore)
-+        op0 = force_not_mem (op0);
-+      preserve_temp_slots (op0);
-+      expand_end_bindings (NULL_TREE, 0, 0);
-+      }
-+      return op0;
-+
-+    case CALL_EXPR:
-+      /* Check for a built-in function.  */
-+      if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
-+        && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
-+            == FUNCTION_DECL)
-+        && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
-+      {
-+        if (DECL_BUILT_IN_CLASS (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
-+            == BUILT_IN_FRONTEND)
-+          return (*lang_hooks.expand_expr) (exp, original_target,
-+                                            tmode, modifier);
-+        else
-+          return expand_builtin (exp, target, subtarget, tmode, ignore);
-+      }
-+
-+      return expand_call (exp, target, ignore);
-+
-+    case NON_LVALUE_EXPR:
-+    case NOP_EXPR:
-+    case CONVERT_EXPR:
-+    case REFERENCE_EXPR:
-+      if (TREE_OPERAND (exp, 0) == error_mark_node)
-+      return const0_rtx;
-+
-+      if (TREE_CODE (type) == UNION_TYPE)
-+      {
-+        tree valtype = TREE_TYPE (TREE_OPERAND (exp, 0));
-+
-+        /* If both input and output are BLKmode, this conversion isn't doing
-+           anything except possibly changing memory attribute.  */
-+        if (mode == BLKmode && TYPE_MODE (valtype) == BLKmode)
-+          {
-+            rtx result = expand_expr (TREE_OPERAND (exp, 0), target, tmode,
-+                                      modifier);
-+
-+            result = copy_rtx (result);
-+            set_mem_attributes (result, exp, 0);
-+            return result;
-+          }
-+
-+        if (target == 0)
-+          target = assign_temp (type, 0, 1, 1);
-+
-+        if (GET_CODE (target) == MEM)
-+          /* Store data into beginning of memory target.  */
-+          store_expr (TREE_OPERAND (exp, 0),
-+                      adjust_address (target, TYPE_MODE (valtype), 0),
-+                      modifier == EXPAND_STACK_PARM ? 2 : 0);
-+
-+        else if (GET_CODE (target) == REG)
-+          /* Store this field into a union of the proper type.  */
-+          store_field (target,
-+                       MIN ((int_size_in_bytes (TREE_TYPE
-+                                                (TREE_OPERAND (exp, 0)))
-+                             * BITS_PER_UNIT),
-+                            (HOST_WIDE_INT) GET_MODE_BITSIZE (mode)),
-+                       0, TYPE_MODE (valtype), TREE_OPERAND (exp, 0),
-+                       VOIDmode, 0, type, 0);
-+        else
-+          abort ();
-+
-+        /* Return the entire union.  */
-+        return target;
-+      }
-+
-+      if (mode == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
-+      {
-+        op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode,
-+                           modifier);
-+
-+        /* If the signedness of the conversion differs and OP0 is
-+           a promoted SUBREG, clear that indication since we now
-+           have to do the proper extension.  */
-+        if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))) != unsignedp
-+            && GET_CODE (op0) == SUBREG)
-+          SUBREG_PROMOTED_VAR_P (op0) = 0;
-+
-+        return op0;
-+      }
-+
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, modifier);
-+      if (GET_MODE (op0) == mode)
-+      return op0;
-+
-+      /* If OP0 is a constant, just convert it into the proper mode.  */
-+      if (CONSTANT_P (op0))
-+      {
-+        tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
-+        enum machine_mode inner_mode = TYPE_MODE (inner_type);
-+
-+        if (modifier == EXPAND_INITIALIZER)
-+          return simplify_gen_subreg (mode, op0, inner_mode,
-+                                      subreg_lowpart_offset (mode,
-+                                                             inner_mode));
-+        else
-+          return convert_modes (mode, inner_mode, op0,
-+                                TREE_UNSIGNED (inner_type));
-+      }
-+
-+      if (modifier == EXPAND_INITIALIZER)
-+      return gen_rtx_fmt_e (unsignedp ? ZERO_EXTEND : SIGN_EXTEND, mode, op0);
-+
-+      if (target == 0)
-+      return
-+        convert_to_mode (mode, op0,
-+                         TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))));
-+      else
-+      convert_move (target, op0,
-+                    TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))));
-+      return target;
-+
-+    case VIEW_CONVERT_EXPR:
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, modifier);
-+
-+      /* If the input and output modes are both the same, we are done.
-+       Otherwise, if neither mode is BLKmode and both are within a word, we
-+       can use gen_lowpart.  If neither is true, make sure the operand is
-+       in memory and convert the MEM to the new mode.  */
-+      if (TYPE_MODE (type) == GET_MODE (op0))
-+      ;
-+      else if (TYPE_MODE (type) != BLKmode && GET_MODE (op0) != BLKmode
-+             && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD
-+             && GET_MODE_SIZE (GET_MODE (op0)) <= UNITS_PER_WORD)
-+      op0 = gen_lowpart (TYPE_MODE (type), op0);
-+      else if (GET_CODE (op0) != MEM)
-+      {
-+        /* If the operand is not a MEM, force it into memory.  Since we
-+           are going to be be changing the mode of the MEM, don't call
-+           force_const_mem for constants because we don't allow pool
-+           constants to change mode.  */
-+        tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
-+
-+        if (TREE_ADDRESSABLE (exp))
-+          abort ();
-+
-+        if (target == 0 || GET_MODE (target) != TYPE_MODE (inner_type))
-+          target
-+            = assign_stack_temp_for_type
-+              (TYPE_MODE (inner_type),
-+               GET_MODE_SIZE (TYPE_MODE (inner_type)), 0, inner_type);
-+
-+        emit_move_insn (target, op0);
-+        op0 = target;
-+      }
-+
-+      /* At this point, OP0 is in the correct mode.  If the output type is such
-+       that the operand is known to be aligned, indicate that it is.
-+       Otherwise, we need only be concerned about alignment for non-BLKmode
-+       results.  */
-+      if (GET_CODE (op0) == MEM)
-+      {
-+        op0 = copy_rtx (op0);
-+
-+        if (TYPE_ALIGN_OK (type))
-+          set_mem_align (op0, MAX (MEM_ALIGN (op0), TYPE_ALIGN (type)));
-+        else if (TYPE_MODE (type) != BLKmode && STRICT_ALIGNMENT
-+                 && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
-+          {
-+            tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
-+            HOST_WIDE_INT temp_size
-+              = MAX (int_size_in_bytes (inner_type),
-+                     (HOST_WIDE_INT) GET_MODE_SIZE (TYPE_MODE (type)));
-+            rtx new = assign_stack_temp_for_type (TYPE_MODE (type),
-+                                                  temp_size, 0, type);
-+            rtx new_with_op0_mode = adjust_address (new, GET_MODE (op0), 0);
-+
-+            if (TREE_ADDRESSABLE (exp))
-+              abort ();
-+
-+            if (GET_MODE (op0) == BLKmode)
-+              emit_block_move (new_with_op0_mode, op0,
-+                               GEN_INT (GET_MODE_SIZE (TYPE_MODE (type))),
-+                               (modifier == EXPAND_STACK_PARM
-+                                ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
-+            else
-+              emit_move_insn (new_with_op0_mode, op0);
-+
-+            op0 = new;
-+          }
-+
-+        op0 = adjust_address (op0, TYPE_MODE (type), 0);
-+      }
-+
-+      return op0;
-+
-+    case PLUS_EXPR:
-+      this_optab = ! unsignedp && flag_trapv
-+                   && (GET_MODE_CLASS (mode) == MODE_INT)
-+                   ? addv_optab : add_optab;
-+
-+      /* If we are adding a constant, an RTL_EXPR that is sp, fp, or ap, and
-+       something else, make sure we add the register to the constant and
-+       then to the other thing.  This case can occur during strength
-+       reduction and doing it this way will produce better code if the
-+       frame pointer or argument pointer is eliminated.
-+
-+       fold-const.c will ensure that the constant is always in the inner
-+       PLUS_EXPR, so the only case we need to do anything about is if
-+       sp, ap, or fp is our second argument, in which case we must swap
-+       the innermost first argument and our second argument.  */
-+
-+      if (TREE_CODE (TREE_OPERAND (exp, 0)) == PLUS_EXPR
-+        && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 1)) == INTEGER_CST
-+        && TREE_CODE (TREE_OPERAND (exp, 1)) == RTL_EXPR
-+        && (RTL_EXPR_RTL (TREE_OPERAND (exp, 1)) == frame_pointer_rtx
-+            || RTL_EXPR_RTL (TREE_OPERAND (exp, 1)) == stack_pointer_rtx
-+            || RTL_EXPR_RTL (TREE_OPERAND (exp, 1)) == arg_pointer_rtx))
-+      {
-+        tree t = TREE_OPERAND (exp, 1);
-+
-+        TREE_OPERAND (exp, 1) = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
-+        TREE_OPERAND (TREE_OPERAND (exp, 0), 0) = t;
-+      }
-+
-+      /* If the result is to be ptr_mode and we are adding an integer to
-+       something, we might be forming a constant.  So try to use
-+       plus_constant.  If it produces a sum and we can't accept it,
-+       use force_operand.  This allows P = &ARR[const] to generate
-+       efficient code on machines where a SYMBOL_REF is not a valid
-+       address.
-+
-+       If this is an EXPAND_SUM call, always return the sum.  */
-+      if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER
-+        || (mode == ptr_mode && (unsignedp || ! flag_trapv)))
-+      {
-+        if (modifier == EXPAND_STACK_PARM)
-+          target = 0;
-+        if (TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST
-+            && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
-+            && TREE_CONSTANT (TREE_OPERAND (exp, 1)))
-+          {
-+            rtx constant_part;
-+
-+            op1 = expand_expr (TREE_OPERAND (exp, 1), subtarget, VOIDmode,
-+                               EXPAND_SUM);
-+            /* Use immed_double_const to ensure that the constant is
-+               truncated according to the mode of OP1, then sign extended
-+               to a HOST_WIDE_INT.  Using the constant directly can result
-+               in non-canonical RTL in a 64x32 cross compile.  */
-+            constant_part
-+              = immed_double_const (TREE_INT_CST_LOW (TREE_OPERAND (exp, 0)),
-+                                    (HOST_WIDE_INT) 0,
-+                                    TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 1))));
-+            op1 = plus_constant (op1, INTVAL (constant_part));
-+            if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
-+              op1 = force_operand (op1, target);
-+            return op1;
-+          }
-+
-+        else if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
-+                 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_INT
-+                 && TREE_CONSTANT (TREE_OPERAND (exp, 0)))
-+          {
-+            rtx constant_part;
-+
-+            op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode,
-+                               (modifier == EXPAND_INITIALIZER
-+                               ? EXPAND_INITIALIZER : EXPAND_SUM));
-+            if (! CONSTANT_P (op0))
-+              {
-+                op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
-+                                   VOIDmode, modifier);
-+                /* Don't go to both_summands if modifier
-+                   says it's not right to return a PLUS.  */
-+                if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
-+                  goto binop2;
-+                goto both_summands;
-+              }
-+            /* Use immed_double_const to ensure that the constant is
-+               truncated according to the mode of OP1, then sign extended
-+               to a HOST_WIDE_INT.  Using the constant directly can result
-+               in non-canonical RTL in a 64x32 cross compile.  */
-+            constant_part
-+              = immed_double_const (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)),
-+                                    (HOST_WIDE_INT) 0,
-+                                    TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))));
-+            op0 = plus_constant (op0, INTVAL (constant_part));
-+            if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
-+              op0 = force_operand (op0, target);
-+            return op0;
-+          }
-+      }
-+
-+      if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
-+      subtarget = 0;
-+
-+      /* No sense saving up arithmetic to be done
-+       if it's all in the wrong mode to form part of an address.
-+       And force_operand won't know whether to sign-extend or
-+       zero-extend.  */
-+      if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
-+        || mode != ptr_mode)
-+      {
-+        op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-+        op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
-+        if (op0 == const0_rtx)
-+          return op1;
-+        if (op1 == const0_rtx)
-+          return op0;
-+        goto binop2;
-+      }
-+
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier);
-+      op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, modifier);
-+
-+      /* We come here from MINUS_EXPR when the second operand is a
-+         constant.  */
-+    both_summands:
-+      /* Make sure any term that's a sum with a constant comes last.  */
-+      if (GET_CODE (op0) == PLUS
-+        && CONSTANT_P (XEXP (op0, 1)))
-+      {
-+        temp = op0;
-+        op0 = op1;
-+        op1 = temp;
-+      }
-+      /* If adding to a sum including a constant,
-+       associate it to put the constant outside.  */
-+      if (GET_CODE (op1) == PLUS
-+        && CONSTANT_P (XEXP (op1, 1)))
-+      {
-+        rtx constant_term = const0_rtx;
-+
-+        temp = simplify_binary_operation (PLUS, mode, XEXP (op1, 0), op0);
-+        if (temp != 0)
-+          op0 = temp;
-+        /* Ensure that MULT comes first if there is one.  */
-+        else if (GET_CODE (op0) == MULT)
-+          op0 = gen_rtx_PLUS (mode, op0, XEXP (op1, 0));
-+        else
-+          op0 = gen_rtx_PLUS (mode, XEXP (op1, 0), op0);
-+
-+        /* Let's also eliminate constants from op0 if possible.  */
-+        op0 = eliminate_constant_term (op0, &constant_term);
-+
-+        /* CONSTANT_TERM and XEXP (op1, 1) are known to be constant, so
-+           their sum should be a constant.  Form it into OP1, since the
-+           result we want will then be OP0 + OP1.  */
-+
-+        temp = simplify_binary_operation (PLUS, mode, constant_term,
-+                                          XEXP (op1, 1));
-+        if (temp != 0)
-+          op1 = temp;
-+        else
-+          op1 = gen_rtx_PLUS (mode, constant_term, XEXP (op1, 1));
-+      }
-+
-+      /* Put a constant term last and put a multiplication first.  */
-+      if (CONSTANT_P (op0) || GET_CODE (op1) == MULT)
-+      temp = op1, op1 = op0, op0 = temp;
-+
-+      temp = simplify_binary_operation (PLUS, mode, op0, op1);
-+      return temp ? temp : gen_rtx_PLUS (mode, op0, op1);
-+
-+    case MINUS_EXPR:
-+      /* For initializers, we are allowed to return a MINUS of two
-+       symbolic constants.  Here we handle all cases when both operands
-+       are constant.  */
-+      /* Handle difference of two symbolic constants,
-+       for the sake of an initializer.  */
-+      if ((modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
-+        && really_constant_p (TREE_OPERAND (exp, 0))
-+        && really_constant_p (TREE_OPERAND (exp, 1)))
-+      {
-+        rtx op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode,
-+                               modifier);
-+        rtx op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode,
-+                               modifier);
-+
-+        /* If the last operand is a CONST_INT, use plus_constant of
-+           the negated constant.  Else make the MINUS.  */
-+        if (GET_CODE (op1) == CONST_INT)
-+          return plus_constant (op0, - INTVAL (op1));
-+        else
-+          return gen_rtx_MINUS (mode, op0, op1);
-+      }
-+
-+      this_optab = ! unsignedp && flag_trapv
-+                   && (GET_MODE_CLASS(mode) == MODE_INT)
-+                   ? subv_optab : sub_optab;
-+
-+      /* No sense saving up arithmetic to be done
-+       if it's all in the wrong mode to form part of an address.
-+       And force_operand won't know whether to sign-extend or
-+       zero-extend.  */
-+      if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
-+        || mode != ptr_mode)
-+      goto binop;
-+
-+      if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
-+      subtarget = 0;
-+
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier);
-+      op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, modifier);
-+
-+      /* Convert A - const to A + (-const).  */
-+      if (GET_CODE (op1) == CONST_INT)
-+      {
-+        op1 = negate_rtx (mode, op1);
-+        goto both_summands;
-+      }
-+
-+      goto binop2;
-+
-+    case MULT_EXPR:
-+      /* If first operand is constant, swap them.
-+       Thus the following special case checks need only
-+       check the second operand.  */
-+      if (TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST)
-+      {
-+        tree t1 = TREE_OPERAND (exp, 0);
-+        TREE_OPERAND (exp, 0) = TREE_OPERAND (exp, 1);
-+        TREE_OPERAND (exp, 1) = t1;
-+      }
-+
-+      /* Attempt to return something suitable for generating an
-+       indexed address, for machines that support that.  */
-+
-+      if (modifier == EXPAND_SUM && mode == ptr_mode
-+        && host_integerp (TREE_OPERAND (exp, 1), 0))
-+      {
-+        tree exp1 = TREE_OPERAND (exp, 1);
-+
-+        op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode,
-+                           EXPAND_SUM);
-+
-+        /* If we knew for certain that this is arithmetic for an array
-+           reference, and we knew the bounds of the array, then we could
-+           apply the distributive law across (PLUS X C) for constant C.
-+           Without such knowledge, we risk overflowing the computation
-+           when both X and C are large, but X+C isn't.  */
-+        /* ??? Could perhaps special-case EXP being unsigned and C being
-+           positive.  In that case we are certain that X+C is no smaller
-+           than X and so the transformed expression will overflow iff the
-+           original would have.  */
-+
-+        if (GET_CODE (op0) != REG)
-+          op0 = force_operand (op0, NULL_RTX);
-+        if (GET_CODE (op0) != REG)
-+          op0 = copy_to_mode_reg (mode, op0);
-+
-+        return gen_rtx_MULT (mode, op0,
-+                             gen_int_mode (tree_low_cst (exp1, 0),
-+                                           TYPE_MODE (TREE_TYPE (exp1))));
-+      }
-+
-+      if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
-+      subtarget = 0;
-+
-+      if (modifier == EXPAND_STACK_PARM)
-+      target = 0;
-+
-+      /* Check for multiplying things that have been extended
-+       from a narrower type.  If this machine supports multiplying
-+       in that narrower type with a result in the desired type,
-+       do it that way, and avoid the explicit type-conversion.  */
-+      if (TREE_CODE (TREE_OPERAND (exp, 0)) == NOP_EXPR
-+        && TREE_CODE (type) == INTEGER_TYPE
-+        && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
-+            < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0))))
-+        && ((TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
-+             && int_fits_type_p (TREE_OPERAND (exp, 1),
-+                                 TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
-+             /* Don't use a widening multiply if a shift will do.  */
-+             && ((GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 1))))
-+                  > HOST_BITS_PER_WIDE_INT)
-+                 || exact_log2 (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))) < 0))
-+            ||
-+            (TREE_CODE (TREE_OPERAND (exp, 1)) == NOP_EXPR
-+             && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 1), 0)))
-+                 ==
-+                 TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))))
-+             /* If both operands are extended, they must either both
-+                be zero-extended or both be sign-extended.  */
-+             && (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 1), 0)))
-+                 ==
-+                 TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))))))
-+      {
-+        enum machine_mode innermode
-+          = TYPE_MODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)));
-+        optab other_optab = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
-+                      ? smul_widen_optab : umul_widen_optab);
-+        this_optab = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
-+                      ? umul_widen_optab : smul_widen_optab);
-+        if (mode == GET_MODE_WIDER_MODE (innermode))
-+          {
-+            if (this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
-+              {
-+                op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
-+                                   NULL_RTX, VOIDmode, 0);
-+                if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
-+                  op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
-+                                     VOIDmode, 0);
-+                else
-+                  op1 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 1), 0),
-+                                     NULL_RTX, VOIDmode, 0);
-+                goto binop2;
-+              }
-+            else if (other_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
-+                     && innermode == word_mode)
-+              {
-+                rtx htem;
-+                op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
-+                                   NULL_RTX, VOIDmode, 0);
-+                if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
-+                  op1 = convert_modes (innermode, mode,
-+                                       expand_expr (TREE_OPERAND (exp, 1),
-+                                                    NULL_RTX, VOIDmode, 0),
-+                                       unsignedp);
-+                else
-+                  op1 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 1), 0),
-+                                     NULL_RTX, VOIDmode, 0);
-+                temp = expand_binop (mode, other_optab, op0, op1, target,
-+                                     unsignedp, OPTAB_LIB_WIDEN);
-+                htem = expand_mult_highpart_adjust (innermode,
-+                                                    gen_highpart (innermode, temp),
-+                                                    op0, op1,
-+                                                    gen_highpart (innermode, temp),
-+                                                    unsignedp);
-+                emit_move_insn (gen_highpart (innermode, temp), htem);
-+                return temp;
-+              }
-+          }
-+      }
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-+      op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
-+      return expand_mult (mode, op0, op1, target, unsignedp);
-+
-+    case TRUNC_DIV_EXPR:
-+    case FLOOR_DIV_EXPR:
-+    case CEIL_DIV_EXPR:
-+    case ROUND_DIV_EXPR:
-+    case EXACT_DIV_EXPR:
-+      if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
-+      subtarget = 0;
-+      if (modifier == EXPAND_STACK_PARM)
-+      target = 0;
-+      /* Possible optimization: compute the dividend with EXPAND_SUM
-+       then if the divisor is constant can optimize the case
-+       where some terms of the dividend have coeffs divisible by it.  */
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-+      op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
-+      return expand_divmod (0, code, mode, op0, op1, target, unsignedp);
-+
-+    case RDIV_EXPR:
-+      /* Emit a/b as a*(1/b).  Later we may manage CSE the reciprocal saving
-+         expensive divide.  If not, combine will rebuild the original
-+         computation.  */
-+      if (flag_unsafe_math_optimizations && optimize && !optimize_size
-+        && TREE_CODE (type) == REAL_TYPE
-+        && !real_onep (TREE_OPERAND (exp, 0)))
-+        return expand_expr (build (MULT_EXPR, type, TREE_OPERAND (exp, 0),
-+                                 build (RDIV_EXPR, type,
-+                                        build_real (type, dconst1),
-+                                        TREE_OPERAND (exp, 1))),
-+                          target, tmode, modifier);
-+      this_optab = sdiv_optab;
-+      goto binop;
-+
-+    case TRUNC_MOD_EXPR:
-+    case FLOOR_MOD_EXPR:
-+    case CEIL_MOD_EXPR:
-+    case ROUND_MOD_EXPR:
-+      if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
-+      subtarget = 0;
-+      if (modifier == EXPAND_STACK_PARM)
-+      target = 0;
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-+      op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
-+      return expand_divmod (1, code, mode, op0, op1, target, unsignedp);
-+
-+    case FIX_ROUND_EXPR:
-+    case FIX_FLOOR_EXPR:
-+    case FIX_CEIL_EXPR:
-+      abort ();                       /* Not used for C.  */
-+
-+    case FIX_TRUNC_EXPR:
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
-+      if (target == 0 || modifier == EXPAND_STACK_PARM)
-+      target = gen_reg_rtx (mode);
-+      expand_fix (target, op0, unsignedp);
-+      return target;
-+
-+    case FLOAT_EXPR:
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
-+      if (target == 0 || modifier == EXPAND_STACK_PARM)
-+      target = gen_reg_rtx (mode);
-+      /* expand_float can't figure out what to do if FROM has VOIDmode.
-+       So give it the correct mode.  With -O, cse will optimize this.  */
-+      if (GET_MODE (op0) == VOIDmode)
-+      op0 = copy_to_mode_reg (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))),
-+                              op0);
-+      expand_float (target, op0,
-+                  TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))));
-+      return target;
-+
-+    case NEGATE_EXPR:
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-+      if (modifier == EXPAND_STACK_PARM)
-+      target = 0;
-+      temp = expand_unop (mode,
-+                        ! unsignedp && flag_trapv
-+                        && (GET_MODE_CLASS(mode) == MODE_INT)
-+                        ? negv_optab : neg_optab, op0, target, 0);
-+      if (temp == 0)
-+      abort ();
-+      return temp;
-+
-+    case ABS_EXPR:
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-+      if (modifier == EXPAND_STACK_PARM)
-+      target = 0;
-+
-+      /* Handle complex values specially.  */
-+      if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
-+        || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
-+      return expand_complex_abs (mode, op0, target, unsignedp);
-+
-+      /* Unsigned abs is simply the operand.  Testing here means we don't
-+       risk generating incorrect code below.  */
-+      if (TREE_UNSIGNED (type))
-+      return op0;
-+
-+      return expand_abs (mode, op0, target, unsignedp,
-+                       safe_from_p (target, TREE_OPERAND (exp, 0), 1));
-+
-+    case MAX_EXPR:
-+    case MIN_EXPR:
-+      target = original_target;
-+      if (target == 0
-+        || modifier == EXPAND_STACK_PARM
-+        || ! safe_from_p (target, TREE_OPERAND (exp, 1), 1)
-+        || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
-+        || GET_MODE (target) != mode
-+        || (GET_CODE (target) == REG
-+            && REGNO (target) < FIRST_PSEUDO_REGISTER))
-+      target = gen_reg_rtx (mode);
-+      op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, 0);
-+
-+      /* First try to do it with a special MIN or MAX instruction.
-+       If that does not win, use a conditional jump to select the proper
-+       value.  */
-+      this_optab = (TREE_UNSIGNED (type)
-+                  ? (code == MIN_EXPR ? umin_optab : umax_optab)
-+                  : (code == MIN_EXPR ? smin_optab : smax_optab));
-+
-+      temp = expand_binop (mode, this_optab, op0, op1, target, unsignedp,
-+                         OPTAB_WIDEN);
-+      if (temp != 0)
-+      return temp;
-+
-+      /* At this point, a MEM target is no longer useful; we will get better
-+       code without it.  */
-+
-+      if (GET_CODE (target) == MEM)
-+      target = gen_reg_rtx (mode);
-+
-+      if (target != op0)
-+      emit_move_insn (target, op0);
-+
-+      op0 = gen_label_rtx ();
-+
-+      /* If this mode is an integer too wide to compare properly,
-+       compare word by word.  Rely on cse to optimize constant cases.  */
-+      if (GET_MODE_CLASS (mode) == MODE_INT
-+        && ! can_compare_p (GE, mode, ccp_jump))
-+      {
-+        if (code == MAX_EXPR)
-+          do_jump_by_parts_greater_rtx (mode, TREE_UNSIGNED (type),
-+                                        target, op1, NULL_RTX, op0);
-+        else
-+          do_jump_by_parts_greater_rtx (mode, TREE_UNSIGNED (type),
-+                                        op1, target, NULL_RTX, op0);
-+      }
-+      else
-+      {
-+        int unsignedp = TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 1)));
-+        do_compare_rtx_and_jump (target, op1, code == MAX_EXPR ? GE : LE,
-+                                 unsignedp, mode, NULL_RTX, NULL_RTX,
-+                                 op0);
-+      }
-+      emit_move_insn (target, op1);
-+      emit_label (op0);
-+      return target;
-+
-+    case BIT_NOT_EXPR:
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-+      if (modifier == EXPAND_STACK_PARM)
-+      target = 0;
-+      temp = expand_unop (mode, one_cmpl_optab, op0, target, 1);
-+      if (temp == 0)
-+      abort ();
-+      return temp;
-+
-+    case FFS_EXPR:
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-+      if (modifier == EXPAND_STACK_PARM)
-+      target = 0;
-+      temp = expand_unop (mode, ffs_optab, op0, target, 1);
-+      if (temp == 0)
-+      abort ();
-+      return temp;
-+
-+      /* ??? Can optimize bitwise operations with one arg constant.
-+       Can optimize (a bitwise1 n) bitwise2 (a bitwise3 b)
-+       and (a bitwise1 b) bitwise2 b (etc)
-+       but that is probably not worth while.  */
-+
-+      /* BIT_AND_EXPR is for bitwise anding.  TRUTH_AND_EXPR is for anding two
-+       boolean values when we want in all cases to compute both of them.  In
-+       general it is fastest to do TRUTH_AND_EXPR by computing both operands
-+       as actual zero-or-1 values and then bitwise anding.  In cases where
-+       there cannot be any side effects, better code would be made by
-+       treating TRUTH_AND_EXPR like TRUTH_ANDIF_EXPR; but the question is
-+       how to recognize those cases.  */
-+
-+    case TRUTH_AND_EXPR:
-+    case BIT_AND_EXPR:
-+      this_optab = and_optab;
-+      goto binop;
-+
-+    case TRUTH_OR_EXPR:
-+    case BIT_IOR_EXPR:
-+      this_optab = ior_optab;
-+      goto binop;
-+
-+    case TRUTH_XOR_EXPR:
-+    case BIT_XOR_EXPR:
-+      this_optab = xor_optab;
-+      goto binop;
-+
-+    case LSHIFT_EXPR:
-+    case RSHIFT_EXPR:
-+    case LROTATE_EXPR:
-+    case RROTATE_EXPR:
-+      if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
-+      subtarget = 0;
-+      if (modifier == EXPAND_STACK_PARM)
-+      target = 0;
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-+      return expand_shift (code, mode, op0, TREE_OPERAND (exp, 1), target,
-+                         unsignedp);
-+
-+      /* Could determine the answer when only additive constants differ.  Also,
-+       the addition of one can be handled by changing the condition.  */
-+    case LT_EXPR:
-+    case LE_EXPR:
-+    case GT_EXPR:
-+    case GE_EXPR:
-+    case EQ_EXPR:
-+    case NE_EXPR:
-+    case UNORDERED_EXPR:
-+    case ORDERED_EXPR:
-+    case UNLT_EXPR:
-+    case UNLE_EXPR:
-+    case UNGT_EXPR:
-+    case UNGE_EXPR:
-+    case UNEQ_EXPR:
-+      temp = do_store_flag (exp,
-+                          modifier != EXPAND_STACK_PARM ? target : NULL_RTX,
-+                          tmode != VOIDmode ? tmode : mode, 0);
-+      if (temp != 0)
-+      return temp;
-+
-+      /* For foo != 0, load foo, and if it is nonzero load 1 instead.  */
-+      if (code == NE_EXPR && integer_zerop (TREE_OPERAND (exp, 1))
-+        && original_target
-+        && GET_CODE (original_target) == REG
-+        && (GET_MODE (original_target)
-+            == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))
-+      {
-+        temp = expand_expr (TREE_OPERAND (exp, 0), original_target,
-+                            VOIDmode, 0);
-+
-+        /* If temp is constant, we can just compute the result.  */
-+        if (GET_CODE (temp) == CONST_INT)
-+          {
-+            if (INTVAL (temp) != 0)
-+              emit_move_insn (target, const1_rtx);
-+            else
-+              emit_move_insn (target, const0_rtx);
-+
-+            return target;
-+          }
-+
-+        if (temp != original_target)
-+          {
-+            enum machine_mode mode1 = GET_MODE (temp);
-+            if (mode1 == VOIDmode)
-+              mode1 = tmode != VOIDmode ? tmode : mode;
-+
-+            temp = copy_to_mode_reg (mode1, temp);
-+          }
-+
-+        op1 = gen_label_rtx ();
-+        emit_cmp_and_jump_insns (temp, const0_rtx, EQ, NULL_RTX,
-+                                 GET_MODE (temp), unsignedp, op1);
-+        emit_move_insn (temp, const1_rtx);
-+        emit_label (op1);
-+        return temp;
-+      }
-+
-+      /* If no set-flag instruction, must generate a conditional
-+       store into a temporary variable.  Drop through
-+       and handle this like && and ||.  */
-+
-+    case TRUTH_ANDIF_EXPR:
-+    case TRUTH_ORIF_EXPR:
-+      if (! ignore
-+        && (target == 0
-+            || modifier == EXPAND_STACK_PARM
-+            || ! safe_from_p (target, exp, 1)
-+            /* Make sure we don't have a hard reg (such as function's return
-+               value) live across basic blocks, if not optimizing.  */
-+            || (!optimize && GET_CODE (target) == REG
-+                && REGNO (target) < FIRST_PSEUDO_REGISTER)))
-+      target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
-+
-+      if (target)
-+      emit_clr_insn (target);
-+
-+      op1 = gen_label_rtx ();
-+      jumpifnot (exp, op1);
-+
-+      if (target)
-+      emit_0_to_1_insn (target);
-+
-+      emit_label (op1);
-+      return ignore ? const0_rtx : target;
-+
-+    case TRUTH_NOT_EXPR:
-+      if (modifier == EXPAND_STACK_PARM)
-+      target = 0;
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, 0);
-+      /* The parser is careful to generate TRUTH_NOT_EXPR
-+       only with operands that are always zero or one.  */
-+      temp = expand_binop (mode, xor_optab, op0, const1_rtx,
-+                         target, 1, OPTAB_LIB_WIDEN);
-+      if (temp == 0)
-+      abort ();
-+      return temp;
-+
-+    case COMPOUND_EXPR:
-+      expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
-+      emit_queue ();
-+      return expand_expr (TREE_OPERAND (exp, 1),
-+                        (ignore ? const0_rtx : target),
-+                        VOIDmode, modifier);
-+
-+    case COND_EXPR:
-+      /* If we would have a "singleton" (see below) were it not for a
-+       conversion in each arm, bring that conversion back out.  */
-+      if (TREE_CODE (TREE_OPERAND (exp, 1)) == NOP_EXPR
-+        && TREE_CODE (TREE_OPERAND (exp, 2)) == NOP_EXPR
-+        && (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 1), 0))
-+            == TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 2), 0))))
-+      {
-+        tree iftrue = TREE_OPERAND (TREE_OPERAND (exp, 1), 0);
-+        tree iffalse = TREE_OPERAND (TREE_OPERAND (exp, 2), 0);
-+
-+        if ((TREE_CODE_CLASS (TREE_CODE (iftrue)) == '2'
-+             && operand_equal_p (iffalse, TREE_OPERAND (iftrue, 0), 0))
-+            || (TREE_CODE_CLASS (TREE_CODE (iffalse)) == '2'
-+                && operand_equal_p (iftrue, TREE_OPERAND (iffalse, 0), 0))
-+            || (TREE_CODE_CLASS (TREE_CODE (iftrue)) == '1'
-+                && operand_equal_p (iffalse, TREE_OPERAND (iftrue, 0), 0))
-+            || (TREE_CODE_CLASS (TREE_CODE (iffalse)) == '1'
-+                && operand_equal_p (iftrue, TREE_OPERAND (iffalse, 0), 0)))
-+          return expand_expr (build1 (NOP_EXPR, type,
-+                                      build (COND_EXPR, TREE_TYPE (iftrue),
-+                                             TREE_OPERAND (exp, 0),
-+                                             iftrue, iffalse)),
-+                              target, tmode, modifier);
-+      }
-+
-+      {
-+      /* Note that COND_EXPRs whose type is a structure or union
-+         are required to be constructed to contain assignments of
-+         a temporary variable, so that we can evaluate them here
-+         for side effect only.  If type is void, we must do likewise.  */
-+
-+      /* If an arm of the branch requires a cleanup,
-+         only that cleanup is performed.  */
-+
-+      tree singleton = 0;
-+      tree binary_op = 0, unary_op = 0;
-+
-+      /* If this is (A ? 1 : 0) and A is a condition, just evaluate it and
-+         convert it to our mode, if necessary.  */
-+      if (integer_onep (TREE_OPERAND (exp, 1))
-+          && integer_zerop (TREE_OPERAND (exp, 2))
-+          && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<')
-+        {
-+          if (ignore)
-+            {
-+              expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
-+                           modifier);
-+              return const0_rtx;
-+            }
-+
-+          if (modifier == EXPAND_STACK_PARM)
-+            target = 0;
-+          op0 = expand_expr (TREE_OPERAND (exp, 0), target, mode, modifier);
-+          if (GET_MODE (op0) == mode)
-+            return op0;
-+
-+          if (target == 0)
-+            target = gen_reg_rtx (mode);
-+          convert_move (target, op0, unsignedp);
-+          return target;
-+        }
-+
-+      /* Check for X ? A + B : A.  If we have this, we can copy A to the
-+         output and conditionally add B.  Similarly for unary operations.
-+         Don't do this if X has side-effects because those side effects
-+         might affect A or B and the "?" operation is a sequence point in
-+         ANSI.  (operand_equal_p tests for side effects.)  */
-+
-+      if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 1))) == '2'
-+          && operand_equal_p (TREE_OPERAND (exp, 2),
-+                              TREE_OPERAND (TREE_OPERAND (exp, 1), 0), 0))
-+        singleton = TREE_OPERAND (exp, 2), binary_op = TREE_OPERAND (exp, 1);
-+      else if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 2))) == '2'
-+               && operand_equal_p (TREE_OPERAND (exp, 1),
-+                                   TREE_OPERAND (TREE_OPERAND (exp, 2), 0), 0))
-+        singleton = TREE_OPERAND (exp, 1), binary_op = TREE_OPERAND (exp, 2);
-+      else if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 1))) == '1'
-+               && operand_equal_p (TREE_OPERAND (exp, 2),
-+                                   TREE_OPERAND (TREE_OPERAND (exp, 1), 0), 0))
-+        singleton = TREE_OPERAND (exp, 2), unary_op = TREE_OPERAND (exp, 1);
-+      else if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 2))) == '1'
-+               && operand_equal_p (TREE_OPERAND (exp, 1),
-+                                   TREE_OPERAND (TREE_OPERAND (exp, 2), 0), 0))
-+        singleton = TREE_OPERAND (exp, 1), unary_op = TREE_OPERAND (exp, 2);
-+
-+      /* If we are not to produce a result, we have no target.  Otherwise,
-+         if a target was specified use it; it will not be used as an
-+         intermediate target unless it is safe.  If no target, use a
-+         temporary.  */
-+
-+      if (ignore)
-+        temp = 0;
-+      else if (modifier == EXPAND_STACK_PARM)
-+        temp = assign_temp (type, 0, 0, 1);
-+      else if (original_target
-+               && (safe_from_p (original_target, TREE_OPERAND (exp, 0), 1)
-+                   || (singleton && GET_CODE (original_target) == REG
-+                       && REGNO (original_target) >= FIRST_PSEUDO_REGISTER
-+                       && original_target == var_rtx (singleton)))
-+               && GET_MODE (original_target) == mode
-+#ifdef HAVE_conditional_move
-+               && (! can_conditionally_move_p (mode)
-+                   || GET_CODE (original_target) == REG
-+                   || TREE_ADDRESSABLE (type))
-+#endif
-+               && (GET_CODE (original_target) != MEM
-+                   || TREE_ADDRESSABLE (type)))
-+        temp = original_target;
-+      else if (TREE_ADDRESSABLE (type))
-+        abort ();
-+      else
-+        temp = assign_temp (type, 0, 0, 1);
-+
-+      /* If we had X ? A + C : A, with C a constant power of 2, and we can
-+         do the test of X as a store-flag operation, do this as
-+         A + ((X != 0) << log C).  Similarly for other simple binary
-+         operators.  Only do for C == 1 if BRANCH_COST is low.  */
-+      if (temp && singleton && binary_op
-+          && (TREE_CODE (binary_op) == PLUS_EXPR
-+              || TREE_CODE (binary_op) == MINUS_EXPR
-+              || TREE_CODE (binary_op) == BIT_IOR_EXPR
-+              || TREE_CODE (binary_op) == BIT_XOR_EXPR)
-+          && (BRANCH_COST >= 3 ? integer_pow2p (TREE_OPERAND (binary_op, 1))
-+              : integer_onep (TREE_OPERAND (binary_op, 1)))
-+          && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<')
-+        {
-+          rtx result;
-+          tree cond;
-+          optab boptab = (TREE_CODE (binary_op) == PLUS_EXPR
-+                          ? (TYPE_TRAP_SIGNED (TREE_TYPE (binary_op))
-+                             ? addv_optab : add_optab)
-+                          : TREE_CODE (binary_op) == MINUS_EXPR
-+                          ? (TYPE_TRAP_SIGNED (TREE_TYPE (binary_op))
-+                             ? subv_optab : sub_optab)
-+                          : TREE_CODE (binary_op) == BIT_IOR_EXPR ? ior_optab
-+                          : xor_optab);
-+
-+          /* If we had X ? A : A + 1, do this as A + (X == 0).  */
-+          if (singleton == TREE_OPERAND (exp, 1))
-+            cond = invert_truthvalue (TREE_OPERAND (exp, 0));
-+          else
-+            cond = TREE_OPERAND (exp, 0);
-+
-+          result = do_store_flag (cond, (safe_from_p (temp, singleton, 1)
-+                                         ? temp : NULL_RTX),
-+                                  mode, BRANCH_COST <= 1);
-+
-+          if (result != 0 && ! integer_onep (TREE_OPERAND (binary_op, 1)))
-+            result = expand_shift (LSHIFT_EXPR, mode, result,
-+                                   build_int_2 (tree_log2
-+                                                (TREE_OPERAND
-+                                                 (binary_op, 1)),
-+                                                0),
-+                                   (safe_from_p (temp, singleton, 1)
-+                                    ? temp : NULL_RTX), 0);
-+
-+          if (result)
-+            {
-+              op1 = expand_expr (singleton, NULL_RTX, VOIDmode, 0);
-+              return expand_binop (mode, boptab, op1, result, temp,
-+                                   unsignedp, OPTAB_LIB_WIDEN);
-+            }
-+        }
-+
-+      do_pending_stack_adjust ();
-+      NO_DEFER_POP;
-+      op0 = gen_label_rtx ();
-+
-+      if (singleton && ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0)))
-+        {
-+          if (temp != 0)
-+            {
-+              /* If the target conflicts with the other operand of the
-+                 binary op, we can't use it.  Also, we can't use the target
-+                 if it is a hard register, because evaluating the condition
-+                 might clobber it.  */
-+              if ((binary_op
-+                   && ! safe_from_p (temp, TREE_OPERAND (binary_op, 1), 1))
-+                  || (GET_CODE (temp) == REG
-+                      && REGNO (temp) < FIRST_PSEUDO_REGISTER))
-+                temp = gen_reg_rtx (mode);
-+              store_expr (singleton, temp,
-+                          modifier == EXPAND_STACK_PARM ? 2 : 0);
-+            }
-+          else
-+            expand_expr (singleton,
-+                         ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
-+          if (singleton == TREE_OPERAND (exp, 1))
-+            jumpif (TREE_OPERAND (exp, 0), op0);
-+          else
-+            jumpifnot (TREE_OPERAND (exp, 0), op0);
-+
-+          start_cleanup_deferral ();
-+          if (binary_op && temp == 0)
-+            /* Just touch the other operand.  */
-+            expand_expr (TREE_OPERAND (binary_op, 1),
-+                         ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
-+          else if (binary_op)
-+            store_expr (build (TREE_CODE (binary_op), type,
-+                               make_tree (type, temp),
-+                               TREE_OPERAND (binary_op, 1)),
-+                        temp, modifier == EXPAND_STACK_PARM ? 2 : 0);
-+          else
-+            store_expr (build1 (TREE_CODE (unary_op), type,
-+                                make_tree (type, temp)),
-+                        temp, modifier == EXPAND_STACK_PARM ? 2 : 0);
-+          op1 = op0;
-+        }
-+      /* Check for A op 0 ? A : FOO and A op 0 ? FOO : A where OP is any
-+         comparison operator.  If we have one of these cases, set the
-+         output to A, branch on A (cse will merge these two references),
-+         then set the output to FOO.  */
-+      else if (temp
-+               && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<'
-+               && integer_zerop (TREE_OPERAND (TREE_OPERAND (exp, 0), 1))
-+               && operand_equal_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
-+                                   TREE_OPERAND (exp, 1), 0)
-+               && (! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0))
-+                   || TREE_CODE (TREE_OPERAND (exp, 1)) == SAVE_EXPR)
-+               && safe_from_p (temp, TREE_OPERAND (exp, 2), 1))
-+        {
-+          if (GET_CODE (temp) == REG
-+              && REGNO (temp) < FIRST_PSEUDO_REGISTER)
-+            temp = gen_reg_rtx (mode);
-+          store_expr (TREE_OPERAND (exp, 1), temp,
-+                      modifier == EXPAND_STACK_PARM ? 2 : 0);
-+          jumpif (TREE_OPERAND (exp, 0), op0);
-+
-+          start_cleanup_deferral ();
-+          store_expr (TREE_OPERAND (exp, 2), temp,
-+                      modifier == EXPAND_STACK_PARM ? 2 : 0);
-+          op1 = op0;
-+        }
-+      else if (temp
-+               && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<'
-+               && integer_zerop (TREE_OPERAND (TREE_OPERAND (exp, 0), 1))
-+               && operand_equal_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
-+                                   TREE_OPERAND (exp, 2), 0)
-+               && (! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0))
-+                   || TREE_CODE (TREE_OPERAND (exp, 2)) == SAVE_EXPR)
-+               && safe_from_p (temp, TREE_OPERAND (exp, 1), 1))
-+        {
-+          if (GET_CODE (temp) == REG
-+              && REGNO (temp) < FIRST_PSEUDO_REGISTER)
-+            temp = gen_reg_rtx (mode);
-+          store_expr (TREE_OPERAND (exp, 2), temp,
-+                      modifier == EXPAND_STACK_PARM ? 2 : 0);
-+          jumpifnot (TREE_OPERAND (exp, 0), op0);
-+
-+          start_cleanup_deferral ();
-+          store_expr (TREE_OPERAND (exp, 1), temp,
-+                      modifier == EXPAND_STACK_PARM ? 2 : 0);
-+          op1 = op0;
-+        }
-+      else
-+        {
-+          op1 = gen_label_rtx ();
-+          jumpifnot (TREE_OPERAND (exp, 0), op0);
-+
-+          start_cleanup_deferral ();
-+
-+          /* One branch of the cond can be void, if it never returns. For
-+             example A ? throw : E  */
-+          if (temp != 0
-+              && TREE_TYPE (TREE_OPERAND (exp, 1)) != void_type_node)
-+            store_expr (TREE_OPERAND (exp, 1), temp,
-+                        modifier == EXPAND_STACK_PARM ? 2 : 0);
-+          else
-+            expand_expr (TREE_OPERAND (exp, 1),
-+                         ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
-+          end_cleanup_deferral ();
-+          emit_queue ();
-+          emit_jump_insn (gen_jump (op1));
-+          emit_barrier ();
-+          emit_label (op0);
-+          start_cleanup_deferral ();
-+          if (temp != 0
-+              && TREE_TYPE (TREE_OPERAND (exp, 2)) != void_type_node)
-+            store_expr (TREE_OPERAND (exp, 2), temp,
-+                        modifier == EXPAND_STACK_PARM ? 2 : 0);
-+          else
-+            expand_expr (TREE_OPERAND (exp, 2),
-+                         ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
-+        }
-+
-+      end_cleanup_deferral ();
-+
-+      emit_queue ();
-+      emit_label (op1);
-+      OK_DEFER_POP;
-+
-+      return temp;
-+      }
-+
-+    case TARGET_EXPR:
-+      {
-+      /* Something needs to be initialized, but we didn't know
-+         where that thing was when building the tree.  For example,
-+         it could be the return value of a function, or a parameter
-+         to a function which lays down in the stack, or a temporary
-+         variable which must be passed by reference.
-+
-+         We guarantee that the expression will either be constructed
-+         or copied into our original target.  */
-+
-+      tree slot = TREE_OPERAND (exp, 0);
-+      tree cleanups = NULL_TREE;
-+      tree exp1;
-+
-+      if (TREE_CODE (slot) != VAR_DECL)
-+        abort ();
-+
-+      if (! ignore)
-+        target = original_target;
-+
-+      /* Set this here so that if we get a target that refers to a
-+         register variable that's already been used, put_reg_into_stack
-+         knows that it should fix up those uses.  */
-+      TREE_USED (slot) = 1;
-+
-+      if (target == 0)
-+        {
-+          if (DECL_RTL_SET_P (slot))
-+            {
-+              target = DECL_RTL (slot);
-+              /* If we have already expanded the slot, so don't do
-+                 it again.  (mrs)  */
-+              if (TREE_OPERAND (exp, 1) == NULL_TREE)
-+                return target;
-+            }
-+          else
-+            {
-+              target = assign_temp (type, 2, 0, 1);
-+              /* All temp slots at this level must not conflict.  */
-+              preserve_temp_slots (target);
-+              SET_DECL_RTL (slot, target);
-+              if (TREE_ADDRESSABLE (slot))
-+                put_var_into_stack (slot, /*rescan=*/false);
-+
-+              /* Since SLOT is not known to the called function
-+                 to belong to its stack frame, we must build an explicit
-+                 cleanup.  This case occurs when we must build up a reference
-+                 to pass the reference as an argument.  In this case,
-+                 it is very likely that such a reference need not be
-+                 built here.  */
-+
-+              if (TREE_OPERAND (exp, 2) == 0)
-+                TREE_OPERAND (exp, 2)
-+                  = (*lang_hooks.maybe_build_cleanup) (slot);
-+              cleanups = TREE_OPERAND (exp, 2);
-+            }
-+        }
-+      else
-+        {
-+          /* This case does occur, when expanding a parameter which
-+             needs to be constructed on the stack.  The target
-+             is the actual stack address that we want to initialize.
-+             The function we call will perform the cleanup in this case.  */
-+
-+          /* If we have already assigned it space, use that space,
-+             not target that we were passed in, as our target
-+             parameter is only a hint.  */
-+          if (DECL_RTL_SET_P (slot))
-+            {
-+              target = DECL_RTL (slot);
-+              /* If we have already expanded the slot, so don't do
-+                   it again.  (mrs)  */
-+              if (TREE_OPERAND (exp, 1) == NULL_TREE)
-+                return target;
-+            }
-+          else
-+            {
-+              SET_DECL_RTL (slot, target);
-+              /* If we must have an addressable slot, then make sure that
-+                 the RTL that we just stored in slot is OK.  */
-+              if (TREE_ADDRESSABLE (slot))
-+                put_var_into_stack (slot, /*rescan=*/true);
-+            }
-+        }
-+
-+      exp1 = TREE_OPERAND (exp, 3) = TREE_OPERAND (exp, 1);
-+      /* Mark it as expanded.  */
-+      TREE_OPERAND (exp, 1) = NULL_TREE;
-+
-+      store_expr (exp1, target, modifier == EXPAND_STACK_PARM ? 2 : 0);
-+
-+      expand_decl_cleanup_eh (NULL_TREE, cleanups, CLEANUP_EH_ONLY (exp));
-+
-+      return target;
-+      }
-+
-+    case INIT_EXPR:
-+      {
-+      tree lhs = TREE_OPERAND (exp, 0);
-+      tree rhs = TREE_OPERAND (exp, 1);
-+
-+      temp = expand_assignment (lhs, rhs, ! ignore, original_target != 0);
-+      return temp;
-+      }
-+
-+    case MODIFY_EXPR:
-+      {
-+      /* If lhs is complex, expand calls in rhs before computing it.
-+         That's so we don't compute a pointer and save it over a
-+         call.  If lhs is simple, compute it first so we can give it
-+         as a target if the rhs is just a call.  This avoids an
-+         extra temp and copy and that prevents a partial-subsumption
-+         which makes bad code.  Actually we could treat
-+         component_ref's of vars like vars.  */
-+
-+      tree lhs = TREE_OPERAND (exp, 0);
-+      tree rhs = TREE_OPERAND (exp, 1);
-+
-+      temp = 0;
-+
-+      /* Check for |= or &= of a bitfield of size one into another bitfield
-+         of size 1.  In this case, (unless we need the result of the
-+         assignment) we can do this more efficiently with a
-+         test followed by an assignment, if necessary.
-+
-+         ??? At this point, we can't get a BIT_FIELD_REF here.  But if
-+         things change so we do, this code should be enhanced to
-+         support it.  */
-+      if (ignore
-+          && TREE_CODE (lhs) == COMPONENT_REF
-+          && (TREE_CODE (rhs) == BIT_IOR_EXPR
-+              || TREE_CODE (rhs) == BIT_AND_EXPR)
-+          && TREE_OPERAND (rhs, 0) == lhs
-+          && TREE_CODE (TREE_OPERAND (rhs, 1)) == COMPONENT_REF
-+          && integer_onep (DECL_SIZE (TREE_OPERAND (lhs, 1)))
-+          && integer_onep (DECL_SIZE (TREE_OPERAND (TREE_OPERAND (rhs, 1), 1))))
-+        {
-+          rtx label = gen_label_rtx ();
-+
-+          do_jump (TREE_OPERAND (rhs, 1),
-+                   TREE_CODE (rhs) == BIT_IOR_EXPR ? label : 0,
-+                   TREE_CODE (rhs) == BIT_AND_EXPR ? label : 0);
-+          expand_assignment (lhs, convert (TREE_TYPE (rhs),
-+                                           (TREE_CODE (rhs) == BIT_IOR_EXPR
-+                                            ? integer_one_node
-+                                            : integer_zero_node)),
-+                             0, 0);
-+          do_pending_stack_adjust ();
-+          emit_label (label);
-+          return const0_rtx;
-+        }
-+
-+      temp = expand_assignment (lhs, rhs, ! ignore, original_target != 0);
-+
-+      return temp;
-+      }
-+
-+    case RETURN_EXPR:
-+      if (!TREE_OPERAND (exp, 0))
-+      expand_null_return ();
-+      else
-+      expand_return (TREE_OPERAND (exp, 0));
-+      return const0_rtx;
-+
-+    case PREINCREMENT_EXPR:
-+    case PREDECREMENT_EXPR:
-+      return expand_increment (exp, 0, ignore);
-+
-+    case POSTINCREMENT_EXPR:
-+    case POSTDECREMENT_EXPR:
-+      /* Faster to treat as pre-increment if result is not used.  */
-+      return expand_increment (exp, ! ignore, ignore);
-+
-+    case ADDR_EXPR:
-+      if (modifier == EXPAND_STACK_PARM)
-+      target = 0;
-+      /* Are we taking the address of a nested function?  */
-+      if (TREE_CODE (TREE_OPERAND (exp, 0)) == FUNCTION_DECL
-+        && decl_function_context (TREE_OPERAND (exp, 0)) != 0
-+        && ! DECL_NO_STATIC_CHAIN (TREE_OPERAND (exp, 0))
-+        && ! TREE_STATIC (exp))
-+      {
-+        op0 = trampoline_address (TREE_OPERAND (exp, 0));
-+        op0 = force_operand (op0, target);
-+      }
-+      /* If we are taking the address of something erroneous, just
-+       return a zero.  */
-+      else if (TREE_CODE (TREE_OPERAND (exp, 0)) == ERROR_MARK)
-+      return const0_rtx;
-+      /* If we are taking the address of a constant and are at the
-+       top level, we have to use output_constant_def since we can't
-+       call force_const_mem at top level.  */
-+      else if (cfun == 0
-+             && (TREE_CODE (TREE_OPERAND (exp, 0)) == CONSTRUCTOR
-+                 || (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0)))
-+                     == 'c')))
-+      op0 = XEXP (output_constant_def (TREE_OPERAND (exp, 0), 0), 0);
-+      else
-+      {
-+        /* We make sure to pass const0_rtx down if we came in with
-+           ignore set, to avoid doing the cleanups twice for something.  */
-+        op0 = expand_expr (TREE_OPERAND (exp, 0),
-+                           ignore ? const0_rtx : NULL_RTX, VOIDmode,
-+                           (modifier == EXPAND_INITIALIZER
-+                            ? modifier : EXPAND_CONST_ADDRESS));
-+
-+        /* If we are going to ignore the result, OP0 will have been set
-+           to const0_rtx, so just return it.  Don't get confused and
-+           think we are taking the address of the constant.  */
-+        if (ignore)
-+          return op0;
-+
-+        /* Pass 1 for MODIFY, so that protect_from_queue doesn't get
-+           clever and returns a REG when given a MEM.  */
-+        op0 = protect_from_queue (op0, 1);
-+
-+        /* We would like the object in memory.  If it is a constant, we can
-+           have it be statically allocated into memory.  For a non-constant,
-+           we need to allocate some memory and store the value into it.  */
-+
-+        if (CONSTANT_P (op0))
-+          op0 = force_const_mem (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))),
-+                                 op0);
-+        else if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG
-+                 || GET_CODE (op0) == CONCAT || GET_CODE (op0) == ADDRESSOF
-+                 || GET_CODE (op0) == PARALLEL)
-+          {
-+            /* If the operand is a SAVE_EXPR, we can deal with this by
-+               forcing the SAVE_EXPR into memory.  */
-+            if (TREE_CODE (TREE_OPERAND (exp, 0)) == SAVE_EXPR)
-+              {
-+                put_var_into_stack (TREE_OPERAND (exp, 0),
-+                                    /*rescan=*/true);
-+                op0 = SAVE_EXPR_RTL (TREE_OPERAND (exp, 0));
-+              }
-+            else
-+              {
-+                /* If this object is in a register, it can't be BLKmode.  */
-+                tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
-+                rtx memloc = assign_temp (inner_type, 1, 1, 1);
-+
-+                if (GET_CODE (op0) == PARALLEL)
-+                  /* Handle calls that pass values in multiple
-+                     non-contiguous locations.  The Irix 6 ABI has examples
-+                     of this.  */
-+                  emit_group_store (memloc, op0,
-+                                    int_size_in_bytes (inner_type));
-+                else
-+                  emit_move_insn (memloc, op0);
-+
-+                op0 = memloc;
-+              }
-+          }
-+
-+        if (GET_CODE (op0) != MEM)
-+          abort ();
-+
-+        mark_temp_addr_taken (op0);
-+        if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
-+          {
-+            op0 = XEXP (op0, 0);
-+#ifdef POINTERS_EXTEND_UNSIGNED
-+            if (GET_MODE (op0) == Pmode && GET_MODE (op0) != mode
-+                && mode == ptr_mode)
-+              op0 = convert_memory_address (ptr_mode, op0);
-+#endif
-+            return op0;
-+          }
-+
-+        /* If OP0 is not aligned as least as much as the type requires, we
-+           need to make a temporary, copy OP0 to it, and take the address of
-+           the temporary.  We want to use the alignment of the type, not of
-+           the operand.  Note that this is incorrect for FUNCTION_TYPE, but
-+           the test for BLKmode means that can't happen.  The test for
-+           BLKmode is because we never make mis-aligned MEMs with
-+           non-BLKmode.
-+
-+           We don't need to do this at all if the machine doesn't have
-+           strict alignment.  */
-+        if (STRICT_ALIGNMENT && GET_MODE (op0) == BLKmode
-+            && (TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0)))
-+                > MEM_ALIGN (op0))
-+            && MEM_ALIGN (op0) < BIGGEST_ALIGNMENT)
-+          {
-+            tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
-+            rtx new;
-+
-+            if (TYPE_ALIGN_OK (inner_type))
-+              abort ();
-+
-+            if (TREE_ADDRESSABLE (inner_type))
-+              {
-+                /* We can't make a bitwise copy of this object, so fail.  */
-+                error ("cannot take the address of an unaligned member");
-+                return const0_rtx;
-+              }
-+
-+            new = assign_stack_temp_for_type
-+              (TYPE_MODE (inner_type),
-+               MEM_SIZE (op0) ? INTVAL (MEM_SIZE (op0))
-+               : int_size_in_bytes (inner_type),
-+               1, build_qualified_type (inner_type,
-+                                        (TYPE_QUALS (inner_type)
-+                                         | TYPE_QUAL_CONST)));
-+
-+            emit_block_move (new, op0, expr_size (TREE_OPERAND (exp, 0)),
-+                             (modifier == EXPAND_STACK_PARM
-+                              ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
-+
-+            op0 = new;
-+          }
-+
-+        op0 = force_operand (XEXP (op0, 0), target);
-+      }
-+
-+      if (flag_force_addr
-+        && GET_CODE (op0) != REG
-+        && modifier != EXPAND_CONST_ADDRESS
-+        && modifier != EXPAND_INITIALIZER
-+        && modifier != EXPAND_SUM)
-+      op0 = force_reg (Pmode, op0);
-+
-+      if (GET_CODE (op0) == REG
-+        && ! REG_USERVAR_P (op0))
-+      mark_reg_pointer (op0, TYPE_ALIGN (TREE_TYPE (type)));
-+
-+#ifdef POINTERS_EXTEND_UNSIGNED
-+      if (GET_MODE (op0) == Pmode && GET_MODE (op0) != mode
-+        && mode == ptr_mode)
-+      op0 = convert_memory_address (ptr_mode, op0);
-+#endif
-+
-+      return op0;
-+
-+    case ENTRY_VALUE_EXPR:
-+      abort ();
-+
-+    /* COMPLEX type for Extended Pascal & Fortran  */
-+    case COMPLEX_EXPR:
-+      {
-+      enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
-+      rtx insns;
-+
-+      /* Get the rtx code of the operands.  */
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0);
-+      op1 = expand_expr (TREE_OPERAND (exp, 1), 0, VOIDmode, 0);
-+
-+      if (! target)
-+        target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
-+
-+      start_sequence ();
-+
-+      /* Move the real (op0) and imaginary (op1) parts to their location.  */
-+      emit_move_insn (gen_realpart (mode, target), op0);
-+      emit_move_insn (gen_imagpart (mode, target), op1);
-+
-+      insns = get_insns ();
-+      end_sequence ();
-+
-+      /* Complex construction should appear as a single unit.  */
-+      /* If TARGET is a CONCAT, we got insns like RD = RS, ID = IS,
-+         each with a separate pseudo as destination.
-+         It's not correct for flow to treat them as a unit.  */
-+      if (GET_CODE (target) != CONCAT)
-+        emit_no_conflict_block (insns, target, op0, op1, NULL_RTX);
-+      else
-+        emit_insn (insns);
-+
-+      return target;
-+      }
-+
-+    case REALPART_EXPR:
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0);
-+      return gen_realpart (mode, op0);
-+
-+    case IMAGPART_EXPR:
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0);
-+      return gen_imagpart (mode, op0);
-+
-+    case CONJ_EXPR:
-+      {
-+      enum machine_mode partmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
-+      rtx imag_t;
-+      rtx insns;
-+
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0);
-+
-+      if (! target)
-+        target = gen_reg_rtx (mode);
-+
-+      start_sequence ();
-+
-+      /* Store the realpart and the negated imagpart to target.  */
-+      emit_move_insn (gen_realpart (partmode, target),
-+                      gen_realpart (partmode, op0));
-+
-+      imag_t = gen_imagpart (partmode, target);
-+      temp = expand_unop (partmode,
-+                          ! unsignedp && flag_trapv
-+                          && (GET_MODE_CLASS(partmode) == MODE_INT)
-+                          ? negv_optab : neg_optab,
-+                          gen_imagpart (partmode, op0), imag_t, 0);
-+      if (temp != imag_t)
-+        emit_move_insn (imag_t, temp);
-+
-+      insns = get_insns ();
-+      end_sequence ();
-+
-+      /* Conjugate should appear as a single unit
-+         If TARGET is a CONCAT, we got insns like RD = RS, ID = - IS,
-+         each with a separate pseudo as destination.
-+         It's not correct for flow to treat them as a unit.  */
-+      if (GET_CODE (target) != CONCAT)
-+        emit_no_conflict_block (insns, target, op0, NULL_RTX, NULL_RTX);
-+      else
-+        emit_insn (insns);
-+
-+      return target;
-+      }
-+
-+    case TRY_CATCH_EXPR:
-+      {
-+      tree handler = TREE_OPERAND (exp, 1);
-+
-+      expand_eh_region_start ();
-+
-+      op0 = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0);
-+
-+      expand_eh_region_end_cleanup (handler);
-+
-+      return op0;
-+      }
-+
-+    case TRY_FINALLY_EXPR:
-+      {
-+      tree try_block = TREE_OPERAND (exp, 0);
-+      tree finally_block = TREE_OPERAND (exp, 1);
-+
-+        if (!optimize || unsafe_for_reeval (finally_block) > 1)
-+        {
-+          /* In this case, wrapping FINALLY_BLOCK in an UNSAVE_EXPR
-+             is not sufficient, so we cannot expand the block twice.
-+             So we play games with GOTO_SUBROUTINE_EXPR to let us
-+             expand the thing only once.  */
-+          /* When not optimizing, we go ahead with this form since
-+             (1) user breakpoints operate more predictably without
-+                 code duplication, and
-+             (2) we're not running any of the global optimizers
-+                 that would explode in time/space with the highly
-+                 connected CFG created by the indirect branching.  */
-+
-+          rtx finally_label = gen_label_rtx ();
-+          rtx done_label = gen_label_rtx ();
-+          rtx return_link = gen_reg_rtx (Pmode);
-+          tree cleanup = build (GOTO_SUBROUTINE_EXPR, void_type_node,
-+                                (tree) finally_label, (tree) return_link);
-+          TREE_SIDE_EFFECTS (cleanup) = 1;
-+
-+          /* Start a new binding layer that will keep track of all cleanup
-+             actions to be performed.  */
-+          expand_start_bindings (2);
-+          target_temp_slot_level = temp_slot_level;
-+
-+          expand_decl_cleanup (NULL_TREE, cleanup);
-+          op0 = expand_expr (try_block, target, tmode, modifier);
-+
-+          preserve_temp_slots (op0);
-+          expand_end_bindings (NULL_TREE, 0, 0);
-+          emit_jump (done_label);
-+          emit_label (finally_label);
-+          expand_expr (finally_block, const0_rtx, VOIDmode, 0);
-+          emit_indirect_jump (return_link);
-+          emit_label (done_label);
-+        }
-+      else
-+        {
-+          expand_start_bindings (2);
-+          target_temp_slot_level = temp_slot_level;
-+
-+          expand_decl_cleanup (NULL_TREE, finally_block);
-+          op0 = expand_expr (try_block, target, tmode, modifier);
-+
-+          preserve_temp_slots (op0);
-+          expand_end_bindings (NULL_TREE, 0, 0);
-+        }
-+
-+      return op0;
-+      }
-+
-+    case GOTO_SUBROUTINE_EXPR:
-+      {
-+      rtx subr = (rtx) TREE_OPERAND (exp, 0);
-+      rtx return_link = *(rtx *) &TREE_OPERAND (exp, 1);
-+      rtx return_address = gen_label_rtx ();
-+      emit_move_insn (return_link,
-+                      gen_rtx_LABEL_REF (Pmode, return_address));
-+      emit_jump (subr);
-+      emit_label (return_address);
-+      return const0_rtx;
-+      }
-+
-+    case VA_ARG_EXPR:
-+      return expand_builtin_va_arg (TREE_OPERAND (exp, 0), type);
-+
-+    case EXC_PTR_EXPR:
-+      return get_exception_pointer (cfun);
-+
-+    case FDESC_EXPR:
-+      /* Function descriptors are not valid except for as
-+       initialization constants, and should not be expanded.  */
-+      abort ();
-+
-+    default:
-+      return (*lang_hooks.expand_expr) (exp, original_target, tmode, modifier);
-+    }
-+
-+  /* Here to do an ordinary binary operator, generating an instruction
-+     from the optab already placed in `this_optab'.  */
-+ binop:
-+  if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
-+    subtarget = 0;
-+  op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
-+  op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
-+ binop2:
-+  if (modifier == EXPAND_STACK_PARM)
-+    target = 0;
-+  temp = expand_binop (mode, this_optab, op0, op1, target,
-+                     unsignedp, OPTAB_LIB_WIDEN);
-+  if (temp == 0)
-+    abort ();
-+  return temp;
-+}
-+\f
-+/* Subroutine of above: returns 1 if OFFSET corresponds to an offset that
-+   when applied to the address of EXP produces an address known to be
-+   aligned more than BIGGEST_ALIGNMENT.  */
-+
-+static int
-+is_aligning_offset (offset, exp)
-+     tree offset;
-+     tree exp;
-+{
-+  /* Strip off any conversions and WITH_RECORD_EXPR nodes.  */
-+  while (TREE_CODE (offset) == NON_LVALUE_EXPR
-+       || TREE_CODE (offset) == NOP_EXPR
-+       || TREE_CODE (offset) == CONVERT_EXPR
-+       || TREE_CODE (offset) == WITH_RECORD_EXPR)
-+    offset = TREE_OPERAND (offset, 0);
-+
-+  /* We must now have a BIT_AND_EXPR with a constant that is one less than
-+     power of 2 and which is larger than BIGGEST_ALIGNMENT.  */
-+  if (TREE_CODE (offset) != BIT_AND_EXPR
-+      || !host_integerp (TREE_OPERAND (offset, 1), 1)
-+      || compare_tree_int (TREE_OPERAND (offset, 1), BIGGEST_ALIGNMENT) <= 0
-+      || !exact_log2 (tree_low_cst (TREE_OPERAND (offset, 1), 1) + 1) < 0)
-+    return 0;
-+
-+  /* Look at the first operand of BIT_AND_EXPR and strip any conversion.
-+     It must be NEGATE_EXPR.  Then strip any more conversions.  */
-+  offset = TREE_OPERAND (offset, 0);
-+  while (TREE_CODE (offset) == NON_LVALUE_EXPR
-+       || TREE_CODE (offset) == NOP_EXPR
-+       || TREE_CODE (offset) == CONVERT_EXPR)
-+    offset = TREE_OPERAND (offset, 0);
-+
-+  if (TREE_CODE (offset) != NEGATE_EXPR)
-+    return 0;
-+
-+  offset = TREE_OPERAND (offset, 0);
-+  while (TREE_CODE (offset) == NON_LVALUE_EXPR
-+       || TREE_CODE (offset) == NOP_EXPR
-+       || TREE_CODE (offset) == CONVERT_EXPR)
-+    offset = TREE_OPERAND (offset, 0);
-+
-+  /* This must now be the address either of EXP or of a PLACEHOLDER_EXPR
-+     whose type is the same as EXP.  */
-+  return (TREE_CODE (offset) == ADDR_EXPR
-+        && (TREE_OPERAND (offset, 0) == exp
-+            || (TREE_CODE (TREE_OPERAND (offset, 0)) == PLACEHOLDER_EXPR
-+                && (TREE_TYPE (TREE_OPERAND (offset, 0))
-+                    == TREE_TYPE (exp)))));
-+}
-+\f
-+/* Return the tree node if an ARG corresponds to a string constant or zero
-+   if it doesn't.  If we return nonzero, set *PTR_OFFSET to the offset
-+   in bytes within the string that ARG is accessing.  The type of the
-+   offset will be `sizetype'.  */
-+
-+tree
-+string_constant (arg, ptr_offset)
-+     tree arg;
-+     tree *ptr_offset;
-+{
-+  STRIP_NOPS (arg);
-+
-+  if (TREE_CODE (arg) == ADDR_EXPR
-+      && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST)
-+    {
-+      *ptr_offset = size_zero_node;
-+      return TREE_OPERAND (arg, 0);
-+    }
-+  else if (TREE_CODE (arg) == PLUS_EXPR)
-+    {
-+      tree arg0 = TREE_OPERAND (arg, 0);
-+      tree arg1 = TREE_OPERAND (arg, 1);
-+
-+      STRIP_NOPS (arg0);
-+      STRIP_NOPS (arg1);
-+
-+      if (TREE_CODE (arg0) == ADDR_EXPR
-+        && TREE_CODE (TREE_OPERAND (arg0, 0)) == STRING_CST)
-+      {
-+        *ptr_offset = convert (sizetype, arg1);
-+        return TREE_OPERAND (arg0, 0);
-+      }
-+      else if (TREE_CODE (arg1) == ADDR_EXPR
-+             && TREE_CODE (TREE_OPERAND (arg1, 0)) == STRING_CST)
-+      {
-+        *ptr_offset = convert (sizetype, arg0);
-+        return TREE_OPERAND (arg1, 0);
-+      }
-+    }
-+
-+  return 0;
-+}
-+\f
-+/* Expand code for a post- or pre- increment or decrement
-+   and return the RTX for the result.
-+   POST is 1 for postinc/decrements and 0 for preinc/decrements.  */
-+
-+static rtx
-+expand_increment (exp, post, ignore)
-+     tree exp;
-+     int post, ignore;
-+{
-+  rtx op0, op1;
-+  rtx temp, value;
-+  tree incremented = TREE_OPERAND (exp, 0);
-+  optab this_optab = add_optab;
-+  int icode;
-+  enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
-+  int op0_is_copy = 0;
-+  int single_insn = 0;
-+  /* 1 means we can't store into OP0 directly,
-+     because it is a subreg narrower than a word,
-+     and we don't dare clobber the rest of the word.  */
-+  int bad_subreg = 0;
-+
-+  /* Stabilize any component ref that might need to be
-+     evaluated more than once below.  */
-+  if (!post
-+      || TREE_CODE (incremented) == BIT_FIELD_REF
-+      || (TREE_CODE (incremented) == COMPONENT_REF
-+        && (TREE_CODE (TREE_OPERAND (incremented, 0)) != INDIRECT_REF
-+            || DECL_BIT_FIELD (TREE_OPERAND (incremented, 1)))))
-+    incremented = stabilize_reference (incremented);
-+  /* Nested *INCREMENT_EXPRs can happen in C++.  We must force innermost
-+     ones into save exprs so that they don't accidentally get evaluated
-+     more than once by the code below.  */
-+  if (TREE_CODE (incremented) == PREINCREMENT_EXPR
-+      || TREE_CODE (incremented) == PREDECREMENT_EXPR)
-+    incremented = save_expr (incremented);
-+
-+  /* Compute the operands as RTX.
-+     Note whether OP0 is the actual lvalue or a copy of it:
-+     I believe it is a copy iff it is a register or subreg
-+     and insns were generated in computing it.  */
-+
-+  temp = get_last_insn ();
-+  op0 = expand_expr (incremented, NULL_RTX, VOIDmode, 0);
-+
-+  /* If OP0 is a SUBREG made for a promoted variable, we cannot increment
-+     in place but instead must do sign- or zero-extension during assignment,
-+     so we copy it into a new register and let the code below use it as
-+     a copy.
-+
-+     Note that we can safely modify this SUBREG since it is know not to be
-+     shared (it was made by the expand_expr call above).  */
-+
-+  if (GET_CODE (op0) == SUBREG && SUBREG_PROMOTED_VAR_P (op0))
-+    {
-+      if (post)
-+      SUBREG_REG (op0) = copy_to_reg (SUBREG_REG (op0));
-+      else
-+      bad_subreg = 1;
-+    }
-+  else if (GET_CODE (op0) == SUBREG
-+         && GET_MODE_BITSIZE (GET_MODE (op0)) < BITS_PER_WORD)
-+    {
-+      /* We cannot increment this SUBREG in place.  If we are
-+       post-incrementing, get a copy of the old value.  Otherwise,
-+       just mark that we cannot increment in place.  */
-+      if (post)
-+      op0 = copy_to_reg (op0);
-+      else
-+      bad_subreg = 1;
-+    }
-+
-+  op0_is_copy = ((GET_CODE (op0) == SUBREG || GET_CODE (op0) == REG)
-+               && temp != get_last_insn ());
-+  op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
-+
-+  /* Decide whether incrementing or decrementing.  */
-+  if (TREE_CODE (exp) == POSTDECREMENT_EXPR
-+      || TREE_CODE (exp) == PREDECREMENT_EXPR)
-+    this_optab = sub_optab;
-+
-+  /* Convert decrement by a constant into a negative increment.  */
-+  if (this_optab == sub_optab
-+      && GET_CODE (op1) == CONST_INT)
-+    {
-+      op1 = GEN_INT (-INTVAL (op1));
-+      this_optab = add_optab;
-+    }
-+
-+  if (TYPE_TRAP_SIGNED (TREE_TYPE (exp)))
-+    this_optab = this_optab == add_optab ? addv_optab : subv_optab;
-+
-+  /* For a preincrement, see if we can do this with a single instruction.  */
-+  if (!post)
-+    {
-+      icode = (int) this_optab->handlers[(int) mode].insn_code;
-+      if (icode != (int) CODE_FOR_nothing
-+        /* Make sure that OP0 is valid for operands 0 and 1
-+           of the insn we want to queue.  */
-+        && (*insn_data[icode].operand[0].predicate) (op0, mode)
-+        && (*insn_data[icode].operand[1].predicate) (op0, mode)
-+        && (*insn_data[icode].operand[2].predicate) (op1, mode))
-+      single_insn = 1;
-+    }
-+
-+  /* If OP0 is not the actual lvalue, but rather a copy in a register,
-+     then we cannot just increment OP0.  We must therefore contrive to
-+     increment the original value.  Then, for postincrement, we can return
-+     OP0 since it is a copy of the old value.  For preincrement, expand here
-+     unless we can do it with a single insn.
-+
-+     Likewise if storing directly into OP0 would clobber high bits
-+     we need to preserve (bad_subreg).  */
-+  if (op0_is_copy || (!post && !single_insn) || bad_subreg)
-+    {
-+      /* This is the easiest way to increment the value wherever it is.
-+       Problems with multiple evaluation of INCREMENTED are prevented
-+       because either (1) it is a component_ref or preincrement,
-+       in which case it was stabilized above, or (2) it is an array_ref
-+       with constant index in an array in a register, which is
-+       safe to reevaluate.  */
-+      tree newexp = build (((TREE_CODE (exp) == POSTDECREMENT_EXPR
-+                           || TREE_CODE (exp) == PREDECREMENT_EXPR)
-+                          ? MINUS_EXPR : PLUS_EXPR),
-+                         TREE_TYPE (exp),
-+                         incremented,
-+                         TREE_OPERAND (exp, 1));
-+
-+      while (TREE_CODE (incremented) == NOP_EXPR
-+           || TREE_CODE (incremented) == CONVERT_EXPR)
-+      {
-+        newexp = convert (TREE_TYPE (incremented), newexp);
-+        incremented = TREE_OPERAND (incremented, 0);
-+      }
-+
-+      temp = expand_assignment (incremented, newexp, ! post && ! ignore , 0);
-+      return post ? op0 : temp;
-+    }
-+
-+  if (post)
-+    {
-+      /* We have a true reference to the value in OP0.
-+       If there is an insn to add or subtract in this mode, queue it.
-+       Queueing the increment insn avoids the register shuffling
-+       that often results if we must increment now and first save
-+       the old value for subsequent use.  */
-+
-+#if 0  /* Turned off to avoid making extra insn for indexed memref.  */
-+      op0 = stabilize (op0);
-+#endif
-+
-+      icode = (int) this_optab->handlers[(int) mode].insn_code;
-+      if (icode != (int) CODE_FOR_nothing
-+        /* Make sure that OP0 is valid for operands 0 and 1
-+           of the insn we want to queue.  */
-+        && (*insn_data[icode].operand[0].predicate) (op0, mode)
-+        && (*insn_data[icode].operand[1].predicate) (op0, mode))
-+      {
-+        if (! (*insn_data[icode].operand[2].predicate) (op1, mode))
-+          op1 = force_reg (mode, op1);
-+
-+        return enqueue_insn (op0, GEN_FCN (icode) (op0, op0, op1));
-+      }
-+      if (icode != (int) CODE_FOR_nothing && GET_CODE (op0) == MEM)
-+      {
-+        rtx addr = (general_operand (XEXP (op0, 0), mode)
-+                    ? force_reg (Pmode, XEXP (op0, 0))
-+                    : copy_to_reg (XEXP (op0, 0)));
-+        rtx temp, result;
-+
-+        op0 = replace_equiv_address (op0, addr);
-+        temp = force_reg (GET_MODE (op0), op0);
-+        if (! (*insn_data[icode].operand[2].predicate) (op1, mode))
-+          op1 = force_reg (mode, op1);
-+
-+        /* The increment queue is LIFO, thus we have to `queue'
-+           the instructions in reverse order.  */
-+        enqueue_insn (op0, gen_move_insn (op0, temp));
-+        result = enqueue_insn (temp, GEN_FCN (icode) (temp, temp, op1));
-+        return result;
-+      }
-+    }
-+
-+  /* Preincrement, or we can't increment with one simple insn.  */
-+  if (post)
-+    /* Save a copy of the value before inc or dec, to return it later.  */
-+    temp = value = copy_to_reg (op0);
-+  else
-+    /* Arrange to return the incremented value.  */
-+    /* Copy the rtx because expand_binop will protect from the queue,
-+       and the results of that would be invalid for us to return
-+       if our caller does emit_queue before using our result.  */
-+    temp = copy_rtx (value = op0);
-+
-+  /* Increment however we can.  */
-+  op1 = expand_binop (mode, this_optab, value, op1, op0,
-+                    TREE_UNSIGNED (TREE_TYPE (exp)), OPTAB_LIB_WIDEN);
-+
-+  /* Make sure the value is stored into OP0.  */
-+  if (op1 != op0)
-+    emit_move_insn (op0, op1);
-+
-+  return temp;
-+}
-+\f
-+/* At the start of a function, record that we have no previously-pushed
-+   arguments waiting to be popped.  */
-+
-+void
-+init_pending_stack_adjust ()
-+{
-+  pending_stack_adjust = 0;
-+}
-+
-+/* When exiting from function, if safe, clear out any pending stack adjust
-+   so the adjustment won't get done.
-+
-+   Note, if the current function calls alloca, then it must have a
-+   frame pointer regardless of the value of flag_omit_frame_pointer.  */
-+
-+void
-+clear_pending_stack_adjust ()
-+{
-+#ifdef EXIT_IGNORE_STACK
-+  if (optimize > 0
-+      && (! flag_omit_frame_pointer || current_function_calls_alloca)
-+      && EXIT_IGNORE_STACK
-+      && ! (DECL_INLINE (current_function_decl) && ! flag_no_inline)
-+      && ! flag_inline_functions)
-+    {
-+      stack_pointer_delta -= pending_stack_adjust,
-+      pending_stack_adjust = 0;
-+    }
-+#endif
-+}
-+
-+/* Pop any previously-pushed arguments that have not been popped yet.  */
-+
-+void
-+do_pending_stack_adjust ()
-+{
-+  if (inhibit_defer_pop == 0)
-+    {
-+      if (pending_stack_adjust != 0)
-+      adjust_stack (GEN_INT (pending_stack_adjust));
-+      pending_stack_adjust = 0;
-+    }
-+}
-+\f
-+/* Expand conditional expressions.  */
-+
-+/* Generate code to evaluate EXP and jump to LABEL if the value is zero.
-+   LABEL is an rtx of code CODE_LABEL, in this function and all the
-+   functions here.  */
-+
-+void
-+jumpifnot (exp, label)
-+     tree exp;
-+     rtx label;
-+{
-+  do_jump (exp, label, NULL_RTX);
-+}
-+
-+/* Generate code to evaluate EXP and jump to LABEL if the value is nonzero.  */
-+
-+void
-+jumpif (exp, label)
-+     tree exp;
-+     rtx label;
-+{
-+  do_jump (exp, NULL_RTX, label);
-+}
-+
-+/* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
-+   the result is zero, or IF_TRUE_LABEL if the result is one.
-+   Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero,
-+   meaning fall through in that case.
-+
-+   do_jump always does any pending stack adjust except when it does not
-+   actually perform a jump.  An example where there is no jump
-+   is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null.
-+
-+   This function is responsible for optimizing cases such as
-+   &&, || and comparison operators in EXP.  */
-+
-+void
-+do_jump (exp, if_false_label, if_true_label)
-+     tree exp;
-+     rtx if_false_label, if_true_label;
-+{
-+  enum tree_code code = TREE_CODE (exp);
-+  /* Some cases need to create a label to jump to
-+     in order to properly fall through.
-+     These cases set DROP_THROUGH_LABEL nonzero.  */
-+  rtx drop_through_label = 0;
-+  rtx temp;
-+  int i;
-+  tree type;
-+  enum machine_mode mode;
-+
-+#ifdef MAX_INTEGER_COMPUTATION_MODE
-+  check_max_integer_computation_mode (exp);
-+#endif
-+
-+  emit_queue ();
-+
-+  switch (code)
-+    {
-+    case ERROR_MARK:
-+      break;
-+
-+    case INTEGER_CST:
-+      temp = integer_zerop (exp) ? if_false_label : if_true_label;
-+      if (temp)
-+      emit_jump (temp);
-+      break;
-+
-+#if 0
-+      /* This is not true with #pragma weak  */
-+    case ADDR_EXPR:
-+      /* The address of something can never be zero.  */
-+      if (if_true_label)
-+      emit_jump (if_true_label);
-+      break;
-+#endif
-+
-+    case UNSAVE_EXPR:
-+      do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
-+      TREE_OPERAND (exp, 0)
-+      = (*lang_hooks.unsave_expr_now) (TREE_OPERAND (exp, 0));
-+      break;
-+
-+    case NOP_EXPR:
-+      if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF
-+        || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF
-+        || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF
-+        || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF)
-+      goto normal;
-+    case CONVERT_EXPR:
-+      /* If we are narrowing the operand, we have to do the compare in the
-+       narrower mode.  */
-+      if ((TYPE_PRECISION (TREE_TYPE (exp))
-+         < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
-+      goto normal;
-+    case NON_LVALUE_EXPR:
-+    case REFERENCE_EXPR:
-+    case ABS_EXPR:
-+    case NEGATE_EXPR:
-+    case LROTATE_EXPR:
-+    case RROTATE_EXPR:
-+      /* These cannot change zero->nonzero or vice versa.  */
-+      do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
-+      break;
-+
-+    case WITH_RECORD_EXPR:
-+      /* Put the object on the placeholder list, recurse through our first
-+       operand, and pop the list.  */
-+      placeholder_list = tree_cons (TREE_OPERAND (exp, 1), NULL_TREE,
-+                                  placeholder_list);
-+      do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
-+      placeholder_list = TREE_CHAIN (placeholder_list);
-+      break;
-+
-+#if 0
-+      /* This is never less insns than evaluating the PLUS_EXPR followed by
-+       a test and can be longer if the test is eliminated.  */
-+    case PLUS_EXPR:
-+      /* Reduce to minus.  */
-+      exp = build (MINUS_EXPR, TREE_TYPE (exp),
-+                 TREE_OPERAND (exp, 0),
-+                 fold (build1 (NEGATE_EXPR, TREE_TYPE (TREE_OPERAND (exp, 1)),
-+                               TREE_OPERAND (exp, 1))));
-+      /* Process as MINUS.  */
-+#endif
-+
-+    case MINUS_EXPR:
-+      /* Nonzero iff operands of minus differ.  */
-+      do_compare_and_jump (build (NE_EXPR, TREE_TYPE (exp),
-+                                TREE_OPERAND (exp, 0),
-+                                TREE_OPERAND (exp, 1)),
-+                         NE, NE, if_false_label, if_true_label);
-+      break;
-+
-+    case BIT_AND_EXPR:
-+      /* If we are AND'ing with a small constant, do this comparison in the
-+       smallest type that fits.  If the machine doesn't have comparisons
-+       that small, it will be converted back to the wider comparison.
-+       This helps if we are testing the sign bit of a narrower object.
-+       combine can't do this for us because it can't know whether a
-+       ZERO_EXTRACT or a compare in a smaller mode exists, but we do.  */
-+
-+      if (! SLOW_BYTE_ACCESS
-+        && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
-+        && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT
-+        && (i = tree_floor_log2 (TREE_OPERAND (exp, 1))) >= 0
-+        && (mode = mode_for_size (i + 1, MODE_INT, 0)) != BLKmode
-+        && (type = (*lang_hooks.types.type_for_mode) (mode, 1)) != 0
-+        && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
-+        && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
-+            != CODE_FOR_nothing))
-+      {
-+        do_jump (convert (type, exp), if_false_label, if_true_label);
-+        break;
-+      }
-+      goto normal;
-+
-+    case TRUTH_NOT_EXPR:
-+      do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
-+      break;
-+
-+    case TRUTH_ANDIF_EXPR:
-+      if (if_false_label == 0)
-+      if_false_label = drop_through_label = gen_label_rtx ();
-+      do_jump (TREE_OPERAND (exp, 0), if_false_label, NULL_RTX);
-+      start_cleanup_deferral ();
-+      do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
-+      end_cleanup_deferral ();
-+      break;
-+
-+    case TRUTH_ORIF_EXPR:
-+      if (if_true_label == 0)
-+      if_true_label = drop_through_label = gen_label_rtx ();
-+      do_jump (TREE_OPERAND (exp, 0), NULL_RTX, if_true_label);
-+      start_cleanup_deferral ();
-+      do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
-+      end_cleanup_deferral ();
-+      break;
-+
-+    case COMPOUND_EXPR:
-+      push_temp_slots ();
-+      expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
-+      preserve_temp_slots (NULL_RTX);
-+      free_temp_slots ();
-+      pop_temp_slots ();
-+      emit_queue ();
-+      do_pending_stack_adjust ();
-+      do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
-+      break;
-+
-+    case COMPONENT_REF:
-+    case BIT_FIELD_REF:
-+    case ARRAY_REF:
-+    case ARRAY_RANGE_REF:
-+      {
-+      HOST_WIDE_INT bitsize, bitpos;
-+      int unsignedp;
-+      enum machine_mode mode;
-+      tree type;
-+      tree offset;
-+      int volatilep = 0;
-+
-+      /* Get description of this reference.  We don't actually care
-+         about the underlying object here.  */
-+      get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode,
-+                           &unsignedp, &volatilep);
-+
-+      type = (*lang_hooks.types.type_for_size) (bitsize, unsignedp);
-+      if (! SLOW_BYTE_ACCESS
-+          && type != 0 && bitsize >= 0
-+          && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
-+          && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
-+              != CODE_FOR_nothing))
-+        {
-+          do_jump (convert (type, exp), if_false_label, if_true_label);
-+          break;
-+        }
-+      goto normal;
-+      }
-+
-+    case COND_EXPR:
-+      /* Do (a ? 1 : 0) and (a ? 0 : 1) as special cases.  */
-+      if (integer_onep (TREE_OPERAND (exp, 1))
-+        && integer_zerop (TREE_OPERAND (exp, 2)))
-+      do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
-+
-+      else if (integer_zerop (TREE_OPERAND (exp, 1))
-+             && integer_onep (TREE_OPERAND (exp, 2)))
-+      do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
-+
-+      else
-+      {
-+        rtx label1 = gen_label_rtx ();
-+        drop_through_label = gen_label_rtx ();
-+
-+        do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX);
-+
-+        start_cleanup_deferral ();
-+        /* Now the THEN-expression.  */
-+        do_jump (TREE_OPERAND (exp, 1),
-+                 if_false_label ? if_false_label : drop_through_label,
-+                 if_true_label ? if_true_label : drop_through_label);
-+        /* In case the do_jump just above never jumps.  */
-+        do_pending_stack_adjust ();
-+        emit_label (label1);
-+
-+        /* Now the ELSE-expression.  */
-+        do_jump (TREE_OPERAND (exp, 2),
-+                 if_false_label ? if_false_label : drop_through_label,
-+                 if_true_label ? if_true_label : drop_through_label);
-+        end_cleanup_deferral ();
-+      }
-+      break;
-+
-+    case EQ_EXPR:
-+      {
-+      tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
-+
-+      if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_FLOAT
-+          || GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_INT)
-+        {
-+          tree exp0 = save_expr (TREE_OPERAND (exp, 0));
-+          tree exp1 = save_expr (TREE_OPERAND (exp, 1));
-+          do_jump
-+            (fold
-+             (build (TRUTH_ANDIF_EXPR, TREE_TYPE (exp),
-+                     fold (build (EQ_EXPR, TREE_TYPE (exp),
-+                                  fold (build1 (REALPART_EXPR,
-+                                                TREE_TYPE (inner_type),
-+                                                exp0)),
-+                                  fold (build1 (REALPART_EXPR,
-+                                                TREE_TYPE (inner_type),
-+                                                exp1)))),
-+                     fold (build (EQ_EXPR, TREE_TYPE (exp),
-+                                  fold (build1 (IMAGPART_EXPR,
-+                                                TREE_TYPE (inner_type),
-+                                                exp0)),
-+                                  fold (build1 (IMAGPART_EXPR,
-+                                                TREE_TYPE (inner_type),
-+                                                exp1)))))),
-+             if_false_label, if_true_label);
-+        }
-+
-+      else if (integer_zerop (TREE_OPERAND (exp, 1)))
-+        do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
-+
-+      else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
-+               && !can_compare_p (EQ, TYPE_MODE (inner_type), ccp_jump))
-+        do_jump_by_parts_equality (exp, if_false_label, if_true_label);
-+      else
-+        do_compare_and_jump (exp, EQ, EQ, if_false_label, if_true_label);
-+      break;
-+      }
-+
-+    case NE_EXPR:
-+      {
-+      tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
-+
-+      if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_FLOAT
-+          || GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_INT)
-+        {
-+          tree exp0 = save_expr (TREE_OPERAND (exp, 0));
-+          tree exp1 = save_expr (TREE_OPERAND (exp, 1));
-+          do_jump
-+            (fold
-+             (build (TRUTH_ORIF_EXPR, TREE_TYPE (exp),
-+                     fold (build (NE_EXPR, TREE_TYPE (exp),
-+                                  fold (build1 (REALPART_EXPR,
-+                                                TREE_TYPE (inner_type),
-+                                                exp0)),
-+                                  fold (build1 (REALPART_EXPR,
-+                                                TREE_TYPE (inner_type),
-+                                                exp1)))),
-+                     fold (build (NE_EXPR, TREE_TYPE (exp),
-+                                  fold (build1 (IMAGPART_EXPR,
-+                                                TREE_TYPE (inner_type),
-+                                                exp0)),
-+                                  fold (build1 (IMAGPART_EXPR,
-+                                                TREE_TYPE (inner_type),
-+                                                exp1)))))),
-+             if_false_label, if_true_label);
-+        }
-+
-+      else if (integer_zerop (TREE_OPERAND (exp, 1)))
-+        do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
-+
-+      else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
-+               && !can_compare_p (NE, TYPE_MODE (inner_type), ccp_jump))
-+        do_jump_by_parts_equality (exp, if_true_label, if_false_label);
-+      else
-+        do_compare_and_jump (exp, NE, NE, if_false_label, if_true_label);
-+      break;
-+      }
-+
-+    case LT_EXPR:
-+      mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
-+      if (GET_MODE_CLASS (mode) == MODE_INT
-+        && ! can_compare_p (LT, mode, ccp_jump))
-+      do_jump_by_parts_greater (exp, 1, if_false_label, if_true_label);
-+      else
-+      do_compare_and_jump (exp, LT, LTU, if_false_label, if_true_label);
-+      break;
-+
-+    case LE_EXPR:
-+      mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
-+      if (GET_MODE_CLASS (mode) == MODE_INT
-+        && ! can_compare_p (LE, mode, ccp_jump))
-+      do_jump_by_parts_greater (exp, 0, if_true_label, if_false_label);
-+      else
-+      do_compare_and_jump (exp, LE, LEU, if_false_label, if_true_label);
-+      break;
-+
-+    case GT_EXPR:
-+      mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
-+      if (GET_MODE_CLASS (mode) == MODE_INT
-+        && ! can_compare_p (GT, mode, ccp_jump))
-+      do_jump_by_parts_greater (exp, 0, if_false_label, if_true_label);
-+      else
-+      do_compare_and_jump (exp, GT, GTU, if_false_label, if_true_label);
-+      break;
-+
-+    case GE_EXPR:
-+      mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
-+      if (GET_MODE_CLASS (mode) == MODE_INT
-+        && ! can_compare_p (GE, mode, ccp_jump))
-+      do_jump_by_parts_greater (exp, 1, if_true_label, if_false_label);
-+      else
-+      do_compare_and_jump (exp, GE, GEU, if_false_label, if_true_label);
-+      break;
-+
-+    case UNORDERED_EXPR:
-+    case ORDERED_EXPR:
-+      {
-+      enum rtx_code cmp, rcmp;
-+      int do_rev;
-+
-+      if (code == UNORDERED_EXPR)
-+        cmp = UNORDERED, rcmp = ORDERED;
-+      else
-+        cmp = ORDERED, rcmp = UNORDERED;
-+      mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
-+
-+      do_rev = 0;
-+      if (! can_compare_p (cmp, mode, ccp_jump)
-+          && (can_compare_p (rcmp, mode, ccp_jump)
-+              /* If the target doesn't provide either UNORDERED or ORDERED
-+                 comparisons, canonicalize on UNORDERED for the library.  */
-+              || rcmp == UNORDERED))
-+        do_rev = 1;
-+
-+      if (! do_rev)
-+        do_compare_and_jump (exp, cmp, cmp, if_false_label, if_true_label);
-+      else
-+        do_compare_and_jump (exp, rcmp, rcmp, if_true_label, if_false_label);
-+      }
-+      break;
-+
-+    {
-+      enum rtx_code rcode1;
-+      enum tree_code tcode2;
-+
-+      case UNLT_EXPR:
-+      rcode1 = UNLT;
-+      tcode2 = LT_EXPR;
-+      goto unordered_bcc;
-+      case UNLE_EXPR:
-+      rcode1 = UNLE;
-+      tcode2 = LE_EXPR;
-+      goto unordered_bcc;
-+      case UNGT_EXPR:
-+      rcode1 = UNGT;
-+      tcode2 = GT_EXPR;
-+      goto unordered_bcc;
-+      case UNGE_EXPR:
-+      rcode1 = UNGE;
-+      tcode2 = GE_EXPR;
-+      goto unordered_bcc;
-+      case UNEQ_EXPR:
-+      rcode1 = UNEQ;
-+      tcode2 = EQ_EXPR;
-+      goto unordered_bcc;
-+
-+      unordered_bcc:
-+      mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
-+      if (can_compare_p (rcode1, mode, ccp_jump))
-+        do_compare_and_jump (exp, rcode1, rcode1, if_false_label,
-+                             if_true_label);
-+      else
-+        {
-+          tree op0 = save_expr (TREE_OPERAND (exp, 0));
-+          tree op1 = save_expr (TREE_OPERAND (exp, 1));
-+          tree cmp0, cmp1;
-+
-+          /* If the target doesn't support combined unordered
-+             compares, decompose into UNORDERED + comparison.  */
-+          cmp0 = fold (build (UNORDERED_EXPR, TREE_TYPE (exp), op0, op1));
-+          cmp1 = fold (build (tcode2, TREE_TYPE (exp), op0, op1));
-+          exp = build (TRUTH_ORIF_EXPR, TREE_TYPE (exp), cmp0, cmp1);
-+          do_jump (exp, if_false_label, if_true_label);
-+        }
-+      }
-+      break;
-+
-+      /* Special case:
-+              __builtin_expect (<test>, 0)    and
-+              __builtin_expect (<test>, 1)
-+
-+       We need to do this here, so that <test> is not converted to a SCC
-+       operation on machines that use condition code registers and COMPARE
-+       like the PowerPC, and then the jump is done based on whether the SCC
-+       operation produced a 1 or 0.  */
-+    case CALL_EXPR:
-+      /* Check for a built-in function.  */
-+      if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR)
-+      {
-+        tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
-+        tree arglist = TREE_OPERAND (exp, 1);
-+
-+        if (TREE_CODE (fndecl) == FUNCTION_DECL
-+            && DECL_BUILT_IN (fndecl)
-+            && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
-+            && arglist != NULL_TREE
-+            && TREE_CHAIN (arglist) != NULL_TREE)
-+          {
-+            rtx seq = expand_builtin_expect_jump (exp, if_false_label,
-+                                                  if_true_label);
-+
-+            if (seq != NULL_RTX)
-+              {
-+                emit_insn (seq);
-+                return;
-+              }
-+          }
-+      }
-+      /* fall through and generate the normal code.  */
-+
-+    default:
-+    normal:
-+      temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
-+#if 0
-+      /* This is not needed any more and causes poor code since it causes
-+       comparisons and tests from non-SI objects to have different code
-+       sequences.  */
-+      /* Copy to register to avoid generating bad insns by cse
-+       from (set (mem ...) (arithop))  (set (cc0) (mem ...)).  */
-+      if (!cse_not_expected && GET_CODE (temp) == MEM)
-+      temp = copy_to_reg (temp);
-+#endif
-+      do_pending_stack_adjust ();
-+      /* Do any postincrements in the expression that was tested.  */
-+      emit_queue ();
-+
-+      if (GET_CODE (temp) == CONST_INT
-+        || (GET_CODE (temp) == CONST_DOUBLE && GET_MODE (temp) == VOIDmode)
-+        || GET_CODE (temp) == LABEL_REF)
-+      {
-+        rtx target = temp == const0_rtx ? if_false_label : if_true_label;
-+        if (target)
-+          emit_jump (target);
-+      }
-+      else if (GET_MODE_CLASS (GET_MODE (temp)) == MODE_INT
-+             && ! can_compare_p (NE, GET_MODE (temp), ccp_jump))
-+      /* Note swapping the labels gives us not-equal.  */
-+      do_jump_by_parts_equality_rtx (temp, if_true_label, if_false_label);
-+      else if (GET_MODE (temp) != VOIDmode)
-+      do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)),
-+                               NE, TREE_UNSIGNED (TREE_TYPE (exp)),
-+                               GET_MODE (temp), NULL_RTX,
-+                               if_false_label, if_true_label);
-+      else
-+      abort ();
-+    }
-+
-+  if (drop_through_label)
-+    {
-+      /* If do_jump produces code that might be jumped around,
-+       do any stack adjusts from that code, before the place
-+       where control merges in.  */
-+      do_pending_stack_adjust ();
-+      emit_label (drop_through_label);
-+    }
-+}
-+\f
-+/* Given a comparison expression EXP for values too wide to be compared
-+   with one insn, test the comparison and jump to the appropriate label.
-+   The code of EXP is ignored; we always test GT if SWAP is 0,
-+   and LT if SWAP is 1.  */
-+
-+static void
-+do_jump_by_parts_greater (exp, swap, if_false_label, if_true_label)
-+     tree exp;
-+     int swap;
-+     rtx if_false_label, if_true_label;
-+{
-+  rtx op0 = expand_expr (TREE_OPERAND (exp, swap), NULL_RTX, VOIDmode, 0);
-+  rtx op1 = expand_expr (TREE_OPERAND (exp, !swap), NULL_RTX, VOIDmode, 0);
-+  enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
-+  int unsignedp = TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0)));
-+
-+  do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label, if_true_label);
-+}
-+
-+/* Compare OP0 with OP1, word at a time, in mode MODE.
-+   UNSIGNEDP says to do unsigned comparison.
-+   Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise.  */
-+
-+void
-+do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label, if_true_label)
-+     enum machine_mode mode;
-+     int unsignedp;
-+     rtx op0, op1;
-+     rtx if_false_label, if_true_label;
-+{
-+  int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
-+  rtx drop_through_label = 0;
-+  int i;
-+
-+  if (! if_true_label || ! if_false_label)
-+    drop_through_label = gen_label_rtx ();
-+  if (! if_true_label)
-+    if_true_label = drop_through_label;
-+  if (! if_false_label)
-+    if_false_label = drop_through_label;
-+
-+  /* Compare a word at a time, high order first.  */
-+  for (i = 0; i < nwords; i++)
-+    {
-+      rtx op0_word, op1_word;
-+
-+      if (WORDS_BIG_ENDIAN)
-+      {
-+        op0_word = operand_subword_force (op0, i, mode);
-+        op1_word = operand_subword_force (op1, i, mode);
-+      }
-+      else
-+      {
-+        op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
-+        op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
-+      }
-+
-+      /* All but high-order word must be compared as unsigned.  */
-+      do_compare_rtx_and_jump (op0_word, op1_word, GT,
-+                             (unsignedp || i > 0), word_mode, NULL_RTX,
-+                             NULL_RTX, if_true_label);
-+
-+      /* Consider lower words only if these are equal.  */
-+      do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode,
-+                             NULL_RTX, NULL_RTX, if_false_label);
-+    }
-+
-+  if (if_false_label)
-+    emit_jump (if_false_label);
-+  if (drop_through_label)
-+    emit_label (drop_through_label);
-+}
-+
-+/* Given an EQ_EXPR expression EXP for values too wide to be compared
-+   with one insn, test the comparison and jump to the appropriate label.  */
-+
-+static void
-+do_jump_by_parts_equality (exp, if_false_label, if_true_label)
-+     tree exp;
-+     rtx if_false_label, if_true_label;
-+{
-+  rtx op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
-+  rtx op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
-+  enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
-+  int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
-+  int i;
-+  rtx drop_through_label = 0;
-+
-+  if (! if_false_label)
-+    drop_through_label = if_false_label = gen_label_rtx ();
-+
-+  for (i = 0; i < nwords; i++)
-+    do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
-+                           operand_subword_force (op1, i, mode),
-+                           EQ, TREE_UNSIGNED (TREE_TYPE (exp)),
-+                           word_mode, NULL_RTX, if_false_label, NULL_RTX);
-+
-+  if (if_true_label)
-+    emit_jump (if_true_label);
-+  if (drop_through_label)
-+    emit_label (drop_through_label);
-+}
-+\f
-+/* Jump according to whether OP0 is 0.
-+   We assume that OP0 has an integer mode that is too wide
-+   for the available compare insns.  */
-+
-+void
-+do_jump_by_parts_equality_rtx (op0, if_false_label, if_true_label)
-+     rtx op0;
-+     rtx if_false_label, if_true_label;
-+{
-+  int nwords = GET_MODE_SIZE (GET_MODE (op0)) / UNITS_PER_WORD;
-+  rtx part;
-+  int i;
-+  rtx drop_through_label = 0;
-+
-+  /* The fastest way of doing this comparison on almost any machine is to
-+     "or" all the words and compare the result.  If all have to be loaded
-+     from memory and this is a very wide item, it's possible this may
-+     be slower, but that's highly unlikely.  */
-+
-+  part = gen_reg_rtx (word_mode);
-+  emit_move_insn (part, operand_subword_force (op0, 0, GET_MODE (op0)));
-+  for (i = 1; i < nwords && part != 0; i++)
-+    part = expand_binop (word_mode, ior_optab, part,
-+                       operand_subword_force (op0, i, GET_MODE (op0)),
-+                       part, 1, OPTAB_WIDEN);
-+
-+  if (part != 0)
-+    {
-+      do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode,
-+                             NULL_RTX, if_false_label, if_true_label);
-+
-+      return;
-+    }
-+
-+  /* If we couldn't do the "or" simply, do this with a series of compares.  */
-+  if (! if_false_label)
-+    drop_through_label = if_false_label = gen_label_rtx ();
-+
-+  for (i = 0; i < nwords; i++)
-+    do_compare_rtx_and_jump (operand_subword_force (op0, i, GET_MODE (op0)),
-+                           const0_rtx, EQ, 1, word_mode, NULL_RTX,
-+                           if_false_label, NULL_RTX);
-+
-+  if (if_true_label)
-+    emit_jump (if_true_label);
-+
-+  if (drop_through_label)
-+    emit_label (drop_through_label);
-+}
-+\f
-+/* Generate code for a comparison of OP0 and OP1 with rtx code CODE.
-+   (including code to compute the values to be compared)
-+   and set (CC0) according to the result.
-+   The decision as to signed or unsigned comparison must be made by the caller.
-+
-+   We force a stack adjustment unless there are currently
-+   things pushed on the stack that aren't yet used.
-+
-+   If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
-+   compared.  */
-+
-+rtx
-+compare_from_rtx (op0, op1, code, unsignedp, mode, size)
-+     rtx op0, op1;
-+     enum rtx_code code;
-+     int unsignedp;
-+     enum machine_mode mode;
-+     rtx size;
-+{
-+  enum rtx_code ucode;
-+  rtx tem;
-+
-+  /* If one operand is constant, make it the second one.  Only do this
-+     if the other operand is not constant as well.  */
-+
-+  if (swap_commutative_operands_p (op0, op1))
-+    {
-+      tem = op0;
-+      op0 = op1;
-+      op1 = tem;
-+      code = swap_condition (code);
-+    }
-+
-+  if (flag_force_mem)
-+    {
-+      op0 = force_not_mem (op0);
-+      op1 = force_not_mem (op1);
-+    }
-+
-+  do_pending_stack_adjust ();
-+
-+  ucode = unsignedp ? unsigned_condition (code) : code;
-+  if ((tem = simplify_relational_operation (ucode, mode, op0, op1)) != 0)
-+    return tem;
-+
-+#if 0
-+  /* There's no need to do this now that combine.c can eliminate lots of
-+     sign extensions.  This can be less efficient in certain cases on other
-+     machines.  */
-+
-+  /* If this is a signed equality comparison, we can do it as an
-+     unsigned comparison since zero-extension is cheaper than sign
-+     extension and comparisons with zero are done as unsigned.  This is
-+     the case even on machines that can do fast sign extension, since
-+     zero-extension is easier to combine with other operations than
-+     sign-extension is.  If we are comparing against a constant, we must
-+     convert it to what it would look like unsigned.  */
-+  if ((code == EQ || code == NE) && ! unsignedp
-+      && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
-+    {
-+      if (GET_CODE (op1) == CONST_INT
-+        && (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0))) != INTVAL (op1))
-+      op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0)));
-+      unsignedp = 1;
-+    }
-+#endif
-+
-+  emit_cmp_insn (op0, op1, code, size, mode, unsignedp);
-+
-+#if HAVE_cc0
-+  return gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
-+#else
-+  return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
-+#endif
-+}
-+
-+/* Like do_compare_and_jump but expects the values to compare as two rtx's.
-+   The decision as to signed or unsigned comparison must be made by the caller.
-+
-+   If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
-+   compared.  */
-+
-+void
-+do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode, size,
-+                       if_false_label, if_true_label)
-+     rtx op0, op1;
-+     enum rtx_code code;
-+     int unsignedp;
-+     enum machine_mode mode;
-+     rtx size;
-+     rtx if_false_label, if_true_label;
-+{
-+  enum rtx_code ucode;
-+  rtx tem;
-+  int dummy_true_label = 0;
-+
-+  /* Reverse the comparison if that is safe and we want to jump if it is
-+     false.  */
-+  if (! if_true_label && ! FLOAT_MODE_P (mode))
-+    {
-+      if_true_label = if_false_label;
-+      if_false_label = 0;
-+      code = reverse_condition (code);
-+    }
-+
-+  /* If one operand is constant, make it the second one.  Only do this
-+     if the other operand is not constant as well.  */
-+
-+  if (swap_commutative_operands_p (op0, op1))
-+    {
-+      tem = op0;
-+      op0 = op1;
-+      op1 = tem;
-+      code = swap_condition (code);
-+    }
-+
-+  if (flag_force_mem)
-+    {
-+      op0 = force_not_mem (op0);
-+      op1 = force_not_mem (op1);
-+    }
-+
-+  do_pending_stack_adjust ();
-+
-+  ucode = unsignedp ? unsigned_condition (code) : code;
-+  if ((tem = simplify_relational_operation (ucode, mode, op0, op1)) != 0)
-+    {
-+      if (tem == const_true_rtx)
-+      {
-+        if (if_true_label)
-+          emit_jump (if_true_label);
-+      }
-+      else
-+      {
-+        if (if_false_label)
-+          emit_jump (if_false_label);
-+      }
-+      return;
-+    }
-+
-+#if 0
-+  /* There's no need to do this now that combine.c can eliminate lots of
-+     sign extensions.  This can be less efficient in certain cases on other
-+     machines.  */
-+
-+  /* If this is a signed equality comparison, we can do it as an
-+     unsigned comparison since zero-extension is cheaper than sign
-+     extension and comparisons with zero are done as unsigned.  This is
-+     the case even on machines that can do fast sign extension, since
-+     zero-extension is easier to combine with other operations than
-+     sign-extension is.  If we are comparing against a constant, we must
-+     convert it to what it would look like unsigned.  */
-+  if ((code == EQ || code == NE) && ! unsignedp
-+      && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
-+    {
-+      if (GET_CODE (op1) == CONST_INT
-+        && (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0))) != INTVAL (op1))
-+      op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0)));
-+      unsignedp = 1;
-+    }
-+#endif
-+
-+  if (! if_true_label)
-+    {
-+      dummy_true_label = 1;
-+      if_true_label = gen_label_rtx ();
-+    }
-+
-+  emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp,
-+                         if_true_label);
-+
-+  if (if_false_label)
-+    emit_jump (if_false_label);
-+  if (dummy_true_label)
-+    emit_label (if_true_label);
-+}
-+
-+/* Generate code for a comparison expression EXP (including code to compute
-+   the values to be compared) and a conditional jump to IF_FALSE_LABEL and/or
-+   IF_TRUE_LABEL.  One of the labels can be NULL_RTX, in which case the
-+   generated code will drop through.
-+   SIGNED_CODE should be the rtx operation for this comparison for
-+   signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
-+
-+   We force a stack adjustment unless there are currently
-+   things pushed on the stack that aren't yet used.  */
-+
-+static void
-+do_compare_and_jump (exp, signed_code, unsigned_code, if_false_label,
-+                   if_true_label)
-+     tree exp;
-+     enum rtx_code signed_code, unsigned_code;
-+     rtx if_false_label, if_true_label;
-+{
-+  rtx op0, op1;
-+  tree type;
-+  enum machine_mode mode;
-+  int unsignedp;
-+  enum rtx_code code;
-+
-+  /* Don't crash if the comparison was erroneous.  */
-+  op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
-+  if (TREE_CODE (TREE_OPERAND (exp, 0)) == ERROR_MARK)
-+    return;
-+
-+  op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
-+  if (TREE_CODE (TREE_OPERAND (exp, 1)) == ERROR_MARK)
-+    return;
-+
-+  type = TREE_TYPE (TREE_OPERAND (exp, 0));
-+  mode = TYPE_MODE (type);
-+  if (TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST
-+      && (TREE_CODE (TREE_OPERAND (exp, 1)) != INTEGER_CST
-+        || (GET_MODE_BITSIZE (mode)
-+            > GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp,
-+                                                                    1)))))))
-+    {
-+      /* op0 might have been replaced by promoted constant, in which
-+       case the type of second argument should be used.  */
-+      type = TREE_TYPE (TREE_OPERAND (exp, 1));
-+      mode = TYPE_MODE (type);
-+    }
-+  unsignedp = TREE_UNSIGNED (type);
-+  code = unsignedp ? unsigned_code : signed_code;
-+
-+#ifdef HAVE_canonicalize_funcptr_for_compare
-+  /* If function pointers need to be "canonicalized" before they can
-+     be reliably compared, then canonicalize them.  */
-+  if (HAVE_canonicalize_funcptr_for_compare
-+      && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
-+      && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))))
-+        == FUNCTION_TYPE))
-+    {
-+      rtx new_op0 = gen_reg_rtx (mode);
-+
-+      emit_insn (gen_canonicalize_funcptr_for_compare (new_op0, op0));
-+      op0 = new_op0;
-+    }
-+
-+  if (HAVE_canonicalize_funcptr_for_compare
-+      && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 1))) == POINTER_TYPE
-+      && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 1))))
-+        == FUNCTION_TYPE))
-+    {
-+      rtx new_op1 = gen_reg_rtx (mode);
-+
-+      emit_insn (gen_canonicalize_funcptr_for_compare (new_op1, op1));
-+      op1 = new_op1;
-+    }
-+#endif
-+
-+  /* Do any postincrements in the expression that was tested.  */
-+  emit_queue ();
-+
-+  do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode,
-+                         ((mode == BLKmode)
-+                          ? expr_size (TREE_OPERAND (exp, 0)) : NULL_RTX),
-+                         if_false_label, if_true_label);
-+}
-+\f
-+/* Generate code to calculate EXP using a store-flag instruction
-+   and return an rtx for the result.  EXP is either a comparison
-+   or a TRUTH_NOT_EXPR whose operand is a comparison.
-+
-+   If TARGET is nonzero, store the result there if convenient.
-+
-+   If ONLY_CHEAP is nonzero, only do this if it is likely to be very
-+   cheap.
-+
-+   Return zero if there is no suitable set-flag instruction
-+   available on this machine.
-+
-+   Once expand_expr has been called on the arguments of the comparison,
-+   we are committed to doing the store flag, since it is not safe to
-+   re-evaluate the expression.  We emit the store-flag insn by calling
-+   emit_store_flag, but only expand the arguments if we have a reason
-+   to believe that emit_store_flag will be successful.  If we think that
-+   it will, but it isn't, we have to simulate the store-flag with a
-+   set/jump/set sequence.  */
-+
-+static rtx
-+do_store_flag (exp, target, mode, only_cheap)
-+     tree exp;
-+     rtx target;
-+     enum machine_mode mode;
-+     int only_cheap;
-+{
-+  enum rtx_code code;
-+  tree arg0, arg1, type;
-+  tree tem;
-+  enum machine_mode operand_mode;
-+  int invert = 0;
-+  int unsignedp;
-+  rtx op0, op1;
-+  enum insn_code icode;
-+  rtx subtarget = target;
-+  rtx result, label;
-+
-+  /* If this is a TRUTH_NOT_EXPR, set a flag indicating we must invert the
-+     result at the end.  We can't simply invert the test since it would
-+     have already been inverted if it were valid.  This case occurs for
-+     some floating-point comparisons.  */
-+
-+  if (TREE_CODE (exp) == TRUTH_NOT_EXPR)
-+    invert = 1, exp = TREE_OPERAND (exp, 0);
-+
-+  arg0 = TREE_OPERAND (exp, 0);
-+  arg1 = TREE_OPERAND (exp, 1);
-+
-+  /* Don't crash if the comparison was erroneous.  */
-+  if (arg0 == error_mark_node || arg1 == error_mark_node)
-+    return const0_rtx;
-+
-+  type = TREE_TYPE (arg0);
-+  operand_mode = TYPE_MODE (type);
-+  unsignedp = TREE_UNSIGNED (type);
-+
-+  /* We won't bother with BLKmode store-flag operations because it would mean
-+     passing a lot of information to emit_store_flag.  */
-+  if (operand_mode == BLKmode)
-+    return 0;
-+
-+  /* We won't bother with store-flag operations involving function pointers
-+     when function pointers must be canonicalized before comparisons.  */
-+#ifdef HAVE_canonicalize_funcptr_for_compare
-+  if (HAVE_canonicalize_funcptr_for_compare
-+      && ((TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
-+         && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))))
-+             == FUNCTION_TYPE))
-+        || (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 1))) == POINTER_TYPE
-+            && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 1))))
-+                == FUNCTION_TYPE))))
-+    return 0;
-+#endif
-+
-+  STRIP_NOPS (arg0);
-+  STRIP_NOPS (arg1);
-+
-+  /* Get the rtx comparison code to use.  We know that EXP is a comparison
-+     operation of some type.  Some comparisons against 1 and -1 can be
-+     converted to comparisons with zero.  Do so here so that the tests
-+     below will be aware that we have a comparison with zero.   These
-+     tests will not catch constants in the first operand, but constants
-+     are rarely passed as the first operand.  */
-+
-+  switch (TREE_CODE (exp))
-+    {
-+    case EQ_EXPR:
-+      code = EQ;
-+      break;
-+    case NE_EXPR:
-+      code = NE;
-+      break;
-+    case LT_EXPR:
-+      if (integer_onep (arg1))
-+      arg1 = integer_zero_node, code = unsignedp ? LEU : LE;
-+      else
-+      code = unsignedp ? LTU : LT;
-+      break;
-+    case LE_EXPR:
-+      if (! unsignedp && integer_all_onesp (arg1))
-+      arg1 = integer_zero_node, code = LT;
-+      else
-+      code = unsignedp ? LEU : LE;
-+      break;
-+    case GT_EXPR:
-+      if (! unsignedp && integer_all_onesp (arg1))
-+      arg1 = integer_zero_node, code = GE;
-+      else
-+      code = unsignedp ? GTU : GT;
-+      break;
-+    case GE_EXPR:
-+      if (integer_onep (arg1))
-+      arg1 = integer_zero_node, code = unsignedp ? GTU : GT;
-+      else
-+      code = unsignedp ? GEU : GE;
-+      break;
-+
-+    case UNORDERED_EXPR:
-+      code = UNORDERED;
-+      break;
-+    case ORDERED_EXPR:
-+      code = ORDERED;
-+      break;
-+    case UNLT_EXPR:
-+      code = UNLT;
-+      break;
-+    case UNLE_EXPR:
-+      code = UNLE;
-+      break;
-+    case UNGT_EXPR:
-+      code = UNGT;
-+      break;
-+    case UNGE_EXPR:
-+      code = UNGE;
-+      break;
-+    case UNEQ_EXPR:
-+      code = UNEQ;
-+      break;
-+
-+    default:
-+      abort ();
-+    }
-+
-+  /* Put a constant second.  */
-+  if (TREE_CODE (arg0) == REAL_CST || TREE_CODE (arg0) == INTEGER_CST)
-+    {
-+      tem = arg0; arg0 = arg1; arg1 = tem;
-+      code = swap_condition (code);
-+    }
-+
-+  /* If this is an equality or inequality test of a single bit, we can
-+     do this by shifting the bit being tested to the low-order bit and
-+     masking the result with the constant 1.  If the condition was EQ,
-+     we xor it with 1.  This does not require an scc insn and is faster
-+     than an scc insn even if we have it.  */
-+
-+  if ((code == NE || code == EQ)
-+      && TREE_CODE (arg0) == BIT_AND_EXPR && integer_zerop (arg1)
-+      && integer_pow2p (TREE_OPERAND (arg0, 1)))
-+    {
-+      tree inner = TREE_OPERAND (arg0, 0);
-+      int bitnum = tree_log2 (TREE_OPERAND (arg0, 1));
-+      int ops_unsignedp;
-+
-+      /* If INNER is a right shift of a constant and it plus BITNUM does
-+       not overflow, adjust BITNUM and INNER.  */
-+
-+      if (TREE_CODE (inner) == RSHIFT_EXPR
-+        && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST
-+        && TREE_INT_CST_HIGH (TREE_OPERAND (inner, 1)) == 0
-+        && bitnum < TYPE_PRECISION (type)
-+        && 0 > compare_tree_int (TREE_OPERAND (inner, 1),
-+                                 bitnum - TYPE_PRECISION (type)))
-+      {
-+        bitnum += TREE_INT_CST_LOW (TREE_OPERAND (inner, 1));
-+        inner = TREE_OPERAND (inner, 0);
-+      }
-+
-+      /* If we are going to be able to omit the AND below, we must do our
-+       operations as unsigned.  If we must use the AND, we have a choice.
-+       Normally unsigned is faster, but for some machines signed is.  */
-+      ops_unsignedp = (bitnum == TYPE_PRECISION (type) - 1 ? 1
-+#ifdef LOAD_EXTEND_OP
-+                     : (LOAD_EXTEND_OP (operand_mode) == SIGN_EXTEND ? 0 : 1)
-+#else
-+                     : 1
-+#endif
-+                     );
-+
-+      if (! get_subtarget (subtarget)
-+        || GET_MODE (subtarget) != operand_mode
-+        || ! safe_from_p (subtarget, inner, 1))
-+      subtarget = 0;
-+
-+      op0 = expand_expr (inner, subtarget, VOIDmode, 0);
-+
-+      if (bitnum != 0)
-+      op0 = expand_shift (RSHIFT_EXPR, operand_mode, op0,
-+                          size_int (bitnum), subtarget, ops_unsignedp);
-+
-+      if (GET_MODE (op0) != mode)
-+      op0 = convert_to_mode (mode, op0, ops_unsignedp);
-+
-+      if ((code == EQ && ! invert) || (code == NE && invert))
-+      op0 = expand_binop (mode, xor_optab, op0, const1_rtx, subtarget,
-+                          ops_unsignedp, OPTAB_LIB_WIDEN);
-+
-+      /* Put the AND last so it can combine with more things.  */
-+      if (bitnum != TYPE_PRECISION (type) - 1)
-+      op0 = expand_and (mode, op0, const1_rtx, subtarget);
-+
-+      return op0;
-+    }
-+
-+  /* Now see if we are likely to be able to do this.  Return if not.  */
-+  if (! can_compare_p (code, operand_mode, ccp_store_flag))
-+    return 0;
-+
-+  icode = setcc_gen_code[(int) code];
-+  if (icode == CODE_FOR_nothing
-+      || (only_cheap && insn_data[(int) icode].operand[0].mode != mode))
-+    {
-+      /* We can only do this if it is one of the special cases that
-+       can be handled without an scc insn.  */
-+      if ((code == LT && integer_zerop (arg1))
-+        || (! only_cheap && code == GE && integer_zerop (arg1)))
-+      ;
-+      else if (BRANCH_COST >= 0
-+             && ! only_cheap && (code == NE || code == EQ)
-+             && TREE_CODE (type) != REAL_TYPE
-+             && ((abs_optab->handlers[(int) operand_mode].insn_code
-+                  != CODE_FOR_nothing)
-+                 || (ffs_optab->handlers[(int) operand_mode].insn_code
-+                     != CODE_FOR_nothing)))
-+      ;
-+      else
-+      return 0;
-+    }
-+
-+  if (! get_subtarget (target)
-+      || GET_MODE (subtarget) != operand_mode
-+      || ! safe_from_p (subtarget, arg1, 1))
-+    subtarget = 0;
-+
-+  op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
-+  op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
-+
-+  if (target == 0)
-+    target = gen_reg_rtx (mode);
-+
-+  /* Pass copies of OP0 and OP1 in case they contain a QUEUED.  This is safe
-+     because, if the emit_store_flag does anything it will succeed and
-+     OP0 and OP1 will not be used subsequently.  */
-+
-+  result = emit_store_flag (target, code,
-+                          queued_subexp_p (op0) ? copy_rtx (op0) : op0,
-+                          queued_subexp_p (op1) ? copy_rtx (op1) : op1,
-+                          operand_mode, unsignedp, 1);
-+
-+  if (result)
-+    {
-+      if (invert)
-+      result = expand_binop (mode, xor_optab, result, const1_rtx,
-+                             result, 0, OPTAB_LIB_WIDEN);
-+      return result;
-+    }
-+
-+  /* If this failed, we have to do this with set/compare/jump/set code.  */
-+  if (GET_CODE (target) != REG
-+      || reg_mentioned_p (target, op0) || reg_mentioned_p (target, op1))
-+    target = gen_reg_rtx (GET_MODE (target));
-+
-+  emit_move_insn (target, invert ? const0_rtx : const1_rtx);
-+  result = compare_from_rtx (op0, op1, code, unsignedp,
-+                           operand_mode, NULL_RTX);
-+  if (GET_CODE (result) == CONST_INT)
-+    return (((result == const0_rtx && ! invert)
-+           || (result != const0_rtx && invert))
-+          ? const0_rtx : const1_rtx);
-+
-+  /* The code of RESULT may not match CODE if compare_from_rtx
-+     decided to swap its operands and reverse the original code.
-+
-+     We know that compare_from_rtx returns either a CONST_INT or
-+     a new comparison code, so it is safe to just extract the
-+     code from RESULT.  */
-+  code = GET_CODE (result);
-+
-+  label = gen_label_rtx ();
-+  if (bcc_gen_fctn[(int) code] == 0)
-+    abort ();
-+
-+  emit_jump_insn ((*bcc_gen_fctn[(int) code]) (label));
-+  emit_move_insn (target, invert ? const1_rtx : const0_rtx);
-+  emit_label (label);
-+
-+  return target;
-+}
-+\f
-+
-+/* Stubs in case we haven't got a casesi insn.  */
-+#ifndef HAVE_casesi
-+# define HAVE_casesi 0
-+# define gen_casesi(a, b, c, d, e) (0)
-+# define CODE_FOR_casesi CODE_FOR_nothing
-+#endif
-+
-+/* If the machine does not have a case insn that compares the bounds,
-+   this means extra overhead for dispatch tables, which raises the
-+   threshold for using them.  */
-+#ifndef CASE_VALUES_THRESHOLD
-+#define CASE_VALUES_THRESHOLD (HAVE_casesi ? 4 : 5)
-+#endif /* CASE_VALUES_THRESHOLD */
-+
-+unsigned int
-+case_values_threshold ()
-+{
-+  return CASE_VALUES_THRESHOLD;
-+}
-+
-+/* Attempt to generate a casesi instruction.  Returns 1 if successful,
-+   0 otherwise (i.e. if there is no casesi instruction).  */
-+int
-+try_casesi (index_type, index_expr, minval, range,
-+          table_label, default_label)
-+     tree index_type, index_expr, minval, range;
-+     rtx table_label ATTRIBUTE_UNUSED;
-+     rtx default_label;
-+{
-+  enum machine_mode index_mode = SImode;
-+  int index_bits = GET_MODE_BITSIZE (index_mode);
-+  rtx op1, op2, index;
-+  enum machine_mode op_mode;
-+
-+  if (! HAVE_casesi)
-+    return 0;
-+
-+  /* Convert the index to SImode.  */
-+  if (GET_MODE_BITSIZE (TYPE_MODE (index_type)) > GET_MODE_BITSIZE (index_mode))
-+    {
-+      enum machine_mode omode = TYPE_MODE (index_type);
-+      rtx rangertx = expand_expr (range, NULL_RTX, VOIDmode, 0);
-+
-+      /* We must handle the endpoints in the original mode.  */
-+      index_expr = build (MINUS_EXPR, index_type,
-+                        index_expr, minval);
-+      minval = integer_zero_node;
-+      index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
-+      emit_cmp_and_jump_insns (rangertx, index, LTU, NULL_RTX,
-+                             omode, 1, default_label);
-+      /* Now we can safely truncate.  */
-+      index = convert_to_mode (index_mode, index, 0);
-+    }
-+  else
-+    {
-+      if (TYPE_MODE (index_type) != index_mode)
-+      {
-+        index_expr = convert ((*lang_hooks.types.type_for_size)
-+                              (index_bits, 0), index_expr);
-+        index_type = TREE_TYPE (index_expr);
-+      }
-+
-+      index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
-+    }
-+  emit_queue ();
-+  index = protect_from_queue (index, 0);
-+  do_pending_stack_adjust ();
-+
-+  op_mode = insn_data[(int) CODE_FOR_casesi].operand[0].mode;
-+  if (! (*insn_data[(int) CODE_FOR_casesi].operand[0].predicate)
-+      (index, op_mode))
-+    index = copy_to_mode_reg (op_mode, index);
-+
-+  op1 = expand_expr (minval, NULL_RTX, VOIDmode, 0);
-+
-+  op_mode = insn_data[(int) CODE_FOR_casesi].operand[1].mode;
-+  op1 = convert_modes (op_mode, TYPE_MODE (TREE_TYPE (minval)),
-+                     op1, TREE_UNSIGNED (TREE_TYPE (minval)));
-+  if (! (*insn_data[(int) CODE_FOR_casesi].operand[1].predicate)
-+      (op1, op_mode))
-+    op1 = copy_to_mode_reg (op_mode, op1);
-+
-+  op2 = expand_expr (range, NULL_RTX, VOIDmode, 0);
-+
-+  op_mode = insn_data[(int) CODE_FOR_casesi].operand[2].mode;
-+  op2 = convert_modes (op_mode, TYPE_MODE (TREE_TYPE (range)),
-+                     op2, TREE_UNSIGNED (TREE_TYPE (range)));
-+  if (! (*insn_data[(int) CODE_FOR_casesi].operand[2].predicate)
-+      (op2, op_mode))
-+    op2 = copy_to_mode_reg (op_mode, op2);
-+
-+  emit_jump_insn (gen_casesi (index, op1, op2,
-+                            table_label, default_label));
-+  return 1;
-+}
-+
-+/* Attempt to generate a tablejump instruction; same concept.  */
-+#ifndef HAVE_tablejump
-+#define HAVE_tablejump 0
-+#define gen_tablejump(x, y) (0)
-+#endif
-+
-+/* Subroutine of the next function.
-+
-+   INDEX is the value being switched on, with the lowest value
-+   in the table already subtracted.
-+   MODE is its expected mode (needed if INDEX is constant).
-+   RANGE is the length of the jump table.
-+   TABLE_LABEL is a CODE_LABEL rtx for the table itself.
-+
-+   DEFAULT_LABEL is a CODE_LABEL rtx to jump to if the
-+   index value is out of range.  */
-+
-+static void
-+do_tablejump (index, mode, range, table_label, default_label)
-+     rtx index, range, table_label, default_label;
-+     enum machine_mode mode;
-+{
-+  rtx temp, vector;
-+
-+  if (INTVAL (range) > cfun->max_jumptable_ents)
-+    cfun->max_jumptable_ents = INTVAL (range);
-+
-+  /* Do an unsigned comparison (in the proper mode) between the index
-+     expression and the value which represents the length of the range.
-+     Since we just finished subtracting the lower bound of the range
-+     from the index expression, this comparison allows us to simultaneously
-+     check that the original index expression value is both greater than
-+     or equal to the minimum value of the range and less than or equal to
-+     the maximum value of the range.  */
-+
-+  emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
-+                         default_label);
-+
-+  /* If index is in range, it must fit in Pmode.
-+     Convert to Pmode so we can index with it.  */
-+  if (mode != Pmode)
-+    index = convert_to_mode (Pmode, index, 1);
-+
-+  /* Don't let a MEM slip thru, because then INDEX that comes
-+     out of PIC_CASE_VECTOR_ADDRESS won't be a valid address,
-+     and break_out_memory_refs will go to work on it and mess it up.  */
-+#ifdef PIC_CASE_VECTOR_ADDRESS
-+  if (flag_pic && GET_CODE (index) != REG)
-+    index = copy_to_mode_reg (Pmode, index);
-+#endif
-+
-+  /* If flag_force_addr were to affect this address
-+     it could interfere with the tricky assumptions made
-+     about addresses that contain label-refs,
-+     which may be valid only very near the tablejump itself.  */
-+  /* ??? The only correct use of CASE_VECTOR_MODE is the one inside the
-+     GET_MODE_SIZE, because this indicates how large insns are.  The other
-+     uses should all be Pmode, because they are addresses.  This code
-+     could fail if addresses and insns are not the same size.  */
-+  index = gen_rtx_PLUS (Pmode,
-+                      gen_rtx_MULT (Pmode, index,
-+                                    GEN_INT (GET_MODE_SIZE (CASE_VECTOR_MODE))),
-+                      gen_rtx_LABEL_REF (Pmode, table_label));
-+#ifdef PIC_CASE_VECTOR_ADDRESS
-+  if (flag_pic)
-+    index = PIC_CASE_VECTOR_ADDRESS (index);
-+  else
-+#endif
-+    index = memory_address_noforce (CASE_VECTOR_MODE, index);
-+  temp = gen_reg_rtx (CASE_VECTOR_MODE);
-+  vector = gen_rtx_MEM (CASE_VECTOR_MODE, index);
-+  RTX_UNCHANGING_P (vector) = 1;
-+  MEM_NOTRAP_P (vector) = 1;
-+  convert_move (temp, vector, 0);
-+
-+  emit_jump_insn (gen_tablejump (temp, table_label));
-+
-+  /* If we are generating PIC code or if the table is PC-relative, the
-+     table and JUMP_INSN must be adjacent, so don't output a BARRIER.  */
-+  if (! CASE_VECTOR_PC_RELATIVE && ! flag_pic)
-+    emit_barrier ();
-+}
-+
-+int
-+try_tablejump (index_type, index_expr, minval, range,
-+             table_label, default_label)
-+     tree index_type, index_expr, minval, range;
-+     rtx table_label, default_label;
-+{
-+  rtx index;
-+
-+  if (! HAVE_tablejump)
-+    return 0;
-+
-+  index_expr = fold (build (MINUS_EXPR, index_type,
-+                          convert (index_type, index_expr),
-+                          convert (index_type, minval)));
-+  index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
-+  emit_queue ();
-+  index = protect_from_queue (index, 0);
-+  do_pending_stack_adjust ();
-+
-+  do_tablejump (index, TYPE_MODE (index_type),
-+              convert_modes (TYPE_MODE (index_type),
-+                             TYPE_MODE (TREE_TYPE (range)),
-+                             expand_expr (range, NULL_RTX,
-+                                          VOIDmode, 0),
-+                             TREE_UNSIGNED (TREE_TYPE (range))),
-+              table_label, default_label);
-+  return 1;
-+}
-+
-+/* Nonzero if the mode is a valid vector mode for this architecture.
-+   This returns nonzero even if there is no hardware support for the
-+   vector mode, but we can emulate with narrower modes.  */
-+
-+int
-+vector_mode_valid_p (mode)
-+     enum machine_mode mode;
-+{
-+  enum mode_class class = GET_MODE_CLASS (mode);
-+  enum machine_mode innermode;
-+
-+  /* Doh!  What's going on?  */
-+  if (class != MODE_VECTOR_INT
-+      && class != MODE_VECTOR_FLOAT)
-+    return 0;
-+
-+  /* Hardware support.  Woo hoo!  */
-+  if (VECTOR_MODE_SUPPORTED_P (mode))
-+    return 1;
-+
-+  innermode = GET_MODE_INNER (mode);
-+
-+  /* We should probably return 1 if requesting V4DI and we have no DI,
-+     but we have V2DI, but this is probably very unlikely.  */
-+
-+  /* If we have support for the inner mode, we can safely emulate it.
-+     We may not have V2DI, but me can emulate with a pair of DIs.  */
-+  return mov_optab->handlers[innermode].insn_code != CODE_FOR_nothing;
-+}
-+
-+/* Return a CONST_VECTOR rtx for a VECTOR_CST tree.  */
-+static rtx
-+const_vector_from_tree (exp)
-+     tree exp;
-+{
-+  rtvec v;
-+  int units, i;
-+  tree link, elt;
-+  enum machine_mode inner, mode;
-+
-+  mode = TYPE_MODE (TREE_TYPE (exp));
-+
-+  if (is_zeros_p (exp))
-+    return CONST0_RTX (mode);
-+
-+  units = GET_MODE_NUNITS (mode);
-+  inner = GET_MODE_INNER (mode);
-+
-+  v = rtvec_alloc (units);
-+
-+  link = TREE_VECTOR_CST_ELTS (exp);
-+  for (i = 0; link; link = TREE_CHAIN (link), ++i)
-+    {
-+      elt = TREE_VALUE (link);
-+
-+      if (TREE_CODE (elt) == REAL_CST)
-+      RTVEC_ELT (v, i) = CONST_DOUBLE_FROM_REAL_VALUE (TREE_REAL_CST (elt),
-+                                                       inner);
-+      else
-+      RTVEC_ELT (v, i) = immed_double_const (TREE_INT_CST_LOW (elt),
-+                                             TREE_INT_CST_HIGH (elt),
-+                                             inner);
-+    }
-+
-+  return gen_rtx_raw_CONST_VECTOR (mode, v);
-+}
-+
-+#include "gt-expr.h"
-diff -ruN gcc-3.3.1/gcc/flags.h gcc-3.3.1.pp/gcc/flags.h
---- gcc-3.3.1/gcc/flags.h      2003-06-20 21:18:41.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/flags.h   2003-09-05 11:58:59.000000000 +0000
-@@ -690,4 +690,12 @@
- #define HONOR_SIGN_DEPENDENT_ROUNDING(MODE) \
-   (MODE_HAS_SIGN_DEPENDENT_ROUNDING (MODE) && !flag_unsafe_math_optimizations)
-+/* Nonzero means use propolice as a stack protection method */
-+
-+extern int flag_propolice_protection;
-+
-+/* Warn when not issuing stack smashing protection for some reason */
-+
-+extern int warn_stack_protector;
-+
- #endif /* ! GCC_FLAGS_H */
-diff -ruN gcc-3.3.1/gcc/flags.h.orig gcc-3.3.1.pp/gcc/flags.h.orig
---- gcc-3.3.1/gcc/flags.h.orig 1970-01-01 00:00:00.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/flags.h.orig      2003-06-20 21:18:41.000000000 +0000
-@@ -0,0 +1,693 @@
-+/* Compilation switch flag definitions for GCC.
-+   Copyright (C) 1987, 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002
-+   Free Software Foundation, Inc.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify it under
-+the terms of the GNU General Public License as published by the Free
-+Software Foundation; either version 2, or (at your option) any later
-+version.
-+
-+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-+WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING.  If not, write to the Free
-+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-+02111-1307, USA.  */
-+
-+#ifndef GCC_FLAGS_H
-+#define GCC_FLAGS_H
-+
-+/* Name of the input .c file being compiled.  */
-+extern const char *main_input_filename;
-+
-+enum debug_info_type
-+{
-+  NO_DEBUG,       /* Write no debug info.  */
-+  DBX_DEBUG,      /* Write BSD .stabs for DBX (using dbxout.c).  */
-+  SDB_DEBUG,      /* Write COFF for (old) SDB (using sdbout.c).  */
-+  DWARF_DEBUG,            /* Write Dwarf debug info (using dwarfout.c).  */
-+  DWARF2_DEBUG,           /* Write Dwarf v2 debug info (using dwarf2out.c).  */
-+  XCOFF_DEBUG,            /* Write IBM/Xcoff debug info (using dbxout.c).  */
-+  VMS_DEBUG,        /* Write VMS debug info (using vmsdbgout.c).  */
-+  VMS_AND_DWARF2_DEBUG /* Write VMS debug info (using vmsdbgout.c).
-+                          and DWARF v2 debug info (using dwarf2out.c).  */
-+};
-+
-+/* Specify which kind of debugging info to generate.  */
-+extern enum debug_info_type write_symbols;
-+
-+enum debug_info_level
-+{
-+  DINFO_LEVEL_NONE,   /* Write no debugging info.  */
-+  DINFO_LEVEL_TERSE,  /* Write minimal info to support tracebacks only.  */
-+  DINFO_LEVEL_NORMAL, /* Write info for all declarations (and line table).  */
-+  DINFO_LEVEL_VERBOSE /* Write normal info plus #define/#undef info.  */
-+};
-+
-+/* Specify how much debugging info to generate.  */
-+extern enum debug_info_level debug_info_level;
-+
-+/* Nonzero means use GNU-only extensions in the generated symbolic
-+   debugging information.  */
-+extern int use_gnu_debug_info_extensions;
-+
-+/* Nonzero means do optimizations.  -opt.  */
-+
-+extern int optimize;
-+
-+/* Nonzero means optimize for size.  -Os.  */
-+
-+extern int optimize_size;
-+
-+/* Don't print functions as they are compiled and don't print
-+   times taken by the various passes.  -quiet.  */
-+
-+extern int quiet_flag;
-+
-+/* Print times taken by the various passes.  -ftime-report.  */
-+
-+extern int time_report;
-+
-+/* Print memory still in use at end of compilation (which may have little
-+   to do with peak memory consumption).  -fmem-report.  */
-+
-+extern int mem_report;
-+
-+/* Don't print warning messages.  -w.  */
-+
-+extern int inhibit_warnings;
-+
-+/* Don't suppress warnings from system headers.  -Wsystem-headers.  */
-+
-+extern int warn_system_headers;
-+
-+/* Do print extra warnings (such as for uninitialized variables).  -W.  */
-+
-+extern int extra_warnings;
-+
-+/* Nonzero to warn about unused variables, functions et.al.  Use
-+   set_Wunused() to update the -Wunused-* flags that correspond to the
-+   -Wunused option.  */
-+
-+extern void set_Wunused PARAMS ((int setting));
-+
-+extern int warn_unused_function;
-+extern int warn_unused_label;
-+extern int warn_unused_parameter;
-+extern int warn_unused_variable;
-+extern int warn_unused_value;
-+
-+/* Nonzero to warn about code which is never reached.  */
-+
-+extern int warn_notreached;
-+
-+/* Nonzero means warn if inline function is too large.  */
-+
-+extern int warn_inline;
-+
-+/* Nonzero to warn about variables used before they are initialized.  */
-+
-+extern int warn_uninitialized;
-+
-+/* Zero if unknown pragmas are ignored
-+   One if the compiler should warn about an unknown pragma not in
-+   a system include file.
-+   Greater than one if the compiler should warn for all unknown
-+   pragmas.  */
-+
-+extern int warn_unknown_pragmas;
-+
-+/* Nonzero means warn about all declarations which shadow others.  */
-+
-+extern int warn_shadow;
-+
-+/* Warn if a switch on an enum, that does not have a default case,
-+   fails to have a case for every enum value.  */
-+
-+extern int warn_switch;
-+
-+/* Warn if a switch does not have a default case.  */
-+
-+extern int warn_switch_default;
-+
-+/* Warn if a switch on an enum fails to have a case for every enum
-+   value (regardless of the presence or otherwise of a default case).  */
-+
-+extern int warn_switch_enum;
-+
-+/* Nonzero means warn about function definitions that default the return type
-+   or that use a null return and have a return-type other than void.  */
-+
-+extern int warn_return_type;
-+
-+/* Warn about functions which might be candidates for attribute noreturn.  */
-+
-+extern int warn_missing_noreturn;
-+
-+/* Nonzero means warn about pointer casts that increase the required
-+   alignment of the target type (and might therefore lead to a crash
-+   due to a misaligned access).  */
-+
-+extern int warn_cast_align;
-+
-+/* Nonzero means warn about any objects definitions whose size is larger
-+   than N bytes.  Also want about function definitions whose returned
-+   values are larger than N bytes. The value N is in `larger_than_size'.  */
-+
-+extern int warn_larger_than;
-+extern HOST_WIDE_INT larger_than_size;
-+
-+/* Warn if a function returns an aggregate,
-+   since there are often incompatible calling conventions for doing this.  */
-+
-+extern int warn_aggregate_return;
-+
-+/* Warn if packed attribute on struct is unnecessary and inefficient.  */
-+
-+extern int warn_packed;
-+
-+/* Warn when gcc pads a structure to an alignment boundary.  */
-+
-+extern int warn_padded;
-+
-+/* Warn when an optimization pass is disabled.  */
-+
-+extern int warn_disabled_optimization;
-+
-+/* Nonzero means warn about uses of __attribute__((deprecated)) 
-+   declarations.  */
-+
-+extern int warn_deprecated_decl;
-+
-+/* Nonzero means warn about constructs which might not be strict
-+   aliasing safe.  */
-+
-+extern int warn_strict_aliasing;
-+
-+/* Nonzero if generating code to do profiling.  */
-+
-+extern int profile_flag;
-+
-+/* Nonzero if generating code to profile program flow graph arcs.  */
-+
-+extern int profile_arc_flag;
-+
-+/* Nonzero if generating info for gcov to calculate line test coverage.  */
-+
-+extern int flag_test_coverage;
-+
-+/* Nonzero indicates that branch taken probabilities should be calculated.  */
-+
-+extern int flag_branch_probabilities;
-+
-+/* Nonzero if basic blocks should be reordered.  */
-+
-+extern int flag_reorder_blocks;
-+
-+/* Nonzero if functions should be reordered.  */
-+
-+extern int flag_reorder_functions;
-+
-+/* Nonzero if registers should be renamed.  */
-+
-+extern int flag_rename_registers;
-+
-+/* Nonzero for -pedantic switch: warn about anything
-+   that standard C forbids.  */
-+
-+extern int pedantic;
-+
-+/* Temporarily suppress certain warnings.
-+   This is set while reading code from a system header file.  */
-+
-+extern int in_system_header;
-+
-+/* Nonzero for -dp: annotate the assembly with a comment describing the
-+   pattern and alternative used.  */
-+
-+extern int flag_print_asm_name;
-+\f
-+/* Now the symbols that are set with `-f' switches.  */
-+
-+/* Nonzero means `char' should be signed.  */
-+
-+extern int flag_signed_char;
-+
-+/* Nonzero means give an enum type only as many bytes as it needs.  */
-+
-+extern int flag_short_enums;
-+
-+/* Nonzero for -fcaller-saves: allocate values in regs that need to
-+   be saved across function calls, if that produces overall better code.
-+   Optional now, so people can test it.  */
-+
-+extern int flag_caller_saves;
-+
-+/* Nonzero for -fpcc-struct-return: return values the same way PCC does.  */
-+
-+extern int flag_pcc_struct_return;
-+
-+/* Nonzero for -fforce-mem: load memory value into a register
-+   before arithmetic on it.  This makes better cse but slower compilation.  */
-+
-+extern int flag_force_mem;
-+
-+/* Nonzero for -fforce-addr: load memory address into a register before
-+   reference to memory.  This makes better cse but slower compilation.  */
-+
-+extern int flag_force_addr;
-+
-+/* Nonzero for -fdefer-pop: don't pop args after each function call;
-+   instead save them up to pop many calls' args with one insns.  */
-+
-+extern int flag_defer_pop;
-+
-+/* Nonzero for -ffloat-store: don't allocate floats and doubles
-+   in extended-precision registers.  */
-+
-+extern int flag_float_store;
-+
-+/* Nonzero enables strength-reduction in loop.c.  */
-+
-+extern int flag_strength_reduce;
-+
-+/* Nonzero enables loop unrolling in unroll.c.  Only loops for which the
-+   number of iterations can be calculated at compile-time (UNROLL_COMPLETELY,
-+   UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are
-+   unrolled.  */
-+
-+extern int flag_unroll_loops;
-+
-+/* Nonzero enables loop unrolling in unroll.c.  All loops are unrolled.
-+   This is generally not a win.  */
-+
-+extern int flag_unroll_all_loops;
-+
-+/* Nonzero forces all invariant computations in loops to be moved
-+   outside the loop.  */
-+
-+extern int flag_move_all_movables;
-+
-+/* Nonzero enables prefetch optimizations for arrays in loops.  */
-+
-+extern int flag_prefetch_loop_arrays;
-+
-+/* Nonzero forces all general induction variables in loops to be
-+   strength reduced.  */
-+
-+extern int flag_reduce_all_givs;
-+
-+/* Nonzero for -fcse-follow-jumps:
-+   have cse follow jumps to do a more extensive job.  */
-+
-+extern int flag_cse_follow_jumps;
-+
-+/* Nonzero for -fcse-skip-blocks:
-+   have cse follow a branch around a block.  */
-+
-+extern int flag_cse_skip_blocks;
-+
-+/* Nonzero for -fexpensive-optimizations:
-+   perform miscellaneous relatively-expensive optimizations.  */
-+extern int flag_expensive_optimizations;
-+
-+/* Nonzero for -fwritable-strings:
-+   store string constants in data segment and don't uniquize them.  */
-+
-+extern int flag_writable_strings;
-+
-+/* Nonzero means don't put addresses of constant functions in registers.
-+   Used for compiling the Unix kernel, where strange substitutions are
-+   done on the assembly output.  */
-+
-+extern int flag_no_function_cse;
-+
-+/* Nonzero for -fomit-frame-pointer:
-+   don't make a frame pointer in simple functions that don't require one.  */
-+
-+extern int flag_omit_frame_pointer;
-+
-+/* Nonzero to inhibit use of define_optimization peephole opts.  */
-+
-+extern int flag_no_peephole;
-+
-+/* Nonzero means all references through pointers are volatile.  */
-+
-+extern int flag_volatile;
-+
-+/* Nonzero means treat all global and extern variables as volatile.  */
-+
-+extern int flag_volatile_global;
-+
-+/* Nonzero means treat all static variables as volatile.  */
-+
-+extern int flag_volatile_static;
-+
-+/* Nonzero allows GCC to optimize sibling and tail recursive calls.  */
-+
-+extern int flag_optimize_sibling_calls;
-+
-+/* Nonzero means the front end generally wants `errno' maintained by math
-+   operations, like built-in SQRT.  */
-+
-+extern int flag_errno_math;
-+
-+/* Nonzero means that unsafe floating-point math optimizations are allowed
-+   for the sake of speed.  IEEE compliance is not guaranteed, and operations
-+   are allowed to assume that their arguments and results are "normal"
-+   (e.g., nonnegative for SQRT).  */
-+
-+extern int flag_unsafe_math_optimizations;
-+
-+/* Nonzero means that no NaNs or +-Infs are expected.  */
-+
-+extern int flag_finite_math_only;
-+
-+/* Zero means that floating-point math operations cannot generate a
-+   (user-visible) trap.  This is the case, for example, in nonstop
-+   IEEE 754 arithmetic.  */
-+
-+extern int flag_trapping_math;
-+
-+/* 0 means straightforward implementation of complex divide acceptable.
-+   1 means wide ranges of inputs must work for complex divide.
-+   2 means C99-like requirements for complex divide (not yet implemented).  */
-+
-+extern int flag_complex_divide_method;
-+
-+/* Nonzero means to run loop optimizations twice.  */
-+
-+extern int flag_rerun_loop_opt;
-+
-+/* Nonzero means make functions that look like good inline candidates
-+   go inline.  */
-+
-+extern int flag_inline_functions;
-+
-+/* Nonzero for -fkeep-inline-functions: even if we make a function
-+   go inline everywhere, keep its definition around for debugging
-+   purposes.  */
-+
-+extern int flag_keep_inline_functions;
-+
-+/* Nonzero means that functions declared `inline' will be treated
-+   as `static'.  Prevents generation of zillions of copies of unused
-+   static inline functions; instead, `inlines' are written out
-+   only when actually used.  Used in conjunction with -g.  Also
-+   does the right thing with #pragma interface.  */
-+
-+extern int flag_no_inline;
-+
-+/* Nonzero means that we don't want inlining by virtue of -fno-inline,
-+   not just because the tree inliner turned us off.  */
-+
-+extern int flag_really_no_inline;
-+
-+/* Nonzero if we are only using compiler to check syntax errors.  */
-+
-+extern int flag_syntax_only;
-+
-+/* Nonzero means we should save auxiliary info into a .X file.  */
-+
-+extern int flag_gen_aux_info;
-+
-+/* Nonzero means make the text shared if supported.  */
-+
-+extern int flag_shared_data;
-+
-+/* flag_schedule_insns means schedule insns within basic blocks (before
-+   local_alloc).
-+   flag_schedule_insns_after_reload means schedule insns after
-+   global_alloc.  */
-+
-+extern int flag_schedule_insns;
-+extern int flag_schedule_insns_after_reload;
-+
-+/* The following flags have effect only for scheduling before register
-+   allocation:
-+
-+   flag_schedule_interblock means schedule insns across basic blocks.
-+   flag_schedule_speculative means allow speculative motion of non-load insns.
-+   flag_schedule_speculative_load means allow speculative motion of some
-+   load insns.
-+   flag_schedule_speculative_load_dangerous allows speculative motion of more
-+   load insns.  */
-+
-+extern int flag_schedule_interblock;
-+extern int flag_schedule_speculative;
-+extern int flag_schedule_speculative_load;
-+extern int flag_schedule_speculative_load_dangerous;
-+
-+/* flag_branch_on_count_reg means try to replace add-1,compare,branch tupple
-+   by a cheaper branch, on a count register.  */
-+extern int flag_branch_on_count_reg;
-+
-+/* This option is set to 1 on -fsingle-precision-constant option which is
-+   used to convert the floating point constants to single precision 
-+   constants.  */
-+
-+extern int flag_single_precision_constant;
-+
-+/* Nonzero means put things in delayed-branch slots if supported.  */
-+
-+extern int flag_delayed_branch;
-+
-+/* Nonzero means suppress output of instruction numbers and line number
-+   notes in debugging dumps.  */
-+
-+extern int flag_dump_unnumbered;
-+
-+/* Nonzero means change certain warnings into errors.
-+   Usually these are warnings about failure to conform to some standard.  */
-+
-+extern int flag_pedantic_errors;
-+
-+/* Nonzero means generate position-independent code.  1 vs 2 for a 
-+   target-dependent "small" or "large" mode.  */
-+
-+extern int flag_pic;
-+
-+/* Nonzero means generate extra code for exception handling and enable
-+   exception handling.  */
-+
-+extern int flag_exceptions;
-+
-+/* Nonzero means generate frame unwind info table when supported */
-+
-+extern int flag_unwind_tables;
-+
-+/* Nonzero means generate frame unwind info table exact at each insn boundary */
-+
-+extern int flag_asynchronous_unwind_tables;
-+
-+/* Nonzero means don't place uninitialized global data in common storage
-+   by default.  */
-+
-+extern int flag_no_common;
-+
-+/* -finhibit-size-directive inhibits output of .size for ELF.
-+   This is used only for compiling crtstuff.c,
-+   and it may be extended to other effects
-+   needed for crtstuff.c on other systems.  */
-+extern int flag_inhibit_size_directive;
-+
-+/* Nonzero means place each function into its own section on those platforms
-+   which support arbitrary section names and unlimited numbers of sections.  */
-+
-+extern int flag_function_sections;
-+
-+/* ... and similar for data.  */
-+ 
-+extern int flag_data_sections;
-+
-+/* -fverbose-asm causes extra commentary information to be produced in
-+   the generated assembly code (to make it more readable).  This option
-+   is generally only of use to those who actually need to read the
-+   generated assembly code (perhaps while debugging the compiler itself).
-+   -fno-verbose-asm, the default, causes the extra information
-+   to not be added and is useful when comparing two assembler files.  */
-+
-+extern int flag_verbose_asm;
-+
-+/* -dA causes debug information to be produced in
-+   the generated assembly code (to make it more readable).  This option
-+   is generally only of use to those who actually need to read the
-+   generated assembly code (perhaps while debugging the compiler itself).
-+   Currently, this switch is only used by dwarfout.c; however, it is intended
-+   to be a catchall for printing debug information in the assembler file.  */
-+
-+extern int flag_debug_asm;
-+
-+extern int flag_dump_rtl_in_asm;
-+
-+/* -fgnu-linker specifies use of the GNU linker for initializations.
-+   -fno-gnu-linker says that collect will be used.  */
-+extern int flag_gnu_linker;
-+
-+/* Tag all structures with __attribute__(packed) */
-+extern int flag_pack_struct;
-+
-+/* This flag is only tested if alias checking is enabled.
-+   0 if pointer arguments may alias each other.  True in C.
-+   1 if pointer arguments may not alias each other but may alias
-+   global variables.
-+   2 if pointer arguments may not alias each other and may not
-+   alias global variables.  True in Fortran.
-+   The value is ignored if flag_alias_check is 0.  */
-+extern int flag_argument_noalias;
-+
-+/* Nonzero if we should do (language-dependent) alias analysis.
-+   Typically, this analysis will assume that expressions of certain
-+   types do not alias expressions of certain other types.  Only used
-+   if alias analysis (in general) is enabled.  */
-+extern int flag_strict_aliasing;
-+
-+/* Emit code to probe the stack, to help detect stack overflow; also
-+   may cause large objects to be allocated dynamically.  */
-+extern int flag_stack_check;
-+
-+/* Do the full regmove optimization pass.  */
-+extern int flag_regmove;
-+
-+/* Instrument functions with calls at entry and exit, for profiling.  */
-+extern int flag_instrument_function_entry_exit;
-+
-+/* Perform a peephole pass before sched2.  */
-+extern int flag_peephole2;
-+
-+/* Try to guess branch probablities.  */
-+extern int flag_guess_branch_prob;
-+
-+/* -fcheck-bounds causes gcc to generate array bounds checks.
-+   For C, C++ and ObjC: defaults off.
-+   For Java: defaults to on.
-+   For Fortran: defaults to off.  */
-+extern int flag_bounds_check;
-+
-+/* This will attempt to merge constant section constants, if 1 only
-+   string constants and constants from constant pool, if 2 also constant
-+   variables.  */
-+extern int flag_merge_constants;
-+
-+/* If one, renumber instruction UIDs to reduce the number of
-+   unused UIDs if there are a lot of instructions.  If greater than
-+   one, unconditionally renumber instruction UIDs.  */
-+extern int flag_renumber_insns;
-+\f
-+/* Other basic status info about current function.  */
-+
-+/* Nonzero means current function must be given a frame pointer.
-+   Set in stmt.c if anything is allocated on the stack there.
-+   Set in reload1.c if anything is allocated on the stack there.  */
-+
-+extern int frame_pointer_needed;
-+
-+/* Nonzero if the generated code should trap on signed overflow
-+   for PLUS / SUB / MULT.  */
-+extern int flag_trapv;
-+
-+/* Value of the -G xx switch, and whether it was passed or not.  */
-+extern int g_switch_value;
-+extern int g_switch_set;
-+
-+/* Values of the -falign-* flags: how much to align labels in code. 
-+   0 means `use default', 1 means `don't align'.  
-+   For each variable, there is an _log variant which is the power
-+   of two not less than the variable, for .align output.  */
-+
-+extern int align_loops;
-+extern int align_loops_log;
-+extern int align_loops_max_skip;
-+extern int align_jumps;
-+extern int align_jumps_log;
-+extern int align_jumps_max_skip;
-+extern int align_labels;
-+extern int align_labels_log;
-+extern int align_labels_max_skip;
-+extern int align_functions;
-+extern int align_functions_log;
-+
-+/* Like align_functions_log above, but used by front-ends to force the
-+   minimum function alignment.  Zero means no alignment is forced.  */
-+extern int force_align_functions_log;
-+
-+/* Nonzero if we dump in VCG format, not plain text.  */
-+extern int dump_for_graph;
-+
-+/* Selection of the graph form.  */
-+enum graph_dump_types
-+{
-+  no_graph = 0,
-+  vcg
-+};
-+extern enum graph_dump_types graph_dump_format;
-+
-+/* Nonzero means ignore `#ident' directives.  0 means handle them.
-+   On SVR4 targets, it also controls whether or not to emit a
-+   string identifying the compiler.  */
-+
-+extern int flag_no_ident;
-+
-+/* Nonzero if we want to perform enhanced load motion during gcse.  */
-+
-+extern int flag_gcse_lm;
-+
-+/* Nonzero if we want to perform store motion after gcse.  */
-+
-+extern int flag_gcse_sm;
-+
-+
-+/* Nonzero means we should do dwarf2 duplicate elimination.  */
-+
-+extern int flag_eliminate_dwarf2_dups;
-+
-+/* Nonzero means to collect statistics which might be expensive
-+   and to print them when we are done.  */
-+extern int flag_detailed_statistics;
-+
-+/* Nonzero means enable synchronous exceptions for non-call instructions.  */
-+extern int flag_non_call_exceptions;
-+
-+/* Nonzero means put zero initialized data in the bss section.  */
-+extern int flag_zero_initialized_in_bss;
-+
-+/* Nonzero means disable transformations observable by signaling NaNs.  */
-+extern int flag_signaling_nans;
-+
-+/* A string that's used when a random name is required.  NULL means
-+   to make it really random.  */
-+
-+extern const char *flag_random_seed;
-+
-+/* True if the given mode has a NaN representation and the treatment of
-+   NaN operands is important.  Certain optimizations, such as folding
-+   x * 0 into x, are not correct for NaN operands, and are normally
-+   disabled for modes with NaNs.  The user can ask for them to be
-+   done anyway using the -funsafe-math-optimizations switch.  */
-+#define HONOR_NANS(MODE) \
-+  (MODE_HAS_NANS (MODE) && !flag_finite_math_only)
-+
-+/* Like HONOR_NANs, but true if we honor signaling NaNs (or sNaNs).  */
-+#define HONOR_SNANS(MODE) (flag_signaling_nans && HONOR_NANS (MODE))
-+
-+/* As for HONOR_NANS, but true if the mode can represent infinity and
-+   the treatment of infinite values is important.  */
-+#define HONOR_INFINITIES(MODE) \
-+  (MODE_HAS_INFINITIES (MODE) && !flag_finite_math_only)
-+
-+/* Like HONOR_NANS, but true if the given mode distinguishes between
-+   postive and negative zero, and the sign of zero is important.  */
-+#define HONOR_SIGNED_ZEROS(MODE) \
-+  (MODE_HAS_SIGNED_ZEROS (MODE) && !flag_unsafe_math_optimizations)
-+
-+/* Like HONOR_NANS, but true if given mode supports sign-dependent rounding,
-+   and the rounding mode is important.  */
-+#define HONOR_SIGN_DEPENDENT_ROUNDING(MODE) \
-+  (MODE_HAS_SIGN_DEPENDENT_ROUNDING (MODE) && !flag_unsafe_math_optimizations)
-+
-+#endif /* ! GCC_FLAGS_H */
-diff -ruN gcc-3.3.1/gcc/function.c gcc-3.3.1.pp/gcc/function.c
---- gcc-3.3.1/gcc/function.c   2003-04-10 22:26:04.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/function.c        2003-09-05 11:58:59.000000000 +0000
-@@ -59,6 +59,7 @@
- #include "tm_p.h"
- #include "integrate.h"
- #include "langhooks.h"
-+#include "protector.h"
- #ifndef TRAMPOLINE_ALIGNMENT
- #define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
-@@ -142,6 +143,10 @@
- /* Array of INSN_UIDs to hold the INSN_UIDs for each sibcall epilogue
-    in this function.  */
- static GTY(()) varray_type sibcall_epilogue;
-+
-+/* Current boundary mark for character arrays.  */
-+int temp_boundary_mark = 0;
-+
\f
- /* In order to evaluate some expressions, such as function calls returning
-    structures in memory, we need to temporarily allocate stack locations.
-@@ -195,6 +200,8 @@
-   /* The size of the slot, including extra space for alignment.  This
-      info is for combine_temp_slots.  */
-   HOST_WIDE_INT full_size;
-+  /* Boundary mark of a character array and the others. This info is for propolice */
-+  int boundary_mark;
- };
\f
- /* This structure is used to record MEMs or pseudos used to replace VAR, any
-@@ -629,6 +636,7 @@
-    whose lifetime is controlled by CLEANUP_POINT_EXPRs.  KEEP is 3
-    if we are to allocate something at an inner level to be treated as
-    a variable in the block (e.g., a SAVE_EXPR).
-+   KEEP is 5 if we allocate a place to return structure.
-    TYPE is the type that will be used for the stack slot.  */
-@@ -642,6 +650,8 @@
-   unsigned int align;
-   struct temp_slot *p, *best_p = 0;
-   rtx slot;
-+  int char_array = (flag_propolice_protection
-+                  && keep == 1 && search_string_def (type));
-   /* If SIZE is -1 it means that somebody tried to allocate a temporary
-      of a variable size.  */
-@@ -667,7 +677,8 @@
-       && ! p->in_use
-       && objects_must_conflict_p (p->type, type)
-       && (best_p == 0 || best_p->size > p->size
--          || (best_p->size == p->size && best_p->align > p->align)))
-+          || (best_p->size == p->size && best_p->align > p->align))
-+      && (! char_array || p->boundary_mark != 0))
-       {
-       if (p->align == align && p->size == size)
-         {
-@@ -702,6 +713,7 @@
-             p->address = 0;
-             p->rtl_expr = 0;
-             p->type = best_p->type;
-+            p->boundary_mark = best_p->boundary_mark;
-             p->next = temp_slots;
-             temp_slots = p;
-@@ -762,6 +774,7 @@
-       p->full_size = frame_offset - frame_offset_old;
- #endif
-       p->address = 0;
-+      p->boundary_mark = char_array?++temp_boundary_mark:0;
-       p->next = temp_slots;
-       temp_slots = p;
-     }
-@@ -932,14 +945,16 @@
-           int delete_q = 0;
-           if (! q->in_use && GET_MODE (q->slot) == BLKmode)
-             {
--              if (p->base_offset + p->full_size == q->base_offset)
-+              if (p->base_offset + p->full_size == q->base_offset &&
-+                  p->boundary_mark == q->boundary_mark)
-                 {
-                   /* Q comes after P; combine Q into P.  */
-                   p->size += q->size;
-                   p->full_size += q->full_size;
-                   delete_q = 1;
-                 }
--              else if (q->base_offset + q->full_size == p->base_offset)
-+              else if (q->base_offset + q->full_size == p->base_offset &&
-+                       p->boundary_mark == q->boundary_mark)
-                 {
-                   /* P comes after Q; combine P into Q.  */
-                   q->size += p->size;
-@@ -1497,7 +1512,9 @@
-     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);
-+    new = function ?
-+      assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode), 0, func):
-+      assign_stack_local_for_pseudo_reg (decl_mode, GET_MODE_SIZE (decl_mode), 0);
-   PUT_CODE (reg, MEM);
-   PUT_MODE (reg, decl_mode);
-@@ -3961,7 +3978,8 @@
-                constant with that register.  */
-             temp = gen_reg_rtx (Pmode);
-             XEXP (x, 0) = new;
--            if (validate_change (object, &XEXP (x, 1), temp, 0))
-+            if (validate_change (object, &XEXP (x, 1), temp, 0)
-+                && ! flag_propolice_protection)
-               emit_insn_before (gen_move_insn (temp, new_offset), object);
-             else
-               {
-diff -ruN gcc-3.3.1/gcc/gcse.c gcc-3.3.1.pp/gcc/gcse.c
---- gcc-3.3.1/gcc/gcse.c       2003-07-14 09:21:22.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/gcse.c    2003-09-05 11:58:59.000000000 +0000
-@@ -4211,7 +4211,7 @@
-       /* Find an assignment that sets reg_used and is available
-        at the start of the block.  */
-       set = find_avail_set (regno, insn);
--      if (! set)
-+      if (! set || set->expr->volatil)
-       continue;
-       pat = set->expr;
-diff -ruN gcc-3.3.1/gcc/gcse.c.orig gcc-3.3.1.pp/gcc/gcse.c.orig
---- gcc-3.3.1/gcc/gcse.c.orig  1970-01-01 00:00:00.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/gcse.c.orig       2003-07-14 09:21:22.000000000 +0000
-@@ -0,0 +1,7477 @@
-+/* Global common subexpression elimination/Partial redundancy elimination
-+   and global constant/copy propagation for GNU compiler.
-+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
-+   Free Software Foundation, Inc.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify it under
-+the terms of the GNU General Public License as published by the Free
-+Software Foundation; either version 2, or (at your option) any later
-+version.
-+
-+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-+WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING.  If not, write to the Free
-+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-+02111-1307, USA.  */
-+
-+/* TODO
-+   - reordering of memory allocation and freeing to be more space efficient
-+   - do rough calc of how many regs are needed in each block, and a rough
-+     calc of how many regs are available in each class and use that to
-+     throttle back the code in cases where RTX_COST is minimal.
-+   - a store to the same address as a load does not kill the load if the
-+     source of the store is also the destination of the load.  Handling this
-+     allows more load motion, particularly out of loops.
-+   - ability to realloc sbitmap vectors would allow one initial computation
-+     of reg_set_in_block with only subsequent additions, rather than
-+     recomputing it for each pass
-+
-+*/
-+
-+/* References searched while implementing this.
-+
-+   Compilers Principles, Techniques and Tools
-+   Aho, Sethi, Ullman
-+   Addison-Wesley, 1988
-+
-+   Global Optimization by Suppression of Partial Redundancies
-+   E. Morel, C. Renvoise
-+   communications of the acm, Vol. 22, Num. 2, Feb. 1979
-+
-+   A Portable Machine-Independent Global Optimizer - Design and Measurements
-+   Frederick Chow
-+   Stanford Ph.D. thesis, Dec. 1983
-+
-+   A Fast Algorithm for Code Movement Optimization
-+   D.M. Dhamdhere
-+   SIGPLAN Notices, Vol. 23, Num. 10, Oct. 1988
-+
-+   A Solution to a Problem with Morel and Renvoise's
-+   Global Optimization by Suppression of Partial Redundancies
-+   K-H Drechsler, M.P. Stadel
-+   ACM TOPLAS, Vol. 10, Num. 4, Oct. 1988
-+
-+   Practical Adaptation of the Global Optimization
-+   Algorithm of Morel and Renvoise
-+   D.M. Dhamdhere
-+   ACM TOPLAS, Vol. 13, Num. 2. Apr. 1991
-+
-+   Efficiently Computing Static Single Assignment Form and the Control
-+   Dependence Graph
-+   R. Cytron, J. Ferrante, B.K. Rosen, M.N. Wegman, and F.K. Zadeck
-+   ACM TOPLAS, Vol. 13, Num. 4, Oct. 1991
-+
-+   Lazy Code Motion
-+   J. Knoop, O. Ruthing, B. Steffen
-+   ACM SIGPLAN Notices Vol. 27, Num. 7, Jul. 1992, '92 Conference on PLDI
-+
-+   What's In a Region?  Or Computing Control Dependence Regions in Near-Linear
-+   Time for Reducible Flow Control
-+   Thomas Ball
-+   ACM Letters on Programming Languages and Systems,
-+   Vol. 2, Num. 1-4, Mar-Dec 1993
-+
-+   An Efficient Representation for Sparse Sets
-+   Preston Briggs, Linda Torczon
-+   ACM Letters on Programming Languages and Systems,
-+   Vol. 2, Num. 1-4, Mar-Dec 1993
-+
-+   A Variation of Knoop, Ruthing, and Steffen's Lazy Code Motion
-+   K-H Drechsler, M.P. Stadel
-+   ACM SIGPLAN Notices, Vol. 28, Num. 5, May 1993
-+
-+   Partial Dead Code Elimination
-+   J. Knoop, O. Ruthing, B. Steffen
-+   ACM SIGPLAN Notices, Vol. 29, Num. 6, Jun. 1994
-+
-+   Effective Partial Redundancy Elimination
-+   P. Briggs, K.D. Cooper
-+   ACM SIGPLAN Notices, Vol. 29, Num. 6, Jun. 1994
-+
-+   The Program Structure Tree: Computing Control Regions in Linear Time
-+   R. Johnson, D. Pearson, K. Pingali
-+   ACM SIGPLAN Notices, Vol. 29, Num. 6, Jun. 1994
-+
-+   Optimal Code Motion: Theory and Practice
-+   J. Knoop, O. Ruthing, B. Steffen
-+   ACM TOPLAS, Vol. 16, Num. 4, Jul. 1994
-+
-+   The power of assignment motion
-+   J. Knoop, O. Ruthing, B. Steffen
-+   ACM SIGPLAN Notices Vol. 30, Num. 6, Jun. 1995, '95 Conference on PLDI
-+
-+   Global code motion / global value numbering
-+   C. Click
-+   ACM SIGPLAN Notices Vol. 30, Num. 6, Jun. 1995, '95 Conference on PLDI
-+
-+   Value Driven Redundancy Elimination
-+   L.T. Simpson
-+   Rice University Ph.D. thesis, Apr. 1996
-+
-+   Value Numbering
-+   L.T. Simpson
-+   Massively Scalar Compiler Project, Rice University, Sep. 1996
-+
-+   High Performance Compilers for Parallel Computing
-+   Michael Wolfe
-+   Addison-Wesley, 1996
-+
-+   Advanced Compiler Design and Implementation
-+   Steven Muchnick
-+   Morgan Kaufmann, 1997
-+
-+   Building an Optimizing Compiler
-+   Robert Morgan
-+   Digital Press, 1998
-+
-+   People wishing to speed up the code here should read:
-+     Elimination Algorithms for Data Flow Analysis
-+     B.G. Ryder, M.C. Paull
-+     ACM Computing Surveys, Vol. 18, Num. 3, Sep. 1986
-+
-+     How to Analyze Large Programs Efficiently and Informatively
-+     D.M. Dhamdhere, B.K. Rosen, F.K. Zadeck
-+     ACM SIGPLAN Notices Vol. 27, Num. 7, Jul. 1992, '92 Conference on PLDI
-+
-+   People wishing to do something different can find various possibilities
-+   in the above papers and elsewhere.
-+*/
-+
-+#include "config.h"
-+#include "system.h"
-+#include "toplev.h"
-+
-+#include "rtl.h"
-+#include "tm_p.h"
-+#include "regs.h"
-+#include "hard-reg-set.h"
-+#include "flags.h"
-+#include "real.h"
-+#include "insn-config.h"
-+#include "recog.h"
-+#include "basic-block.h"
-+#include "output.h"
-+#include "function.h"
-+#include "expr.h"
-+#include "except.h"
-+#include "ggc.h"
-+#include "params.h"
-+#include "cselib.h"
-+
-+#include "obstack.h"
-+
-+/* Propagate flow information through back edges and thus enable PRE's
-+   moving loop invariant calculations out of loops.
-+
-+   Originally this tended to create worse overall code, but several
-+   improvements during the development of PRE seem to have made following
-+   back edges generally a win.
-+
-+   Note much of the loop invariant code motion done here would normally
-+   be done by loop.c, which has more heuristics for when to move invariants
-+   out of loops.  At some point we might need to move some of those
-+   heuristics into gcse.c.  */
-+
-+/* We support GCSE via Partial Redundancy Elimination.  PRE optimizations
-+   are a superset of those done by GCSE.
-+
-+   We perform the following steps:
-+
-+   1) Compute basic block information.
-+
-+   2) Compute table of places where registers are set.
-+
-+   3) Perform copy/constant propagation.
-+
-+   4) Perform global cse.
-+
-+   5) Perform another pass of copy/constant propagation.
-+
-+   Two passes of copy/constant propagation are done because the first one
-+   enables more GCSE and the second one helps to clean up the copies that
-+   GCSE creates.  This is needed more for PRE than for Classic because Classic
-+   GCSE will try to use an existing register containing the common
-+   subexpression rather than create a new one.  This is harder to do for PRE
-+   because of the code motion (which Classic GCSE doesn't do).
-+
-+   Expressions we are interested in GCSE-ing are of the form
-+   (set (pseudo-reg) (expression)).
-+   Function want_to_gcse_p says what these are.
-+
-+   PRE handles moving invariant expressions out of loops (by treating them as
-+   partially redundant).
-+
-+   Eventually it would be nice to replace cse.c/gcse.c with SSA (static single
-+   assignment) based GVN (global value numbering).  L. T. Simpson's paper
-+   (Rice University) on value numbering is a useful reference for this.
-+
-+   **********************
-+
-+   We used to support multiple passes but there are diminishing returns in
-+   doing so.  The first pass usually makes 90% of the changes that are doable.
-+   A second pass can make a few more changes made possible by the first pass.
-+   Experiments show any further passes don't make enough changes to justify
-+   the expense.
-+
-+   A study of spec92 using an unlimited number of passes:
-+   [1 pass] = 1208 substitutions, [2] = 577, [3] = 202, [4] = 192, [5] = 83,
-+   [6] = 34, [7] = 17, [8] = 9, [9] = 4, [10] = 4, [11] = 2,
-+   [12] = 2, [13] = 1, [15] = 1, [16] = 2, [41] = 1
-+
-+   It was found doing copy propagation between each pass enables further
-+   substitutions.
-+
-+   PRE is quite expensive in complicated functions because the DFA can take
-+   awhile to converge.  Hence we only perform one pass.  The parameter max-gcse-passes can
-+   be modified if one wants to experiment.
-+
-+   **********************
-+
-+   The steps for PRE are:
-+
-+   1) Build the hash table of expressions we wish to GCSE (expr_hash_table).
-+
-+   2) Perform the data flow analysis for PRE.
-+
-+   3) Delete the redundant instructions
-+
-+   4) Insert the required copies [if any] that make the partially
-+      redundant instructions fully redundant.
-+
-+   5) For other reaching expressions, insert an instruction to copy the value
-+      to a newly created pseudo that will reach the redundant instruction.
-+
-+   The deletion is done first so that when we do insertions we
-+   know which pseudo reg to use.
-+
-+   Various papers have argued that PRE DFA is expensive (O(n^2)) and others
-+   argue it is not.  The number of iterations for the algorithm to converge
-+   is typically 2-4 so I don't view it as that expensive (relatively speaking).
-+
-+   PRE GCSE depends heavily on the second CSE pass to clean up the copies
-+   we create.  To make an expression reach the place where it's redundant,
-+   the result of the expression is copied to a new register, and the redundant
-+   expression is deleted by replacing it with this new register.  Classic GCSE
-+   doesn't have this problem as much as it computes the reaching defs of
-+   each register in each block and thus can try to use an existing register.
-+
-+   **********************
-+
-+   A fair bit of simplicity is created by creating small functions for simple
-+   tasks, even when the function is only called in one place.  This may
-+   measurably slow things down [or may not] by creating more function call
-+   overhead than is necessary.  The source is laid out so that it's trivial
-+   to make the affected functions inline so that one can measure what speed
-+   up, if any, can be achieved, and maybe later when things settle things can
-+   be rearranged.
-+
-+   Help stamp out big monolithic functions!  */
-+\f
-+/* GCSE global vars.  */
-+
-+/* -dG dump file.  */
-+static FILE *gcse_file;
-+
-+/* Note whether or not we should run jump optimization after gcse.  We
-+   want to do this for two cases.
-+
-+    * If we changed any jumps via cprop.
-+
-+    * If we added any labels via edge splitting.  */
-+
-+static int run_jump_opt_after_gcse;
-+
-+/* Bitmaps are normally not included in debugging dumps.
-+   However it's useful to be able to print them from GDB.
-+   We could create special functions for this, but it's simpler to
-+   just allow passing stderr to the dump_foo fns.  Since stderr can
-+   be a macro, we store a copy here.  */
-+static FILE *debug_stderr;
-+
-+/* An obstack for our working variables.  */
-+static struct obstack gcse_obstack;
-+
-+/* Nonzero for each mode that supports (set (reg) (reg)).
-+   This is trivially true for integer and floating point values.
-+   It may or may not be true for condition codes.  */
-+static char can_copy_p[(int) NUM_MACHINE_MODES];
-+
-+/* Nonzero if can_copy_p has been initialized.  */
-+static int can_copy_init_p;
-+
-+struct reg_use {rtx reg_rtx; };
-+
-+/* Hash table of expressions.  */
-+
-+struct expr
-+{
-+  /* The expression (SET_SRC for expressions, PATTERN for assignments).  */
-+  rtx expr;
-+  /* Index in the available expression bitmaps.  */
-+  int bitmap_index;
-+  /* Next entry with the same hash.  */
-+  struct expr *next_same_hash;
-+  /* List of anticipatable occurrences in basic blocks in the function.
-+     An "anticipatable occurrence" is one that is the first occurrence in the
-+     basic block, the operands are not modified in the basic block prior
-+     to the occurrence and the output is not used between the start of
-+     the block and the occurrence.  */
-+  struct occr *antic_occr;
-+  /* List of available occurrence in basic blocks in the function.
-+     An "available occurrence" is one that is the last occurrence in the
-+     basic block and the operands are not modified by following statements in
-+     the basic block [including this insn].  */
-+  struct occr *avail_occr;
-+  /* Non-null if the computation is PRE redundant.
-+     The value is the newly created pseudo-reg to record a copy of the
-+     expression in all the places that reach the redundant copy.  */
-+  rtx reaching_reg;
-+};
-+
-+/* Occurrence of an expression.
-+   There is one per basic block.  If a pattern appears more than once the
-+   last appearance is used [or first for anticipatable expressions].  */
-+
-+struct occr
-+{
-+  /* Next occurrence of this expression.  */
-+  struct occr *next;
-+  /* The insn that computes the expression.  */
-+  rtx insn;
-+  /* Nonzero if this [anticipatable] occurrence has been deleted.  */
-+  char deleted_p;
-+  /* Nonzero if this [available] occurrence has been copied to
-+     reaching_reg.  */
-+  /* ??? This is mutually exclusive with deleted_p, so they could share
-+     the same byte.  */
-+  char copied_p;
-+};
-+
-+/* Expression and copy propagation hash tables.
-+   Each hash table is an array of buckets.
-+   ??? It is known that if it were an array of entries, structure elements
-+   `next_same_hash' and `bitmap_index' wouldn't be necessary.  However, it is
-+   not clear whether in the final analysis a sufficient amount of memory would
-+   be saved as the size of the available expression bitmaps would be larger
-+   [one could build a mapping table without holes afterwards though].
-+   Someday I'll perform the computation and figure it out.  */
-+
-+struct hash_table
-+{
-+  /* The table itself.
-+     This is an array of `expr_hash_table_size' elements.  */
-+  struct expr **table;
-+
-+  /* Size of the hash table, in elements.  */
-+  unsigned int size;
-+
-+  /* Number of hash table elements.  */
-+  unsigned int n_elems;
-+
-+  /* Whether the table is expression of copy propagation one.  */
-+  int set_p;
-+};
-+
-+/* Expression hash table.  */
-+static struct hash_table expr_hash_table;
-+
-+/* Copy propagation hash table.  */
-+static struct hash_table set_hash_table;
-+
-+/* Mapping of uids to cuids.
-+   Only real insns get cuids.  */
-+static int *uid_cuid;
-+
-+/* Highest UID in UID_CUID.  */
-+static int max_uid;
-+
-+/* Get the cuid of an insn.  */
-+#ifdef ENABLE_CHECKING
-+#define INSN_CUID(INSN) (INSN_UID (INSN) > max_uid ? (abort (), 0) : uid_cuid[INSN_UID (INSN)])
-+#else
-+#define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)])
-+#endif
-+
-+/* Number of cuids.  */
-+static int max_cuid;
-+
-+/* Mapping of cuids to insns.  */
-+static rtx *cuid_insn;
-+
-+/* Get insn from cuid.  */
-+#define CUID_INSN(CUID) (cuid_insn[CUID])
-+
-+/* 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 unsigned int max_gcse_regno;
-+
-+/* Table of registers that are modified.
-+
-+   For each register, each element is a list of places where the pseudo-reg
-+   is set.
-+
-+   For simplicity, GCSE is done on sets of pseudo-regs only.  PRE GCSE only
-+   requires knowledge of which blocks kill which regs [and thus could use
-+   a bitmap instead of the lists `reg_set_table' uses].
-+
-+   `reg_set_table' and could be turned into an array of bitmaps (num-bbs x
-+   num-regs) [however perhaps it may be useful to keep the data as is].  One
-+   advantage of recording things this way is that `reg_set_table' is fairly
-+   sparse with respect to pseudo regs but for hard regs could be fairly dense
-+   [relatively speaking].  And recording sets of pseudo-regs in lists speeds
-+   up functions like compute_transp since in the case of pseudo-regs we only
-+   need to iterate over the number of times a pseudo-reg is set, not over the
-+   number of basic blocks [clearly there is a bit of a slow down in the cases
-+   where a pseudo is set more than once in a block, however it is believed
-+   that the net effect is to speed things up].  This isn't done for hard-regs
-+   because recording call-clobbered hard-regs in `reg_set_table' at each
-+   function call can consume a fair bit of memory, and iterating over
-+   hard-regs stored this way in compute_transp will be more expensive.  */
-+
-+typedef struct reg_set
-+{
-+  /* The next setting of this register.  */
-+  struct reg_set *next;
-+  /* The insn where it was set.  */
-+  rtx insn;
-+} reg_set;
-+
-+static reg_set **reg_set_table;
-+
-+/* Size of `reg_set_table'.
-+   The table starts out at max_gcse_regno + slop, and is enlarged as
-+   necessary.  */
-+static int reg_set_table_size;
-+
-+/* Amount to grow `reg_set_table' by when it's full.  */
-+#define REG_SET_TABLE_SLOP 100
-+
-+/* This is a list of expressions which are MEMs and will be used by load
-+   or store motion.
-+   Load motion tracks MEMs which aren't killed by
-+   anything except itself. (ie, loads and stores to a single location).
-+   We can then allow movement of these MEM refs with a little special
-+   allowance. (all stores copy the same value to the reaching reg used
-+   for the loads).  This means all values used to store into memory must have
-+   no side effects so we can re-issue the setter value.
-+   Store Motion uses this structure as an expression table to track stores
-+   which look interesting, and might be moveable towards the exit block.  */
-+
-+struct ls_expr
-+{
-+  struct expr * expr;         /* Gcse expression reference for LM.  */
-+  rtx pattern;                        /* Pattern of this mem.  */
-+  rtx loads;                  /* INSN list of loads seen.  */
-+  rtx stores;                 /* INSN list of stores seen.  */
-+  struct ls_expr * next;      /* Next in the list.  */
-+  int invalid;                        /* Invalid for some reason.  */
-+  int index;                  /* If it maps to a bitmap index.  */
-+  int hash_index;             /* Index when in a hash table.  */
-+  rtx reaching_reg;           /* Register to use when re-writing.  */
-+};
-+
-+/* Head of the list of load/store memory refs.  */
-+static struct ls_expr * pre_ldst_mems = NULL;
-+
-+/* Bitmap containing one bit for each register in the program.
-+   Used when performing GCSE to track which registers have been set since
-+   the start of the basic block.  */
-+static regset reg_set_bitmap;
-+
-+/* For each block, a bitmap of registers set in the block.
-+   This is used by expr_killed_p and compute_transp.
-+   It is computed during hash table computation and not by compute_sets
-+   as it includes registers added since the last pass (or between cprop and
-+   gcse) and it's currently not easy to realloc sbitmap vectors.  */
-+static sbitmap *reg_set_in_block;
-+
-+/* Array, indexed by basic block number for a list of insns which modify
-+   memory within that block.  */
-+static rtx * modify_mem_list;
-+bitmap modify_mem_list_set;
-+
-+/* This array parallels modify_mem_list, but is kept canonicalized.  */
-+static rtx * canon_modify_mem_list;
-+bitmap canon_modify_mem_list_set;
-+/* Various variables for statistics gathering.  */
-+
-+/* Memory used in a pass.
-+   This isn't intended to be absolutely precise.  Its intent is only
-+   to keep an eye on memory usage.  */
-+static int bytes_used;
-+
-+/* GCSE substitutions made.  */
-+static int gcse_subst_count;
-+/* Number of copy instructions created.  */
-+static int gcse_create_count;
-+/* Number of constants propagated.  */
-+static int const_prop_count;
-+/* Number of copys propagated.  */
-+static int copy_prop_count;
-+\f
-+/* These variables are used by classic GCSE.
-+   Normally they'd be defined a bit later, but `rd_gen' needs to
-+   be declared sooner.  */
-+
-+/* Each block has a bitmap of each type.
-+   The length of each blocks bitmap is:
-+
-+       max_cuid  - for reaching definitions
-+       n_exprs - for available expressions
-+
-+   Thus we view the bitmaps as 2 dimensional arrays.  i.e.
-+   rd_kill[block_num][cuid_num]
-+   ae_kill[block_num][expr_num]                        */
-+
-+/* For reaching defs */
-+static sbitmap *rd_kill, *rd_gen, *reaching_defs, *rd_out;
-+
-+/* for available exprs */
-+static sbitmap *ae_kill, *ae_gen, *ae_in, *ae_out;
-+
-+/* Objects of this type are passed around by the null-pointer check
-+   removal routines.  */
-+struct null_pointer_info
-+{
-+  /* The basic block being processed.  */
-+  basic_block current_block;
-+  /* The first register to be handled in this pass.  */
-+  unsigned int min_reg;
-+  /* One greater than the last register to be handled in this pass.  */
-+  unsigned int max_reg;
-+  sbitmap *nonnull_local;
-+  sbitmap *nonnull_killed;
-+};
-+\f
-+static void compute_can_copy  PARAMS ((void));
-+static char *gmalloc          PARAMS ((unsigned int));
-+static char *grealloc         PARAMS ((char *, unsigned int));
-+static char *gcse_alloc               PARAMS ((unsigned long));
-+static void alloc_gcse_mem    PARAMS ((rtx));
-+static void free_gcse_mem     PARAMS ((void));
-+static void alloc_reg_set_mem PARAMS ((int));
-+static void free_reg_set_mem  PARAMS ((void));
-+static int get_bitmap_width     PARAMS ((int, int, int));
-+static void record_one_set    PARAMS ((int, rtx));
-+static void record_set_info   PARAMS ((rtx, rtx, void *));
-+static void compute_sets      PARAMS ((rtx));
-+static void hash_scan_insn    PARAMS ((rtx, struct hash_table *, int));
-+static void hash_scan_set     PARAMS ((rtx, rtx, struct hash_table *));
-+static void hash_scan_clobber PARAMS ((rtx, rtx, struct hash_table *));
-+static void hash_scan_call    PARAMS ((rtx, rtx, struct hash_table *));
-+static int want_to_gcse_p     PARAMS ((rtx));
-+static int oprs_unchanged_p   PARAMS ((rtx, rtx, int));
-+static int oprs_anticipatable_p PARAMS ((rtx, rtx));
-+static int oprs_available_p   PARAMS ((rtx, rtx));
-+static void insert_expr_in_table PARAMS ((rtx, enum machine_mode, rtx,
-+                                        int, int, struct hash_table *));
-+static void insert_set_in_table PARAMS ((rtx, rtx, struct hash_table *));
-+static unsigned int hash_expr PARAMS ((rtx, enum machine_mode, int *, int));
-+static unsigned int hash_expr_1 PARAMS ((rtx, enum machine_mode, int *));
-+static unsigned int hash_string_1 PARAMS ((const char *));
-+static unsigned int hash_set  PARAMS ((int, int));
-+static int expr_equiv_p               PARAMS ((rtx, rtx));
-+static void record_last_reg_set_info PARAMS ((rtx, int));
-+static void record_last_mem_set_info PARAMS ((rtx));
-+static void record_last_set_info PARAMS ((rtx, rtx, void *));
-+static void compute_hash_table        PARAMS ((struct hash_table *));
-+static void alloc_hash_table PARAMS ((int, struct hash_table *, int));
-+static void free_hash_table PARAMS ((struct hash_table *));
-+static void compute_hash_table_work PARAMS ((struct hash_table *));
-+static void dump_hash_table   PARAMS ((FILE *, const char *,
-+                                      struct hash_table *));
-+static struct expr *lookup_expr       PARAMS ((rtx, struct hash_table *));
-+static struct expr *lookup_set        PARAMS ((unsigned int, rtx, struct hash_table *));
-+static struct expr *next_set  PARAMS ((unsigned int, struct expr *));
-+static void reset_opr_set_tables PARAMS ((void));
-+static int oprs_not_set_p     PARAMS ((rtx, rtx));
-+static void mark_call         PARAMS ((rtx));
-+static void mark_set          PARAMS ((rtx, rtx));
-+static void mark_clobber      PARAMS ((rtx, rtx));
-+static void mark_oprs_set     PARAMS ((rtx));
-+static void alloc_cprop_mem   PARAMS ((int, int));
-+static void free_cprop_mem    PARAMS ((void));
-+static void compute_transp    PARAMS ((rtx, int, sbitmap *, int));
-+static void compute_transpout PARAMS ((void));
-+static void compute_local_properties PARAMS ((sbitmap *, sbitmap *, sbitmap *,
-+                                            struct hash_table *));
-+static void compute_cprop_data        PARAMS ((void));
-+static void find_used_regs    PARAMS ((rtx *, void *));
-+static int try_replace_reg    PARAMS ((rtx, rtx, rtx));
-+static struct expr *find_avail_set PARAMS ((int, rtx));
-+static int cprop_jump         PARAMS ((basic_block, rtx, rtx, rtx, rtx));
-+static void mems_conflict_for_gcse_p PARAMS ((rtx, rtx, void *));
-+static int load_killed_in_block_p    PARAMS ((basic_block, int, rtx, int));
-+static void canon_list_insert        PARAMS ((rtx, rtx, void *));
-+static int cprop_insn         PARAMS ((rtx, int));
-+static int cprop              PARAMS ((int));
-+static int one_cprop_pass     PARAMS ((int, int));
-+static bool constprop_register        PARAMS ((rtx, rtx, rtx, int));
-+static struct expr *find_bypass_set PARAMS ((int, int));
-+static bool reg_killed_on_edge            PARAMS ((rtx, edge));
-+static int bypass_block                   PARAMS ((basic_block, rtx, rtx));
-+static int bypass_conditional_jumps PARAMS ((void));
-+static void alloc_pre_mem     PARAMS ((int, int));
-+static void free_pre_mem      PARAMS ((void));
-+static void compute_pre_data  PARAMS ((void));
-+static int pre_expr_reaches_here_p PARAMS ((basic_block, struct expr *,
-+                                          basic_block));
-+static void insert_insn_end_bb        PARAMS ((struct expr *, basic_block, int));
-+static void pre_insert_copy_insn PARAMS ((struct expr *, rtx));
-+static void pre_insert_copies PARAMS ((void));
-+static int pre_delete         PARAMS ((void));
-+static int pre_gcse           PARAMS ((void));
-+static int one_pre_gcse_pass  PARAMS ((int));
-+static void add_label_notes   PARAMS ((rtx, rtx));
-+static void alloc_code_hoist_mem PARAMS ((int, int));
-+static void free_code_hoist_mem       PARAMS ((void));
-+static void compute_code_hoist_vbeinout       PARAMS ((void));
-+static void compute_code_hoist_data PARAMS ((void));
-+static int hoist_expr_reaches_here_p PARAMS ((basic_block, int, basic_block,
-+                                            char *));
-+static void hoist_code                PARAMS ((void));
-+static int one_code_hoisting_pass PARAMS ((void));
-+static void alloc_rd_mem      PARAMS ((int, int));
-+static void free_rd_mem               PARAMS ((void));
-+static void handle_rd_kill_set        PARAMS ((rtx, int, basic_block));
-+static void compute_kill_rd   PARAMS ((void));
-+static void compute_rd                PARAMS ((void));
-+static void alloc_avail_expr_mem PARAMS ((int, int));
-+static void free_avail_expr_mem PARAMS ((void));
-+static void compute_ae_gen    PARAMS ((struct hash_table *));
-+static int expr_killed_p      PARAMS ((rtx, basic_block));
-+static void compute_ae_kill   PARAMS ((sbitmap *, sbitmap *, struct hash_table *));
-+static int expr_reaches_here_p        PARAMS ((struct occr *, struct expr *,
-+                                       basic_block, int));
-+static rtx computing_insn     PARAMS ((struct expr *, rtx));
-+static int def_reaches_here_p PARAMS ((rtx, rtx));
-+static int can_disregard_other_sets PARAMS ((struct reg_set **, rtx, int));
-+static int handle_avail_expr  PARAMS ((rtx, struct expr *));
-+static int classic_gcse               PARAMS ((void));
-+static int one_classic_gcse_pass PARAMS ((int));
-+static void invalidate_nonnull_info PARAMS ((rtx, rtx, void *));
-+static int delete_null_pointer_checks_1 PARAMS ((unsigned int *,
-+                                                sbitmap *, sbitmap *,
-+                                                struct null_pointer_info *));
-+static rtx process_insert_insn        PARAMS ((struct expr *));
-+static int pre_edge_insert    PARAMS ((struct edge_list *, struct expr **));
-+static int expr_reaches_here_p_work PARAMS ((struct occr *, struct expr *,
-+                                           basic_block, int, char *));
-+static int pre_expr_reaches_here_p_work       PARAMS ((basic_block, struct expr *,
-+                                               basic_block, char *));
-+static struct ls_expr * ldst_entry    PARAMS ((rtx));
-+static void free_ldst_entry           PARAMS ((struct ls_expr *));
-+static void free_ldst_mems            PARAMS ((void));
-+static void print_ldst_list           PARAMS ((FILE *));
-+static struct ls_expr * find_rtx_in_ldst PARAMS ((rtx));
-+static int enumerate_ldsts            PARAMS ((void));
-+static inline struct ls_expr * first_ls_expr PARAMS ((void));
-+static inline struct ls_expr * next_ls_expr  PARAMS ((struct ls_expr *));
-+static int simple_mem                 PARAMS ((rtx));
-+static void invalidate_any_buried_refs        PARAMS ((rtx));
-+static void compute_ld_motion_mems    PARAMS ((void));
-+static void trim_ld_motion_mems               PARAMS ((void));
-+static void update_ld_motion_stores   PARAMS ((struct expr *));
-+static void reg_set_info              PARAMS ((rtx, rtx, void *));
-+static int store_ops_ok                       PARAMS ((rtx, basic_block));
-+static void find_moveable_store               PARAMS ((rtx));
-+static int compute_store_table                PARAMS ((void));
-+static int load_kills_store           PARAMS ((rtx, rtx));
-+static int find_loads                 PARAMS ((rtx, rtx));
-+static int store_killed_in_insn               PARAMS ((rtx, rtx));
-+static int store_killed_after         PARAMS ((rtx, rtx, basic_block));
-+static int store_killed_before                PARAMS ((rtx, rtx, basic_block));
-+static void build_store_vectors               PARAMS ((void));
-+static void insert_insn_start_bb      PARAMS ((rtx, basic_block));
-+static int insert_store                       PARAMS ((struct ls_expr *, edge));
-+static void replace_store_insn                PARAMS ((rtx, rtx, basic_block));
-+static void delete_store              PARAMS ((struct ls_expr *,
-+                                               basic_block));
-+static void free_store_memory         PARAMS ((void));
-+static void store_motion              PARAMS ((void));
-+static void free_insn_expr_list_list  PARAMS ((rtx *));
-+static void clear_modify_mem_tables   PARAMS ((void));
-+static void free_modify_mem_tables    PARAMS ((void));
-+static rtx gcse_emit_move_after               PARAMS ((rtx, rtx, rtx));
-+static void local_cprop_find_used_regs        PARAMS ((rtx *, void *));
-+static bool do_local_cprop            PARAMS ((rtx, rtx, int, rtx*));
-+static bool adjust_libcall_notes      PARAMS ((rtx, rtx, rtx, rtx*));
-+static void local_cprop_pass          PARAMS ((int));
-+\f
-+/* Entry point for global common subexpression elimination.
-+   F is the first instruction in the function.  */
-+
-+int
-+gcse_main (f, file)
-+     rtx f;
-+     FILE *file;
-+{
-+  int changed, pass;
-+  /* Bytes used at start of pass.  */
-+  int initial_bytes_used;
-+  /* Maximum number of bytes used by a pass.  */
-+  int max_pass_bytes;
-+  /* Point to release obstack data from for each pass.  */
-+  char *gcse_obstack_bottom;
-+
-+  /* Insertion of instructions on edges can create new basic blocks; we
-+     need the original basic block count so that we can properly deallocate
-+     arrays sized on the number of basic blocks originally in the cfg.  */
-+  int orig_bb_count;
-+  /* We do not construct an accurate cfg in functions which call
-+     setjmp, so just punt to be safe.  */
-+  if (current_function_calls_setjmp)
-+    return 0;
-+
-+  /* Assume that we do not need to run jump optimizations after gcse.  */
-+  run_jump_opt_after_gcse = 0;
-+
-+  /* For calling dump_foo fns from gdb.  */
-+  debug_stderr = stderr;
-+  gcse_file = file;
-+
-+  /* Identify the basic block information for this function, including
-+     successors and predecessors.  */
-+  max_gcse_regno = max_reg_num ();
-+
-+  if (file)
-+    dump_flow_info (file);
-+
-+  orig_bb_count = n_basic_blocks;
-+  /* Return if there's nothing to do.  */
-+  if (n_basic_blocks <= 1)
-+    return 0;
-+
-+  /* Trying to perform global optimizations on flow graphs which have
-+     a high connectivity will take a long time and is unlikely to be
-+     particularly useful.
-+
-+     In normal circumstances a cfg should have about twice as many edges
-+     as blocks.  But we do not want to punish small functions which have
-+     a couple switch statements.  So we require a relatively large number
-+     of basic blocks and the ratio of edges to blocks to be high.  */
-+  if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20)
-+    {
-+      if (warn_disabled_optimization)
-+      warning ("GCSE disabled: %d > 1000 basic blocks and %d >= 20 edges/basic block",
-+               n_basic_blocks, n_edges / n_basic_blocks);
-+      return 0;
-+    }
-+
-+  /* If allocating memory for the cprop bitmap would take up too much
-+     storage it's better just to disable the optimization.  */
-+  if ((n_basic_blocks
-+       * SBITMAP_SET_SIZE (max_gcse_regno)
-+       * sizeof (SBITMAP_ELT_TYPE)) > MAX_GCSE_MEMORY)
-+    {
-+      if (warn_disabled_optimization)
-+      warning ("GCSE disabled: %d basic blocks and %d registers",
-+               n_basic_blocks, max_gcse_regno);
-+
-+      return 0;
-+    }
-+
-+  /* See what modes support reg/reg copy operations.  */
-+  if (! can_copy_init_p)
-+    {
-+      compute_can_copy ();
-+      can_copy_init_p = 1;
-+    }
-+
-+  gcc_obstack_init (&gcse_obstack);
-+  bytes_used = 0;
-+
-+  /* We need alias.  */
-+  init_alias_analysis ();
-+  /* Record where pseudo-registers are set.  This data is kept accurate
-+     during each pass.  ??? We could also record hard-reg information here
-+     [since it's unchanging], however it is currently done during hash table
-+     computation.
-+
-+     It may be tempting to compute MEM set information here too, but MEM sets
-+     will be subject to code motion one day and thus we need to compute
-+     information about memory sets when we build the hash tables.  */
-+
-+  alloc_reg_set_mem (max_gcse_regno);
-+  compute_sets (f);
-+
-+  pass = 0;
-+  initial_bytes_used = bytes_used;
-+  max_pass_bytes = 0;
-+  gcse_obstack_bottom = gcse_alloc (1);
-+  changed = 1;
-+  while (changed && pass < MAX_GCSE_PASSES)
-+    {
-+      changed = 0;
-+      if (file)
-+      fprintf (file, "GCSE pass %d\n\n", pass + 1);
-+
-+      /* Initialize bytes_used to the space for the pred/succ lists,
-+       and the reg_set_table data.  */
-+      bytes_used = initial_bytes_used;
-+
-+      /* Each pass may create new registers, so recalculate each time.  */
-+      max_gcse_regno = max_reg_num ();
-+
-+      alloc_gcse_mem (f);
-+
-+      /* Don't allow constant propagation to modify jumps
-+       during this pass.  */
-+      changed = one_cprop_pass (pass + 1, 0);
-+
-+      if (optimize_size)
-+      changed |= one_classic_gcse_pass (pass + 1);
-+      else
-+      {
-+        changed |= one_pre_gcse_pass (pass + 1);
-+        /* We may have just created new basic blocks.  Release and
-+           recompute various things which are sized on the number of
-+           basic blocks.  */
-+        if (changed)
-+          {
-+            free_modify_mem_tables ();
-+            modify_mem_list
-+              = (rtx *) gmalloc (last_basic_block * sizeof (rtx));
-+            canon_modify_mem_list
-+              = (rtx *) gmalloc (last_basic_block * sizeof (rtx));
-+            memset ((char *) modify_mem_list, 0, last_basic_block * sizeof (rtx));
-+            memset ((char *) canon_modify_mem_list, 0, last_basic_block * sizeof (rtx));
-+            orig_bb_count = n_basic_blocks;
-+          }
-+        free_reg_set_mem ();
-+        alloc_reg_set_mem (max_reg_num ());
-+        compute_sets (f);
-+        run_jump_opt_after_gcse = 1;
-+      }
-+
-+      if (max_pass_bytes < bytes_used)
-+      max_pass_bytes = bytes_used;
-+
-+      /* Free up memory, then reallocate for code hoisting.  We can
-+       not re-use the existing allocated memory because the tables
-+       will not have info for the insns or registers created by
-+       partial redundancy elimination.  */
-+      free_gcse_mem ();
-+
-+      /* It does not make sense to run code hoisting unless we optimizing
-+       for code size -- it rarely makes programs faster, and can make
-+       them bigger if we did partial redundancy elimination (when optimizing
-+       for space, we use a classic gcse algorithm instead of partial
-+       redundancy algorithms).  */
-+      if (optimize_size)
-+      {
-+        max_gcse_regno = max_reg_num ();
-+        alloc_gcse_mem (f);
-+        changed |= one_code_hoisting_pass ();
-+        free_gcse_mem ();
-+
-+        if (max_pass_bytes < bytes_used)
-+          max_pass_bytes = bytes_used;
-+      }
-+
-+      if (file)
-+      {
-+        fprintf (file, "\n");
-+        fflush (file);
-+      }
-+
-+      obstack_free (&gcse_obstack, gcse_obstack_bottom);
-+      pass++;
-+    }
-+
-+  /* Do one last pass of copy propagation, including cprop into
-+     conditional jumps.  */
-+
-+  max_gcse_regno = max_reg_num ();
-+  alloc_gcse_mem (f);
-+  /* This time, go ahead and allow cprop to alter jumps.  */
-+  one_cprop_pass (pass + 1, 1);
-+  free_gcse_mem ();
-+
-+  if (file)
-+    {
-+      fprintf (file, "GCSE of %s: %d basic blocks, ",
-+             current_function_name, n_basic_blocks);
-+      fprintf (file, "%d pass%s, %d bytes\n\n",
-+             pass, pass > 1 ? "es" : "", max_pass_bytes);
-+    }
-+
-+  obstack_free (&gcse_obstack, NULL);
-+  free_reg_set_mem ();
-+  /* We are finished with alias.  */
-+  end_alias_analysis ();
-+  allocate_reg_info (max_reg_num (), FALSE, FALSE);
-+
-+  /* Store motion disabled until it is fixed.  */
-+  if (0 && !optimize_size && flag_gcse_sm)
-+    store_motion ();
-+  /* Record where pseudo-registers are set.  */
-+  return run_jump_opt_after_gcse;
-+}
-+\f
-+/* Misc. utilities.  */
-+
-+/* Compute which modes support reg/reg copy operations.  */
-+
-+static void
-+compute_can_copy ()
-+{
-+  int i;
-+#ifndef AVOID_CCMODE_COPIES
-+  rtx reg, insn;
-+#endif
-+  memset (can_copy_p, 0, NUM_MACHINE_MODES);
-+
-+  start_sequence ();
-+  for (i = 0; i < NUM_MACHINE_MODES; i++)
-+    if (GET_MODE_CLASS (i) == MODE_CC)
-+      {
-+#ifdef AVOID_CCMODE_COPIES
-+      can_copy_p[i] = 0;
-+#else
-+      reg = gen_rtx_REG ((enum machine_mode) i, LAST_VIRTUAL_REGISTER + 1);
-+      insn = emit_insn (gen_rtx_SET (VOIDmode, reg, reg));
-+      if (recog (PATTERN (insn), insn, NULL) >= 0)
-+        can_copy_p[i] = 1;
-+#endif
-+      }
-+    else
-+      can_copy_p[i] = 1;
-+
-+  end_sequence ();
-+}
-+\f
-+/* Cover function to xmalloc to record bytes allocated.  */
-+
-+static char *
-+gmalloc (size)
-+     unsigned int size;
-+{
-+  bytes_used += size;
-+  return xmalloc (size);
-+}
-+
-+/* Cover function to xrealloc.
-+   We don't record the additional size since we don't know it.
-+   It won't affect memory usage stats much anyway.  */
-+
-+static char *
-+grealloc (ptr, size)
-+     char *ptr;
-+     unsigned int size;
-+{
-+  return xrealloc (ptr, size);
-+}
-+
-+/* Cover function to obstack_alloc.  */
-+
-+static char *
-+gcse_alloc (size)
-+     unsigned long size;
-+{
-+  bytes_used += size;
-+  return (char *) obstack_alloc (&gcse_obstack, size);
-+}
-+
-+/* Allocate memory for the cuid mapping array,
-+   and reg/memory set tracking tables.
-+
-+   This is called at the start of each pass.  */
-+
-+static void
-+alloc_gcse_mem (f)
-+     rtx f;
-+{
-+  int i, n;
-+  rtx insn;
-+
-+  /* Find the largest UID and create a mapping from UIDs to CUIDs.
-+     CUIDs are like UIDs except they increase monotonically, have no gaps,
-+     and only apply to real insns.  */
-+
-+  max_uid = get_max_uid ();
-+  n = (max_uid + 1) * sizeof (int);
-+  uid_cuid = (int *) gmalloc (n);
-+  memset ((char *) uid_cuid, 0, n);
-+  for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
-+    {
-+      if (INSN_P (insn))
-+      uid_cuid[INSN_UID (insn)] = i++;
-+      else
-+      uid_cuid[INSN_UID (insn)] = i;
-+    }
-+
-+  /* Create a table mapping cuids to insns.  */
-+
-+  max_cuid = i;
-+  n = (max_cuid + 1) * sizeof (rtx);
-+  cuid_insn = (rtx *) gmalloc (n);
-+  memset ((char *) cuid_insn, 0, n);
-+  for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
-+    if (INSN_P (insn))
-+      CUID_INSN (i++) = insn;
-+
-+  /* Allocate vars to track sets of regs.  */
-+  reg_set_bitmap = BITMAP_XMALLOC ();
-+
-+  /* Allocate vars to track sets of regs, memory per block.  */
-+  reg_set_in_block = (sbitmap *) sbitmap_vector_alloc (last_basic_block,
-+                                                     max_gcse_regno);
-+  /* Allocate array to keep a list of insns which modify memory in each
-+     basic block.  */
-+  modify_mem_list = (rtx *) gmalloc (last_basic_block * sizeof (rtx));
-+  canon_modify_mem_list = (rtx *) gmalloc (last_basic_block * sizeof (rtx));
-+  memset ((char *) modify_mem_list, 0, last_basic_block * sizeof (rtx));
-+  memset ((char *) canon_modify_mem_list, 0, last_basic_block * sizeof (rtx));
-+  modify_mem_list_set = BITMAP_XMALLOC ();
-+  canon_modify_mem_list_set = BITMAP_XMALLOC ();
-+}
-+
-+/* Free memory allocated by alloc_gcse_mem.  */
-+
-+static void
-+free_gcse_mem ()
-+{
-+  free (uid_cuid);
-+  free (cuid_insn);
-+
-+  BITMAP_XFREE (reg_set_bitmap);
-+
-+  sbitmap_vector_free (reg_set_in_block);
-+  free_modify_mem_tables ();
-+  BITMAP_XFREE (modify_mem_list_set);
-+  BITMAP_XFREE (canon_modify_mem_list_set);
-+}
-+
-+/* Many of the global optimization algorithms work by solving dataflow
-+   equations for various expressions.  Initially, some local value is
-+   computed for each expression in each block.  Then, the values across the
-+   various blocks are combined (by following flow graph edges) to arrive at
-+   global values.  Conceptually, each set of equations is independent.  We
-+   may therefore solve all the equations in parallel, solve them one at a
-+   time, or pick any intermediate approach.
-+
-+   When you're going to need N two-dimensional bitmaps, each X (say, the
-+   number of blocks) by Y (say, the number of expressions), call this
-+   function.  It's not important what X and Y represent; only that Y
-+   correspond to the things that can be done in parallel.  This function will
-+   return an appropriate chunking factor C; you should solve C sets of
-+   equations in parallel.  By going through this function, we can easily
-+   trade space against time; by solving fewer equations in parallel we use
-+   less space.  */
-+
-+static int
-+get_bitmap_width (n, x, y)
-+     int n;
-+     int x;
-+     int y;
-+{
-+  /* It's not really worth figuring out *exactly* how much memory will
-+     be used by a particular choice.  The important thing is to get
-+     something approximately right.  */
-+  size_t max_bitmap_memory = 10 * 1024 * 1024;
-+
-+  /* The number of bytes we'd use for a single column of minimum
-+     width.  */
-+  size_t column_size = n * x * sizeof (SBITMAP_ELT_TYPE);
-+
-+  /* Often, it's reasonable just to solve all the equations in
-+     parallel.  */
-+  if (column_size * SBITMAP_SET_SIZE (y) <= max_bitmap_memory)
-+    return y;
-+
-+  /* Otherwise, pick the largest width we can, without going over the
-+     limit.  */
-+  return SBITMAP_ELT_BITS * ((max_bitmap_memory + column_size - 1)
-+                           / column_size);
-+}
-+\f
-+/* Compute the local properties of each recorded expression.
-+
-+   Local properties are those that are defined by the block, irrespective of
-+   other blocks.
-+
-+   An expression is transparent in a block if its operands are not modified
-+   in the block.
-+
-+   An expression is computed (locally available) in a block if it is computed
-+   at least once and expression would contain the same value if the
-+   computation was moved to the end of the block.
-+
-+   An expression is locally anticipatable in a block if it is computed at
-+   least once and expression would contain the same value if the computation
-+   was moved to the beginning of the block.
-+
-+   We call this routine for cprop, pre and code hoisting.  They all compute
-+   basically the same information and thus can easily share this code.
-+
-+   TRANSP, COMP, and ANTLOC are destination sbitmaps for recording local
-+   properties.  If NULL, then it is not necessary to compute or record that
-+   particular property.
-+
-+   TABLE controls which hash table to look at.  If it is  set hash table,
-+   additionally, TRANSP is computed as ~TRANSP, since this is really cprop's
-+   ABSALTERED.  */
-+
-+static void
-+compute_local_properties (transp, comp, antloc, table)
-+     sbitmap *transp;
-+     sbitmap *comp;
-+     sbitmap *antloc;
-+     struct hash_table *table;
-+{
-+  unsigned int i;
-+
-+  /* Initialize any bitmaps that were passed in.  */
-+  if (transp)
-+    {
-+      if (table->set_p)
-+      sbitmap_vector_zero (transp, last_basic_block);
-+      else
-+      sbitmap_vector_ones (transp, last_basic_block);
-+    }
-+
-+  if (comp)
-+    sbitmap_vector_zero (comp, last_basic_block);
-+  if (antloc)
-+    sbitmap_vector_zero (antloc, last_basic_block);
-+
-+  for (i = 0; i < table->size; i++)
-+    {
-+      struct expr *expr;
-+
-+      for (expr = table->table[i]; expr != NULL; expr = expr->next_same_hash)
-+      {
-+        int indx = expr->bitmap_index;
-+        struct occr *occr;
-+
-+        /* The expression is transparent in this block if it is not killed.
-+           We start by assuming all are transparent [none are killed], and
-+           then reset the bits for those that are.  */
-+        if (transp)
-+          compute_transp (expr->expr, indx, transp, table->set_p);
-+
-+        /* The occurrences recorded in antic_occr are exactly those that
-+           we want to set to nonzero in ANTLOC.  */
-+        if (antloc)
-+          for (occr = expr->antic_occr; occr != NULL; occr = occr->next)
-+            {
-+              SET_BIT (antloc[BLOCK_NUM (occr->insn)], indx);
-+
-+              /* While we're scanning the table, this is a good place to
-+                 initialize this.  */
-+              occr->deleted_p = 0;
-+            }
-+
-+        /* The occurrences recorded in avail_occr are exactly those that
-+           we want to set to nonzero in COMP.  */
-+        if (comp)
-+          for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
-+            {
-+              SET_BIT (comp[BLOCK_NUM (occr->insn)], indx);
-+
-+              /* While we're scanning the table, this is a good place to
-+                 initialize this.  */
-+              occr->copied_p = 0;
-+            }
-+
-+        /* While we're scanning the table, this is a good place to
-+           initialize this.  */
-+        expr->reaching_reg = 0;
-+      }
-+    }
-+}
-+\f
-+/* Register set information.
-+
-+   `reg_set_table' records where each register is set or otherwise
-+   modified.  */
-+
-+static struct obstack reg_set_obstack;
-+
-+static void
-+alloc_reg_set_mem (n_regs)
-+     int n_regs;
-+{
-+  unsigned int n;
-+
-+  reg_set_table_size = n_regs + REG_SET_TABLE_SLOP;
-+  n = reg_set_table_size * sizeof (struct reg_set *);
-+  reg_set_table = (struct reg_set **) gmalloc (n);
-+  memset ((char *) reg_set_table, 0, n);
-+
-+  gcc_obstack_init (&reg_set_obstack);
-+}
-+
-+static void
-+free_reg_set_mem ()
-+{
-+  free (reg_set_table);
-+  obstack_free (&reg_set_obstack, NULL);
-+}
-+
-+/* Record REGNO in the reg_set table.  */
-+
-+static void
-+record_one_set (regno, insn)
-+     int regno;
-+     rtx insn;
-+{
-+  /* Allocate a new reg_set element and link it onto the list.  */
-+  struct reg_set *new_reg_info;
-+
-+  /* If the table isn't big enough, enlarge it.  */
-+  if (regno >= reg_set_table_size)
-+    {
-+      int new_size = regno + REG_SET_TABLE_SLOP;
-+
-+      reg_set_table
-+      = (struct reg_set **) grealloc ((char *) reg_set_table,
-+                                      new_size * sizeof (struct reg_set *));
-+      memset ((char *) (reg_set_table + reg_set_table_size), 0,
-+            (new_size - reg_set_table_size) * sizeof (struct reg_set *));
-+      reg_set_table_size = new_size;
-+    }
-+
-+  new_reg_info = (struct reg_set *) obstack_alloc (&reg_set_obstack,
-+                                                 sizeof (struct reg_set));
-+  bytes_used += sizeof (struct reg_set);
-+  new_reg_info->insn = insn;
-+  new_reg_info->next = reg_set_table[regno];
-+  reg_set_table[regno] = new_reg_info;
-+}
-+
-+/* Called from compute_sets via note_stores to handle one SET or CLOBBER in
-+   an insn.  The DATA is really the instruction in which the SET is
-+   occurring.  */
-+
-+static void
-+record_set_info (dest, setter, data)
-+     rtx dest, setter ATTRIBUTE_UNUSED;
-+     void *data;
-+{
-+  rtx record_set_insn = (rtx) data;
-+
-+  if (GET_CODE (dest) == REG && REGNO (dest) >= FIRST_PSEUDO_REGISTER)
-+    record_one_set (REGNO (dest), record_set_insn);
-+}
-+
-+/* Scan the function and record each set of each pseudo-register.
-+
-+   This is called once, at the start of the gcse pass.  See the comments for
-+   `reg_set_table' for further documenation.  */
-+
-+static void
-+compute_sets (f)
-+     rtx f;
-+{
-+  rtx insn;
-+
-+  for (insn = f; insn != 0; insn = NEXT_INSN (insn))
-+    if (INSN_P (insn))
-+      note_stores (PATTERN (insn), record_set_info, insn);
-+}
-+\f
-+/* Hash table support.  */
-+
-+struct reg_avail_info
-+{
-+  basic_block last_bb;
-+  int first_set;
-+  int last_set;
-+};
-+
-+static struct reg_avail_info *reg_avail_info;
-+static basic_block current_bb;
-+
-+
-+/* See whether X, the source of a set, is something we want to consider for
-+   GCSE.  */
-+
-+static GTY(()) rtx test_insn;
-+static int
-+want_to_gcse_p (x)
-+     rtx x;
-+{
-+  int num_clobbers = 0;
-+  int icode;
-+
-+  switch (GET_CODE (x))
-+    {
-+    case REG:
-+    case SUBREG:
-+    case CONST_INT:
-+    case CONST_DOUBLE:
-+    case CONST_VECTOR:
-+    case CALL:
-+      return 0;
-+
-+    default:
-+      break;
-+    }
-+
-+  /* If this is a valid operand, we are OK.  If it's VOIDmode, we aren't.  */
-+  if (general_operand (x, GET_MODE (x)))
-+    return 1;
-+  else if (GET_MODE (x) == VOIDmode)
-+    return 0;
-+
-+  /* Otherwise, check if we can make a valid insn from it.  First initialize
-+     our test insn if we haven't already.  */
-+  if (test_insn == 0)
-+    {
-+      test_insn
-+      = make_insn_raw (gen_rtx_SET (VOIDmode,
-+                                    gen_rtx_REG (word_mode,
-+                                                 FIRST_PSEUDO_REGISTER * 2),
-+                                    const0_rtx));
-+      NEXT_INSN (test_insn) = PREV_INSN (test_insn) = 0;
-+    }
-+
-+  /* Now make an insn like the one we would make when GCSE'ing and see if
-+     valid.  */
-+  PUT_MODE (SET_DEST (PATTERN (test_insn)), GET_MODE (x));
-+  SET_SRC (PATTERN (test_insn)) = x;
-+  return ((icode = recog (PATTERN (test_insn), test_insn, &num_clobbers)) >= 0
-+        && (num_clobbers == 0 || ! added_clobbers_hard_reg_p (icode)));
-+}
-+
-+/* Return nonzero if the operands of expression X are unchanged from the
-+   start of INSN's basic block up to but not including INSN (if AVAIL_P == 0),
-+   or from INSN to the end of INSN's basic block (if AVAIL_P != 0).  */
-+
-+static int
-+oprs_unchanged_p (x, insn, avail_p)
-+     rtx x, insn;
-+     int avail_p;
-+{
-+  int i, j;
-+  enum rtx_code code;
-+  const char *fmt;
-+
-+  if (x == 0)
-+    return 1;
-+
-+  code = GET_CODE (x);
-+  switch (code)
-+    {
-+    case REG:
-+      {
-+      struct reg_avail_info *info = &reg_avail_info[REGNO (x)];
-+
-+      if (info->last_bb != current_bb)
-+        return 1;
-+      if (avail_p)
-+        return info->last_set < INSN_CUID (insn);
-+      else
-+        return info->first_set >= INSN_CUID (insn);
-+      }
-+
-+    case MEM:
-+      if (load_killed_in_block_p (current_bb, INSN_CUID (insn),
-+                                x, avail_p))
-+      return 0;
-+      else
-+      return oprs_unchanged_p (XEXP (x, 0), insn, avail_p);
-+
-+    case PRE_DEC:
-+    case PRE_INC:
-+    case POST_DEC:
-+    case POST_INC:
-+    case PRE_MODIFY:
-+    case POST_MODIFY:
-+      return 0;
-+
-+    case PC:
-+    case CC0: /*FIXME*/
-+    case CONST:
-+    case CONST_INT:
-+    case CONST_DOUBLE:
-+    case CONST_VECTOR:
-+    case SYMBOL_REF:
-+    case LABEL_REF:
-+    case ADDR_VEC:
-+    case ADDR_DIFF_VEC:
-+      return 1;
-+
-+    default:
-+      break;
-+    }
-+
-+  for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
-+    {
-+      if (fmt[i] == 'e')
-+      {
-+        /* If we are about to do the last recursive call needed at this
-+           level, change it into iteration.  This function is called enough
-+           to be worth it.  */
-+        if (i == 0)
-+          return oprs_unchanged_p (XEXP (x, i), insn, avail_p);
-+
-+        else if (! oprs_unchanged_p (XEXP (x, i), insn, avail_p))
-+          return 0;
-+      }
-+      else if (fmt[i] == 'E')
-+      for (j = 0; j < XVECLEN (x, i); j++)
-+        if (! oprs_unchanged_p (XVECEXP (x, i, j), insn, avail_p))
-+          return 0;
-+    }
-+
-+  return 1;
-+}
-+
-+/* Used for communication between mems_conflict_for_gcse_p and
-+   load_killed_in_block_p.  Nonzero if mems_conflict_for_gcse_p finds a
-+   conflict between two memory references.  */
-+static int gcse_mems_conflict_p;
-+
-+/* Used for communication between mems_conflict_for_gcse_p and
-+   load_killed_in_block_p.  A memory reference for a load instruction,
-+   mems_conflict_for_gcse_p will see if a memory store conflicts with
-+   this memory load.  */
-+static rtx gcse_mem_operand;
-+
-+/* DEST is the output of an instruction.  If it is a memory reference, and
-+   possibly conflicts with the load found in gcse_mem_operand, then set
-+   gcse_mems_conflict_p to a nonzero value.  */
-+
-+static void
-+mems_conflict_for_gcse_p (dest, setter, data)
-+     rtx dest, setter ATTRIBUTE_UNUSED;
-+     void *data ATTRIBUTE_UNUSED;
-+{
-+  while (GET_CODE (dest) == SUBREG
-+       || GET_CODE (dest) == ZERO_EXTRACT
-+       || GET_CODE (dest) == SIGN_EXTRACT
-+       || GET_CODE (dest) == STRICT_LOW_PART)
-+    dest = XEXP (dest, 0);
-+
-+  /* If DEST is not a MEM, then it will not conflict with the load.  Note
-+     that function calls are assumed to clobber memory, but are handled
-+     elsewhere.  */
-+  if (GET_CODE (dest) != MEM)
-+    return;
-+
-+  /* If we are setting a MEM in our list of specially recognized MEMs,
-+     don't mark as killed this time.  */
-+
-+  if (dest == gcse_mem_operand && pre_ldst_mems != NULL)
-+    {
-+      if (!find_rtx_in_ldst (dest))
-+      gcse_mems_conflict_p = 1;
-+      return;
-+    }
-+
-+  if (true_dependence (dest, GET_MODE (dest), gcse_mem_operand,
-+                     rtx_addr_varies_p))
-+    gcse_mems_conflict_p = 1;
-+}
-+
-+/* Return nonzero if the expression in X (a memory reference) is killed
-+   in block BB before or after the insn with the CUID in UID_LIMIT.
-+   AVAIL_P is nonzero for kills after UID_LIMIT, and zero for kills
-+   before UID_LIMIT.
-+
-+   To check the entire block, set UID_LIMIT to max_uid + 1 and
-+   AVAIL_P to 0.  */
-+
-+static int
-+load_killed_in_block_p (bb, uid_limit, x, avail_p)
-+     basic_block bb;
-+     int uid_limit;
-+     rtx x;
-+     int avail_p;
-+{
-+  rtx list_entry = modify_mem_list[bb->index];
-+  while (list_entry)
-+    {
-+      rtx setter;
-+      /* Ignore entries in the list that do not apply.  */
-+      if ((avail_p
-+         && INSN_CUID (XEXP (list_entry, 0)) < uid_limit)
-+        || (! avail_p
-+            && INSN_CUID (XEXP (list_entry, 0)) > uid_limit))
-+      {
-+        list_entry = XEXP (list_entry, 1);
-+        continue;
-+      }
-+
-+      setter = XEXP (list_entry, 0);
-+
-+      /* If SETTER is a call everything is clobbered.  Note that calls
-+       to pure functions are never put on the list, so we need not
-+       worry about them.  */
-+      if (GET_CODE (setter) == CALL_INSN)
-+      return 1;
-+
-+      /* SETTER must be an INSN of some kind that sets memory.  Call
-+       note_stores to examine each hunk of memory that is modified.
-+
-+       The note_stores interface is pretty limited, so we have to
-+       communicate via global variables.  Yuk.  */
-+      gcse_mem_operand = x;
-+      gcse_mems_conflict_p = 0;
-+      note_stores (PATTERN (setter), mems_conflict_for_gcse_p, NULL);
-+      if (gcse_mems_conflict_p)
-+      return 1;
-+      list_entry = XEXP (list_entry, 1);
-+    }
-+  return 0;
-+}
-+
-+/* Return nonzero if the operands of expression X are unchanged from
-+   the start of INSN's basic block up to but not including INSN.  */
-+
-+static int
-+oprs_anticipatable_p (x, insn)
-+     rtx x, insn;
-+{
-+  return oprs_unchanged_p (x, insn, 0);
-+}
-+
-+/* Return nonzero if the operands of expression X are unchanged from
-+   INSN to the end of INSN's basic block.  */
-+
-+static int
-+oprs_available_p (x, insn)
-+     rtx x, insn;
-+{
-+  return oprs_unchanged_p (x, insn, 1);
-+}
-+
-+/* Hash expression X.
-+
-+   MODE is only used if X is a CONST_INT.  DO_NOT_RECORD_P is a boolean
-+   indicating if a volatile operand is found or if the expression contains
-+   something we don't want to insert in the table.
-+
-+   ??? One might want to merge this with canon_hash.  Later.  */
-+
-+static unsigned int
-+hash_expr (x, mode, do_not_record_p, hash_table_size)
-+     rtx x;
-+     enum machine_mode mode;
-+     int *do_not_record_p;
-+     int hash_table_size;
-+{
-+  unsigned int hash;
-+
-+  *do_not_record_p = 0;
-+
-+  hash = hash_expr_1 (x, mode, do_not_record_p);
-+  return hash % hash_table_size;
-+}
-+
-+/* Hash a string.  Just add its bytes up.  */
-+
-+static inline unsigned
-+hash_string_1 (ps)
-+     const char *ps;
-+{
-+  unsigned hash = 0;
-+  const unsigned char *p = (const unsigned char *) ps;
-+
-+  if (p)
-+    while (*p)
-+      hash += *p++;
-+
-+  return hash;
-+}
-+
-+/* Subroutine of hash_expr to do the actual work.  */
-+
-+static unsigned int
-+hash_expr_1 (x, mode, do_not_record_p)
-+     rtx x;
-+     enum machine_mode mode;
-+     int *do_not_record_p;
-+{
-+  int i, j;
-+  unsigned hash = 0;
-+  enum rtx_code code;
-+  const char *fmt;
-+
-+  /* Used to turn recursion into iteration.  We can't rely on GCC's
-+     tail-recursion eliminatio since we need to keep accumulating values
-+     in HASH.  */
-+
-+  if (x == 0)
-+    return hash;
-+
-+ repeat:
-+  code = GET_CODE (x);
-+  switch (code)
-+    {
-+    case REG:
-+      hash += ((unsigned int) REG << 7) + REGNO (x);
-+      return hash;
-+
-+    case CONST_INT:
-+      hash += (((unsigned int) CONST_INT << 7) + (unsigned int) mode
-+             + (unsigned int) INTVAL (x));
-+      return hash;
-+
-+    case CONST_DOUBLE:
-+      /* This is like the general case, except that it only counts
-+       the integers representing the constant.  */
-+      hash += (unsigned int) code + (unsigned int) GET_MODE (x);
-+      if (GET_MODE (x) != VOIDmode)
-+      for (i = 2; i < GET_RTX_LENGTH (CONST_DOUBLE); i++)
-+        hash += (unsigned int) XWINT (x, i);
-+      else
-+      hash += ((unsigned int) CONST_DOUBLE_LOW (x)
-+               + (unsigned int) CONST_DOUBLE_HIGH (x));
-+      return hash;
-+
-+    case CONST_VECTOR:
-+      {
-+      int units;
-+      rtx elt;
-+
-+      units = CONST_VECTOR_NUNITS (x);
-+
-+      for (i = 0; i < units; ++i)
-+        {
-+          elt = CONST_VECTOR_ELT (x, i);
-+          hash += hash_expr_1 (elt, GET_MODE (elt), do_not_record_p);
-+        }
-+
-+      return hash;
-+      }
-+
-+      /* Assume there is only one rtx object for any given label.  */
-+    case LABEL_REF:
-+      /* We don't hash on the address of the CODE_LABEL to avoid bootstrap
-+       differences and differences between each stage's debugging dumps.  */
-+      hash += (((unsigned int) LABEL_REF << 7)
-+             + CODE_LABEL_NUMBER (XEXP (x, 0)));
-+      return hash;
-+
-+    case SYMBOL_REF:
-+      {
-+      /* Don't hash on the symbol's address to avoid bootstrap differences.
-+         Different hash values may cause expressions to be recorded in
-+         different orders and thus different registers to be used in the
-+         final assembler.  This also avoids differences in the dump files
-+         between various stages.  */
-+      unsigned int h = 0;
-+      const unsigned char *p = (const unsigned char *) XSTR (x, 0);
-+
-+      while (*p)
-+        h += (h << 7) + *p++; /* ??? revisit */
-+
-+      hash += ((unsigned int) SYMBOL_REF << 7) + h;
-+      return hash;
-+      }
-+
-+    case MEM:
-+      if (MEM_VOLATILE_P (x))
-+      {
-+        *do_not_record_p = 1;
-+        return 0;
-+      }
-+
-+      hash += (unsigned int) MEM;
-+      /* We used alias set for hashing, but this is not good, since the alias
-+       set may differ in -fprofile-arcs and -fbranch-probabilities compilation
-+       causing the profiles to fail to match.  */
-+      x = XEXP (x, 0);
-+      goto repeat;
-+
-+    case PRE_DEC:
-+    case PRE_INC:
-+    case POST_DEC:
-+    case POST_INC:
-+    case PC:
-+    case CC0:
-+    case CALL:
-+    case UNSPEC_VOLATILE:
-+      *do_not_record_p = 1;
-+      return 0;
-+
-+    case ASM_OPERANDS:
-+      if (MEM_VOLATILE_P (x))
-+      {
-+        *do_not_record_p = 1;
-+        return 0;
-+      }
-+      else
-+      {
-+        /* We don't want to take the filename and line into account.  */
-+        hash += (unsigned) code + (unsigned) GET_MODE (x)
-+          + hash_string_1 (ASM_OPERANDS_TEMPLATE (x))
-+          + hash_string_1 (ASM_OPERANDS_OUTPUT_CONSTRAINT (x))
-+          + (unsigned) ASM_OPERANDS_OUTPUT_IDX (x);
-+
-+        if (ASM_OPERANDS_INPUT_LENGTH (x))
-+          {
-+            for (i = 1; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
-+              {
-+                hash += (hash_expr_1 (ASM_OPERANDS_INPUT (x, i),
-+                                      GET_MODE (ASM_OPERANDS_INPUT (x, i)),
-+                                      do_not_record_p)
-+                         + hash_string_1 (ASM_OPERANDS_INPUT_CONSTRAINT
-+                                          (x, i)));
-+              }
-+
-+            hash += hash_string_1 (ASM_OPERANDS_INPUT_CONSTRAINT (x, 0));
-+            x = ASM_OPERANDS_INPUT (x, 0);
-+            mode = GET_MODE (x);
-+            goto repeat;
-+          }
-+        return hash;
-+      }
-+
-+    default:
-+      break;
-+    }
-+
-+  hash += (unsigned) code + (unsigned) GET_MODE (x);
-+  for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
-+    {
-+      if (fmt[i] == 'e')
-+      {
-+        /* If we are about to do the last recursive call
-+           needed at this level, change it into iteration.
-+           This function is called enough to be worth it.  */
-+        if (i == 0)
-+          {
-+            x = XEXP (x, i);
-+            goto repeat;
-+          }
-+
-+        hash += hash_expr_1 (XEXP (x, i), 0, do_not_record_p);
-+        if (*do_not_record_p)
-+          return 0;
-+      }
-+
-+      else if (fmt[i] == 'E')
-+      for (j = 0; j < XVECLEN (x, i); j++)
-+        {
-+          hash += hash_expr_1 (XVECEXP (x, i, j), 0, do_not_record_p);
-+          if (*do_not_record_p)
-+            return 0;
-+        }
-+
-+      else if (fmt[i] == 's')
-+      hash += hash_string_1 (XSTR (x, i));
-+      else if (fmt[i] == 'i')
-+      hash += (unsigned int) XINT (x, i);
-+      else
-+      abort ();
-+    }
-+
-+  return hash;
-+}
-+
-+/* Hash a set of register REGNO.
-+
-+   Sets are hashed on the register that is set.  This simplifies the PRE copy
-+   propagation code.
-+
-+   ??? May need to make things more elaborate.  Later, as necessary.  */
-+
-+static unsigned int
-+hash_set (regno, hash_table_size)
-+     int regno;
-+     int hash_table_size;
-+{
-+  unsigned int hash;
-+
-+  hash = regno;
-+  return hash % hash_table_size;
-+}
-+
-+/* Return nonzero if exp1 is equivalent to exp2.
-+   ??? Borrowed from cse.c.  Might want to remerge with cse.c.  Later.  */
-+
-+static int
-+expr_equiv_p (x, y)
-+     rtx x, y;
-+{
-+  int i, j;
-+  enum rtx_code code;
-+  const char *fmt;
-+
-+  if (x == y)
-+    return 1;
-+
-+  if (x == 0 || y == 0)
-+    return x == y;
-+
-+  code = GET_CODE (x);
-+  if (code != GET_CODE (y))
-+    return 0;
-+
-+  /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.  */
-+  if (GET_MODE (x) != GET_MODE (y))
-+    return 0;
-+
-+  switch (code)
-+    {
-+    case PC:
-+    case CC0:
-+      return x == y;
-+
-+    case CONST_INT:
-+      return INTVAL (x) == INTVAL (y);
-+
-+    case LABEL_REF:
-+      return XEXP (x, 0) == XEXP (y, 0);
-+
-+    case SYMBOL_REF:
-+      return XSTR (x, 0) == XSTR (y, 0);
-+
-+    case REG:
-+      return REGNO (x) == REGNO (y);
-+
-+    case MEM:
-+      /* Can't merge two expressions in different alias sets, since we can
-+       decide that the expression is transparent in a block when it isn't,
-+       due to it being set with the different alias set.  */
-+      if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y))
-+      return 0;
-+      break;
-+
-+    /*  For commutative operations, check both orders.  */
-+    case PLUS:
-+    case MULT:
-+    case AND:
-+    case IOR:
-+    case XOR:
-+    case NE:
-+    case EQ:
-+      return ((expr_equiv_p (XEXP (x, 0), XEXP (y, 0))
-+             && expr_equiv_p (XEXP (x, 1), XEXP (y, 1)))
-+            || (expr_equiv_p (XEXP (x, 0), XEXP (y, 1))
-+                && expr_equiv_p (XEXP (x, 1), XEXP (y, 0))));
-+
-+    case ASM_OPERANDS:
-+      /* We don't use the generic code below because we want to
-+       disregard filename and line numbers.  */
-+
-+      /* A volatile asm isn't equivalent to any other.  */
-+      if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
-+      return 0;
-+
-+      if (GET_MODE (x) != GET_MODE (y)
-+        || strcmp (ASM_OPERANDS_TEMPLATE (x), ASM_OPERANDS_TEMPLATE (y))
-+        || strcmp (ASM_OPERANDS_OUTPUT_CONSTRAINT (x),
-+                   ASM_OPERANDS_OUTPUT_CONSTRAINT (y))
-+        || ASM_OPERANDS_OUTPUT_IDX (x) != ASM_OPERANDS_OUTPUT_IDX (y)
-+        || ASM_OPERANDS_INPUT_LENGTH (x) != ASM_OPERANDS_INPUT_LENGTH (y))
-+      return 0;
-+
-+      if (ASM_OPERANDS_INPUT_LENGTH (x))
-+      {
-+        for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
-+          if (! expr_equiv_p (ASM_OPERANDS_INPUT (x, i),
-+                              ASM_OPERANDS_INPUT (y, i))
-+              || strcmp (ASM_OPERANDS_INPUT_CONSTRAINT (x, i),
-+                         ASM_OPERANDS_INPUT_CONSTRAINT (y, i)))
-+            return 0;
-+      }
-+
-+      return 1;
-+
-+    default:
-+      break;
-+    }
-+
-+  /* Compare the elements.  If any pair of corresponding elements
-+     fail to match, return 0 for the whole thing.  */
-+
-+  fmt = GET_RTX_FORMAT (code);
-+  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-+    {
-+      switch (fmt[i])
-+      {
-+      case 'e':
-+        if (! expr_equiv_p (XEXP (x, i), XEXP (y, i)))
-+          return 0;
-+        break;
-+
-+      case 'E':
-+        if (XVECLEN (x, i) != XVECLEN (y, i))
-+          return 0;
-+        for (j = 0; j < XVECLEN (x, i); j++)
-+          if (! expr_equiv_p (XVECEXP (x, i, j), XVECEXP (y, i, j)))
-+            return 0;
-+        break;
-+
-+      case 's':
-+        if (strcmp (XSTR (x, i), XSTR (y, i)))
-+          return 0;
-+        break;
-+
-+      case 'i':
-+        if (XINT (x, i) != XINT (y, i))
-+          return 0;
-+        break;
-+
-+      case 'w':
-+        if (XWINT (x, i) != XWINT (y, i))
-+          return 0;
-+      break;
-+
-+      case '0':
-+        break;
-+
-+      default:
-+        abort ();
-+      }
-+    }
-+
-+  return 1;
-+}
-+
-+/* Insert expression X in INSN in the hash TABLE.
-+   If it is already present, record it as the last occurrence in INSN's
-+   basic block.
-+
-+   MODE is the mode of the value X is being stored into.
-+   It is only used if X is a CONST_INT.
-+
-+   ANTIC_P is nonzero if X is an anticipatable expression.
-+   AVAIL_P is nonzero if X is an available expression.  */
-+
-+static void
-+insert_expr_in_table (x, mode, insn, antic_p, avail_p, table)
-+     rtx x;
-+     enum machine_mode mode;
-+     rtx insn;
-+     int antic_p, avail_p;
-+     struct hash_table *table;
-+{
-+  int found, do_not_record_p;
-+  unsigned int hash;
-+  struct expr *cur_expr, *last_expr = NULL;
-+  struct occr *antic_occr, *avail_occr;
-+  struct occr *last_occr = NULL;
-+
-+  hash = hash_expr (x, mode, &do_not_record_p, table->size);
-+
-+  /* Do not insert expression in table if it contains volatile operands,
-+     or if hash_expr determines the expression is something we don't want
-+     to or can't handle.  */
-+  if (do_not_record_p)
-+    return;
-+
-+  cur_expr = table->table[hash];
-+  found = 0;
-+
-+  while (cur_expr && 0 == (found = expr_equiv_p (cur_expr->expr, x)))
-+    {
-+      /* If the expression isn't found, save a pointer to the end of
-+       the list.  */
-+      last_expr = cur_expr;
-+      cur_expr = cur_expr->next_same_hash;
-+    }
-+
-+  if (! found)
-+    {
-+      cur_expr = (struct expr *) gcse_alloc (sizeof (struct expr));
-+      bytes_used += sizeof (struct expr);
-+      if (table->table[hash] == NULL)
-+      /* This is the first pattern that hashed to this index.  */
-+      table->table[hash] = cur_expr;
-+      else
-+      /* Add EXPR to end of this hash chain.  */
-+      last_expr->next_same_hash = cur_expr;
-+
-+      /* Set the fields of the expr element.  */
-+      cur_expr->expr = x;
-+      cur_expr->bitmap_index = table->n_elems++;
-+      cur_expr->next_same_hash = NULL;
-+      cur_expr->antic_occr = NULL;
-+      cur_expr->avail_occr = NULL;
-+    }
-+
-+  /* Now record the occurrence(s).  */
-+  if (antic_p)
-+    {
-+      antic_occr = cur_expr->antic_occr;
-+
-+      /* Search for another occurrence in the same basic block.  */
-+      while (antic_occr && BLOCK_NUM (antic_occr->insn) != BLOCK_NUM (insn))
-+      {
-+        /* If an occurrence isn't found, save a pointer to the end of
-+           the list.  */
-+        last_occr = antic_occr;
-+        antic_occr = antic_occr->next;
-+      }
-+
-+      if (antic_occr)
-+      /* Found another instance of the expression in the same basic block.
-+         Prefer the currently recorded one.  We want the first one in the
-+         block and the block is scanned from start to end.  */
-+      ; /* nothing to do */
-+      else
-+      {
-+        /* First occurrence of this expression in this basic block.  */
-+        antic_occr = (struct occr *) gcse_alloc (sizeof (struct occr));
-+        bytes_used += sizeof (struct occr);
-+        /* First occurrence of this expression in any block?  */
-+        if (cur_expr->antic_occr == NULL)
-+          cur_expr->antic_occr = antic_occr;
-+        else
-+          last_occr->next = antic_occr;
-+
-+        antic_occr->insn = insn;
-+        antic_occr->next = NULL;
-+      }
-+    }
-+
-+  if (avail_p)
-+    {
-+      avail_occr = cur_expr->avail_occr;
-+
-+      /* Search for another occurrence in the same basic block.  */
-+      while (avail_occr && BLOCK_NUM (avail_occr->insn) != BLOCK_NUM (insn))
-+      {
-+        /* If an occurrence isn't found, save a pointer to the end of
-+           the list.  */
-+        last_occr = avail_occr;
-+        avail_occr = avail_occr->next;
-+      }
-+
-+      if (avail_occr)
-+      /* Found another instance of the expression in the same basic block.
-+         Prefer this occurrence to the currently recorded one.  We want
-+         the last one in the block and the block is scanned from start
-+         to end.  */
-+      avail_occr->insn = insn;
-+      else
-+      {
-+        /* First occurrence of this expression in this basic block.  */
-+        avail_occr = (struct occr *) gcse_alloc (sizeof (struct occr));
-+        bytes_used += sizeof (struct occr);
-+
-+        /* First occurrence of this expression in any block?  */
-+        if (cur_expr->avail_occr == NULL)
-+          cur_expr->avail_occr = avail_occr;
-+        else
-+          last_occr->next = avail_occr;
-+
-+        avail_occr->insn = insn;
-+        avail_occr->next = NULL;
-+      }
-+    }
-+}
-+
-+/* Insert pattern X in INSN in the hash table.
-+   X is a SET of a reg to either another reg or a constant.
-+   If it is already present, record it as the last occurrence in INSN's
-+   basic block.  */
-+
-+static void
-+insert_set_in_table (x, insn, table)
-+     rtx x;
-+     rtx insn;
-+     struct hash_table *table;
-+{
-+  int found;
-+  unsigned int hash;
-+  struct expr *cur_expr, *last_expr = NULL;
-+  struct occr *cur_occr, *last_occr = NULL;
-+
-+  if (GET_CODE (x) != SET
-+      || GET_CODE (SET_DEST (x)) != REG)
-+    abort ();
-+
-+  hash = hash_set (REGNO (SET_DEST (x)), table->size);
-+
-+  cur_expr = table->table[hash];
-+  found = 0;
-+
-+  while (cur_expr && 0 == (found = expr_equiv_p (cur_expr->expr, x)))
-+    {
-+      /* If the expression isn't found, save a pointer to the end of
-+       the list.  */
-+      last_expr = cur_expr;
-+      cur_expr = cur_expr->next_same_hash;
-+    }
-+
-+  if (! found)
-+    {
-+      cur_expr = (struct expr *) gcse_alloc (sizeof (struct expr));
-+      bytes_used += sizeof (struct expr);
-+      if (table->table[hash] == NULL)
-+      /* This is the first pattern that hashed to this index.  */
-+      table->table[hash] = cur_expr;
-+      else
-+      /* Add EXPR to end of this hash chain.  */
-+      last_expr->next_same_hash = cur_expr;
-+
-+      /* Set the fields of the expr element.
-+       We must copy X because it can be modified when copy propagation is
-+       performed on its operands.  */
-+      cur_expr->expr = copy_rtx (x);
-+      cur_expr->bitmap_index = table->n_elems++;
-+      cur_expr->next_same_hash = NULL;
-+      cur_expr->antic_occr = NULL;
-+      cur_expr->avail_occr = NULL;
-+    }
-+
-+  /* Now record the occurrence.  */
-+  cur_occr = cur_expr->avail_occr;
-+
-+  /* Search for another occurrence in the same basic block.  */
-+  while (cur_occr && BLOCK_NUM (cur_occr->insn) != BLOCK_NUM (insn))
-+    {
-+      /* If an occurrence isn't found, save a pointer to the end of
-+       the list.  */
-+      last_occr = cur_occr;
-+      cur_occr = cur_occr->next;
-+    }
-+
-+  if (cur_occr)
-+    /* Found another instance of the expression in the same basic block.
-+       Prefer this occurrence to the currently recorded one.  We want the
-+       last one in the block and the block is scanned from start to end.  */
-+    cur_occr->insn = insn;
-+  else
-+    {
-+      /* First occurrence of this expression in this basic block.  */
-+      cur_occr = (struct occr *) gcse_alloc (sizeof (struct occr));
-+      bytes_used += sizeof (struct occr);
-+
-+      /* First occurrence of this expression in any block?  */
-+      if (cur_expr->avail_occr == NULL)
-+      cur_expr->avail_occr = cur_occr;
-+      else
-+      last_occr->next = cur_occr;
-+
-+      cur_occr->insn = insn;
-+      cur_occr->next = NULL;
-+    }
-+}
-+
-+/* Scan pattern PAT of INSN and add an entry to the hash TABLE (set or
-+   expression one).  */
-+
-+static void
-+hash_scan_set (pat, insn, table)
-+     rtx pat, insn;
-+     struct hash_table *table;
-+{
-+  rtx src = SET_SRC (pat);
-+  rtx dest = SET_DEST (pat);
-+  rtx note;
-+
-+  if (GET_CODE (src) == CALL)
-+    hash_scan_call (src, insn, table);
-+
-+  else if (GET_CODE (dest) == REG)
-+    {
-+      unsigned int regno = REGNO (dest);
-+      rtx tmp;
-+
-+      /* If this is a single set and we are doing constant propagation,
-+       see if a REG_NOTE shows this equivalent to a constant.  */
-+      if (table->set_p && (note = find_reg_equal_equiv_note (insn)) != 0
-+        && CONSTANT_P (XEXP (note, 0)))
-+      src = XEXP (note, 0), pat = gen_rtx_SET (VOIDmode, dest, src);
-+
-+      /* Only record sets of pseudo-regs in the hash table.  */
-+      if (! table->set_p
-+        && regno >= FIRST_PSEUDO_REGISTER
-+        /* Don't GCSE something if we can't do a reg/reg copy.  */
-+        && can_copy_p [GET_MODE (dest)]
-+        /* GCSE commonly inserts instruction after the insn.  We can't
-+           do that easily for EH_REGION notes so disable GCSE on these
-+           for now.  */
-+        && !find_reg_note (insn, REG_EH_REGION, NULL_RTX)
-+        /* Is SET_SRC something we want to gcse?  */
-+        && want_to_gcse_p (src)
-+        /* Don't CSE a nop.  */
-+        && ! set_noop_p (pat)
-+        /* Don't GCSE if it has attached REG_EQUIV note.
-+           At this point this only function parameters should have
-+           REG_EQUIV notes and if the argument slot is used somewhere
-+           explicitly, it means address of parameter has been taken,
-+           so we should not extend the lifetime of the pseudo.  */
-+        && ((note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) == 0
-+            || GET_CODE (XEXP (note, 0)) != MEM))
-+      {
-+        /* An expression is not anticipatable if its operands are
-+           modified before this insn or if this is not the only SET in
-+           this insn.  */
-+        int antic_p = oprs_anticipatable_p (src, insn) && single_set (insn);
-+        /* An expression is not available if its operands are
-+           subsequently modified, including this insn.  It's also not
-+           available if this is a branch, because we can't insert
-+           a set after the branch.  */
-+        int avail_p = (oprs_available_p (src, insn)
-+                       && ! JUMP_P (insn));
-+
-+        insert_expr_in_table (src, GET_MODE (dest), insn, antic_p, avail_p, table);
-+      }
-+
-+      /* Record sets for constant/copy propagation.  */
-+      else if (table->set_p
-+             && regno >= FIRST_PSEUDO_REGISTER
-+             && ((GET_CODE (src) == REG
-+                  && REGNO (src) >= FIRST_PSEUDO_REGISTER
-+                  && can_copy_p [GET_MODE (dest)]
-+                  && REGNO (src) != regno)
-+                 || CONSTANT_P (src))
-+             /* A copy is not available if its src or dest is subsequently
-+                modified.  Here we want to search from INSN+1 on, but
-+                oprs_available_p searches from INSN on.  */
-+             && (insn == BLOCK_END (BLOCK_NUM (insn))
-+                 || ((tmp = next_nonnote_insn (insn)) != NULL_RTX
-+                     && oprs_available_p (pat, tmp))))
-+      insert_set_in_table (pat, insn, table);
-+    }
-+}
-+
-+static void
-+hash_scan_clobber (x, insn, table)
-+     rtx x ATTRIBUTE_UNUSED, insn ATTRIBUTE_UNUSED;
-+     struct hash_table *table ATTRIBUTE_UNUSED;
-+{
-+  /* Currently nothing to do.  */
-+}
-+
-+static void
-+hash_scan_call (x, insn, table)
-+     rtx x ATTRIBUTE_UNUSED, insn ATTRIBUTE_UNUSED;
-+     struct hash_table *table ATTRIBUTE_UNUSED;
-+{
-+  /* Currently nothing to do.  */
-+}
-+
-+/* Process INSN and add hash table entries as appropriate.
-+
-+   Only available expressions that set a single pseudo-reg are recorded.
-+
-+   Single sets in a PARALLEL could be handled, but it's an extra complication
-+   that isn't dealt with right now.  The trick is handling the CLOBBERs that
-+   are also in the PARALLEL.  Later.
-+
-+   If SET_P is nonzero, this is for the assignment hash table,
-+   otherwise it is for the expression hash table.
-+   If IN_LIBCALL_BLOCK nonzero, we are in a libcall block, and should
-+   not record any expressions.  */
-+
-+static void
-+hash_scan_insn (insn, table, in_libcall_block)
-+     rtx insn;
-+     struct hash_table *table;
-+     int in_libcall_block;
-+{
-+  rtx pat = PATTERN (insn);
-+  int i;
-+
-+  if (in_libcall_block)
-+    return;
-+
-+  /* Pick out the sets of INSN and for other forms of instructions record
-+     what's been modified.  */
-+
-+  if (GET_CODE (pat) == SET)
-+    hash_scan_set (pat, insn, table);
-+  else if (GET_CODE (pat) == PARALLEL)
-+    for (i = 0; i < XVECLEN (pat, 0); i++)
-+      {
-+      rtx x = XVECEXP (pat, 0, i);
-+
-+      if (GET_CODE (x) == SET)
-+        hash_scan_set (x, insn, table);
-+      else if (GET_CODE (x) == CLOBBER)
-+        hash_scan_clobber (x, insn, table);
-+      else if (GET_CODE (x) == CALL)
-+        hash_scan_call (x, insn, table);
-+      }
-+
-+  else if (GET_CODE (pat) == CLOBBER)
-+    hash_scan_clobber (pat, insn, table);
-+  else if (GET_CODE (pat) == CALL)
-+    hash_scan_call (pat, insn, table);
-+}
-+
-+static void
-+dump_hash_table (file, name, table)
-+     FILE *file;
-+     const char *name;
-+     struct hash_table *table;
-+{
-+  int i;
-+  /* Flattened out table, so it's printed in proper order.  */
-+  struct expr **flat_table;
-+  unsigned int *hash_val;
-+  struct expr *expr;
-+
-+  flat_table
-+    = (struct expr **) xcalloc (table->n_elems, sizeof (struct expr *));
-+  hash_val = (unsigned int *) xmalloc (table->n_elems * sizeof (unsigned int));
-+
-+  for (i = 0; i < (int) table->size; i++)
-+    for (expr = table->table[i]; expr != NULL; expr = expr->next_same_hash)
-+      {
-+      flat_table[expr->bitmap_index] = expr;
-+      hash_val[expr->bitmap_index] = i;
-+      }
-+
-+  fprintf (file, "%s hash table (%d buckets, %d entries)\n",
-+         name, table->size, table->n_elems);
-+
-+  for (i = 0; i < (int) table->n_elems; i++)
-+    if (flat_table[i] != 0)
-+      {
-+      expr = flat_table[i];
-+      fprintf (file, "Index %d (hash value %d)\n  ",
-+               expr->bitmap_index, hash_val[i]);
-+      print_rtl (file, expr->expr);
-+      fprintf (file, "\n");
-+      }
-+
-+  fprintf (file, "\n");
-+
-+  free (flat_table);
-+  free (hash_val);
-+}
-+
-+/* Record register first/last/block set information for REGNO in INSN.
-+
-+   first_set records the first place in the block where the register
-+   is set and is used to compute "anticipatability".
-+
-+   last_set records the last place in the block where the register
-+   is set and is used to compute "availability".
-+
-+   last_bb records the block for which first_set and last_set are
-+   valid, as a quick test to invalidate them.
-+
-+   reg_set_in_block records whether the register is set in the block
-+   and is used to compute "transparency".  */
-+
-+static void
-+record_last_reg_set_info (insn, regno)
-+     rtx insn;
-+     int regno;
-+{
-+  struct reg_avail_info *info = &reg_avail_info[regno];
-+  int cuid = INSN_CUID (insn);
-+
-+  info->last_set = cuid;
-+  if (info->last_bb != current_bb)
-+    {
-+      info->last_bb = current_bb;
-+      info->first_set = cuid;
-+      SET_BIT (reg_set_in_block[current_bb->index], regno);
-+    }
-+}
-+
-+
-+/* Record all of the canonicalized MEMs of record_last_mem_set_info's insn.
-+   Note we store a pair of elements in the list, so they have to be
-+   taken off pairwise.  */
-+
-+static void
-+canon_list_insert (dest, unused1, v_insn)
-+     rtx    dest ATTRIBUTE_UNUSED;
-+     rtx    unused1 ATTRIBUTE_UNUSED;
-+     void * v_insn;
-+{
-+  rtx dest_addr, insn;
-+  int bb;
-+
-+  while (GET_CODE (dest) == SUBREG
-+      || GET_CODE (dest) == ZERO_EXTRACT
-+      || GET_CODE (dest) == SIGN_EXTRACT
-+      || GET_CODE (dest) == STRICT_LOW_PART)
-+    dest = XEXP (dest, 0);
-+
-+  /* If DEST is not a MEM, then it will not conflict with a load.  Note
-+     that function calls are assumed to clobber memory, but are handled
-+     elsewhere.  */
-+
-+  if (GET_CODE (dest) != MEM)
-+    return;
-+
-+  dest_addr = get_addr (XEXP (dest, 0));
-+  dest_addr = canon_rtx (dest_addr);
-+  insn = (rtx) v_insn;
-+  bb = BLOCK_NUM (insn);
-+
-+  canon_modify_mem_list[bb] =
-+    alloc_EXPR_LIST (VOIDmode, dest_addr, canon_modify_mem_list[bb]);
-+  canon_modify_mem_list[bb] =
-+    alloc_EXPR_LIST (VOIDmode, dest, canon_modify_mem_list[bb]);
-+  bitmap_set_bit (canon_modify_mem_list_set, bb);
-+}
-+
-+/* Record memory modification information for INSN.  We do not actually care
-+   about the memory location(s) that are set, or even how they are set (consider
-+   a CALL_INSN).  We merely need to record which insns modify memory.  */
-+
-+static void
-+record_last_mem_set_info (insn)
-+     rtx insn;
-+{
-+  int bb = BLOCK_NUM (insn);
-+
-+  /* load_killed_in_block_p will handle the case of calls clobbering
-+     everything.  */
-+  modify_mem_list[bb] = alloc_INSN_LIST (insn, modify_mem_list[bb]);
-+  bitmap_set_bit (modify_mem_list_set, bb);
-+
-+  if (GET_CODE (insn) == CALL_INSN)
-+    {
-+      /* Note that traversals of this loop (other than for free-ing)
-+       will break after encountering a CALL_INSN.  So, there's no
-+       need to insert a pair of items, as canon_list_insert does.  */
-+      canon_modify_mem_list[bb] =
-+      alloc_INSN_LIST (insn, canon_modify_mem_list[bb]);
-+      bitmap_set_bit (canon_modify_mem_list_set, bb);
-+    }
-+  else
-+    note_stores (PATTERN (insn), canon_list_insert, (void*) insn);
-+}
-+
-+/* Called from compute_hash_table via note_stores to handle one
-+   SET or CLOBBER in an insn.  DATA is really the instruction in which
-+   the SET is taking place.  */
-+
-+static void
-+record_last_set_info (dest, setter, data)
-+     rtx dest, setter ATTRIBUTE_UNUSED;
-+     void *data;
-+{
-+  rtx last_set_insn = (rtx) data;
-+
-+  if (GET_CODE (dest) == SUBREG)
-+    dest = SUBREG_REG (dest);
-+
-+  if (GET_CODE (dest) == REG)
-+    record_last_reg_set_info (last_set_insn, REGNO (dest));
-+  else if (GET_CODE (dest) == MEM
-+         /* Ignore pushes, they clobber nothing.  */
-+         && ! push_operand (dest, GET_MODE (dest)))
-+    record_last_mem_set_info (last_set_insn);
-+}
-+
-+/* Top level function to create an expression or assignment hash table.
-+
-+   Expression entries are placed in the hash table if
-+   - they are of the form (set (pseudo-reg) src),
-+   - src is something we want to perform GCSE on,
-+   - none of the operands are subsequently modified in the block
-+
-+   Assignment entries are placed in the hash table if
-+   - they are of the form (set (pseudo-reg) src),
-+   - src is something we want to perform const/copy propagation on,
-+   - none of the operands or target are subsequently modified in the block
-+
-+   Currently src must be a pseudo-reg or a const_int.
-+
-+   F is the first insn.
-+   TABLE is the table computed.  */
-+
-+static void
-+compute_hash_table_work (table)
-+     struct hash_table *table;
-+{
-+  unsigned int i;
-+
-+  /* While we compute the hash table we also compute a bit array of which
-+     registers are set in which blocks.
-+     ??? This isn't needed during const/copy propagation, but it's cheap to
-+     compute.  Later.  */
-+  sbitmap_vector_zero (reg_set_in_block, last_basic_block);
-+
-+  /* re-Cache any INSN_LIST nodes we have allocated.  */
-+  clear_modify_mem_tables ();
-+  /* Some working arrays used to track first and last set in each block.  */
-+  reg_avail_info = (struct reg_avail_info*)
-+    gmalloc (max_gcse_regno * sizeof (struct reg_avail_info));
-+
-+  for (i = 0; i < max_gcse_regno; ++i)
-+    reg_avail_info[i].last_bb = NULL;
-+
-+  FOR_EACH_BB (current_bb)
-+    {
-+      rtx insn;
-+      unsigned int regno;
-+      int in_libcall_block;
-+
-+      /* First pass over the instructions records information used to
-+       determine when registers and memory are first and last set.
-+       ??? hard-reg reg_set_in_block computation
-+       could be moved to compute_sets since they currently don't change.  */
-+
-+      for (insn = current_bb->head;
-+         insn && insn != NEXT_INSN (current_bb->end);
-+         insn = NEXT_INSN (insn))
-+      {
-+        if (! INSN_P (insn))
-+          continue;
-+
-+        if (GET_CODE (insn) == CALL_INSN)
-+          {
-+            bool clobbers_all = false;
-+#ifdef NON_SAVING_SETJMP
-+            if (NON_SAVING_SETJMP
-+                && find_reg_note (insn, REG_SETJMP, NULL_RTX))
-+              clobbers_all = true;
-+#endif
-+
-+            for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
-+              if (clobbers_all
-+                  || TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
-+                record_last_reg_set_info (insn, regno);
-+
-+            mark_call (insn);
-+          }
-+
-+        note_stores (PATTERN (insn), record_last_set_info, insn);
-+      }
-+
-+      /* The next pass builds the hash table.  */
-+
-+      for (insn = current_bb->head, in_libcall_block = 0;
-+         insn && insn != NEXT_INSN (current_bb->end);
-+         insn = NEXT_INSN (insn))
-+      if (INSN_P (insn))
-+        {
-+          if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
-+            in_libcall_block = 1;
-+          else if (table->set_p && find_reg_note (insn, REG_RETVAL, NULL_RTX))
-+            in_libcall_block = 0;
-+          hash_scan_insn (insn, table, in_libcall_block);
-+          if (!table->set_p && find_reg_note (insn, REG_RETVAL, NULL_RTX))
-+            in_libcall_block = 0;
-+        }
-+    }
-+
-+  free (reg_avail_info);
-+  reg_avail_info = NULL;
-+}
-+
-+/* Allocate space for the set/expr hash TABLE.
-+   N_INSNS is the number of instructions in the function.
-+   It is used to determine the number of buckets to use.
-+   SET_P determines whether set or expression table will
-+   be created.  */
-+
-+static void
-+alloc_hash_table (n_insns, table, set_p)
-+     int n_insns;
-+     struct hash_table *table;
-+     int set_p;
-+{
-+  int n;
-+
-+  table->size = n_insns / 4;
-+  if (table->size < 11)
-+    table->size = 11;
-+
-+  /* Attempt to maintain efficient use of hash table.
-+     Making it an odd number is simplest for now.
-+     ??? Later take some measurements.  */
-+  table->size |= 1;
-+  n = table->size * sizeof (struct expr *);
-+  table->table = (struct expr **) gmalloc (n);
-+  table->set_p = set_p;
-+}
-+
-+/* Free things allocated by alloc_hash_table.  */
-+
-+static void
-+free_hash_table (table)
-+     struct hash_table *table;
-+{
-+  free (table->table);
-+}
-+
-+/* Compute the hash TABLE for doing copy/const propagation or
-+   expression hash table.  */
-+
-+static void
-+compute_hash_table (table)
-+    struct hash_table *table;
-+{
-+  /* Initialize count of number of entries in hash table.  */
-+  table->n_elems = 0;
-+  memset ((char *) table->table, 0,
-+        table->size * sizeof (struct expr *));
-+
-+  compute_hash_table_work (table);
-+}
-+\f
-+/* Expression tracking support.  */
-+
-+/* Lookup pattern PAT in the expression TABLE.
-+   The result is a pointer to the table entry, or NULL if not found.  */
-+
-+static struct expr *
-+lookup_expr (pat, table)
-+     rtx pat;
-+     struct hash_table *table;
-+{
-+  int do_not_record_p;
-+  unsigned int hash = hash_expr (pat, GET_MODE (pat), &do_not_record_p,
-+                               table->size);
-+  struct expr *expr;
-+
-+  if (do_not_record_p)
-+    return NULL;
-+
-+  expr = table->table[hash];
-+
-+  while (expr && ! expr_equiv_p (expr->expr, pat))
-+    expr = expr->next_same_hash;
-+
-+  return expr;
-+}
-+
-+/* Lookup REGNO in the set TABLE.  If PAT is non-NULL look for the entry that
-+   matches it, otherwise return the first entry for REGNO.  The result is a
-+   pointer to the table entry, or NULL if not found.  */
-+
-+static struct expr *
-+lookup_set (regno, pat, table)
-+     unsigned int regno;
-+     rtx pat;
-+     struct hash_table *table;
-+{
-+  unsigned int hash = hash_set (regno, table->size);
-+  struct expr *expr;
-+
-+  expr = table->table[hash];
-+
-+  if (pat)
-+    {
-+      while (expr && ! expr_equiv_p (expr->expr, pat))
-+      expr = expr->next_same_hash;
-+    }
-+  else
-+    {
-+      while (expr && REGNO (SET_DEST (expr->expr)) != regno)
-+      expr = expr->next_same_hash;
-+    }
-+
-+  return expr;
-+}
-+
-+/* Return the next entry for REGNO in list EXPR.  */
-+
-+static struct expr *
-+next_set (regno, expr)
-+     unsigned int regno;
-+     struct expr *expr;
-+{
-+  do
-+    expr = expr->next_same_hash;
-+  while (expr && REGNO (SET_DEST (expr->expr)) != regno);
-+
-+  return expr;
-+}
-+
-+/* Like free_INSN_LIST_list or free_EXPR_LIST_list, except that the node
-+   types may be mixed.  */
-+
-+static void
-+free_insn_expr_list_list (listp)
-+     rtx *listp;
-+{
-+  rtx list, next;
-+
-+  for (list = *listp; list ; list = next)
-+    {
-+      next = XEXP (list, 1);
-+      if (GET_CODE (list) == EXPR_LIST)
-+      free_EXPR_LIST_node (list);
-+      else
-+      free_INSN_LIST_node (list);
-+    }
-+
-+  *listp = NULL;
-+}
-+
-+/* Clear canon_modify_mem_list and modify_mem_list tables.  */
-+static void
-+clear_modify_mem_tables ()
-+{
-+  int i;
-+
-+  EXECUTE_IF_SET_IN_BITMAP
-+    (modify_mem_list_set, 0, i, free_INSN_LIST_list (modify_mem_list + i));
-+  bitmap_clear (modify_mem_list_set);
-+
-+  EXECUTE_IF_SET_IN_BITMAP
-+    (canon_modify_mem_list_set, 0, i,
-+     free_insn_expr_list_list (canon_modify_mem_list + i));
-+  bitmap_clear (canon_modify_mem_list_set);
-+}
-+
-+/* Release memory used by modify_mem_list_set and canon_modify_mem_list_set.  */
-+
-+static void
-+free_modify_mem_tables ()
-+{
-+  clear_modify_mem_tables ();
-+  free (modify_mem_list);
-+  free (canon_modify_mem_list);
-+  modify_mem_list = 0;
-+  canon_modify_mem_list = 0;
-+}
-+
-+/* Reset tables used to keep track of what's still available [since the
-+   start of the block].  */
-+
-+static void
-+reset_opr_set_tables ()
-+{
-+  /* Maintain a bitmap of which regs have been set since beginning of
-+     the block.  */
-+  CLEAR_REG_SET (reg_set_bitmap);
-+
-+  /* Also keep a record of the last instruction to modify memory.
-+     For now this is very trivial, we only record whether any memory
-+     location has been modified.  */
-+  clear_modify_mem_tables ();
-+}
-+
-+/* Return nonzero if the operands of X are not set before INSN in
-+   INSN's basic block.  */
-+
-+static int
-+oprs_not_set_p (x, insn)
-+     rtx x, insn;
-+{
-+  int i, j;
-+  enum rtx_code code;
-+  const char *fmt;
-+
-+  if (x == 0)
-+    return 1;
-+
-+  code = GET_CODE (x);
-+  switch (code)
-+    {
-+    case PC:
-+    case CC0:
-+    case CONST:
-+    case CONST_INT:
-+    case CONST_DOUBLE:
-+    case CONST_VECTOR:
-+    case SYMBOL_REF:
-+    case LABEL_REF:
-+    case ADDR_VEC:
-+    case ADDR_DIFF_VEC:
-+      return 1;
-+
-+    case MEM:
-+      if (load_killed_in_block_p (BLOCK_FOR_INSN (insn),
-+                                INSN_CUID (insn), x, 0))
-+      return 0;
-+      else
-+      return oprs_not_set_p (XEXP (x, 0), insn);
-+
-+    case REG:
-+      return ! REGNO_REG_SET_P (reg_set_bitmap, REGNO (x));
-+
-+    default:
-+      break;
-+    }
-+
-+  for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
-+    {
-+      if (fmt[i] == 'e')
-+      {
-+        /* If we are about to do the last recursive call
-+           needed at this level, change it into iteration.
-+           This function is called enough to be worth it.  */
-+        if (i == 0)
-+          return oprs_not_set_p (XEXP (x, i), insn);
-+
-+        if (! oprs_not_set_p (XEXP (x, i), insn))
-+          return 0;
-+      }
-+      else if (fmt[i] == 'E')
-+      for (j = 0; j < XVECLEN (x, i); j++)
-+        if (! oprs_not_set_p (XVECEXP (x, i, j), insn))
-+          return 0;
-+    }
-+
-+  return 1;
-+}
-+
-+/* Mark things set by a CALL.  */
-+
-+static void
-+mark_call (insn)
-+     rtx insn;
-+{
-+  if (! CONST_OR_PURE_CALL_P (insn))
-+    record_last_mem_set_info (insn);
-+}
-+
-+/* Mark things set by a SET.  */
-+
-+static void
-+mark_set (pat, insn)
-+     rtx pat, insn;
-+{
-+  rtx dest = SET_DEST (pat);
-+
-+  while (GET_CODE (dest) == SUBREG
-+       || GET_CODE (dest) == ZERO_EXTRACT
-+       || GET_CODE (dest) == SIGN_EXTRACT
-+       || GET_CODE (dest) == STRICT_LOW_PART)
-+    dest = XEXP (dest, 0);
-+
-+  if (GET_CODE (dest) == REG)
-+    SET_REGNO_REG_SET (reg_set_bitmap, REGNO (dest));
-+  else if (GET_CODE (dest) == MEM)
-+    record_last_mem_set_info (insn);
-+
-+  if (GET_CODE (SET_SRC (pat)) == CALL)
-+    mark_call (insn);
-+}
-+
-+/* Record things set by a CLOBBER.  */
-+
-+static void
-+mark_clobber (pat, insn)
-+     rtx pat, insn;
-+{
-+  rtx clob = XEXP (pat, 0);
-+
-+  while (GET_CODE (clob) == SUBREG || GET_CODE (clob) == STRICT_LOW_PART)
-+    clob = XEXP (clob, 0);
-+
-+  if (GET_CODE (clob) == REG)
-+    SET_REGNO_REG_SET (reg_set_bitmap, REGNO (clob));
-+  else
-+    record_last_mem_set_info (insn);
-+}
-+
-+/* Record things set by INSN.
-+   This data is used by oprs_not_set_p.  */
-+
-+static void
-+mark_oprs_set (insn)
-+     rtx insn;
-+{
-+  rtx pat = PATTERN (insn);
-+  int i;
-+
-+  if (GET_CODE (pat) == SET)
-+    mark_set (pat, insn);
-+  else if (GET_CODE (pat) == PARALLEL)
-+    for (i = 0; i < XVECLEN (pat, 0); i++)
-+      {
-+      rtx x = XVECEXP (pat, 0, i);
-+
-+      if (GET_CODE (x) == SET)
-+        mark_set (x, insn);
-+      else if (GET_CODE (x) == CLOBBER)
-+        mark_clobber (x, insn);
-+      else if (GET_CODE (x) == CALL)
-+        mark_call (insn);
-+      }
-+
-+  else if (GET_CODE (pat) == CLOBBER)
-+    mark_clobber (pat, insn);
-+  else if (GET_CODE (pat) == CALL)
-+    mark_call (insn);
-+}
-+
-+\f
-+/* Classic GCSE reaching definition support.  */
-+
-+/* Allocate reaching def variables.  */
-+
-+static void
-+alloc_rd_mem (n_blocks, n_insns)
-+     int n_blocks, n_insns;
-+{
-+  rd_kill = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
-+  sbitmap_vector_zero (rd_kill, n_blocks);
-+
-+  rd_gen = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
-+  sbitmap_vector_zero (rd_gen, n_blocks);
-+
-+  reaching_defs = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
-+  sbitmap_vector_zero (reaching_defs, n_blocks);
-+
-+  rd_out = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
-+  sbitmap_vector_zero (rd_out, n_blocks);
-+}
-+
-+/* Free reaching def variables.  */
-+
-+static void
-+free_rd_mem ()
-+{
-+  sbitmap_vector_free (rd_kill);
-+  sbitmap_vector_free (rd_gen);
-+  sbitmap_vector_free (reaching_defs);
-+  sbitmap_vector_free (rd_out);
-+}
-+
-+/* Add INSN to the kills of BB.  REGNO, set in BB, is killed by INSN.  */
-+
-+static void
-+handle_rd_kill_set (insn, regno, bb)
-+     rtx insn;
-+     int regno;
-+     basic_block bb;
-+{
-+  struct reg_set *this_reg;
-+
-+  for (this_reg = reg_set_table[regno]; this_reg; this_reg = this_reg ->next)
-+    if (BLOCK_NUM (this_reg->insn) != BLOCK_NUM (insn))
-+      SET_BIT (rd_kill[bb->index], INSN_CUID (this_reg->insn));
-+}
-+
-+/* Compute the set of kill's for reaching definitions.  */
-+
-+static void
-+compute_kill_rd ()
-+{
-+  int cuid;
-+  unsigned int regno;
-+  int i;
-+  basic_block bb;
-+
-+  /* For each block
-+       For each set bit in `gen' of the block (i.e each insn which
-+         generates a definition in the block)
-+       Call the reg set by the insn corresponding to that bit regx
-+       Look at the linked list starting at reg_set_table[regx]
-+       For each setting of regx in the linked list, which is not in
-+           this block
-+         Set the bit in `kill' corresponding to that insn.  */
-+  FOR_EACH_BB (bb)
-+    for (cuid = 0; cuid < max_cuid; cuid++)
-+      if (TEST_BIT (rd_gen[bb->index], cuid))
-+      {
-+        rtx insn = CUID_INSN (cuid);
-+        rtx pat = PATTERN (insn);
-+
-+        if (GET_CODE (insn) == CALL_INSN)
-+          {
-+            for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
-+              if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
-+                handle_rd_kill_set (insn, regno, bb);
-+          }
-+
-+        if (GET_CODE (pat) == PARALLEL)
-+          {
-+            for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
-+              {
-+                enum rtx_code code = GET_CODE (XVECEXP (pat, 0, i));
-+
-+                if ((code == SET || code == CLOBBER)
-+                    && GET_CODE (XEXP (XVECEXP (pat, 0, i), 0)) == REG)
-+                  handle_rd_kill_set (insn,
-+                                      REGNO (XEXP (XVECEXP (pat, 0, i), 0)),
-+                                      bb);
-+              }
-+          }
-+        else if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == REG)
-+          /* Each setting of this register outside of this block
-+             must be marked in the set of kills in this block.  */
-+          handle_rd_kill_set (insn, REGNO (SET_DEST (pat)), bb);
-+      }
-+}
-+
-+/* Compute the reaching definitions as in
-+   Compilers Principles, Techniques, and Tools. Aho, Sethi, Ullman,
-+   Chapter 10.  It is the same algorithm as used for computing available
-+   expressions but applied to the gens and kills of reaching definitions.  */
-+
-+static void
-+compute_rd ()
-+{
-+  int changed, passes;
-+  basic_block bb;
-+
-+  FOR_EACH_BB (bb)
-+    sbitmap_copy (rd_out[bb->index] /*dst*/, rd_gen[bb->index] /*src*/);
-+
-+  passes = 0;
-+  changed = 1;
-+  while (changed)
-+    {
-+      changed = 0;
-+      FOR_EACH_BB (bb)
-+      {
-+        sbitmap_union_of_preds (reaching_defs[bb->index], rd_out, bb->index);
-+        changed |= sbitmap_union_of_diff_cg (rd_out[bb->index], rd_gen[bb->index],
-+                                             reaching_defs[bb->index], rd_kill[bb->index]);
-+      }
-+      passes++;
-+    }
-+
-+  if (gcse_file)
-+    fprintf (gcse_file, "reaching def computation: %d passes\n", passes);
-+}
-+\f
-+/* Classic GCSE available expression support.  */
-+
-+/* Allocate memory for available expression computation.  */
-+
-+static void
-+alloc_avail_expr_mem (n_blocks, n_exprs)
-+     int n_blocks, n_exprs;
-+{
-+  ae_kill = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
-+  sbitmap_vector_zero (ae_kill, n_blocks);
-+
-+  ae_gen = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
-+  sbitmap_vector_zero (ae_gen, n_blocks);
-+
-+  ae_in = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
-+  sbitmap_vector_zero (ae_in, n_blocks);
-+
-+  ae_out = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
-+  sbitmap_vector_zero (ae_out, n_blocks);
-+}
-+
-+static void
-+free_avail_expr_mem ()
-+{
-+  sbitmap_vector_free (ae_kill);
-+  sbitmap_vector_free (ae_gen);
-+  sbitmap_vector_free (ae_in);
-+  sbitmap_vector_free (ae_out);
-+}
-+
-+/* Compute the set of available expressions generated in each basic block.  */
-+
-+static void
-+compute_ae_gen (expr_hash_table)
-+     struct hash_table *expr_hash_table;
-+{
-+  unsigned int i;
-+  struct expr *expr;
-+  struct occr *occr;
-+
-+  /* For each recorded occurrence of each expression, set ae_gen[bb][expr].
-+     This is all we have to do because an expression is not recorded if it
-+     is not available, and the only expressions we want to work with are the
-+     ones that are recorded.  */
-+  for (i = 0; i < expr_hash_table->size; i++)
-+    for (expr = expr_hash_table->table[i]; expr != 0; expr = expr->next_same_hash)
-+      for (occr = expr->avail_occr; occr != 0; occr = occr->next)
-+      SET_BIT (ae_gen[BLOCK_NUM (occr->insn)], expr->bitmap_index);
-+}
-+
-+/* Return nonzero if expression X is killed in BB.  */
-+
-+static int
-+expr_killed_p (x, bb)
-+     rtx x;
-+     basic_block bb;
-+{
-+  int i, j;
-+  enum rtx_code code;
-+  const char *fmt;
-+
-+  if (x == 0)
-+    return 1;
-+
-+  code = GET_CODE (x);
-+  switch (code)
-+    {
-+    case REG:
-+      return TEST_BIT (reg_set_in_block[bb->index], REGNO (x));
-+
-+    case MEM:
-+      if (load_killed_in_block_p (bb, get_max_uid () + 1, x, 0))
-+      return 1;
-+      else
-+      return expr_killed_p (XEXP (x, 0), bb);
-+
-+    case PC:
-+    case CC0: /*FIXME*/
-+    case CONST:
-+    case CONST_INT:
-+    case CONST_DOUBLE:
-+    case CONST_VECTOR:
-+    case SYMBOL_REF:
-+    case LABEL_REF:
-+    case ADDR_VEC:
-+    case ADDR_DIFF_VEC:
-+      return 0;
-+
-+    default:
-+      break;
-+    }
-+
-+  for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
-+    {
-+      if (fmt[i] == 'e')
-+      {
-+        /* If we are about to do the last recursive call
-+           needed at this level, change it into iteration.
-+           This function is called enough to be worth it.  */
-+        if (i == 0)
-+          return expr_killed_p (XEXP (x, i), bb);
-+        else if (expr_killed_p (XEXP (x, i), bb))
-+          return 1;
-+      }
-+      else if (fmt[i] == 'E')
-+      for (j = 0; j < XVECLEN (x, i); j++)
-+        if (expr_killed_p (XVECEXP (x, i, j), bb))
-+          return 1;
-+    }
-+
-+  return 0;
-+}
-+
-+/* Compute the set of available expressions killed in each basic block.  */
-+
-+static void
-+compute_ae_kill (ae_gen, ae_kill, expr_hash_table)
-+     sbitmap *ae_gen, *ae_kill;
-+     struct hash_table *expr_hash_table;
-+{
-+  basic_block bb;
-+  unsigned int i;
-+  struct expr *expr;
-+
-+  FOR_EACH_BB (bb)
-+    for (i = 0; i < expr_hash_table->size; i++)
-+      for (expr = expr_hash_table->table[i]; expr; expr = expr->next_same_hash)
-+      {
-+        /* Skip EXPR if generated in this block.  */
-+        if (TEST_BIT (ae_gen[bb->index], expr->bitmap_index))
-+          continue;
-+
-+        if (expr_killed_p (expr->expr, bb))
-+          SET_BIT (ae_kill[bb->index], expr->bitmap_index);
-+      }
-+}
-+\f
-+/* Actually perform the Classic GCSE optimizations.  */
-+
-+/* Return nonzero if occurrence OCCR of expression EXPR reaches block BB.
-+
-+   CHECK_SELF_LOOP is nonzero if we should consider a block reaching itself
-+   as a positive reach.  We want to do this when there are two computations
-+   of the expression in the block.
-+
-+   VISITED is a pointer to a working buffer for tracking which BB's have
-+   been visited.  It is NULL for the top-level call.
-+
-+   We treat reaching expressions that go through blocks containing the same
-+   reaching expression as "not reaching".  E.g. if EXPR is generated in blocks
-+   2 and 3, INSN is in block 4, and 2->3->4, we treat the expression in block
-+   2 as not reaching.  The intent is to improve the probability of finding
-+   only one reaching expression and to reduce register lifetimes by picking
-+   the closest such expression.  */
-+
-+static int
-+expr_reaches_here_p_work (occr, expr, bb, check_self_loop, visited)
-+     struct occr *occr;
-+     struct expr *expr;
-+     basic_block bb;
-+     int check_self_loop;
-+     char *visited;
-+{
-+  edge pred;
-+
-+  for (pred = bb->pred; pred != NULL; pred = pred->pred_next)
-+    {
-+      basic_block pred_bb = pred->src;
-+
-+      if (visited[pred_bb->index])
-+      /* This predecessor has already been visited. Nothing to do.  */
-+        ;
-+      else if (pred_bb == bb)
-+      {
-+        /* BB loops on itself.  */
-+        if (check_self_loop
-+            && TEST_BIT (ae_gen[pred_bb->index], expr->bitmap_index)
-+            && BLOCK_NUM (occr->insn) == pred_bb->index)
-+          return 1;
-+
-+        visited[pred_bb->index] = 1;
-+      }
-+
-+      /* Ignore this predecessor if it kills the expression.  */
-+      else if (TEST_BIT (ae_kill[pred_bb->index], expr->bitmap_index))
-+      visited[pred_bb->index] = 1;
-+
-+      /* Does this predecessor generate this expression?  */
-+      else if (TEST_BIT (ae_gen[pred_bb->index], expr->bitmap_index))
-+      {
-+        /* Is this the occurrence we're looking for?
-+           Note that there's only one generating occurrence per block
-+           so we just need to check the block number.  */
-+        if (BLOCK_NUM (occr->insn) == pred_bb->index)
-+          return 1;
-+
-+        visited[pred_bb->index] = 1;
-+      }
-+
-+      /* Neither gen nor kill.  */
-+      else
-+      {
-+        visited[pred_bb->index] = 1;
-+        if (expr_reaches_here_p_work (occr, expr, pred_bb, check_self_loop,
-+            visited))
-+
-+          return 1;
-+      }
-+    }
-+
-+  /* All paths have been checked.  */
-+  return 0;
-+}
-+
-+/* This wrapper for expr_reaches_here_p_work() is to ensure that any
-+   memory allocated for that function is returned.  */
-+
-+static int
-+expr_reaches_here_p (occr, expr, bb, check_self_loop)
-+     struct occr *occr;
-+     struct expr *expr;
-+     basic_block bb;
-+     int check_self_loop;
-+{
-+  int rval;
-+  char *visited = (char *) xcalloc (last_basic_block, 1);
-+
-+  rval = expr_reaches_here_p_work (occr, expr, bb, check_self_loop, visited);
-+
-+  free (visited);
-+  return rval;
-+}
-+
-+/* Return the instruction that computes EXPR that reaches INSN's basic block.
-+   If there is more than one such instruction, return NULL.
-+
-+   Called only by handle_avail_expr.  */
-+
-+static rtx
-+computing_insn (expr, insn)
-+     struct expr *expr;
-+     rtx insn;
-+{
-+  basic_block bb = BLOCK_FOR_INSN (insn);
-+
-+  if (expr->avail_occr->next == NULL)
-+    {
-+      if (BLOCK_FOR_INSN (expr->avail_occr->insn) == bb)
-+      /* The available expression is actually itself
-+         (i.e. a loop in the flow graph) so do nothing.  */
-+      return NULL;
-+
-+      /* (FIXME) Case that we found a pattern that was created by
-+       a substitution that took place.  */
-+      return expr->avail_occr->insn;
-+    }
-+  else
-+    {
-+      /* Pattern is computed more than once.
-+       Search backwards from this insn to see how many of these
-+       computations actually reach this insn.  */
-+      struct occr *occr;
-+      rtx insn_computes_expr = NULL;
-+      int can_reach = 0;
-+
-+      for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
-+      {
-+        if (BLOCK_FOR_INSN (occr->insn) == bb)
-+          {
-+            /* The expression is generated in this block.
-+               The only time we care about this is when the expression
-+               is generated later in the block [and thus there's a loop].
-+               We let the normal cse pass handle the other cases.  */
-+            if (INSN_CUID (insn) < INSN_CUID (occr->insn)
-+                && expr_reaches_here_p (occr, expr, bb, 1))
-+              {
-+                can_reach++;
-+                if (can_reach > 1)
-+                  return NULL;
-+
-+                insn_computes_expr = occr->insn;
-+              }
-+          }
-+        else if (expr_reaches_here_p (occr, expr, bb, 0))
-+          {
-+            can_reach++;
-+            if (can_reach > 1)
-+              return NULL;
-+
-+            insn_computes_expr = occr->insn;
-+          }
-+      }
-+
-+      if (insn_computes_expr == NULL)
-+      abort ();
-+
-+      return insn_computes_expr;
-+    }
-+}
-+
-+/* Return nonzero if the definition in DEF_INSN can reach INSN.
-+   Only called by can_disregard_other_sets.  */
-+
-+static int
-+def_reaches_here_p (insn, def_insn)
-+     rtx insn, def_insn;
-+{
-+  rtx reg;
-+
-+  if (TEST_BIT (reaching_defs[BLOCK_NUM (insn)], INSN_CUID (def_insn)))
-+    return 1;
-+
-+  if (BLOCK_NUM (insn) == BLOCK_NUM (def_insn))
-+    {
-+      if (INSN_CUID (def_insn) < INSN_CUID (insn))
-+      {
-+        if (GET_CODE (PATTERN (def_insn)) == PARALLEL)
-+          return 1;
-+        else if (GET_CODE (PATTERN (def_insn)) == CLOBBER)
-+          reg = XEXP (PATTERN (def_insn), 0);
-+        else if (GET_CODE (PATTERN (def_insn)) == SET)
-+          reg = SET_DEST (PATTERN (def_insn));
-+        else
-+          abort ();
-+
-+        return ! reg_set_between_p (reg, NEXT_INSN (def_insn), insn);
-+      }
-+      else
-+      return 0;
-+    }
-+
-+  return 0;
-+}
-+
-+/* Return nonzero if *ADDR_THIS_REG can only have one value at INSN.  The
-+   value returned is the number of definitions that reach INSN.  Returning a
-+   value of zero means that [maybe] more than one definition reaches INSN and
-+   the caller can't perform whatever optimization it is trying.  i.e. it is
-+   always safe to return zero.  */
-+
-+static int
-+can_disregard_other_sets (addr_this_reg, insn, for_combine)
-+     struct reg_set **addr_this_reg;
-+     rtx insn;
-+     int for_combine;
-+{
-+  int number_of_reaching_defs = 0;
-+  struct reg_set *this_reg;
-+
-+  for (this_reg = *addr_this_reg; this_reg != 0; this_reg = this_reg->next)
-+    if (def_reaches_here_p (insn, this_reg->insn))
-+      {
-+      number_of_reaching_defs++;
-+      /* Ignore parallels for now.  */
-+      if (GET_CODE (PATTERN (this_reg->insn)) == PARALLEL)
-+        return 0;
-+
-+      if (!for_combine
-+          && (GET_CODE (PATTERN (this_reg->insn)) == CLOBBER
-+              || ! rtx_equal_p (SET_SRC (PATTERN (this_reg->insn)),
-+                                SET_SRC (PATTERN (insn)))))
-+        /* A setting of the reg to a different value reaches INSN.  */
-+        return 0;
-+
-+      if (number_of_reaching_defs > 1)
-+        {
-+          /* If in this setting the value the register is being set to is
-+             equal to the previous value the register was set to and this
-+             setting reaches the insn we are trying to do the substitution
-+             on then we are ok.  */
-+          if (GET_CODE (PATTERN (this_reg->insn)) == CLOBBER)
-+            return 0;
-+          else if (! rtx_equal_p (SET_SRC (PATTERN (this_reg->insn)),
-+                                  SET_SRC (PATTERN (insn))))
-+            return 0;
-+        }
-+
-+      *addr_this_reg = this_reg;
-+      }
-+
-+  return number_of_reaching_defs;
-+}
-+
-+/* Expression computed by insn is available and the substitution is legal,
-+   so try to perform the substitution.
-+
-+   The result is nonzero if any changes were made.  */
-+
-+static int
-+handle_avail_expr (insn, expr)
-+     rtx insn;
-+     struct expr *expr;
-+{
-+  rtx pat, insn_computes_expr, expr_set;
-+  rtx to;
-+  struct reg_set *this_reg;
-+  int found_setting, use_src;
-+  int changed = 0;
-+
-+  /* We only handle the case where one computation of the expression
-+     reaches this instruction.  */
-+  insn_computes_expr = computing_insn (expr, insn);
-+  if (insn_computes_expr == NULL)
-+    return 0;
-+  expr_set = single_set (insn_computes_expr);
-+  if (!expr_set)
-+    abort ();
-+
-+  found_setting = 0;
-+  use_src = 0;
-+
-+  /* At this point we know only one computation of EXPR outside of this
-+     block reaches this insn.  Now try to find a register that the
-+     expression is computed into.  */
-+  if (GET_CODE (SET_SRC (expr_set)) == REG)
-+    {
-+      /* This is the case when the available expression that reaches
-+       here has already been handled as an available expression.  */
-+      unsigned int regnum_for_replacing
-+      = REGNO (SET_SRC (expr_set));
-+
-+      /* If the register was created by GCSE we can't use `reg_set_table',
-+       however we know it's set only once.  */
-+      if (regnum_for_replacing >= max_gcse_regno
-+        /* If the register the expression is computed into is set only once,
-+           or only one set reaches this insn, we can use it.  */
-+        || (((this_reg = reg_set_table[regnum_for_replacing]),
-+             this_reg->next == NULL)
-+            || can_disregard_other_sets (&this_reg, insn, 0)))
-+      {
-+        use_src = 1;
-+        found_setting = 1;
-+      }
-+    }
-+
-+  if (!found_setting)
-+    {
-+      unsigned int regnum_for_replacing
-+      = REGNO (SET_DEST (expr_set));
-+
-+      /* This shouldn't happen.  */
-+      if (regnum_for_replacing >= max_gcse_regno)
-+      abort ();
-+
-+      this_reg = reg_set_table[regnum_for_replacing];
-+
-+      /* If the register the expression is computed into is set only once,
-+       or only one set reaches this insn, use it.  */
-+      if (this_reg->next == NULL
-+        || can_disregard_other_sets (&this_reg, insn, 0))
-+      found_setting = 1;
-+    }
-+
-+  if (found_setting)
-+    {
-+      pat = PATTERN (insn);
-+      if (use_src)
-+      to = SET_SRC (expr_set);
-+      else
-+      to = SET_DEST (expr_set);
-+      changed = validate_change (insn, &SET_SRC (pat), to, 0);
-+
-+      /* We should be able to ignore the return code from validate_change but
-+       to play it safe we check.  */
-+      if (changed)
-+      {
-+        gcse_subst_count++;
-+        if (gcse_file != NULL)
-+          {
-+            fprintf (gcse_file, "GCSE: Replacing the source in insn %d with",
-+                     INSN_UID (insn));
-+            fprintf (gcse_file, " reg %d %s insn %d\n",
-+                     REGNO (to), use_src ? "from" : "set in",
-+                     INSN_UID (insn_computes_expr));
-+          }
-+      }
-+    }
-+
-+  /* The register that the expr is computed into is set more than once.  */
-+  else if (1 /*expensive_op(this_pattrn->op) && do_expensive_gcse)*/)
-+    {
-+      /* Insert an insn after insnx that copies the reg set in insnx
-+       into a new pseudo register call this new register REGN.
-+       From insnb until end of basic block or until REGB is set
-+       replace all uses of REGB with REGN.  */
-+      rtx new_insn;
-+
-+      to = gen_reg_rtx (GET_MODE (SET_DEST (expr_set)));
-+
-+      /* Generate the new insn.  */
-+      /* ??? If the change fails, we return 0, even though we created
-+       an insn.  I think this is ok.  */
-+      new_insn
-+      = emit_insn_after (gen_rtx_SET (VOIDmode, to,
-+                                      SET_DEST (expr_set)),
-+                         insn_computes_expr);
-+
-+      /* Keep register set table up to date.  */
-+      record_one_set (REGNO (to), new_insn);
-+
-+      gcse_create_count++;
-+      if (gcse_file != NULL)
-+      {
-+        fprintf (gcse_file, "GCSE: Creating insn %d to copy value of reg %d",
-+                 INSN_UID (NEXT_INSN (insn_computes_expr)),
-+                 REGNO (SET_SRC (PATTERN (NEXT_INSN (insn_computes_expr)))));
-+        fprintf (gcse_file, ", computed in insn %d,\n",
-+                 INSN_UID (insn_computes_expr));
-+        fprintf (gcse_file, "      into newly allocated reg %d\n",
-+                 REGNO (to));
-+      }
-+
-+      pat = PATTERN (insn);
-+
-+      /* Do register replacement for INSN.  */
-+      changed = validate_change (insn, &SET_SRC (pat),
-+                               SET_DEST (PATTERN
-+                                         (NEXT_INSN (insn_computes_expr))),
-+                               0);
-+
-+      /* We should be able to ignore the return code from validate_change but
-+       to play it safe we check.  */
-+      if (changed)
-+      {
-+        gcse_subst_count++;
-+        if (gcse_file != NULL)
-+          {
-+            fprintf (gcse_file,
-+                     "GCSE: Replacing the source in insn %d with reg %d ",
-+                     INSN_UID (insn),
-+                     REGNO (SET_DEST (PATTERN (NEXT_INSN
-+                                               (insn_computes_expr)))));
-+            fprintf (gcse_file, "set in insn %d\n",
-+                     INSN_UID (insn_computes_expr));
-+          }
-+      }
-+    }
-+
-+  return changed;
-+}
-+
-+/* Perform classic GCSE.  This is called by one_classic_gcse_pass after all
-+   the dataflow analysis has been done.
-+
-+   The result is nonzero if a change was made.  */
-+
-+static int
-+classic_gcse ()
-+{
-+  int changed;
-+  rtx insn;
-+  basic_block bb;
-+
-+  /* Note we start at block 1.  */
-+
-+  if (ENTRY_BLOCK_PTR->next_bb == EXIT_BLOCK_PTR)
-+    return 0;
-+
-+  changed = 0;
-+  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb->next_bb, EXIT_BLOCK_PTR, next_bb)
-+    {
-+      /* Reset tables used to keep track of what's still valid [since the
-+       start of the block].  */
-+      reset_opr_set_tables ();
-+
-+      for (insn = bb->head;
-+         insn != NULL && insn != NEXT_INSN (bb->end);
-+         insn = NEXT_INSN (insn))
-+      {
-+        /* Is insn of form (set (pseudo-reg) ...)?  */
-+        if (GET_CODE (insn) == INSN
-+            && GET_CODE (PATTERN (insn)) == SET
-+            && GET_CODE (SET_DEST (PATTERN (insn))) == REG
-+            && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_PSEUDO_REGISTER)
-+          {
-+            rtx pat = PATTERN (insn);
-+            rtx src = SET_SRC (pat);
-+            struct expr *expr;
-+
-+            if (want_to_gcse_p (src)
-+                /* Is the expression recorded?  */
-+                && ((expr = lookup_expr (src, &expr_hash_table)) != NULL)
-+                /* Is the expression available [at the start of the
-+                   block]?  */
-+                && TEST_BIT (ae_in[bb->index], expr->bitmap_index)
-+                /* Are the operands unchanged since the start of the
-+                   block?  */
-+                && oprs_not_set_p (src, insn))
-+              changed |= handle_avail_expr (insn, expr);
-+          }
-+
-+        /* Keep track of everything modified by this insn.  */
-+        /* ??? Need to be careful w.r.t. mods done to INSN.  */
-+        if (INSN_P (insn))
-+          mark_oprs_set (insn);
-+      }
-+    }
-+
-+  return changed;
-+}
-+
-+/* Top level routine to perform one classic GCSE pass.
-+
-+   Return nonzero if a change was made.  */
-+
-+static int
-+one_classic_gcse_pass (pass)
-+     int pass;
-+{
-+  int changed = 0;
-+
-+  gcse_subst_count = 0;
-+  gcse_create_count = 0;
-+
-+  alloc_hash_table (max_cuid, &expr_hash_table, 0);
-+  alloc_rd_mem (last_basic_block, max_cuid);
-+  compute_hash_table (&expr_hash_table);
-+  if (gcse_file)
-+    dump_hash_table (gcse_file, "Expression", &expr_hash_table);
-+
-+  if (expr_hash_table.n_elems > 0)
-+    {
-+      compute_kill_rd ();
-+      compute_rd ();
-+      alloc_avail_expr_mem (last_basic_block, expr_hash_table.n_elems);
-+      compute_ae_gen (&expr_hash_table);
-+      compute_ae_kill (ae_gen, ae_kill, &expr_hash_table);
-+      compute_available (ae_gen, ae_kill, ae_out, ae_in);
-+      changed = classic_gcse ();
-+      free_avail_expr_mem ();
-+    }
-+
-+  free_rd_mem ();
-+  free_hash_table (&expr_hash_table);
-+
-+  if (gcse_file)
-+    {
-+      fprintf (gcse_file, "\n");
-+      fprintf (gcse_file, "GCSE of %s, pass %d: %d bytes needed, %d substs,",
-+             current_function_name, pass, bytes_used, gcse_subst_count);
-+      fprintf (gcse_file, "%d insns created\n", gcse_create_count);
-+    }
-+
-+  return changed;
-+}
-+\f
-+/* Compute copy/constant propagation working variables.  */
-+
-+/* Local properties of assignments.  */
-+static sbitmap *cprop_pavloc;
-+static sbitmap *cprop_absaltered;
-+
-+/* Global properties of assignments (computed from the local properties).  */
-+static sbitmap *cprop_avin;
-+static sbitmap *cprop_avout;
-+
-+/* Allocate vars used for copy/const propagation.  N_BLOCKS is the number of
-+   basic blocks.  N_SETS is the number of sets.  */
-+
-+static void
-+alloc_cprop_mem (n_blocks, n_sets)
-+     int n_blocks, n_sets;
-+{
-+  cprop_pavloc = sbitmap_vector_alloc (n_blocks, n_sets);
-+  cprop_absaltered = sbitmap_vector_alloc (n_blocks, n_sets);
-+
-+  cprop_avin = sbitmap_vector_alloc (n_blocks, n_sets);
-+  cprop_avout = sbitmap_vector_alloc (n_blocks, n_sets);
-+}
-+
-+/* Free vars used by copy/const propagation.  */
-+
-+static void
-+free_cprop_mem ()
-+{
-+  sbitmap_vector_free (cprop_pavloc);
-+  sbitmap_vector_free (cprop_absaltered);
-+  sbitmap_vector_free (cprop_avin);
-+  sbitmap_vector_free (cprop_avout);
-+}
-+
-+/* For each block, compute whether X is transparent.  X is either an
-+   expression or an assignment [though we don't care which, for this context
-+   an assignment is treated as an expression].  For each block where an
-+   element of X is modified, set (SET_P == 1) or reset (SET_P == 0) the INDX
-+   bit in BMAP.  */
-+
-+static void
-+compute_transp (x, indx, bmap, set_p)
-+     rtx x;
-+     int indx;
-+     sbitmap *bmap;
-+     int set_p;
-+{
-+  int i, j;
-+  basic_block bb;
-+  enum rtx_code code;
-+  reg_set *r;
-+  const char *fmt;
-+
-+  /* repeat is used to turn tail-recursion into iteration since GCC
-+     can't do it when there's no return value.  */
-+ repeat:
-+
-+  if (x == 0)
-+    return;
-+
-+  code = GET_CODE (x);
-+  switch (code)
-+    {
-+    case REG:
-+      if (set_p)
-+      {
-+        if (REGNO (x) < FIRST_PSEUDO_REGISTER)
-+          {
-+            FOR_EACH_BB (bb)
-+              if (TEST_BIT (reg_set_in_block[bb->index], REGNO (x)))
-+                SET_BIT (bmap[bb->index], indx);
-+          }
-+        else
-+          {
-+            for (r = reg_set_table[REGNO (x)]; r != NULL; r = r->next)
-+              SET_BIT (bmap[BLOCK_NUM (r->insn)], indx);
-+          }
-+      }
-+      else
-+      {
-+        if (REGNO (x) < FIRST_PSEUDO_REGISTER)
-+          {
-+            FOR_EACH_BB (bb)
-+              if (TEST_BIT (reg_set_in_block[bb->index], REGNO (x)))
-+                RESET_BIT (bmap[bb->index], indx);
-+          }
-+        else
-+          {
-+            for (r = reg_set_table[REGNO (x)]; r != NULL; r = r->next)
-+              RESET_BIT (bmap[BLOCK_NUM (r->insn)], indx);
-+          }
-+      }
-+
-+      return;
-+
-+    case MEM:
-+      FOR_EACH_BB (bb)
-+      {
-+        rtx list_entry = canon_modify_mem_list[bb->index];
-+
-+        while (list_entry)
-+          {
-+            rtx dest, dest_addr;
-+
-+            if (GET_CODE (XEXP (list_entry, 0)) == CALL_INSN)
-+              {
-+                if (set_p)
-+                  SET_BIT (bmap[bb->index], indx);
-+                else
-+                  RESET_BIT (bmap[bb->index], indx);
-+                break;
-+              }
-+            /* LIST_ENTRY must be an INSN of some kind that sets memory.
-+               Examine each hunk of memory that is modified.  */
-+
-+            dest = XEXP (list_entry, 0);
-+            list_entry = XEXP (list_entry, 1);
-+            dest_addr = XEXP (list_entry, 0);
-+
-+            if (canon_true_dependence (dest, GET_MODE (dest), dest_addr,
-+                                       x, rtx_addr_varies_p))
-+              {
-+                if (set_p)
-+                  SET_BIT (bmap[bb->index], indx);
-+                else
-+                  RESET_BIT (bmap[bb->index], indx);
-+                break;
-+              }
-+            list_entry = XEXP (list_entry, 1);
-+          }
-+      }
-+
-+      x = XEXP (x, 0);
-+      goto repeat;
-+
-+    case PC:
-+    case CC0: /*FIXME*/
-+    case CONST:
-+    case CONST_INT:
-+    case CONST_DOUBLE:
-+    case CONST_VECTOR:
-+    case SYMBOL_REF:
-+    case LABEL_REF:
-+    case ADDR_VEC:
-+    case ADDR_DIFF_VEC:
-+      return;
-+
-+    default:
-+      break;
-+    }
-+
-+  for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
-+    {
-+      if (fmt[i] == 'e')
-+      {
-+        /* If we are about to do the last recursive call
-+           needed at this level, change it into iteration.
-+           This function is called enough to be worth it.  */
-+        if (i == 0)
-+          {
-+            x = XEXP (x, i);
-+            goto repeat;
-+          }
-+
-+        compute_transp (XEXP (x, i), indx, bmap, set_p);
-+      }
-+      else if (fmt[i] == 'E')
-+      for (j = 0; j < XVECLEN (x, i); j++)
-+        compute_transp (XVECEXP (x, i, j), indx, bmap, set_p);
-+    }
-+}
-+
-+/* Top level routine to do the dataflow analysis needed by copy/const
-+   propagation.  */
-+
-+static void
-+compute_cprop_data ()
-+{
-+  compute_local_properties (cprop_absaltered, cprop_pavloc, NULL, &set_hash_table);
-+  compute_available (cprop_pavloc, cprop_absaltered,
-+                   cprop_avout, cprop_avin);
-+}
-+\f
-+/* Copy/constant propagation.  */
-+
-+/* Maximum number of register uses in an insn that we handle.  */
-+#define MAX_USES 8
-+
-+/* Table of uses found in an insn.
-+   Allocated statically to avoid alloc/free complexity and overhead.  */
-+static struct reg_use reg_use_table[MAX_USES];
-+
-+/* Index into `reg_use_table' while building it.  */
-+static int reg_use_count;
-+
-+/* Set up a list of register numbers used in INSN.  The found uses are stored
-+   in `reg_use_table'.  `reg_use_count' is initialized to zero before entry,
-+   and contains the number of uses in the table upon exit.
-+
-+   ??? If a register appears multiple times we will record it multiple times.
-+   This doesn't hurt anything but it will slow things down.  */
-+
-+static void
-+find_used_regs (xptr, data)
-+     rtx *xptr;
-+     void *data ATTRIBUTE_UNUSED;
-+{
-+  int i, j;
-+  enum rtx_code code;
-+  const char *fmt;
-+  rtx x = *xptr;
-+
-+  /* repeat is used to turn tail-recursion into iteration since GCC
-+     can't do it when there's no return value.  */
-+ repeat:
-+  if (x == 0)
-+    return;
-+
-+  code = GET_CODE (x);
-+  if (REG_P (x))
-+    {
-+      if (reg_use_count == MAX_USES)
-+      return;
-+
-+      reg_use_table[reg_use_count].reg_rtx = x;
-+      reg_use_count++;
-+    }
-+
-+  /* Recursively scan the operands of this expression.  */
-+
-+  for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
-+    {
-+      if (fmt[i] == 'e')
-+      {
-+        /* If we are about to do the last recursive call
-+           needed at this level, change it into iteration.
-+           This function is called enough to be worth it.  */
-+        if (i == 0)
-+          {
-+            x = XEXP (x, 0);
-+            goto repeat;
-+          }
-+
-+        find_used_regs (&XEXP (x, i), data);
-+      }
-+      else if (fmt[i] == 'E')
-+      for (j = 0; j < XVECLEN (x, i); j++)
-+        find_used_regs (&XVECEXP (x, i, j), data);
-+    }
-+}
-+
-+/* Try to replace all non-SET_DEST occurrences of FROM in INSN with TO.
-+   Returns nonzero is successful.  */
-+
-+static int
-+try_replace_reg (from, to, insn)
-+     rtx from, to, insn;
-+{
-+  rtx note = find_reg_equal_equiv_note (insn);
-+  rtx src = 0;
-+  int success = 0;
-+  rtx set = single_set (insn);
-+
-+  validate_replace_src_group (from, to, insn);
-+  if (num_changes_pending () && apply_change_group ())
-+    success = 1;
-+
-+  /* Try to simplify SET_SRC if we have substituted a constant.  */
-+  if (success && set && CONSTANT_P (to))
-+    {
-+      src = simplify_rtx (SET_SRC (set));
-+
-+      if (src)
-+      validate_change (insn, &SET_SRC (set), src, 0);
-+    }
-+
-+  if (!success && set && reg_mentioned_p (from, SET_SRC (set)))
-+    {
-+      /* If above failed and this is a single set, try to simplify the source of
-+       the set given our substitution.  We could perhaps try this for multiple
-+       SETs, but it probably won't buy us anything.  */
-+      src = simplify_replace_rtx (SET_SRC (set), from, to);
-+
-+      if (!rtx_equal_p (src, SET_SRC (set))
-+        && validate_change (insn, &SET_SRC (set), src, 0))
-+      success = 1;
-+
-+      /* If we've failed to do replacement, have a single SET, don't already
-+       have a note, and have no special SET, add a REG_EQUAL note to not
-+       lose information.  */
-+      if (!success && note == 0 && set != 0
-+        && GET_CODE (XEXP (set, 0)) != ZERO_EXTRACT
-+        && GET_CODE (XEXP (set, 0)) != SIGN_EXTRACT)
-+      note = set_unique_reg_note (insn, REG_EQUAL, copy_rtx (src));
-+    }
-+
-+  /* If there is already a NOTE, update the expression in it with our
-+     replacement.  */
-+  else if (note != 0)
-+    XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0), from, to);
-+
-+  /* REG_EQUAL may get simplified into register.
-+     We don't allow that. Remove that note. This code ought
-+     not to hapen, because previous code ought to syntetize
-+     reg-reg move, but be on the safe side.  */
-+  if (note && REG_P (XEXP (note, 0)))
-+    remove_note (insn, note);
-+
-+  return success;
-+}
-+
-+/* Find a set of REGNOs that are available on entry to INSN's block.  Returns
-+   NULL no such set is found.  */
-+
-+static struct expr *
-+find_avail_set (regno, insn)
-+     int regno;
-+     rtx insn;
-+{
-+  /* SET1 contains the last set found that can be returned to the caller for
-+     use in a substitution.  */
-+  struct expr *set1 = 0;
-+
-+  /* Loops are not possible here.  To get a loop we would need two sets
-+     available at the start of the block containing INSN.  ie we would
-+     need two sets like this available at the start of the block:
-+
-+       (set (reg X) (reg Y))
-+       (set (reg Y) (reg X))
-+
-+     This can not happen since the set of (reg Y) would have killed the
-+     set of (reg X) making it unavailable at the start of this block.  */
-+  while (1)
-+    {
-+      rtx src;
-+      struct expr *set = lookup_set (regno, NULL_RTX, &set_hash_table);
-+
-+      /* Find a set that is available at the start of the block
-+       which contains INSN.  */
-+      while (set)
-+      {
-+        if (TEST_BIT (cprop_avin[BLOCK_NUM (insn)], set->bitmap_index))
-+          break;
-+        set = next_set (regno, set);
-+      }
-+
-+      /* If no available set was found we've reached the end of the
-+       (possibly empty) copy chain.  */
-+      if (set == 0)
-+      break;
-+
-+      if (GET_CODE (set->expr) != SET)
-+      abort ();
-+
-+      src = SET_SRC (set->expr);
-+
-+      /* We know the set is available.
-+       Now check that SRC is ANTLOC (i.e. none of the source operands
-+       have changed since the start of the block).
-+
-+         If the source operand changed, we may still use it for the next
-+         iteration of this loop, but we may not use it for substitutions.  */
-+
-+      if (CONSTANT_P (src) || oprs_not_set_p (src, insn))
-+      set1 = set;
-+
-+      /* If the source of the set is anything except a register, then
-+       we have reached the end of the copy chain.  */
-+      if (GET_CODE (src) != REG)
-+      break;
-+
-+      /* Follow the copy chain, ie start another iteration of the loop
-+       and see if we have an available copy into SRC.  */
-+      regno = REGNO (src);
-+    }
-+
-+  /* SET1 holds the last set that was available and anticipatable at
-+     INSN.  */
-+  return set1;
-+}
-+
-+/* Subroutine of cprop_insn that tries to propagate constants into
-+   JUMP_INSNS.  JUMP must be a conditional jump.  If SETCC is non-NULL
-+   it is the instruction that immediately preceeds JUMP, and must be a
-+   single SET of a register.  FROM is what we will try to replace,
-+   SRC is the constant we will try to substitute for it.  Returns nonzero
-+   if a change was made.  */
-+
-+static int
-+cprop_jump (bb, setcc, jump, from, src)
-+     basic_block bb;
-+     rtx setcc;
-+     rtx jump;
-+     rtx from;
-+     rtx src;
-+{
-+  rtx new, new_set;
-+  rtx set = pc_set (jump);
-+
-+  /* First substitute in the INSN condition as the SET_SRC of the JUMP,
-+     then substitute that given values in this expanded JUMP.  */
-+  if (setcc != NULL
-+      && !modified_between_p (from, setcc, jump)
-+      && !modified_between_p (src, setcc, jump))
-+    {
-+      rtx setcc_set = single_set (setcc);
-+      new_set = simplify_replace_rtx (SET_SRC (set),
-+                                    SET_DEST (setcc_set),
-+                                    SET_SRC (setcc_set));
-+    }
-+  else
-+    new_set = set;
-+
-+  new = simplify_replace_rtx (new_set, from, src);
-+
-+  /* If no simplification can be made, then try the next
-+     register.  */
-+  if (rtx_equal_p (new, new_set) || rtx_equal_p (new, SET_SRC (set)))
-+    return 0;
-+
-+  /* If this is now a no-op delete it, otherwise this must be a valid insn.  */
-+  if (new == pc_rtx)
-+    delete_insn (jump);
-+  else
-+    {
-+      /* Ensure the value computed inside the jump insn to be equivalent
-+         to one computed by setcc.  */
-+      if (setcc 
-+        && modified_in_p (new, setcc))
-+      return 0;
-+      if (! validate_change (jump, &SET_SRC (set), new, 0))
-+      return 0;
-+
-+      /* If this has turned into an unconditional jump,
-+       then put a barrier after it so that the unreachable
-+       code will be deleted.  */
-+      if (GET_CODE (SET_SRC (set)) == LABEL_REF)
-+      emit_barrier_after (jump);
-+     }
-+
-+#ifdef HAVE_cc0
-+  /* Delete the cc0 setter.  */
-+  if (setcc != NULL && CC0_P (SET_DEST (single_set (setcc))))
-+    delete_insn (setcc);
-+#endif
-+
-+  run_jump_opt_after_gcse = 1;
-+
-+  const_prop_count++;
-+  if (gcse_file != NULL)
-+    {
-+      fprintf (gcse_file,
-+             "CONST-PROP: Replacing reg %d in jump_insn %d with constant ",
-+             REGNO (from), INSN_UID (jump));
-+      print_rtl (gcse_file, src);
-+      fprintf (gcse_file, "\n");
-+    }
-+  purge_dead_edges (bb);
-+
-+  return 1;
-+}
-+
-+static bool
-+constprop_register (insn, from, to, alter_jumps)
-+     rtx insn;
-+     rtx from;
-+     rtx to;
-+     int alter_jumps;
-+{
-+  rtx sset;
-+
-+  /* Check for reg or cc0 setting instructions followed by
-+     conditional branch instructions first.  */
-+  if (alter_jumps
-+      && (sset = single_set (insn)) != NULL
-+      && NEXT_INSN (insn)
-+      && any_condjump_p (NEXT_INSN (insn)) && onlyjump_p (NEXT_INSN (insn)))
-+    {
-+      rtx dest = SET_DEST (sset);
-+      if ((REG_P (dest) || CC0_P (dest))
-+        && cprop_jump (BLOCK_FOR_INSN (insn), insn, NEXT_INSN (insn), from, to))
-+      return 1;
-+    }
-+
-+  /* Handle normal insns next.  */
-+  if (GET_CODE (insn) == INSN
-+      && try_replace_reg (from, to, insn))
-+    return 1;
-+
-+  /* Try to propagate a CONST_INT into a conditional jump.
-+     We're pretty specific about what we will handle in this
-+     code, we can extend this as necessary over time.
-+
-+     Right now the insn in question must look like
-+     (set (pc) (if_then_else ...))  */
-+  else if (alter_jumps && any_condjump_p (insn) && onlyjump_p (insn))
-+    return cprop_jump (BLOCK_FOR_INSN (insn), NULL, insn, from, to);
-+  return 0;
-+}
-+
-+/* Perform constant and copy propagation on INSN.
-+   The result is nonzero if a change was made.  */
-+
-+static int
-+cprop_insn (insn, alter_jumps)
-+     rtx insn;
-+     int alter_jumps;
-+{
-+  struct reg_use *reg_used;
-+  int changed = 0;
-+  rtx note;
-+
-+  if (!INSN_P (insn))
-+    return 0;
-+
-+  reg_use_count = 0;
-+  note_uses (&PATTERN (insn), find_used_regs, NULL);
-+
-+  note = find_reg_equal_equiv_note (insn);
-+
-+  /* We may win even when propagating constants into notes.  */
-+  if (note)
-+    find_used_regs (&XEXP (note, 0), NULL);
-+
-+  for (reg_used = &reg_use_table[0]; reg_use_count > 0;
-+       reg_used++, reg_use_count--)
-+    {
-+      unsigned int regno = REGNO (reg_used->reg_rtx);
-+      rtx pat, src;
-+      struct expr *set;
-+
-+      /* Ignore registers created by GCSE.
-+       We do this because ...  */
-+      if (regno >= max_gcse_regno)
-+      continue;
-+
-+      /* If the register has already been set in this block, there's
-+       nothing we can do.  */
-+      if (! oprs_not_set_p (reg_used->reg_rtx, insn))
-+      continue;
-+
-+      /* Find an assignment that sets reg_used and is available
-+       at the start of the block.  */
-+      set = find_avail_set (regno, insn);
-+      if (! set)
-+      continue;
-+
-+      pat = set->expr;
-+      /* ??? We might be able to handle PARALLELs.  Later.  */
-+      if (GET_CODE (pat) != SET)
-+      abort ();
-+
-+      src = SET_SRC (pat);
-+
-+      /* Constant propagation.  */
-+      if (CONSTANT_P (src))
-+      {
-+          if (constprop_register (insn, reg_used->reg_rtx, src, alter_jumps))
-+          {
-+            changed = 1;
-+            const_prop_count++;
-+            if (gcse_file != NULL)
-+              {
-+                fprintf (gcse_file, "GLOBAL CONST-PROP: Replacing reg %d in ", regno);
-+                fprintf (gcse_file, "insn %d with constant ", INSN_UID (insn));
-+                print_rtl (gcse_file, src);
-+                fprintf (gcse_file, "\n");
-+              }
-+          }
-+      }
-+      else if (GET_CODE (src) == REG
-+             && REGNO (src) >= FIRST_PSEUDO_REGISTER
-+             && REGNO (src) != regno)
-+      {
-+        if (try_replace_reg (reg_used->reg_rtx, src, insn))
-+          {
-+            changed = 1;
-+            copy_prop_count++;
-+            if (gcse_file != NULL)
-+              {
-+                fprintf (gcse_file, "GLOBAL COPY-PROP: Replacing reg %d in insn %d",
-+                         regno, INSN_UID (insn));
-+                fprintf (gcse_file, " with reg %d\n", REGNO (src));
-+              }
-+
-+            /* The original insn setting reg_used may or may not now be
-+               deletable.  We leave the deletion to flow.  */
-+            /* FIXME: If it turns out that the insn isn't deletable,
-+               then we may have unnecessarily extended register lifetimes
-+               and made things worse.  */
-+          }
-+      }
-+    }
-+
-+  return changed;
-+}
-+
-+/* Like find_used_regs, but avoid recording uses that appear in
-+   input-output contexts such as zero_extract or pre_dec.  This
-+   restricts the cases we consider to those for which local cprop
-+   can legitimately make replacements.  */
-+
-+static void
-+local_cprop_find_used_regs (xptr, data)
-+     rtx *xptr;
-+     void *data;
-+{
-+  rtx x = *xptr;
-+
-+  if (x == 0)
-+    return;
-+
-+  switch (GET_CODE (x))
-+    {
-+    case ZERO_EXTRACT:
-+    case SIGN_EXTRACT:
-+    case STRICT_LOW_PART:
-+      return;
-+
-+    case PRE_DEC:
-+    case PRE_INC:
-+    case POST_DEC:
-+    case POST_INC:
-+    case PRE_MODIFY:
-+    case POST_MODIFY:
-+      /* Can only legitimately appear this early in the context of
-+       stack pushes for function arguments, but handle all of the
-+       codes nonetheless.  */
-+      return;
-+
-+    case SUBREG:
-+      /* Setting a subreg of a register larger than word_mode leaves
-+       the non-written words unchanged.  */
-+      if (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) > BITS_PER_WORD)
-+      return;
-+      break;
-+
-+    default:
-+      break;
-+    }
-+
-+  find_used_regs (xptr, data);
-+}
-+  
-+/* LIBCALL_SP is a zero-terminated array of insns at the end of a libcall;
-+   their REG_EQUAL notes need updating.  */
-+
-+static bool
-+do_local_cprop (x, insn, alter_jumps, libcall_sp)
-+     rtx x;
-+     rtx insn;
-+     int alter_jumps;
-+     rtx *libcall_sp;
-+{
-+  rtx newreg = NULL, newcnst = NULL;
-+
-+  /* Rule out USE instructions and ASM statements as we don't want to
-+     change the hard registers mentioned.  */
-+  if (GET_CODE (x) == REG
-+      && (REGNO (x) >= FIRST_PSEUDO_REGISTER
-+          || (GET_CODE (PATTERN (insn)) != USE
-+            && asm_noperands (PATTERN (insn)) < 0)))
-+    {
-+      cselib_val *val = cselib_lookup (x, GET_MODE (x), 0);
-+      struct elt_loc_list *l;
-+
-+      if (!val)
-+      return false;
-+      for (l = val->locs; l; l = l->next)
-+      {
-+        rtx this_rtx = l->loc;
-+        rtx note;
-+
-+        if (l->in_libcall)
-+          continue;
-+
-+        if (CONSTANT_P (this_rtx))
-+          newcnst = this_rtx;
-+        if (REG_P (this_rtx) && REGNO (this_rtx) >= FIRST_PSEUDO_REGISTER
-+            /* Don't copy propagate if it has attached REG_EQUIV note.
-+               At this point this only function parameters should have
-+               REG_EQUIV notes and if the argument slot is used somewhere
-+               explicitly, it means address of parameter has been taken,
-+               so we should not extend the lifetime of the pseudo.  */
-+            && (!(note = find_reg_note (l->setting_insn, REG_EQUIV, NULL_RTX))
-+                || GET_CODE (XEXP (note, 0)) != MEM))
-+          newreg = this_rtx;
-+      }
-+      if (newcnst && constprop_register (insn, x, newcnst, alter_jumps))
-+      {
-+        /* If we find a case where we can't fix the retval REG_EQUAL notes
-+           match the new register, we either have to abandom this replacement
-+           or fix delete_trivially_dead_insns to preserve the setting insn,
-+           or make it delete the REG_EUAQL note, and fix up all passes that
-+           require the REG_EQUAL note there.  */
-+        if (!adjust_libcall_notes (x, newcnst, insn, libcall_sp))
-+          abort ();
-+        if (gcse_file != NULL)
-+          {
-+            fprintf (gcse_file, "LOCAL CONST-PROP: Replacing reg %d in ",
-+                     REGNO (x));
-+            fprintf (gcse_file, "insn %d with constant ",
-+                     INSN_UID (insn));
-+            print_rtl (gcse_file, newcnst);
-+            fprintf (gcse_file, "\n");
-+          }
-+        const_prop_count++;
-+        return true;
-+      }
-+      else if (newreg && newreg != x && try_replace_reg (x, newreg, insn))
-+      {
-+        adjust_libcall_notes (x, newreg, insn, libcall_sp);
-+        if (gcse_file != NULL)
-+          {
-+            fprintf (gcse_file,
-+                     "LOCAL COPY-PROP: Replacing reg %d in insn %d",
-+                     REGNO (x), INSN_UID (insn));
-+            fprintf (gcse_file, " with reg %d\n", REGNO (newreg));
-+          }
-+        copy_prop_count++;
-+        return true;
-+      }
-+    }
-+  return false;
-+}
-+
-+/* LIBCALL_SP is a zero-terminated array of insns at the end of a libcall;
-+   their REG_EQUAL notes need updating to reflect that OLDREG has been
-+   replaced with NEWVAL in INSN.  Return true if all substitutions could
-+   be made.  */
-+static bool
-+adjust_libcall_notes (oldreg, newval, insn, libcall_sp)
-+     rtx oldreg, newval, insn, *libcall_sp;
-+{
-+  rtx end;
-+
-+  while ((end = *libcall_sp++))
-+    {
-+      rtx note = find_reg_equal_equiv_note (end);
-+
-+      if (! note)
-+      continue;
-+
-+      if (REG_P (newval))
-+      {
-+        if (reg_set_between_p (newval, PREV_INSN (insn), end))
-+          {
-+            do
-+              {
-+                note = find_reg_equal_equiv_note (end);
-+                if (! note)
-+                  continue;
-+                if (reg_mentioned_p (newval, XEXP (note, 0)))
-+                  return false;
-+              }
-+            while ((end = *libcall_sp++));
-+            return true;
-+          }
-+      }
-+      XEXP (note, 0) = replace_rtx (XEXP (note, 0), oldreg, newval);
-+      insn = end;
-+    }
-+  return true;
-+}
-+
-+#define MAX_NESTED_LIBCALLS 9
-+
-+static void
-+local_cprop_pass (alter_jumps)
-+     int alter_jumps;
-+{
-+  rtx insn;
-+  struct reg_use *reg_used;
-+  rtx libcall_stack[MAX_NESTED_LIBCALLS + 1], *libcall_sp;
-+  bool changed = false;
-+
-+  cselib_init ();
-+  libcall_sp = &libcall_stack[MAX_NESTED_LIBCALLS];
-+  *libcall_sp = 0;
-+  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
-+    {
-+      if (INSN_P (insn))
-+      {
-+        rtx note = find_reg_note (insn, REG_LIBCALL, NULL_RTX);
-+
-+        if (note)
-+          {
-+            if (libcall_sp == libcall_stack)
-+              abort ();
-+            *--libcall_sp = XEXP (note, 0);
-+          }
-+        note = find_reg_note (insn, REG_RETVAL, NULL_RTX);
-+        if (note)
-+          libcall_sp++;
-+        note = find_reg_equal_equiv_note (insn);
-+        do
-+          {
-+            reg_use_count = 0;
-+            note_uses (&PATTERN (insn), local_cprop_find_used_regs, NULL);
-+            if (note)
-+              local_cprop_find_used_regs (&XEXP (note, 0), NULL);
-+
-+            for (reg_used = &reg_use_table[0]; reg_use_count > 0;
-+                 reg_used++, reg_use_count--)
-+              if (do_local_cprop (reg_used->reg_rtx, insn, alter_jumps,
-+                  libcall_sp))
-+                {
-+                  changed = true;
-+                  break;
-+                }
-+          }
-+        while (reg_use_count);
-+      }
-+      cselib_process_insn (insn);
-+    }
-+  cselib_finish ();
-+  /* Global analysis may get into infinite loops for unreachable blocks.  */
-+  if (changed && alter_jumps)
-+    {
-+      delete_unreachable_blocks ();
-+      free_reg_set_mem ();
-+      alloc_reg_set_mem (max_reg_num ());
-+      compute_sets (get_insns ());
-+    }
-+}
-+
-+/* Forward propagate copies.  This includes copies and constants.  Return
-+   nonzero if a change was made.  */
-+
-+static int
-+cprop (alter_jumps)
-+     int alter_jumps;
-+{
-+  int changed;
-+  basic_block bb;
-+  rtx insn;
-+
-+  /* Note we start at block 1.  */
-+  if (ENTRY_BLOCK_PTR->next_bb == EXIT_BLOCK_PTR)
-+    {
-+      if (gcse_file != NULL)
-+      fprintf (gcse_file, "\n");
-+      return 0;
-+    }
-+
-+  changed = 0;
-+  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb->next_bb, EXIT_BLOCK_PTR, next_bb)
-+    {
-+      /* Reset tables used to keep track of what's still valid [since the
-+       start of the block].  */
-+      reset_opr_set_tables ();
-+
-+      for (insn = bb->head;
-+         insn != NULL && insn != NEXT_INSN (bb->end);
-+         insn = NEXT_INSN (insn))
-+      if (INSN_P (insn))
-+        {
-+          changed |= cprop_insn (insn, alter_jumps);
-+
-+          /* Keep track of everything modified by this insn.  */
-+          /* ??? Need to be careful w.r.t. mods done to INSN.  Don't
-+             call mark_oprs_set if we turned the insn into a NOTE.  */
-+          if (GET_CODE (insn) != NOTE)
-+            mark_oprs_set (insn);
-+        }
-+    }
-+
-+  if (gcse_file != NULL)
-+    fprintf (gcse_file, "\n");
-+
-+  return changed;
-+}
-+
-+/* Perform one copy/constant propagation pass.
-+   F is the first insn in the function.
-+   PASS is the pass count.  */
-+
-+static int
-+one_cprop_pass (pass, alter_jumps)
-+     int pass;
-+     int alter_jumps;
-+{
-+  int changed = 0;
-+
-+  const_prop_count = 0;
-+  copy_prop_count = 0;
-+
-+  local_cprop_pass (alter_jumps);
-+
-+  alloc_hash_table (max_cuid, &set_hash_table, 1);
-+  compute_hash_table (&set_hash_table);
-+  if (gcse_file)
-+    dump_hash_table (gcse_file, "SET", &set_hash_table);
-+  if (set_hash_table.n_elems > 0)
-+    {
-+      alloc_cprop_mem (last_basic_block, set_hash_table.n_elems);
-+      compute_cprop_data ();
-+      changed = cprop (alter_jumps);
-+      if (alter_jumps)
-+      changed |= bypass_conditional_jumps ();
-+      free_cprop_mem ();
-+    }
-+
-+  free_hash_table (&set_hash_table);
-+
-+  if (gcse_file)
-+    {
-+      fprintf (gcse_file, "CPROP of %s, pass %d: %d bytes needed, ",
-+             current_function_name, pass, bytes_used);
-+      fprintf (gcse_file, "%d const props, %d copy props\n\n",
-+             const_prop_count, copy_prop_count);
-+    }
-+  /* Global analysis may get into infinite loops for unreachable blocks.  */
-+  if (changed && alter_jumps)
-+    delete_unreachable_blocks ();
-+
-+  return changed;
-+}
-+\f
-+/* Bypass conditional jumps.  */
-+
-+/* Find a set of REGNO to a constant that is available at the end of basic
-+   block BB.  Returns NULL if no such set is found.  Based heavily upon
-+   find_avail_set.  */
-+
-+static struct expr *
-+find_bypass_set (regno, bb)
-+     int regno;
-+     int bb;
-+{
-+  struct expr *result = 0;
-+
-+  for (;;)
-+    {
-+      rtx src;
-+      struct expr *set = lookup_set (regno, NULL_RTX, &set_hash_table);
-+
-+      while (set)
-+      {
-+        if (TEST_BIT (cprop_avout[bb], set->bitmap_index))
-+          break;
-+        set = next_set (regno, set);
-+      }
-+
-+      if (set == 0)
-+      break;
-+
-+      if (GET_CODE (set->expr) != SET)
-+      abort ();
-+
-+      src = SET_SRC (set->expr);
-+      if (CONSTANT_P (src))
-+      result = set;
-+
-+      if (GET_CODE (src) != REG)
-+      break;
-+
-+      regno = REGNO (src);
-+    }
-+  return result;
-+}
-+
-+
-+/* Subroutine of bypass_block that checks whether a pseudo is killed by
-+   any of the instructions inserted on an edge.  Jump bypassing places
-+   condition code setters on CFG edges using insert_insn_on_edge.  This
-+   function is required to check that our data flow analysis is still
-+   valid prior to commit_edge_insertions.  */
-+
-+static bool
-+reg_killed_on_edge (reg, e)
-+     rtx reg;
-+     edge e;
-+{
-+  rtx insn;
-+
-+  for (insn = e->insns; insn; insn = NEXT_INSN (insn))
-+    if (INSN_P (insn) && reg_set_p (reg, insn))
-+      return true;
-+
-+  return false;
-+}
-+
-+/* Subroutine of bypass_conditional_jumps that attempts to bypass the given
-+   basic block BB which has more than one predecessor.  If not NULL, SETCC
-+   is the first instruction of BB, which is immediately followed by JUMP_INSN
-+   JUMP.  Otherwise, SETCC is NULL, and JUMP is the first insn of BB.
-+   Returns nonzero if a change was made.
-+
-+   During the jump bypassing pass, we may place copies of SETCC instuctions
-+   on CFG edges.  The following routine must be careful to pay attention to
-+   these inserted insns when performing its transformations.  */
-+
-+static int
-+bypass_block (bb, setcc, jump)
-+     basic_block bb;
-+     rtx setcc, jump;
-+{
-+  rtx insn, note;
-+  edge e, enext, edest;
-+  int i, change;
-+
-+  insn = (setcc != NULL) ? setcc : jump;
-+
-+  /* Determine set of register uses in INSN.  */
-+  reg_use_count = 0;
-+  note_uses (&PATTERN (insn), find_used_regs, NULL);
-+  note = find_reg_equal_equiv_note (insn);
-+  if (note)
-+    find_used_regs (&XEXP (note, 0), NULL);
-+
-+  change = 0;
-+  for (e = bb->pred; e; e = enext)
-+    {
-+      enext = e->pred_next;
-+      for (i = 0; i < reg_use_count; i++)
-+      {
-+        struct reg_use *reg_used = &reg_use_table[i];
-+        unsigned int regno = REGNO (reg_used->reg_rtx);
-+        basic_block dest, old_dest;
-+        struct expr *set;
-+        rtx src, new;
-+
-+        if (regno >= max_gcse_regno)
-+          continue;
-+
-+        set = find_bypass_set (regno, e->src->index);
-+
-+        if (! set)
-+          continue;
-+
-+        /* Check the data flow is valid after edge insertions.  */
-+        if (e->insns && reg_killed_on_edge (reg_used->reg_rtx, e))
-+          continue;
-+
-+        src = SET_SRC (pc_set (jump));
-+
-+        if (setcc != NULL)
-+            src = simplify_replace_rtx (src,
-+                                        SET_DEST (PATTERN (setcc)),
-+                                        SET_SRC (PATTERN (setcc)));
-+
-+        new = simplify_replace_rtx (src, reg_used->reg_rtx,
-+                                    SET_SRC (set->expr));
-+
-+        /* Jump bypassing may have already placed instructions on 
-+           edges of the CFG.  We can't bypass an outgoing edge that
-+           has instructions associated with it, as these insns won't
-+           get executed if the incoming edge is redirected.  */
-+
-+        if (new == pc_rtx)
-+          {
-+            edest = FALLTHRU_EDGE (bb);
-+            dest = edest->insns ? NULL : edest->dest;
-+          }
-+        else if (GET_CODE (new) == LABEL_REF)
-+          {
-+            dest = BLOCK_FOR_INSN (XEXP (new, 0));
-+            /* Don't bypass edges containing instructions.  */
-+            for (edest = bb->succ; edest; edest = edest->succ_next)
-+              if (edest->dest == dest && edest->insns)
-+                {
-+                  dest = NULL;
-+                  break;
-+                }
-+          }
-+        else
-+          dest = NULL;
-+
-+        /* Once basic block indices are stable, we should be able
-+           to use redirect_edge_and_branch_force instead.  */
-+        old_dest = e->dest;
-+        if (dest != NULL && dest != old_dest
-+            && redirect_edge_and_branch (e, dest))
-+          {
-+            /* Copy the register setter to the redirected edge.
-+               Don't copy CC0 setters, as CC0 is dead after jump.  */
-+            if (setcc)
-+              {
-+                rtx pat = PATTERN (setcc);
-+                if (!CC0_P (SET_DEST (pat)))
-+                  insert_insn_on_edge (copy_insn (pat), e);
-+              }
-+
-+            if (gcse_file != NULL)
-+              {
-+                fprintf (gcse_file, "JUMP-BYPASS: Proved reg %d in jump_insn %d equals constant ",
-+                         regno, INSN_UID (jump));
-+                print_rtl (gcse_file, SET_SRC (set->expr));
-+                fprintf (gcse_file, "\nBypass edge from %d->%d to %d\n",
-+                         e->src->index, old_dest->index, dest->index);
-+              }
-+            change = 1;
-+            break;
-+          }
-+      }
-+    }
-+  return change;
-+}
-+
-+/* Find basic blocks with more than one predecessor that only contain a
-+   single conditional jump.  If the result of the comparison is known at
-+   compile-time from any incoming edge, redirect that edge to the
-+   appropriate target.  Returns nonzero if a change was made.  */
-+
-+static int
-+bypass_conditional_jumps ()
-+{
-+  basic_block bb;
-+  int changed;
-+  rtx setcc;
-+  rtx insn;
-+  rtx dest;
-+
-+  /* Note we start at block 1.  */
-+  if (ENTRY_BLOCK_PTR->next_bb == EXIT_BLOCK_PTR)
-+    return 0;
-+
-+  changed = 0;
-+  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb->next_bb,
-+                EXIT_BLOCK_PTR, next_bb)
-+    {
-+      /* Check for more than one predecessor.  */
-+      if (bb->pred && bb->pred->pred_next)
-+      {
-+        setcc = NULL_RTX;
-+        for (insn = bb->head;
-+             insn != NULL && insn != NEXT_INSN (bb->end);
-+             insn = NEXT_INSN (insn))
-+          if (GET_CODE (insn) == INSN)
-+            {
-+              if (setcc)
-+                break;
-+              if (GET_CODE (PATTERN (insn)) != SET)
-+                break;
-+
-+              dest = SET_DEST (PATTERN (insn));
-+              if (REG_P (dest) || CC0_P (dest))
-+                setcc = insn;
-+              else
-+                break;
-+            }
-+          else if (GET_CODE (insn) == JUMP_INSN)
-+            {
-+              if (any_condjump_p (insn) && onlyjump_p (insn))
-+                changed |= bypass_block (bb, setcc, insn);
-+              break;
-+            }
-+          else if (INSN_P (insn))
-+            break;
-+      }
-+    }
-+
-+  /* If we bypassed any register setting insns, we inserted a
-+     copy on the redirected edge.  These need to be commited.  */
-+  if (changed)
-+    commit_edge_insertions();
-+
-+  return changed;
-+}
-+\f
-+/* Compute PRE+LCM working variables.  */
-+
-+/* Local properties of expressions.  */
-+/* Nonzero for expressions that are transparent in the block.  */
-+static sbitmap *transp;
-+
-+/* Nonzero for expressions that are transparent at the end of the block.
-+   This is only zero for expressions killed by abnormal critical edge
-+   created by a calls.  */
-+static sbitmap *transpout;
-+
-+/* Nonzero for expressions that are computed (available) in the block.  */
-+static sbitmap *comp;
-+
-+/* Nonzero for expressions that are locally anticipatable in the block.  */
-+static sbitmap *antloc;
-+
-+/* Nonzero for expressions where this block is an optimal computation
-+   point.  */
-+static sbitmap *pre_optimal;
-+
-+/* Nonzero for expressions which are redundant in a particular block.  */
-+static sbitmap *pre_redundant;
-+
-+/* Nonzero for expressions which should be inserted on a specific edge.  */
-+static sbitmap *pre_insert_map;
-+
-+/* Nonzero for expressions which should be deleted in a specific block.  */
-+static sbitmap *pre_delete_map;
-+
-+/* Contains the edge_list returned by pre_edge_lcm.  */
-+static struct edge_list *edge_list;
-+
-+/* Redundant insns.  */
-+static sbitmap pre_redundant_insns;
-+
-+/* Allocate vars used for PRE analysis.  */
-+
-+static void
-+alloc_pre_mem (n_blocks, n_exprs)
-+     int n_blocks, n_exprs;
-+{
-+  transp = sbitmap_vector_alloc (n_blocks, n_exprs);
-+  comp = sbitmap_vector_alloc (n_blocks, n_exprs);
-+  antloc = sbitmap_vector_alloc (n_blocks, n_exprs);
-+
-+  pre_optimal = NULL;
-+  pre_redundant = NULL;
-+  pre_insert_map = NULL;
-+  pre_delete_map = NULL;
-+  ae_in = NULL;
-+  ae_out = NULL;
-+  ae_kill = sbitmap_vector_alloc (n_blocks, n_exprs);
-+
-+  /* pre_insert and pre_delete are allocated later.  */
-+}
-+
-+/* Free vars used for PRE analysis.  */
-+
-+static void
-+free_pre_mem ()
-+{
-+  sbitmap_vector_free (transp);
-+  sbitmap_vector_free (comp);
-+
-+  /* ANTLOC and AE_KILL are freed just after pre_lcm finishes.  */
-+
-+  if (pre_optimal)
-+    sbitmap_vector_free (pre_optimal);
-+  if (pre_redundant)
-+    sbitmap_vector_free (pre_redundant);
-+  if (pre_insert_map)
-+    sbitmap_vector_free (pre_insert_map);
-+  if (pre_delete_map)
-+    sbitmap_vector_free (pre_delete_map);
-+  if (ae_in)
-+    sbitmap_vector_free (ae_in);
-+  if (ae_out)
-+    sbitmap_vector_free (ae_out);
-+
-+  transp = comp = NULL;
-+  pre_optimal = pre_redundant = pre_insert_map = pre_delete_map = NULL;
-+  ae_in = ae_out = NULL;
-+}
-+
-+/* Top level routine to do the dataflow analysis needed by PRE.  */
-+
-+static void
-+compute_pre_data ()
-+{
-+  sbitmap trapping_expr;
-+  basic_block bb;
-+  unsigned int ui;
-+
-+  compute_local_properties (transp, comp, antloc, &expr_hash_table);
-+  sbitmap_vector_zero (ae_kill, last_basic_block);
-+
-+  /* Collect expressions which might trap.  */
-+  trapping_expr = sbitmap_alloc (expr_hash_table.n_elems);
-+  sbitmap_zero (trapping_expr);
-+  for (ui = 0; ui < expr_hash_table.size; ui++)
-+    {
-+      struct expr *e;
-+      for (e = expr_hash_table.table[ui]; e != NULL; e = e->next_same_hash)
-+      if (may_trap_p (e->expr))
-+        SET_BIT (trapping_expr, e->bitmap_index);
-+    }
-+
-+  /* Compute ae_kill for each basic block using:
-+
-+     ~(TRANSP | COMP)
-+
-+     This is significantly faster than compute_ae_kill.  */
-+
-+  FOR_EACH_BB (bb)
-+    {
-+      edge e;
-+
-+      /* If the current block is the destination of an abnormal edge, we
-+       kill all trapping expressions because we won't be able to properly
-+       place the instruction on the edge.  So make them neither
-+       anticipatable nor transparent.  This is fairly conservative.  */
-+      for (e = bb->pred; e ; e = e->pred_next)
-+      if (e->flags & EDGE_ABNORMAL)
-+        {
-+          sbitmap_difference (antloc[bb->index], antloc[bb->index], trapping_expr);
-+          sbitmap_difference (transp[bb->index], transp[bb->index], trapping_expr);
-+          break;
-+        }
-+
-+      sbitmap_a_or_b (ae_kill[bb->index], transp[bb->index], comp[bb->index]);
-+      sbitmap_not (ae_kill[bb->index], ae_kill[bb->index]);
-+    }
-+
-+  edge_list = pre_edge_lcm (gcse_file, expr_hash_table.n_elems, transp, comp, antloc,
-+                          ae_kill, &pre_insert_map, &pre_delete_map);
-+  sbitmap_vector_free (antloc);
-+  antloc = NULL;
-+  sbitmap_vector_free (ae_kill);
-+  ae_kill = NULL;
-+  sbitmap_free (trapping_expr);
-+}
-+\f
-+/* PRE utilities */
-+
-+/* Return nonzero if an occurrence of expression EXPR in OCCR_BB would reach
-+   block BB.
-+
-+   VISITED is a pointer to a working buffer for tracking which BB's have
-+   been visited.  It is NULL for the top-level call.
-+
-+   We treat reaching expressions that go through blocks containing the same
-+   reaching expression as "not reaching".  E.g. if EXPR is generated in blocks
-+   2 and 3, INSN is in block 4, and 2->3->4, we treat the expression in block
-+   2 as not reaching.  The intent is to improve the probability of finding
-+   only one reaching expression and to reduce register lifetimes by picking
-+   the closest such expression.  */
-+
-+static int
-+pre_expr_reaches_here_p_work (occr_bb, expr, bb, visited)
-+     basic_block occr_bb;
-+     struct expr *expr;
-+     basic_block bb;
-+     char *visited;
-+{
-+  edge pred;
-+
-+  for (pred = bb->pred; pred != NULL; pred = pred->pred_next)
-+    {
-+      basic_block pred_bb = pred->src;
-+
-+      if (pred->src == ENTRY_BLOCK_PTR
-+        /* Has predecessor has already been visited?  */
-+        || visited[pred_bb->index])
-+      ;/* Nothing to do.  */
-+
-+      /* Does this predecessor generate this expression?  */
-+      else if (TEST_BIT (comp[pred_bb->index], expr->bitmap_index))
-+      {
-+        /* Is this the occurrence we're looking for?
-+           Note that there's only one generating occurrence per block
-+           so we just need to check the block number.  */
-+        if (occr_bb == pred_bb)
-+          return 1;
-+
-+        visited[pred_bb->index] = 1;
-+      }
-+      /* Ignore this predecessor if it kills the expression.  */
-+      else if (! TEST_BIT (transp[pred_bb->index], expr->bitmap_index))
-+      visited[pred_bb->index] = 1;
-+
-+      /* Neither gen nor kill.  */
-+      else
-+      {
-+        visited[pred_bb->index] = 1;
-+        if (pre_expr_reaches_here_p_work (occr_bb, expr, pred_bb, visited))
-+          return 1;
-+      }
-+    }
-+
-+  /* All paths have been checked.  */
-+  return 0;
-+}
-+
-+/* The wrapper for pre_expr_reaches_here_work that ensures that any
-+   memory allocated for that function is returned.  */
-+
-+static int
-+pre_expr_reaches_here_p (occr_bb, expr, bb)
-+     basic_block occr_bb;
-+     struct expr *expr;
-+     basic_block bb;
-+{
-+  int rval;
-+  char *visited = (char *) xcalloc (last_basic_block, 1);
-+
-+  rval = pre_expr_reaches_here_p_work (occr_bb, expr, bb, visited);
-+
-+  free (visited);
-+  return rval;
-+}
-+\f
-+
-+/* Given an expr, generate RTL which we can insert at the end of a BB,
-+   or on an edge.  Set the block number of any insns generated to
-+   the value of BB.  */
-+
-+static rtx
-+process_insert_insn (expr)
-+     struct expr *expr;
-+{
-+  rtx reg = expr->reaching_reg;
-+  rtx exp = copy_rtx (expr->expr);
-+  rtx pat;
-+
-+  start_sequence ();
-+
-+  /* If the expression is something that's an operand, like a constant,
-+     just copy it to a register.  */
-+  if (general_operand (exp, GET_MODE (reg)))
-+    emit_move_insn (reg, exp);
-+
-+  /* Otherwise, make a new insn to compute this expression and make sure the
-+     insn will be recognized (this also adds any needed CLOBBERs).  Copy the
-+     expression to make sure we don't have any sharing issues.  */
-+  else if (insn_invalid_p (emit_insn (gen_rtx_SET (VOIDmode, reg, exp))))
-+    abort ();
-+
-+  pat = get_insns ();
-+  end_sequence ();
-+
-+  return pat;
-+}
-+
-+/* Add EXPR to the end of basic block BB.
-+
-+   This is used by both the PRE and code hoisting.
-+
-+   For PRE, we want to verify that the expr is either transparent
-+   or locally anticipatable in the target block.  This check makes
-+   no sense for code hoisting.  */
-+
-+static void
-+insert_insn_end_bb (expr, bb, pre)
-+     struct expr *expr;
-+     basic_block bb;
-+     int pre;
-+{
-+  rtx insn = bb->end;
-+  rtx new_insn;
-+  rtx reg = expr->reaching_reg;
-+  int regno = REGNO (reg);
-+  rtx pat, pat_end;
-+
-+  pat = process_insert_insn (expr);
-+  if (pat == NULL_RTX || ! INSN_P (pat))
-+    abort ();
-+
-+  pat_end = pat;
-+  while (NEXT_INSN (pat_end) != NULL_RTX)
-+    pat_end = NEXT_INSN (pat_end);
-+
-+  /* If the last insn is a jump, insert EXPR in front [taking care to
-+     handle cc0, etc. properly].  Similary we need to care trapping
-+     instructions in presence of non-call exceptions.  */
-+
-+  if (GET_CODE (insn) == JUMP_INSN
-+      || (GET_CODE (insn) == INSN
-+        && (bb->succ->succ_next || (bb->succ->flags & EDGE_ABNORMAL))))
-+    {
-+#ifdef HAVE_cc0
-+      rtx note;
-+#endif
-+      /* It should always be the case that we can put these instructions
-+       anywhere in the basic block with performing PRE optimizations.
-+       Check this.  */
-+      if (GET_CODE (insn) == INSN && pre
-+        && !TEST_BIT (antloc[bb->index], expr->bitmap_index)
-+        && !TEST_BIT (transp[bb->index], expr->bitmap_index))
-+      abort ();
-+
-+      /* If this is a jump table, then we can't insert stuff here.  Since
-+       we know the previous real insn must be the tablejump, we insert
-+       the new instruction just before the tablejump.  */
-+      if (GET_CODE (PATTERN (insn)) == ADDR_VEC
-+        || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
-+      insn = prev_real_insn (insn);
-+
-+#ifdef HAVE_cc0
-+      /* FIXME: 'twould be nice to call prev_cc0_setter here but it aborts
-+       if cc0 isn't set.  */
-+      note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);
-+      if (note)
-+      insn = XEXP (note, 0);
-+      else
-+      {
-+        rtx maybe_cc0_setter = prev_nonnote_insn (insn);
-+        if (maybe_cc0_setter
-+            && INSN_P (maybe_cc0_setter)
-+            && sets_cc0_p (PATTERN (maybe_cc0_setter)))
-+          insn = maybe_cc0_setter;
-+      }
-+#endif
-+      /* FIXME: What if something in cc0/jump uses value set in new insn?  */
-+      new_insn = emit_insn_before (pat, insn);
-+    }
-+
-+  /* Likewise if the last insn is a call, as will happen in the presence
-+     of exception handling.  */
-+  else if (GET_CODE (insn) == CALL_INSN
-+         && (bb->succ->succ_next || (bb->succ->flags & EDGE_ABNORMAL)))
-+    {
-+      /* Keeping in mind SMALL_REGISTER_CLASSES and parameters in registers,
-+       we search backward and place the instructions before the first
-+       parameter is loaded.  Do this for everyone for consistency and a
-+       presumtion that we'll get better code elsewhere as well.
-+
-+       It should always be the case that we can put these instructions
-+       anywhere in the basic block with performing PRE optimizations.
-+       Check this.  */
-+
-+      if (pre
-+        && !TEST_BIT (antloc[bb->index], expr->bitmap_index)
-+        && !TEST_BIT (transp[bb->index], expr->bitmap_index))
-+      abort ();
-+
-+      /* Since different machines initialize their parameter registers
-+       in different orders, assume nothing.  Collect the set of all
-+       parameter registers.  */
-+      insn = find_first_parameter_load (insn, bb->head);
-+
-+      /* If we found all the parameter loads, then we want to insert
-+       before the first parameter load.
-+
-+       If we did not find all the parameter loads, then we might have
-+       stopped on the head of the block, which could be a CODE_LABEL.
-+       If we inserted before the CODE_LABEL, then we would be putting
-+       the insn in the wrong basic block.  In that case, put the insn
-+       after the CODE_LABEL.  Also, respect NOTE_INSN_BASIC_BLOCK.  */
-+      while (GET_CODE (insn) == CODE_LABEL
-+           || NOTE_INSN_BASIC_BLOCK_P (insn))
-+      insn = NEXT_INSN (insn);
-+
-+      new_insn = emit_insn_before (pat, insn);
-+    }
-+  else
-+    new_insn = emit_insn_after (pat, insn);
-+
-+  while (1)
-+    {
-+      if (INSN_P (pat))
-+      {
-+        add_label_notes (PATTERN (pat), new_insn);
-+        note_stores (PATTERN (pat), record_set_info, pat);
-+      }
-+      if (pat == pat_end)
-+      break;
-+      pat = NEXT_INSN (pat);
-+    }
-+
-+  gcse_create_count++;
-+
-+  if (gcse_file)
-+    {
-+      fprintf (gcse_file, "PRE/HOIST: end of bb %d, insn %d, ",
-+             bb->index, INSN_UID (new_insn));
-+      fprintf (gcse_file, "copying expression %d to reg %d\n",
-+             expr->bitmap_index, regno);
-+    }
-+}
-+
-+/* Insert partially redundant expressions on edges in the CFG to make
-+   the expressions fully redundant.  */
-+
-+static int
-+pre_edge_insert (edge_list, index_map)
-+     struct edge_list *edge_list;
-+     struct expr **index_map;
-+{
-+  int e, i, j, num_edges, set_size, did_insert = 0;
-+  sbitmap *inserted;
-+
-+  /* Where PRE_INSERT_MAP is nonzero, we add the expression on that edge
-+     if it reaches any of the deleted expressions.  */
-+
-+  set_size = pre_insert_map[0]->size;
-+  num_edges = NUM_EDGES (edge_list);
-+  inserted = sbitmap_vector_alloc (num_edges, expr_hash_table.n_elems);
-+  sbitmap_vector_zero (inserted, num_edges);
-+
-+  for (e = 0; e < num_edges; e++)
-+    {
-+      int indx;
-+      basic_block bb = INDEX_EDGE_PRED_BB (edge_list, e);
-+
-+      for (i = indx = 0; i < set_size; i++, indx += SBITMAP_ELT_BITS)
-+      {
-+        SBITMAP_ELT_TYPE insert = pre_insert_map[e]->elms[i];
-+
-+        for (j = indx; insert && j < (int) expr_hash_table.n_elems; j++, insert >>= 1)
-+          if ((insert & 1) != 0 && index_map[j]->reaching_reg != NULL_RTX)
-+            {
-+              struct expr *expr = index_map[j];
-+              struct occr *occr;
-+
-+              /* Now look at each deleted occurrence of this expression.  */
-+              for (occr = expr->antic_occr; occr != NULL; occr = occr->next)
-+                {
-+                  if (! occr->deleted_p)
-+                    continue;
-+
-+                  /* Insert this expression on this edge if if it would
-+                     reach the deleted occurrence in BB.  */
-+                  if (!TEST_BIT (inserted[e], j))
-+                    {
-+                      rtx insn;
-+                      edge eg = INDEX_EDGE (edge_list, e);
-+
-+                      /* We can't insert anything on an abnormal and
-+                         critical edge, so we insert the insn at the end of
-+                         the previous block. There are several alternatives
-+                         detailed in Morgans book P277 (sec 10.5) for
-+                         handling this situation.  This one is easiest for
-+                         now.  */
-+
-+                      if ((eg->flags & EDGE_ABNORMAL) == EDGE_ABNORMAL)
-+                        insert_insn_end_bb (index_map[j], bb, 0);
-+                      else
-+                        {
-+                          insn = process_insert_insn (index_map[j]);
-+                          insert_insn_on_edge (insn, eg);
-+                        }
-+
-+                      if (gcse_file)
-+                        {
-+                          fprintf (gcse_file, "PRE/HOIST: edge (%d,%d), ",
-+                                   bb->index,
-+                                   INDEX_EDGE_SUCC_BB (edge_list, e)->index);
-+                          fprintf (gcse_file, "copy expression %d\n",
-+                                   expr->bitmap_index);
-+                        }
-+
-+                      update_ld_motion_stores (expr);
-+                      SET_BIT (inserted[e], j);
-+                      did_insert = 1;
-+                      gcse_create_count++;
-+                    }
-+                }
-+            }
-+      }
-+    }
-+
-+  sbitmap_vector_free (inserted);
-+  return did_insert;
-+}
-+
-+/* Copy the result of INSN to REG.  INDX is the expression number.  */
-+
-+static void
-+pre_insert_copy_insn (expr, insn)
-+     struct expr *expr;
-+     rtx insn;
-+{
-+  rtx reg = expr->reaching_reg;
-+  int regno = REGNO (reg);
-+  int indx = expr->bitmap_index;
-+  rtx set = single_set (insn);
-+  rtx new_insn;
-+
-+  if (!set)
-+    abort ();
-+
-+  new_insn = emit_insn_after (gen_move_insn (reg, SET_DEST (set)), insn);
-+
-+  /* Keep register set table up to date.  */
-+  record_one_set (regno, new_insn);
-+
-+  gcse_create_count++;
-+
-+  if (gcse_file)
-+    fprintf (gcse_file,
-+           "PRE: bb %d, insn %d, copy expression %d in insn %d to reg %d\n",
-+            BLOCK_NUM (insn), INSN_UID (new_insn), indx,
-+            INSN_UID (insn), regno);
-+  update_ld_motion_stores (expr);
-+}
-+
-+/* Copy available expressions that reach the redundant expression
-+   to `reaching_reg'.  */
-+
-+static void
-+pre_insert_copies ()
-+{
-+  unsigned int i;
-+  struct expr *expr;
-+  struct occr *occr;
-+  struct occr *avail;
-+
-+  /* For each available expression in the table, copy the result to
-+     `reaching_reg' if the expression reaches a deleted one.
-+
-+     ??? The current algorithm is rather brute force.
-+     Need to do some profiling.  */
-+
-+  for (i = 0; i < expr_hash_table.size; i++)
-+    for (expr = expr_hash_table.table[i]; expr != NULL; expr = expr->next_same_hash)
-+      {
-+      /* If the basic block isn't reachable, PPOUT will be TRUE.  However,
-+         we don't want to insert a copy here because the expression may not
-+         really be redundant.  So only insert an insn if the expression was
-+         deleted.  This test also avoids further processing if the
-+         expression wasn't deleted anywhere.  */
-+      if (expr->reaching_reg == NULL)
-+        continue;
-+
-+      for (occr = expr->antic_occr; occr != NULL; occr = occr->next)
-+        {
-+          if (! occr->deleted_p)
-+            continue;
-+
-+          for (avail = expr->avail_occr; avail != NULL; avail = avail->next)
-+            {
-+              rtx insn = avail->insn;
-+
-+              /* No need to handle this one if handled already.  */
-+              if (avail->copied_p)
-+                continue;
-+
-+              /* Don't handle this one if it's a redundant one.  */
-+              if (TEST_BIT (pre_redundant_insns, INSN_CUID (insn)))
-+                continue;
-+
-+              /* Or if the expression doesn't reach the deleted one.  */
-+              if (! pre_expr_reaches_here_p (BLOCK_FOR_INSN (avail->insn),
-+                                             expr,
-+                                             BLOCK_FOR_INSN (occr->insn)))
-+                continue;
-+
-+              /* Copy the result of avail to reaching_reg.  */
-+              pre_insert_copy_insn (expr, insn);
-+              avail->copied_p = 1;
-+            }
-+        }
-+      }
-+}
-+
-+/* Emit move from SRC to DEST noting the equivalence with expression computed
-+   in INSN.  */
-+static rtx
-+gcse_emit_move_after (src, dest, insn)
-+     rtx src, dest, insn;
-+{
-+  rtx new;
-+  rtx set = single_set (insn), set2;
-+  rtx note;
-+  rtx eqv;
-+
-+  /* This should never fail since we're creating a reg->reg copy
-+     we've verified to be valid.  */
-+
-+  new = emit_insn_after (gen_move_insn (dest, src), insn);
-+
-+  /* Note the equivalence for local CSE pass.  */
-+  set2 = single_set (new);
-+  if (!set2 || !rtx_equal_p (SET_DEST (set2), dest))
-+    return new;
-+  if ((note = find_reg_equal_equiv_note (insn)))
-+    eqv = XEXP (note, 0);
-+  else
-+    eqv = SET_SRC (set);
-+
-+  set_unique_reg_note (new, REG_EQUAL, copy_insn_1 (eqv));
-+
-+  return new;
-+}
-+
-+/* Delete redundant computations.
-+   Deletion is done by changing the insn to copy the `reaching_reg' of
-+   the expression into the result of the SET.  It is left to later passes
-+   (cprop, cse2, flow, combine, regmove) to propagate the copy or eliminate it.
-+
-+   Returns nonzero if a change is made.  */
-+
-+static int
-+pre_delete ()
-+{
-+  unsigned int i;
-+  int changed;
-+  struct expr *expr;
-+  struct occr *occr;
-+
-+  changed = 0;
-+  for (i = 0; i < expr_hash_table.size; i++)
-+    for (expr = expr_hash_table.table[i]; expr != NULL; expr = expr->next_same_hash)
-+      {
-+      int indx = expr->bitmap_index;
-+
-+      /* We only need to search antic_occr since we require
-+         ANTLOC != 0.  */
-+
-+      for (occr = expr->antic_occr; occr != NULL; occr = occr->next)
-+        {
-+          rtx insn = occr->insn;
-+          rtx set;
-+          basic_block bb = BLOCK_FOR_INSN (insn);
-+
-+          if (TEST_BIT (pre_delete_map[bb->index], indx))
-+            {
-+              set = single_set (insn);
-+              if (! set)
-+                abort ();
-+
-+              /* Create a pseudo-reg to store the result of reaching
-+                 expressions into.  Get the mode for the new pseudo from
-+                 the mode of the original destination pseudo.  */
-+              if (expr->reaching_reg == NULL)
-+                expr->reaching_reg
-+                  = gen_reg_rtx (GET_MODE (SET_DEST (set)));
-+
-+              gcse_emit_move_after (expr->reaching_reg, SET_DEST (set), insn);
-+              delete_insn (insn);
-+              occr->deleted_p = 1;
-+              SET_BIT (pre_redundant_insns, INSN_CUID (insn));
-+              changed = 1;
-+              gcse_subst_count++;
-+
-+              if (gcse_file)
-+                {
-+                  fprintf (gcse_file,
-+                           "PRE: redundant insn %d (expression %d) in ",
-+                             INSN_UID (insn), indx);
-+                  fprintf (gcse_file, "bb %d, reaching reg is %d\n",
-+                           bb->index, REGNO (expr->reaching_reg));
-+                }
-+            }
-+        }
-+      }
-+
-+  return changed;
-+}
-+
-+/* Perform GCSE optimizations using PRE.
-+   This is called by one_pre_gcse_pass after all the dataflow analysis
-+   has been done.
-+
-+   This is based on the original Morel-Renvoise paper Fred Chow's thesis, and
-+   lazy code motion from Knoop, Ruthing and Steffen as described in Advanced
-+   Compiler Design and Implementation.
-+
-+   ??? A new pseudo reg is created to hold the reaching expression.  The nice
-+   thing about the classical approach is that it would try to use an existing
-+   reg.  If the register can't be adequately optimized [i.e. we introduce
-+   reload problems], one could add a pass here to propagate the new register
-+   through the block.
-+
-+   ??? We don't handle single sets in PARALLELs because we're [currently] not
-+   able to copy the rest of the parallel when we insert copies to create full
-+   redundancies from partial redundancies.  However, there's no reason why we
-+   can't handle PARALLELs in the cases where there are no partial
-+   redundancies.  */
-+
-+static int
-+pre_gcse ()
-+{
-+  unsigned int i;
-+  int did_insert, changed;
-+  struct expr **index_map;
-+  struct expr *expr;
-+
-+  /* Compute a mapping from expression number (`bitmap_index') to
-+     hash table entry.  */
-+
-+  index_map = (struct expr **) xcalloc (expr_hash_table.n_elems, sizeof (struct expr *));
-+  for (i = 0; i < expr_hash_table.size; i++)
-+    for (expr = expr_hash_table.table[i]; expr != NULL; expr = expr->next_same_hash)
-+      index_map[expr->bitmap_index] = expr;
-+
-+  /* Reset bitmap used to track which insns are redundant.  */
-+  pre_redundant_insns = sbitmap_alloc (max_cuid);
-+  sbitmap_zero (pre_redundant_insns);
-+
-+  /* Delete the redundant insns first so that
-+     - we know what register to use for the new insns and for the other
-+       ones with reaching expressions
-+     - we know which insns are redundant when we go to create copies  */
-+
-+  changed = pre_delete ();
-+
-+  did_insert = pre_edge_insert (edge_list, index_map);
-+
-+  /* In other places with reaching expressions, copy the expression to the
-+     specially allocated pseudo-reg that reaches the redundant expr.  */
-+  pre_insert_copies ();
-+  if (did_insert)
-+    {
-+      commit_edge_insertions ();
-+      changed = 1;
-+    }
-+
-+  free (index_map);
-+  sbitmap_free (pre_redundant_insns);
-+  return changed;
-+}
-+
-+/* Top level routine to perform one PRE GCSE pass.
-+
-+   Return nonzero if a change was made.  */
-+
-+static int
-+one_pre_gcse_pass (pass)
-+     int pass;
-+{
-+  int changed = 0;
-+
-+  gcse_subst_count = 0;
-+  gcse_create_count = 0;
-+
-+  alloc_hash_table (max_cuid, &expr_hash_table, 0);
-+  add_noreturn_fake_exit_edges ();
-+  if (flag_gcse_lm)
-+    compute_ld_motion_mems ();
-+
-+  compute_hash_table (&expr_hash_table);
-+  trim_ld_motion_mems ();
-+  if (gcse_file)
-+    dump_hash_table (gcse_file, "Expression", &expr_hash_table);
-+
-+  if (expr_hash_table.n_elems > 0)
-+    {
-+      alloc_pre_mem (last_basic_block, expr_hash_table.n_elems);
-+      compute_pre_data ();
-+      changed |= pre_gcse ();
-+      free_edge_list (edge_list);
-+      free_pre_mem ();
-+    }
-+
-+  free_ldst_mems ();
-+  remove_fake_edges ();
-+  free_hash_table (&expr_hash_table);
-+
-+  if (gcse_file)
-+    {
-+      fprintf (gcse_file, "\nPRE GCSE of %s, pass %d: %d bytes needed, ",
-+             current_function_name, pass, bytes_used);
-+      fprintf (gcse_file, "%d substs, %d insns created\n",
-+             gcse_subst_count, gcse_create_count);
-+    }
-+
-+  return changed;
-+}
-+\f
-+/* If X contains any LABEL_REF's, add REG_LABEL notes for them to INSN.
-+   If notes are added to an insn which references a CODE_LABEL, the
-+   LABEL_NUSES count is incremented.  We have to add REG_LABEL notes,
-+   because the following loop optimization pass requires them.  */
-+
-+/* ??? This is very similar to the loop.c add_label_notes function.  We
-+   could probably share code here.  */
-+
-+/* ??? If there was a jump optimization pass after gcse and before loop,
-+   then we would not need to do this here, because jump would add the
-+   necessary REG_LABEL notes.  */
-+
-+static void
-+add_label_notes (x, insn)
-+     rtx x;
-+     rtx insn;
-+{
-+  enum rtx_code code = GET_CODE (x);
-+  int i, j;
-+  const char *fmt;
-+
-+  if (code == LABEL_REF && !LABEL_REF_NONLOCAL_P (x))
-+    {
-+      /* This code used to ignore labels that referred to dispatch tables to
-+       avoid flow generating (slighly) worse code.
-+
-+       We no longer ignore such label references (see LABEL_REF handling in
-+       mark_jump_label for additional information).  */
-+
-+      REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL, XEXP (x, 0),
-+                                          REG_NOTES (insn));
-+      if (LABEL_P (XEXP (x, 0)))
-+      LABEL_NUSES (XEXP (x, 0))++;
-+      return;
-+    }
-+
-+  for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
-+    {
-+      if (fmt[i] == 'e')
-+      add_label_notes (XEXP (x, i), insn);
-+      else if (fmt[i] == 'E')
-+      for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-+        add_label_notes (XVECEXP (x, i, j), insn);
-+    }
-+}
-+
-+/* Compute transparent outgoing information for each block.
-+
-+   An expression is transparent to an edge unless it is killed by
-+   the edge itself.  This can only happen with abnormal control flow,
-+   when the edge is traversed through a call.  This happens with
-+   non-local labels and exceptions.
-+
-+   This would not be necessary if we split the edge.  While this is
-+   normally impossible for abnormal critical edges, with some effort
-+   it should be possible with exception handling, since we still have
-+   control over which handler should be invoked.  But due to increased
-+   EH table sizes, this may not be worthwhile.  */
-+
-+static void
-+compute_transpout ()
-+{
-+  basic_block bb;
-+  unsigned int i;
-+  struct expr *expr;
-+
-+  sbitmap_vector_ones (transpout, last_basic_block);
-+
-+  FOR_EACH_BB (bb)
-+    {
-+      /* Note that flow inserted a nop a the end of basic blocks that
-+       end in call instructions for reasons other than abnormal
-+       control flow.  */
-+      if (GET_CODE (bb->end) != CALL_INSN)
-+      continue;
-+
-+      for (i = 0; i < expr_hash_table.size; i++)
-+      for (expr = expr_hash_table.table[i]; expr ; expr = expr->next_same_hash)
-+        if (GET_CODE (expr->expr) == MEM)
-+          {
-+            if (GET_CODE (XEXP (expr->expr, 0)) == SYMBOL_REF
-+                && CONSTANT_POOL_ADDRESS_P (XEXP (expr->expr, 0)))
-+              continue;
-+
-+            /* ??? Optimally, we would use interprocedural alias
-+               analysis to determine if this mem is actually killed
-+               by this call.  */
-+            RESET_BIT (transpout[bb->index], expr->bitmap_index);
-+          }
-+    }
-+}
-+
-+/* Removal of useless null pointer checks */
-+
-+/* Called via note_stores.  X is set by SETTER.  If X is a register we must
-+   invalidate nonnull_local and set nonnull_killed.  DATA is really a
-+   `null_pointer_info *'.
-+
-+   We ignore hard registers.  */
-+
-+static void
-+invalidate_nonnull_info (x, setter, data)
-+     rtx x;
-+     rtx setter ATTRIBUTE_UNUSED;
-+     void *data;
-+{
-+  unsigned int regno;
-+  struct null_pointer_info *npi = (struct null_pointer_info *) data;
-+
-+  while (GET_CODE (x) == SUBREG)
-+    x = SUBREG_REG (x);
-+
-+  /* Ignore anything that is not a register or is a hard register.  */
-+  if (GET_CODE (x) != REG
-+      || REGNO (x) < npi->min_reg
-+      || REGNO (x) >= npi->max_reg)
-+    return;
-+
-+  regno = REGNO (x) - npi->min_reg;
-+
-+  RESET_BIT (npi->nonnull_local[npi->current_block->index], regno);
-+  SET_BIT (npi->nonnull_killed[npi->current_block->index], regno);
-+}
-+
-+/* Do null-pointer check elimination for the registers indicated in
-+   NPI.  NONNULL_AVIN and NONNULL_AVOUT are pre-allocated sbitmaps;
-+   they are not our responsibility to free.  */
-+
-+static int
-+delete_null_pointer_checks_1 (block_reg, nonnull_avin,
-+                            nonnull_avout, npi)
-+     unsigned int *block_reg;
-+     sbitmap *nonnull_avin;
-+     sbitmap *nonnull_avout;
-+     struct null_pointer_info *npi;
-+{
-+  basic_block bb, current_block;
-+  sbitmap *nonnull_local = npi->nonnull_local;
-+  sbitmap *nonnull_killed = npi->nonnull_killed;
-+  int something_changed = 0;
-+
-+  /* Compute local properties, nonnull and killed.  A register will have
-+     the nonnull property if at the end of the current block its value is
-+     known to be nonnull.  The killed property indicates that somewhere in
-+     the block any information we had about the register is killed.
-+
-+     Note that a register can have both properties in a single block.  That
-+     indicates that it's killed, then later in the block a new value is
-+     computed.  */
-+  sbitmap_vector_zero (nonnull_local, last_basic_block);
-+  sbitmap_vector_zero (nonnull_killed, last_basic_block);
-+
-+  FOR_EACH_BB (current_block)
-+    {
-+      rtx insn, stop_insn;
-+
-+      /* Set the current block for invalidate_nonnull_info.  */
-+      npi->current_block = current_block;
-+
-+      /* Scan each insn in the basic block looking for memory references and
-+       register sets.  */
-+      stop_insn = NEXT_INSN (current_block->end);
-+      for (insn = current_block->head;
-+         insn != stop_insn;
-+         insn = NEXT_INSN (insn))
-+      {
-+        rtx set;
-+        rtx reg;
-+
-+        /* Ignore anything that is not a normal insn.  */
-+        if (! INSN_P (insn))
-+          continue;
-+
-+        /* Basically ignore anything that is not a simple SET.  We do have
-+           to make sure to invalidate nonnull_local and set nonnull_killed
-+           for such insns though.  */
-+        set = single_set (insn);
-+        if (!set)
-+          {
-+            note_stores (PATTERN (insn), invalidate_nonnull_info, npi);
-+            continue;
-+          }
-+
-+        /* See if we've got a usable memory load.  We handle it first
-+           in case it uses its address register as a dest (which kills
-+           the nonnull property).  */
-+        if (GET_CODE (SET_SRC (set)) == MEM
-+            && GET_CODE ((reg = XEXP (SET_SRC (set), 0))) == REG
-+            && REGNO (reg) >= npi->min_reg
-+            && REGNO (reg) < npi->max_reg)
-+          SET_BIT (nonnull_local[current_block->index],
-+                   REGNO (reg) - npi->min_reg);
-+
-+        /* Now invalidate stuff clobbered by this insn.  */
-+        note_stores (PATTERN (insn), invalidate_nonnull_info, npi);
-+
-+        /* And handle stores, we do these last since any sets in INSN can
-+           not kill the nonnull property if it is derived from a MEM
-+           appearing in a SET_DEST.  */
-+        if (GET_CODE (SET_DEST (set)) == MEM
-+            && GET_CODE ((reg = XEXP (SET_DEST (set), 0))) == REG
-+            && REGNO (reg) >= npi->min_reg
-+            && REGNO (reg) < npi->max_reg)
-+          SET_BIT (nonnull_local[current_block->index],
-+                   REGNO (reg) - npi->min_reg);
-+      }
-+    }
-+
-+  /* Now compute global properties based on the local properties.   This
-+     is a classic global availablity algorithm.  */
-+  compute_available (nonnull_local, nonnull_killed,
-+                   nonnull_avout, nonnull_avin);
-+
-+  /* Now look at each bb and see if it ends with a compare of a value
-+     against zero.  */
-+  FOR_EACH_BB (bb)
-+    {
-+      rtx last_insn = bb->end;
-+      rtx condition, earliest;
-+      int compare_and_branch;
-+
-+      /* Since MIN_REG is always at least FIRST_PSEUDO_REGISTER, and
-+       since BLOCK_REG[BB] is zero if this block did not end with a
-+       comparison against zero, this condition works.  */
-+      if (block_reg[bb->index] < npi->min_reg
-+        || block_reg[bb->index] >= npi->max_reg)
-+      continue;
-+
-+      /* LAST_INSN is a conditional jump.  Get its condition.  */
-+      condition = get_condition (last_insn, &earliest);
-+
-+      /* If we can't determine the condition then skip.  */
-+      if (! condition)
-+      continue;
-+
-+      /* Is the register known to have a nonzero value?  */
-+      if (!TEST_BIT (nonnull_avout[bb->index], block_reg[bb->index] - npi->min_reg))
-+      continue;
-+
-+      /* Try to compute whether the compare/branch at the loop end is one or
-+       two instructions.  */
-+      if (earliest == last_insn)
-+      compare_and_branch = 1;
-+      else if (earliest == prev_nonnote_insn (last_insn))
-+      compare_and_branch = 2;
-+      else
-+      continue;
-+
-+      /* We know the register in this comparison is nonnull at exit from
-+       this block.  We can optimize this comparison.  */
-+      if (GET_CODE (condition) == NE)
-+      {
-+        rtx new_jump;
-+
-+        new_jump = emit_jump_insn_after (gen_jump (JUMP_LABEL (last_insn)),
-+                                         last_insn);
-+        JUMP_LABEL (new_jump) = JUMP_LABEL (last_insn);
-+        LABEL_NUSES (JUMP_LABEL (new_jump))++;
-+        emit_barrier_after (new_jump);
-+      }
-+
-+      something_changed = 1;
-+      delete_insn (last_insn);
-+      if (compare_and_branch == 2)
-+      delete_insn (earliest);
-+      purge_dead_edges (bb);
-+
-+      /* Don't check this block again.  (Note that BLOCK_END is
-+       invalid here; we deleted the last instruction in the
-+       block.)  */
-+      block_reg[bb->index] = 0;
-+    }
-+
-+  return something_changed;
-+}
-+
-+/* Find EQ/NE comparisons against zero which can be (indirectly) evaluated
-+   at compile time.
-+
-+   This is conceptually similar to global constant/copy propagation and
-+   classic global CSE (it even uses the same dataflow equations as cprop).
-+
-+   If a register is used as memory address with the form (mem (reg)), then we
-+   know that REG can not be zero at that point in the program.  Any instruction
-+   which sets REG "kills" this property.
-+
-+   So, if every path leading to a conditional branch has an available memory
-+   reference of that form, then we know the register can not have the value
-+   zero at the conditional branch.
-+
-+   So we merely need to compute the local properies and propagate that data
-+   around the cfg, then optimize where possible.
-+
-+   We run this pass two times.  Once before CSE, then again after CSE.  This
-+   has proven to be the most profitable approach.  It is rare for new
-+   optimization opportunities of this nature to appear after the first CSE
-+   pass.
-+
-+   This could probably be integrated with global cprop with a little work.  */
-+
-+int
-+delete_null_pointer_checks (f)
-+     rtx f ATTRIBUTE_UNUSED;
-+{
-+  sbitmap *nonnull_avin, *nonnull_avout;
-+  unsigned int *block_reg;
-+  basic_block bb;
-+  int reg;
-+  int regs_per_pass;
-+  int max_reg;
-+  struct null_pointer_info npi;
-+  int something_changed = 0;
-+
-+  /* If we have only a single block, then there's nothing to do.  */
-+  if (n_basic_blocks <= 1)
-+    return 0;
-+
-+  /* Trying to perform global optimizations on flow graphs which have
-+     a high connectivity will take a long time and is unlikely to be
-+     particularly useful.
-+
-+     In normal circumstances a cfg should have about twice as many edges
-+     as blocks.  But we do not want to punish small functions which have
-+     a couple switch statements.  So we require a relatively large number
-+     of basic blocks and the ratio of edges to blocks to be high.  */
-+  if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20)
-+    return 0;
-+
-+  /* We need four bitmaps, each with a bit for each register in each
-+     basic block.  */
-+  max_reg = max_reg_num ();
-+  regs_per_pass = get_bitmap_width (4, last_basic_block, max_reg);
-+
-+  /* Allocate bitmaps to hold local and global properties.  */
-+  npi.nonnull_local = sbitmap_vector_alloc (last_basic_block, regs_per_pass);
-+  npi.nonnull_killed = sbitmap_vector_alloc (last_basic_block, regs_per_pass);
-+  nonnull_avin = sbitmap_vector_alloc (last_basic_block, regs_per_pass);
-+  nonnull_avout = sbitmap_vector_alloc (last_basic_block, regs_per_pass);
-+
-+  /* Go through the basic blocks, seeing whether or not each block
-+     ends with a conditional branch whose condition is a comparison
-+     against zero.  Record the register compared in BLOCK_REG.  */
-+  block_reg = (unsigned int *) xcalloc (last_basic_block, sizeof (int));
-+  FOR_EACH_BB (bb)
-+    {
-+      rtx last_insn = bb->end;
-+      rtx condition, earliest, reg;
-+
-+      /* We only want conditional branches.  */
-+      if (GET_CODE (last_insn) != JUMP_INSN
-+        || !any_condjump_p (last_insn)
-+        || !onlyjump_p (last_insn))
-+      continue;
-+
-+      /* LAST_INSN is a conditional jump.  Get its condition.  */
-+      condition = get_condition (last_insn, &earliest);
-+
-+      /* If we were unable to get the condition, or it is not an equality
-+       comparison against zero then there's nothing we can do.  */
-+      if (!condition
-+        || (GET_CODE (condition) != NE && GET_CODE (condition) != EQ)
-+        || GET_CODE (XEXP (condition, 1)) != CONST_INT
-+        || (XEXP (condition, 1)
-+            != CONST0_RTX (GET_MODE (XEXP (condition, 0)))))
-+      continue;
-+
-+      /* We must be checking a register against zero.  */
-+      reg = XEXP (condition, 0);
-+      if (GET_CODE (reg) != REG)
-+      continue;
-+
-+      block_reg[bb->index] = REGNO (reg);
-+    }
-+
-+  /* Go through the algorithm for each block of registers.  */
-+  for (reg = FIRST_PSEUDO_REGISTER; reg < max_reg; reg += regs_per_pass)
-+    {
-+      npi.min_reg = reg;
-+      npi.max_reg = MIN (reg + regs_per_pass, max_reg);
-+      something_changed |= delete_null_pointer_checks_1 (block_reg,
-+                                                       nonnull_avin,
-+                                                       nonnull_avout,
-+                                                       &npi);
-+    }
-+
-+  /* Free the table of registers compared at the end of every block.  */
-+  free (block_reg);
-+
-+  /* Free bitmaps.  */
-+  sbitmap_vector_free (npi.nonnull_local);
-+  sbitmap_vector_free (npi.nonnull_killed);
-+  sbitmap_vector_free (nonnull_avin);
-+  sbitmap_vector_free (nonnull_avout);
-+
-+  return something_changed;
-+}
-+
-+/* Code Hoisting variables and subroutines.  */
-+
-+/* Very busy expressions.  */
-+static sbitmap *hoist_vbein;
-+static sbitmap *hoist_vbeout;
-+
-+/* Hoistable expressions.  */
-+static sbitmap *hoist_exprs;
-+
-+/* Dominator bitmaps.  */
-+dominance_info dominators;
-+
-+/* ??? We could compute post dominators and run this algorithm in
-+   reverse to perform tail merging, doing so would probably be
-+   more effective than the tail merging code in jump.c.
-+
-+   It's unclear if tail merging could be run in parallel with
-+   code hoisting.  It would be nice.  */
-+
-+/* Allocate vars used for code hoisting analysis.  */
-+
-+static void
-+alloc_code_hoist_mem (n_blocks, n_exprs)
-+     int n_blocks, n_exprs;
-+{
-+  antloc = sbitmap_vector_alloc (n_blocks, n_exprs);
-+  transp = sbitmap_vector_alloc (n_blocks, n_exprs);
-+  comp = sbitmap_vector_alloc (n_blocks, n_exprs);
-+
-+  hoist_vbein = sbitmap_vector_alloc (n_blocks, n_exprs);
-+  hoist_vbeout = sbitmap_vector_alloc (n_blocks, n_exprs);
-+  hoist_exprs = sbitmap_vector_alloc (n_blocks, n_exprs);
-+  transpout = sbitmap_vector_alloc (n_blocks, n_exprs);
-+}
-+
-+/* Free vars used for code hoisting analysis.  */
-+
-+static void
-+free_code_hoist_mem ()
-+{
-+  sbitmap_vector_free (antloc);
-+  sbitmap_vector_free (transp);
-+  sbitmap_vector_free (comp);
-+
-+  sbitmap_vector_free (hoist_vbein);
-+  sbitmap_vector_free (hoist_vbeout);
-+  sbitmap_vector_free (hoist_exprs);
-+  sbitmap_vector_free (transpout);
-+
-+  free_dominance_info (dominators);
-+}
-+
-+/* Compute the very busy expressions at entry/exit from each block.
-+
-+   An expression is very busy if all paths from a given point
-+   compute the expression.  */
-+
-+static void
-+compute_code_hoist_vbeinout ()
-+{
-+  int changed, passes;
-+  basic_block bb;
-+
-+  sbitmap_vector_zero (hoist_vbeout, last_basic_block);
-+  sbitmap_vector_zero (hoist_vbein, last_basic_block);
-+
-+  passes = 0;
-+  changed = 1;
-+
-+  while (changed)
-+    {
-+      changed = 0;
-+
-+      /* We scan the blocks in the reverse order to speed up
-+       the convergence.  */
-+      FOR_EACH_BB_REVERSE (bb)
-+      {
-+        changed |= sbitmap_a_or_b_and_c_cg (hoist_vbein[bb->index], antloc[bb->index],
-+                                            hoist_vbeout[bb->index], transp[bb->index]);
-+        if (bb->next_bb != EXIT_BLOCK_PTR)
-+          sbitmap_intersection_of_succs (hoist_vbeout[bb->index], hoist_vbein, bb->index);
-+      }
-+
-+      passes++;
-+    }
-+
-+  if (gcse_file)
-+    fprintf (gcse_file, "hoisting vbeinout computation: %d passes\n", passes);
-+}
-+
-+/* Top level routine to do the dataflow analysis needed by code hoisting.  */
-+
-+static void
-+compute_code_hoist_data ()
-+{
-+  compute_local_properties (transp, comp, antloc, &expr_hash_table);
-+  compute_transpout ();
-+  compute_code_hoist_vbeinout ();
-+  dominators = calculate_dominance_info (CDI_DOMINATORS);
-+  if (gcse_file)
-+    fprintf (gcse_file, "\n");
-+}
-+
-+/* Determine if the expression identified by EXPR_INDEX would
-+   reach BB unimpared if it was placed at the end of EXPR_BB.
-+
-+   It's unclear exactly what Muchnick meant by "unimpared".  It seems
-+   to me that the expression must either be computed or transparent in
-+   *every* block in the path(s) from EXPR_BB to BB.  Any other definition
-+   would allow the expression to be hoisted out of loops, even if
-+   the expression wasn't a loop invariant.
-+
-+   Contrast this to reachability for PRE where an expression is
-+   considered reachable if *any* path reaches instead of *all*
-+   paths.  */
-+
-+static int
-+hoist_expr_reaches_here_p (expr_bb, expr_index, bb, visited)
-+     basic_block expr_bb;
-+     int expr_index;
-+     basic_block bb;
-+     char *visited;
-+{
-+  edge pred;
-+  int visited_allocated_locally = 0;
-+
-+
-+  if (visited == NULL)
-+    {
-+      visited_allocated_locally = 1;
-+      visited = xcalloc (last_basic_block, 1);
-+    }
-+
-+  for (pred = bb->pred; pred != NULL; pred = pred->pred_next)
-+    {
-+      basic_block pred_bb = pred->src;
-+
-+      if (pred->src == ENTRY_BLOCK_PTR)
-+      break;
-+      else if (pred_bb == expr_bb)
-+      continue;
-+      else if (visited[pred_bb->index])
-+      continue;
-+
-+      /* Does this predecessor generate this expression?  */
-+      else if (TEST_BIT (comp[pred_bb->index], expr_index))
-+      break;
-+      else if (! TEST_BIT (transp[pred_bb->index], expr_index))
-+      break;
-+
-+      /* Not killed.  */
-+      else
-+      {
-+        visited[pred_bb->index] = 1;
-+        if (! hoist_expr_reaches_here_p (expr_bb, expr_index,
-+                                         pred_bb, visited))
-+          break;
-+      }
-+    }
-+  if (visited_allocated_locally)
-+    free (visited);
-+
-+  return (pred == NULL);
-+}
-+\f
-+/* Actually perform code hoisting.  */
-+
-+static void
-+hoist_code ()
-+{
-+  basic_block bb, dominated;
-+  basic_block *domby;
-+  unsigned int domby_len;
-+  unsigned int i,j;
-+  struct expr **index_map;
-+  struct expr *expr;
-+
-+  sbitmap_vector_zero (hoist_exprs, last_basic_block);
-+
-+  /* Compute a mapping from expression number (`bitmap_index') to
-+     hash table entry.  */
-+
-+  index_map = (struct expr **) xcalloc (expr_hash_table.n_elems, sizeof (struct expr *));
-+  for (i = 0; i < expr_hash_table.size; i++)
-+    for (expr = expr_hash_table.table[i]; expr != NULL; expr = expr->next_same_hash)
-+      index_map[expr->bitmap_index] = expr;
-+
-+  /* Walk over each basic block looking for potentially hoistable
-+     expressions, nothing gets hoisted from the entry block.  */
-+  FOR_EACH_BB (bb)
-+    {
-+      int found = 0;
-+      int insn_inserted_p;
-+
-+      domby_len = get_dominated_by (dominators, bb, &domby);
-+      /* Examine each expression that is very busy at the exit of this
-+       block.  These are the potentially hoistable expressions.  */
-+      for (i = 0; i < hoist_vbeout[bb->index]->n_bits; i++)
-+      {
-+        int hoistable = 0;
-+
-+        if (TEST_BIT (hoist_vbeout[bb->index], i)
-+            && TEST_BIT (transpout[bb->index], i))
-+          {
-+            /* We've found a potentially hoistable expression, now
-+               we look at every block BB dominates to see if it
-+               computes the expression.  */
-+            for (j = 0; j < domby_len; j++)
-+              {
-+                dominated = domby[j];
-+                /* Ignore self dominance.  */
-+                if (bb == dominated)
-+                  continue;
-+                /* We've found a dominated block, now see if it computes
-+                   the busy expression and whether or not moving that
-+                   expression to the "beginning" of that block is safe.  */
-+                if (!TEST_BIT (antloc[dominated->index], i))
-+                  continue;
-+
-+                /* Note if the expression would reach the dominated block
-+                   unimpared if it was placed at the end of BB.
-+
-+                   Keep track of how many times this expression is hoistable
-+                   from a dominated block into BB.  */
-+                if (hoist_expr_reaches_here_p (bb, i, dominated, NULL))
-+                  hoistable++;
-+              }
-+
-+            /* If we found more than one hoistable occurrence of this
-+               expression, then note it in the bitmap of expressions to
-+               hoist.  It makes no sense to hoist things which are computed
-+               in only one BB, and doing so tends to pessimize register
-+               allocation.  One could increase this value to try harder
-+               to avoid any possible code expansion due to register
-+               allocation issues; however experiments have shown that
-+               the vast majority of hoistable expressions are only movable
-+               from two successors, so raising this threshhold is likely
-+               to nullify any benefit we get from code hoisting.  */
-+            if (hoistable > 1)
-+              {
-+                SET_BIT (hoist_exprs[bb->index], i);
-+                found = 1;
-+              }
-+          }
-+      }
-+      /* If we found nothing to hoist, then quit now.  */
-+      if (! found)
-+        {
-+        free (domby);
-+      continue;
-+      }
-+
-+      /* Loop over all the hoistable expressions.  */
-+      for (i = 0; i < hoist_exprs[bb->index]->n_bits; i++)
-+      {
-+        /* We want to insert the expression into BB only once, so
-+           note when we've inserted it.  */
-+        insn_inserted_p = 0;
-+
-+        /* These tests should be the same as the tests above.  */
-+        if (TEST_BIT (hoist_vbeout[bb->index], i))
-+          {
-+            /* We've found a potentially hoistable expression, now
-+               we look at every block BB dominates to see if it
-+               computes the expression.  */
-+            for (j = 0; j < domby_len; j++)
-+              {
-+                dominated = domby[j];
-+                /* Ignore self dominance.  */
-+                if (bb == dominated)
-+                  continue;
-+
-+                /* We've found a dominated block, now see if it computes
-+                   the busy expression and whether or not moving that
-+                   expression to the "beginning" of that block is safe.  */
-+                if (!TEST_BIT (antloc[dominated->index], i))
-+                  continue;
-+
-+                /* The expression is computed in the dominated block and
-+                   it would be safe to compute it at the start of the
-+                   dominated block.  Now we have to determine if the
-+                   expression would reach the dominated block if it was
-+                   placed at the end of BB.  */
-+                if (hoist_expr_reaches_here_p (bb, i, dominated, NULL))
-+                  {
-+                    struct expr *expr = index_map[i];
-+                    struct occr *occr = expr->antic_occr;
-+                    rtx insn;
-+                    rtx set;
-+
-+                    /* Find the right occurrence of this expression.  */
-+                    while (BLOCK_FOR_INSN (occr->insn) != dominated && occr)
-+                      occr = occr->next;
-+
-+                    /* Should never happen.  */
-+                    if (!occr)
-+                      abort ();
-+
-+                    insn = occr->insn;
-+
-+                    set = single_set (insn);
-+                    if (! set)
-+                      abort ();
-+
-+                    /* Create a pseudo-reg to store the result of reaching
-+                       expressions into.  Get the mode for the new pseudo
-+                       from the mode of the original destination pseudo.  */
-+                    if (expr->reaching_reg == NULL)
-+                      expr->reaching_reg
-+                        = gen_reg_rtx (GET_MODE (SET_DEST (set)));
-+
-+                    gcse_emit_move_after (expr->reaching_reg, SET_DEST (set), insn);
-+                    delete_insn (insn);
-+                    occr->deleted_p = 1;
-+                    if (!insn_inserted_p)
-+                      {
-+                        insert_insn_end_bb (index_map[i], bb, 0);
-+                        insn_inserted_p = 1;
-+                      }
-+                  }
-+              }
-+          }
-+      }
-+      free (domby);
-+    }
-+
-+  free (index_map);
-+}
-+
-+/* Top level routine to perform one code hoisting (aka unification) pass
-+
-+   Return nonzero if a change was made.  */
-+
-+static int
-+one_code_hoisting_pass ()
-+{
-+  int changed = 0;
-+
-+  alloc_hash_table (max_cuid, &expr_hash_table, 0);
-+  compute_hash_table (&expr_hash_table);
-+  if (gcse_file)
-+    dump_hash_table (gcse_file, "Code Hosting Expressions", &expr_hash_table);
-+
-+  if (expr_hash_table.n_elems > 0)
-+    {
-+      alloc_code_hoist_mem (last_basic_block, expr_hash_table.n_elems);
-+      compute_code_hoist_data ();
-+      hoist_code ();
-+      free_code_hoist_mem ();
-+    }
-+
-+  free_hash_table (&expr_hash_table);
-+
-+  return changed;
-+}
-+\f
-+/*  Here we provide the things required to do store motion towards
-+    the exit. In order for this to be effective, gcse also needed to
-+    be taught how to move a load when it is kill only by a store to itself.
-+
-+          int i;
-+          float a[10];
-+
-+          void foo(float scale)
-+          {
-+            for (i=0; i<10; i++)
-+              a[i] *= scale;
-+          }
-+
-+    'i' is both loaded and stored to in the loop. Normally, gcse cannot move
-+    the load out since its live around the loop, and stored at the bottom
-+    of the loop.
-+
-+      The 'Load Motion' referred to and implemented in this file is
-+    an enhancement to gcse which when using edge based lcm, recognizes
-+    this situation and allows gcse to move the load out of the loop.
-+
-+      Once gcse has hoisted the load, store motion can then push this
-+    load towards the exit, and we end up with no loads or stores of 'i'
-+    in the loop.  */
-+
-+/* This will search the ldst list for a matching expression. If it
-+   doesn't find one, we create one and initialize it.  */
-+
-+static struct ls_expr *
-+ldst_entry (x)
-+     rtx x;
-+{
-+  struct ls_expr * ptr;
-+
-+  for (ptr = first_ls_expr(); ptr != NULL; ptr = next_ls_expr (ptr))
-+    if (expr_equiv_p (ptr->pattern, x))
-+      break;
-+
-+  if (!ptr)
-+    {
-+      ptr = (struct ls_expr *) xmalloc (sizeof (struct ls_expr));
-+
-+      ptr->next         = pre_ldst_mems;
-+      ptr->expr         = NULL;
-+      ptr->pattern      = x;
-+      ptr->loads        = NULL_RTX;
-+      ptr->stores       = NULL_RTX;
-+      ptr->reaching_reg = NULL_RTX;
-+      ptr->invalid      = 0;
-+      ptr->index        = 0;
-+      ptr->hash_index   = 0;
-+      pre_ldst_mems     = ptr;
-+    }
-+
-+  return ptr;
-+}
-+
-+/* Free up an individual ldst entry.  */
-+
-+static void
-+free_ldst_entry (ptr)
-+     struct ls_expr * ptr;
-+{
-+  free_INSN_LIST_list (& ptr->loads);
-+  free_INSN_LIST_list (& ptr->stores);
-+
-+  free (ptr);
-+}
-+
-+/* Free up all memory associated with the ldst list.  */
-+
-+static void
-+free_ldst_mems ()
-+{
-+  while (pre_ldst_mems)
-+    {
-+      struct ls_expr * tmp = pre_ldst_mems;
-+
-+      pre_ldst_mems = pre_ldst_mems->next;
-+
-+      free_ldst_entry (tmp);
-+    }
-+
-+  pre_ldst_mems = NULL;
-+}
-+
-+/* Dump debugging info about the ldst list.  */
-+
-+static void
-+print_ldst_list (file)
-+     FILE * file;
-+{
-+  struct ls_expr * ptr;
-+
-+  fprintf (file, "LDST list: \n");
-+
-+  for (ptr = first_ls_expr(); ptr != NULL; ptr = next_ls_expr (ptr))
-+    {
-+      fprintf (file, "  Pattern (%3d): ", ptr->index);
-+
-+      print_rtl (file, ptr->pattern);
-+
-+      fprintf (file, "\n       Loads : ");
-+
-+      if (ptr->loads)
-+      print_rtl (file, ptr->loads);
-+      else
-+      fprintf (file, "(nil)");
-+
-+      fprintf (file, "\n      Stores : ");
-+
-+      if (ptr->stores)
-+      print_rtl (file, ptr->stores);
-+      else
-+      fprintf (file, "(nil)");
-+
-+      fprintf (file, "\n\n");
-+    }
-+
-+  fprintf (file, "\n");
-+}
-+
-+/* Returns 1 if X is in the list of ldst only expressions.  */
-+
-+static struct ls_expr *
-+find_rtx_in_ldst (x)
-+     rtx x;
-+{
-+  struct ls_expr * ptr;
-+
-+  for (ptr = pre_ldst_mems; ptr != NULL; ptr = ptr->next)
-+    if (expr_equiv_p (ptr->pattern, x) && ! ptr->invalid)
-+      return ptr;
-+
-+  return NULL;
-+}
-+
-+/* Assign each element of the list of mems a monotonically increasing value.  */
-+
-+static int
-+enumerate_ldsts ()
-+{
-+  struct ls_expr * ptr;
-+  int n = 0;
-+
-+  for (ptr = pre_ldst_mems; ptr != NULL; ptr = ptr->next)
-+    ptr->index = n++;
-+
-+  return n;
-+}
-+
-+/* Return first item in the list.  */
-+
-+static inline struct ls_expr *
-+first_ls_expr ()
-+{
-+  return pre_ldst_mems;
-+}
-+
-+/* Return the next item in ther list after the specified one.  */
-+
-+static inline struct ls_expr *
-+next_ls_expr (ptr)
-+     struct ls_expr * ptr;
-+{
-+  return ptr->next;
-+}
-+\f
-+/* Load Motion for loads which only kill themselves.  */
-+
-+/* Return true if x is a simple MEM operation, with no registers or
-+   side effects. These are the types of loads we consider for the
-+   ld_motion list, otherwise we let the usual aliasing take care of it.  */
-+
-+static int
-+simple_mem (x)
-+     rtx x;
-+{
-+  if (GET_CODE (x) != MEM)
-+    return 0;
-+
-+  if (MEM_VOLATILE_P (x))
-+    return 0;
-+
-+  if (GET_MODE (x) == BLKmode)
-+    return 0;
-+
-+  if (!rtx_varies_p (XEXP (x, 0), 0))
-+    return 1;
-+
-+  return 0;
-+}
-+
-+/* Make sure there isn't a buried reference in this pattern anywhere.
-+   If there is, invalidate the entry for it since we're not capable
-+   of fixing it up just yet.. We have to be sure we know about ALL
-+   loads since the aliasing code will allow all entries in the
-+   ld_motion list to not-alias itself.  If we miss a load, we will get
-+   the wrong value since gcse might common it and we won't know to
-+   fix it up.  */
-+
-+static void
-+invalidate_any_buried_refs (x)
-+     rtx x;
-+{
-+  const char * fmt;
-+  int i, j;
-+  struct ls_expr * ptr;
-+
-+  /* Invalidate it in the list.  */
-+  if (GET_CODE (x) == MEM && simple_mem (x))
-+    {
-+      ptr = ldst_entry (x);
-+      ptr->invalid = 1;
-+    }
-+
-+  /* Recursively process the insn.  */
-+  fmt = GET_RTX_FORMAT (GET_CODE (x));
-+
-+  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
-+    {
-+      if (fmt[i] == 'e')
-+      invalidate_any_buried_refs (XEXP (x, i));
-+      else if (fmt[i] == 'E')
-+      for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-+        invalidate_any_buried_refs (XVECEXP (x, i, j));
-+    }
-+}
-+
-+/* Find all the 'simple' MEMs which are used in LOADs and STORES. Simple
-+   being defined as MEM loads and stores to symbols, with no
-+   side effects and no registers in the expression. If there are any
-+   uses/defs which don't match this criteria, it is invalidated and
-+   trimmed out later.  */
-+
-+static void
-+compute_ld_motion_mems ()
-+{
-+  struct ls_expr * ptr;
-+  basic_block bb;
-+  rtx insn;
-+
-+  pre_ldst_mems = NULL;
-+
-+  FOR_EACH_BB (bb)
-+    {
-+      for (insn = bb->head;
-+         insn && insn != NEXT_INSN (bb->end);
-+         insn = NEXT_INSN (insn))
-+      {
-+        if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
-+          {
-+            if (GET_CODE (PATTERN (insn)) == SET)
-+              {
-+                rtx src = SET_SRC (PATTERN (insn));
-+                rtx dest = SET_DEST (PATTERN (insn));
-+
-+                /* Check for a simple LOAD...  */
-+                if (GET_CODE (src) == MEM && simple_mem (src))
-+                  {
-+                    ptr = ldst_entry (src);
-+                    if (GET_CODE (dest) == REG)
-+                      ptr->loads = alloc_INSN_LIST (insn, ptr->loads);
-+                    else
-+                      ptr->invalid = 1;
-+                  }
-+                else
-+                  {
-+                    /* Make sure there isn't a buried load somewhere.  */
-+                    invalidate_any_buried_refs (src);
-+                  }
-+
-+                /* Check for stores. Don't worry about aliased ones, they
-+                   will block any movement we might do later. We only care
-+                   about this exact pattern since those are the only
-+                   circumstance that we will ignore the aliasing info.  */
-+                if (GET_CODE (dest) == MEM && simple_mem (dest))
-+                  {
-+                    ptr = ldst_entry (dest);
-+
-+                    if (GET_CODE (src) != MEM
-+                        && GET_CODE (src) != ASM_OPERANDS)
-+                      ptr->stores = alloc_INSN_LIST (insn, ptr->stores);
-+                    else
-+                      ptr->invalid = 1;
-+                  }
-+              }
-+            else
-+              invalidate_any_buried_refs (PATTERN (insn));
-+          }
-+      }
-+    }
-+}
-+
-+/* Remove any references that have been either invalidated or are not in the
-+   expression list for pre gcse.  */
-+
-+static void
-+trim_ld_motion_mems ()
-+{
-+  struct ls_expr * last = NULL;
-+  struct ls_expr * ptr = first_ls_expr ();
-+
-+  while (ptr != NULL)
-+    {
-+      int del = ptr->invalid;
-+      struct expr * expr = NULL;
-+
-+      /* Delete if entry has been made invalid.  */
-+      if (!del)
-+      {
-+        unsigned int i;
-+
-+        del = 1;
-+        /* Delete if we cannot find this mem in the expression list.  */
-+        for (i = 0; i < expr_hash_table.size && del; i++)
-+          {
-+            for (expr = expr_hash_table.table[i];
-+                 expr != NULL;
-+                 expr = expr->next_same_hash)
-+              if (expr_equiv_p (expr->expr, ptr->pattern))
-+                {
-+                  del = 0;
-+                  break;
-+                }
-+          }
-+      }
-+
-+      if (del)
-+      {
-+        if (last != NULL)
-+          {
-+            last->next = ptr->next;
-+            free_ldst_entry (ptr);
-+            ptr = last->next;
-+          }
-+        else
-+          {
-+            pre_ldst_mems = pre_ldst_mems->next;
-+            free_ldst_entry (ptr);
-+            ptr = pre_ldst_mems;
-+          }
-+      }
-+      else
-+      {
-+        /* Set the expression field if we are keeping it.  */
-+        last = ptr;
-+        ptr->expr = expr;
-+        ptr = ptr->next;
-+      }
-+    }
-+
-+  /* Show the world what we've found.  */
-+  if (gcse_file && pre_ldst_mems != NULL)
-+    print_ldst_list (gcse_file);
-+}
-+
-+/* This routine will take an expression which we are replacing with
-+   a reaching register, and update any stores that are needed if
-+   that expression is in the ld_motion list.  Stores are updated by
-+   copying their SRC to the reaching register, and then storeing
-+   the reaching register into the store location. These keeps the
-+   correct value in the reaching register for the loads.  */
-+
-+static void
-+update_ld_motion_stores (expr)
-+     struct expr * expr;
-+{
-+  struct ls_expr * mem_ptr;
-+
-+  if ((mem_ptr = find_rtx_in_ldst (expr->expr)))
-+    {
-+      /* We can try to find just the REACHED stores, but is shouldn't
-+       matter to set the reaching reg everywhere...  some might be
-+       dead and should be eliminated later.  */
-+
-+      /* We replace  SET mem = expr   with
-+         SET reg = expr
-+         SET mem = reg , where reg is the
-+         reaching reg used in the load.  */
-+      rtx list = mem_ptr->stores;
-+
-+      for ( ; list != NULL_RTX; list = XEXP (list, 1))
-+      {
-+        rtx insn = XEXP (list, 0);
-+        rtx pat = PATTERN (insn);
-+        rtx src = SET_SRC (pat);
-+        rtx reg = expr->reaching_reg;
-+        rtx copy, new;
-+
-+        /* If we've already copied it, continue.  */
-+        if (expr->reaching_reg == src)
-+          continue;
-+
-+        if (gcse_file)
-+          {
-+            fprintf (gcse_file, "PRE:  store updated with reaching reg ");
-+            print_rtl (gcse_file, expr->reaching_reg);
-+            fprintf (gcse_file, ":\n  ");
-+            print_inline_rtx (gcse_file, insn, 8);
-+            fprintf (gcse_file, "\n");
-+          }
-+
-+        copy = gen_move_insn ( reg, SET_SRC (pat));
-+        new = emit_insn_before (copy, insn);
-+        record_one_set (REGNO (reg), new);
-+        SET_SRC (pat) = reg;
-+
-+        /* un-recognize this pattern since it's probably different now.  */
-+        INSN_CODE (insn) = -1;
-+        gcse_create_count++;
-+      }
-+    }
-+}
-+\f
-+/* Store motion code.  */
-+
-+/* This is used to communicate the target bitvector we want to use in the
-+   reg_set_info routine when called via the note_stores mechanism.  */
-+static sbitmap * regvec;
-+
-+/* Used in computing the reverse edge graph bit vectors.  */
-+static sbitmap * st_antloc;
-+
-+/* Global holding the number of store expressions we are dealing with.  */
-+static int num_stores;
-+
-+/* Checks to set if we need to mark a register set. Called from note_stores.  */
-+
-+static void
-+reg_set_info (dest, setter, data)
-+     rtx dest, setter ATTRIBUTE_UNUSED;
-+     void * data ATTRIBUTE_UNUSED;
-+{
-+  if (GET_CODE (dest) == SUBREG)
-+    dest = SUBREG_REG (dest);
-+
-+  if (GET_CODE (dest) == REG)
-+    SET_BIT (*regvec, REGNO (dest));
-+}
-+
-+/* Return nonzero if the register operands of expression X are killed
-+   anywhere in basic block BB.  */
-+
-+static int
-+store_ops_ok (x, bb)
-+     rtx x;
-+     basic_block bb;
-+{
-+  int i;
-+  enum rtx_code code;
-+  const char * fmt;
-+
-+  /* Repeat is used to turn tail-recursion into iteration.  */
-+ repeat:
-+
-+  if (x == 0)
-+    return 1;
-+
-+  code = GET_CODE (x);
-+  switch (code)
-+    {
-+    case REG:
-+      /* If a reg has changed after us in this
-+         block, the operand has been killed.  */
-+      return TEST_BIT (reg_set_in_block[bb->index], REGNO (x));
-+
-+    case MEM:
-+      x = XEXP (x, 0);
-+      goto repeat;
-+
-+    case PRE_DEC:
-+    case PRE_INC:
-+    case POST_DEC:
-+    case POST_INC:
-+      return 0;
-+
-+    case PC:
-+    case CC0: /*FIXME*/
-+    case CONST:
-+    case CONST_INT:
-+    case CONST_DOUBLE:
-+    case CONST_VECTOR:
-+    case SYMBOL_REF:
-+    case LABEL_REF:
-+    case ADDR_VEC:
-+    case ADDR_DIFF_VEC:
-+      return 1;
-+
-+    default:
-+      break;
-+    }
-+
-+  i = GET_RTX_LENGTH (code) - 1;
-+  fmt = GET_RTX_FORMAT (code);
-+
-+  for (; i >= 0; i--)
-+    {
-+      if (fmt[i] == 'e')
-+      {
-+        rtx tem = XEXP (x, i);
-+
-+        /* If we are about to do the last recursive call
-+           needed at this level, change it into iteration.
-+           This function is called enough to be worth it.  */
-+        if (i == 0)
-+          {
-+            x = tem;
-+            goto repeat;
-+          }
-+
-+        if (! store_ops_ok (tem, bb))
-+          return 0;
-+      }
-+      else if (fmt[i] == 'E')
-+      {
-+        int j;
-+
-+        for (j = 0; j < XVECLEN (x, i); j++)
-+          {
-+            if (! store_ops_ok (XVECEXP (x, i, j), bb))
-+              return 0;
-+          }
-+      }
-+    }
-+
-+  return 1;
-+}
-+
-+/* Determine whether insn is MEM store pattern that we will consider moving.  */
-+
-+static void
-+find_moveable_store (insn)
-+     rtx insn;
-+{
-+  struct ls_expr * ptr;
-+  rtx dest = PATTERN (insn);
-+
-+  if (GET_CODE (dest) != SET
-+      || GET_CODE (SET_SRC (dest)) == ASM_OPERANDS)
-+    return;
-+
-+  dest = SET_DEST (dest);
-+
-+  if (GET_CODE (dest) != MEM || MEM_VOLATILE_P (dest)
-+      || GET_MODE (dest) == BLKmode)
-+    return;
-+
-+  if (GET_CODE (XEXP (dest, 0)) != SYMBOL_REF)
-+      return;
-+
-+  if (rtx_varies_p (XEXP (dest, 0), 0))
-+    return;
-+
-+  ptr = ldst_entry (dest);
-+  ptr->stores = alloc_INSN_LIST (insn, ptr->stores);
-+}
-+
-+/* Perform store motion. Much like gcse, except we move expressions the
-+   other way by looking at the flowgraph in reverse.  */
-+
-+static int
-+compute_store_table ()
-+{
-+  int ret;
-+  basic_block bb;
-+  unsigned regno;
-+  rtx insn, pat;
-+
-+  max_gcse_regno = max_reg_num ();
-+
-+  reg_set_in_block = (sbitmap *) sbitmap_vector_alloc (last_basic_block,
-+                                                     max_gcse_regno);
-+  sbitmap_vector_zero (reg_set_in_block, last_basic_block);
-+  pre_ldst_mems = 0;
-+
-+  /* Find all the stores we care about.  */
-+  FOR_EACH_BB (bb)
-+    {
-+      regvec = & (reg_set_in_block[bb->index]);
-+      for (insn = bb->end;
-+         insn && insn != PREV_INSN (bb->end);
-+         insn = PREV_INSN (insn))
-+      {
-+        /* Ignore anything that is not a normal insn.  */
-+        if (! INSN_P (insn))
-+          continue;
-+
-+        if (GET_CODE (insn) == CALL_INSN)
-+          {
-+            bool clobbers_all = false;
-+#ifdef NON_SAVING_SETJMP
-+            if (NON_SAVING_SETJMP
-+                && find_reg_note (insn, REG_SETJMP, NULL_RTX))
-+              clobbers_all = true;
-+#endif
-+
-+            for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
-+              if (clobbers_all
-+                  || TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
-+                SET_BIT (reg_set_in_block[bb->index], regno);
-+          }
-+
-+        pat = PATTERN (insn);
-+        note_stores (pat, reg_set_info, NULL);
-+
-+        /* Now that we've marked regs, look for stores.  */
-+        if (GET_CODE (pat) == SET)
-+          find_moveable_store (insn);
-+      }
-+    }
-+
-+  ret = enumerate_ldsts ();
-+
-+  if (gcse_file)
-+    {
-+      fprintf (gcse_file, "Store Motion Expressions.\n");
-+      print_ldst_list (gcse_file);
-+    }
-+
-+  return ret;
-+}
-+
-+/* Check to see if the load X is aliased with STORE_PATTERN.  */
-+
-+static int
-+load_kills_store (x, store_pattern)
-+     rtx x, store_pattern;
-+{
-+  if (true_dependence (x, GET_MODE (x), store_pattern, rtx_addr_varies_p))
-+    return 1;
-+  return 0;
-+}
-+
-+/* Go through the entire insn X, looking for any loads which might alias
-+   STORE_PATTERN.  Return 1 if found.  */
-+
-+static int
-+find_loads (x, store_pattern)
-+     rtx x, store_pattern;
-+{
-+  const char * fmt;
-+  int i, j;
-+  int ret = 0;
-+
-+  if (!x)
-+    return 0;
-+
-+  if (GET_CODE (x) == SET)
-+    x = SET_SRC (x);
-+
-+  if (GET_CODE (x) == MEM)
-+    {
-+      if (load_kills_store (x, store_pattern))
-+      return 1;
-+    }
-+
-+  /* Recursively process the insn.  */
-+  fmt = GET_RTX_FORMAT (GET_CODE (x));
-+
-+  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0 && !ret; i--)
-+    {
-+      if (fmt[i] == 'e')
-+      ret |= find_loads (XEXP (x, i), store_pattern);
-+      else if (fmt[i] == 'E')
-+      for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-+        ret |= find_loads (XVECEXP (x, i, j), store_pattern);
-+    }
-+  return ret;
-+}
-+
-+/* Check if INSN kills the store pattern X (is aliased with it).
-+   Return 1 if it it does.  */
-+
-+static int
-+store_killed_in_insn (x, insn)
-+     rtx x, insn;
-+{
-+  if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
-+    return 0;
-+
-+  if (GET_CODE (insn) == CALL_INSN)
-+    {
-+      /* A normal or pure call might read from pattern,
-+       but a const call will not.  */
-+      return ! CONST_OR_PURE_CALL_P (insn) || pure_call_p (insn);
-+    }
-+
-+  if (GET_CODE (PATTERN (insn)) == SET)
-+    {
-+      rtx pat = PATTERN (insn);
-+      /* Check for memory stores to aliased objects.  */
-+      if (GET_CODE (SET_DEST (pat)) == MEM && !expr_equiv_p (SET_DEST (pat), x))
-+      /* pretend its a load and check for aliasing.  */
-+      if (find_loads (SET_DEST (pat), x))
-+        return 1;
-+      return find_loads (SET_SRC (pat), x);
-+    }
-+  else
-+    return find_loads (PATTERN (insn), x);
-+}
-+
-+/* Returns 1 if the expression X is loaded or clobbered on or after INSN
-+   within basic block BB.  */
-+
-+static int
-+store_killed_after (x, insn, bb)
-+     rtx x, insn;
-+     basic_block bb;
-+{
-+  rtx last = bb->end;
-+
-+  if (insn == last)
-+    return 0;
-+
-+  /* Check if the register operands of the store are OK in this block.
-+     Note that if registers are changed ANYWHERE in the block, we'll
-+     decide we can't move it, regardless of whether it changed above
-+     or below the store. This could be improved by checking the register
-+     operands while lookinng for aliasing in each insn.  */
-+  if (!store_ops_ok (XEXP (x, 0), bb))
-+    return 1;
-+
-+  for ( ; insn && insn != NEXT_INSN (last); insn = NEXT_INSN (insn))
-+    if (store_killed_in_insn (x, insn))
-+      return 1;
-+
-+  return 0;
-+}
-+
-+/* Returns 1 if the expression X is loaded or clobbered on or before INSN
-+   within basic block BB.  */
-+static int
-+store_killed_before (x, insn, bb)
-+     rtx x, insn;
-+     basic_block bb;
-+{
-+  rtx first = bb->head;
-+
-+  if (insn == first)
-+    return store_killed_in_insn (x, insn);
-+
-+  /* Check if the register operands of the store are OK in this block.
-+     Note that if registers are changed ANYWHERE in the block, we'll
-+     decide we can't move it, regardless of whether it changed above
-+     or below the store. This could be improved by checking the register
-+     operands while lookinng for aliasing in each insn.  */
-+  if (!store_ops_ok (XEXP (x, 0), bb))
-+    return 1;
-+
-+  for ( ; insn && insn != PREV_INSN (first); insn = PREV_INSN (insn))
-+    if (store_killed_in_insn (x, insn))
-+      return 1;
-+
-+  return 0;
-+}
-+
-+#define ANTIC_STORE_LIST(x)   ((x)->loads)
-+#define AVAIL_STORE_LIST(x)   ((x)->stores)
-+
-+/* Given the table of available store insns at the end of blocks,
-+   determine which ones are not killed by aliasing, and generate
-+   the appropriate vectors for gen and killed.  */
-+static void
-+build_store_vectors ()
-+{
-+  basic_block bb, b;
-+  rtx insn, st;
-+  struct ls_expr * ptr;
-+
-+  /* Build the gen_vector. This is any store in the table which is not killed
-+     by aliasing later in its block.  */
-+  ae_gen = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
-+  sbitmap_vector_zero (ae_gen, last_basic_block);
-+
-+  st_antloc = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
-+  sbitmap_vector_zero (st_antloc, last_basic_block);
-+
-+  for (ptr = first_ls_expr (); ptr != NULL; ptr = next_ls_expr (ptr))
-+    {
-+      /* Put all the stores into either the antic list, or the avail list,
-+       or both.  */
-+      rtx store_list = ptr->stores;
-+      ptr->stores = NULL_RTX;
-+
-+      for (st = store_list; st != NULL; st = XEXP (st, 1))
-+      {
-+        insn = XEXP (st, 0);
-+        bb = BLOCK_FOR_INSN (insn);
-+
-+        if (!store_killed_after (ptr->pattern, insn, bb))
-+          {
-+            /* If we've already seen an availale expression in this block,
-+               we can delete the one we saw already (It occurs earlier in
-+               the block), and replace it with this one). We'll copy the
-+               old SRC expression to an unused register in case there
-+               are any side effects.  */
-+            if (TEST_BIT (ae_gen[bb->index], ptr->index))
-+              {
-+                /* Find previous store.  */
-+                rtx st;
-+                for (st = AVAIL_STORE_LIST (ptr); st ; st = XEXP (st, 1))
-+                  if (BLOCK_FOR_INSN (XEXP (st, 0)) == bb)
-+                    break;
-+                if (st)
-+                  {
-+                    rtx r = gen_reg_rtx (GET_MODE (ptr->pattern));
-+                    if (gcse_file)
-+                      fprintf (gcse_file, "Removing redundant store:\n");
-+                    replace_store_insn (r, XEXP (st, 0), bb);
-+                    XEXP (st, 0) = insn;
-+                    continue;
-+                  }
-+              }
-+            SET_BIT (ae_gen[bb->index], ptr->index);
-+            AVAIL_STORE_LIST (ptr) = alloc_INSN_LIST (insn,
-+                                                      AVAIL_STORE_LIST (ptr));
-+          }
-+
-+        if (!store_killed_before (ptr->pattern, insn, bb))
-+          {
-+            SET_BIT (st_antloc[BLOCK_NUM (insn)], ptr->index);
-+            ANTIC_STORE_LIST (ptr) = alloc_INSN_LIST (insn,
-+                                                      ANTIC_STORE_LIST (ptr));
-+          }
-+      }
-+
-+      /* Free the original list of store insns.  */
-+      free_INSN_LIST_list (&store_list);
-+    }
-+
-+  ae_kill = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
-+  sbitmap_vector_zero (ae_kill, last_basic_block);
-+
-+  transp = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
-+  sbitmap_vector_zero (transp, last_basic_block);
-+
-+  for (ptr = first_ls_expr (); ptr != NULL; ptr = next_ls_expr (ptr))
-+    FOR_EACH_BB (b)
-+      {
-+      if (store_killed_after (ptr->pattern, b->head, b))
-+        {
-+          /* The anticipatable expression is not killed if it's gen'd.  */
-+          /*
-+            We leave this check out for now. If we have a code sequence
-+            in a block which looks like:
-+                      ST MEMa = x
-+                      L     y = MEMa
-+                      ST MEMa = z
-+            We should flag this as having an ANTIC expression, NOT
-+            transparent, NOT killed, and AVAIL.
-+            Unfortunately, since we haven't re-written all loads to
-+            use the reaching reg, we'll end up doing an incorrect
-+            Load in the middle here if we push the store down. It happens in
-+                  gcc.c-torture/execute/960311-1.c with -O3
-+            If we always kill it in this case, we'll sometimes do
-+            uneccessary work, but it shouldn't actually hurt anything.
-+          if (!TEST_BIT (ae_gen[b], ptr->index)).  */
-+          SET_BIT (ae_kill[b->index], ptr->index);
-+        }
-+      else
-+        SET_BIT (transp[b->index], ptr->index);
-+      }
-+
-+  /* Any block with no exits calls some non-returning function, so
-+     we better mark the store killed here, or we might not store to
-+     it at all.  If we knew it was abort, we wouldn't have to store,
-+     but we don't know that for sure.  */
-+  if (gcse_file)
-+    {
-+      fprintf (gcse_file, "ST_avail and ST_antic (shown under loads..)\n");
-+      print_ldst_list (gcse_file);
-+      dump_sbitmap_vector (gcse_file, "st_antloc", "", st_antloc, last_basic_block);
-+      dump_sbitmap_vector (gcse_file, "st_kill", "", ae_kill, last_basic_block);
-+      dump_sbitmap_vector (gcse_file, "Transpt", "", transp, last_basic_block);
-+      dump_sbitmap_vector (gcse_file, "st_avloc", "", ae_gen, last_basic_block);
-+    }
-+}
-+
-+/* Insert an instruction at the begining of a basic block, and update
-+   the BLOCK_HEAD if needed.  */
-+
-+static void
-+insert_insn_start_bb (insn, bb)
-+     rtx insn;
-+     basic_block bb;
-+{
-+  /* Insert at start of successor block.  */
-+  rtx prev = PREV_INSN (bb->head);
-+  rtx before = bb->head;
-+  while (before != 0)
-+    {
-+      if (GET_CODE (before) != CODE_LABEL
-+        && (GET_CODE (before) != NOTE
-+            || NOTE_LINE_NUMBER (before) != NOTE_INSN_BASIC_BLOCK))
-+      break;
-+      prev = before;
-+      if (prev == bb->end)
-+      break;
-+      before = NEXT_INSN (before);
-+    }
-+
-+  insn = emit_insn_after (insn, prev);
-+
-+  if (gcse_file)
-+    {
-+      fprintf (gcse_file, "STORE_MOTION  insert store at start of BB %d:\n",
-+             bb->index);
-+      print_inline_rtx (gcse_file, insn, 6);
-+      fprintf (gcse_file, "\n");
-+    }
-+}
-+
-+/* This routine will insert a store on an edge. EXPR is the ldst entry for
-+   the memory reference, and E is the edge to insert it on.  Returns nonzero
-+   if an edge insertion was performed.  */
-+
-+static int
-+insert_store (expr, e)
-+     struct ls_expr * expr;
-+     edge e;
-+{
-+  rtx reg, insn;
-+  basic_block bb;
-+  edge tmp;
-+
-+  /* We did all the deleted before this insert, so if we didn't delete a
-+     store, then we haven't set the reaching reg yet either.  */
-+  if (expr->reaching_reg == NULL_RTX)
-+    return 0;
-+
-+  reg = expr->reaching_reg;
-+  insn = gen_move_insn (expr->pattern, reg);
-+
-+  /* If we are inserting this expression on ALL predecessor edges of a BB,
-+     insert it at the start of the BB, and reset the insert bits on the other
-+     edges so we don't try to insert it on the other edges.  */
-+  bb = e->dest;
-+  for (tmp = e->dest->pred; tmp ; tmp = tmp->pred_next)
-+    {
-+      int index = EDGE_INDEX (edge_list, tmp->src, tmp->dest);
-+      if (index == EDGE_INDEX_NO_EDGE)
-+      abort ();
-+      if (! TEST_BIT (pre_insert_map[index], expr->index))
-+      break;
-+    }
-+
-+  /* If tmp is NULL, we found an insertion on every edge, blank the
-+     insertion vector for these edges, and insert at the start of the BB.  */
-+  if (!tmp && bb != EXIT_BLOCK_PTR)
-+    {
-+      for (tmp = e->dest->pred; tmp ; tmp = tmp->pred_next)
-+      {
-+        int index = EDGE_INDEX (edge_list, tmp->src, tmp->dest);
-+        RESET_BIT (pre_insert_map[index], expr->index);
-+      }
-+      insert_insn_start_bb (insn, bb);
-+      return 0;
-+    }
-+
-+  /* We can't insert on this edge, so we'll insert at the head of the
-+     successors block.  See Morgan, sec 10.5.  */
-+  if ((e->flags & EDGE_ABNORMAL) == EDGE_ABNORMAL)
-+    {
-+      insert_insn_start_bb (insn, bb);
-+      return 0;
-+    }
-+
-+  insert_insn_on_edge (insn, e);
-+
-+  if (gcse_file)
-+    {
-+      fprintf (gcse_file, "STORE_MOTION  insert insn on edge (%d, %d):\n",
-+             e->src->index, e->dest->index);
-+      print_inline_rtx (gcse_file, insn, 6);
-+      fprintf (gcse_file, "\n");
-+    }
-+
-+  return 1;
-+}
-+
-+/* This routine will replace a store with a SET to a specified register.  */
-+
-+static void
-+replace_store_insn (reg, del, bb)
-+     rtx reg, del;
-+     basic_block bb;
-+{
-+  rtx insn;
-+
-+  insn = gen_move_insn (reg, SET_SRC (PATTERN (del)));
-+  insn = emit_insn_after (insn, del);
-+
-+  if (gcse_file)
-+    {
-+      fprintf (gcse_file,
-+             "STORE_MOTION  delete insn in BB %d:\n      ", bb->index);
-+      print_inline_rtx (gcse_file, del, 6);
-+      fprintf (gcse_file, "\nSTORE MOTION  replaced with insn:\n      ");
-+      print_inline_rtx (gcse_file, insn, 6);
-+      fprintf (gcse_file, "\n");
-+    }
-+
-+  delete_insn (del);
-+}
-+
-+
-+/* Delete a store, but copy the value that would have been stored into
-+   the reaching_reg for later storing.  */
-+
-+static void
-+delete_store (expr, bb)
-+     struct ls_expr * expr;
-+     basic_block bb;
-+{
-+  rtx reg, i, del;
-+
-+  if (expr->reaching_reg == NULL_RTX)
-+    expr->reaching_reg = gen_reg_rtx (GET_MODE (expr->pattern));
-+
-+
-+  /* If there is more than 1 store, the earlier ones will be dead,
-+     but it doesn't hurt to replace them here.  */
-+  reg = expr->reaching_reg;
-+
-+  for (i = AVAIL_STORE_LIST (expr); i; i = XEXP (i, 1))
-+    {
-+      del = XEXP (i, 0);
-+      if (BLOCK_FOR_INSN (del) == bb)
-+      {
-+        /* We know there is only one since we deleted redundant
-+           ones during the available computation.  */
-+        replace_store_insn (reg, del, bb);
-+        break;
-+      }
-+    }
-+}
-+
-+/* Free memory used by store motion.  */
-+
-+static void
-+free_store_memory ()
-+{
-+  free_ldst_mems ();
-+
-+  if (ae_gen)
-+    sbitmap_vector_free (ae_gen);
-+  if (ae_kill)
-+    sbitmap_vector_free (ae_kill);
-+  if (transp)
-+    sbitmap_vector_free (transp);
-+  if (st_antloc)
-+    sbitmap_vector_free (st_antloc);
-+  if (pre_insert_map)
-+    sbitmap_vector_free (pre_insert_map);
-+  if (pre_delete_map)
-+    sbitmap_vector_free (pre_delete_map);
-+  if (reg_set_in_block)
-+    sbitmap_vector_free (reg_set_in_block);
-+
-+  ae_gen = ae_kill = transp = st_antloc = NULL;
-+  pre_insert_map = pre_delete_map = reg_set_in_block = NULL;
-+}
-+
-+/* Perform store motion. Much like gcse, except we move expressions the
-+   other way by looking at the flowgraph in reverse.  */
-+
-+static void
-+store_motion ()
-+{
-+  basic_block bb;
-+  int x;
-+  struct ls_expr * ptr;
-+  int update_flow = 0;
-+
-+  if (gcse_file)
-+    {
-+      fprintf (gcse_file, "before store motion\n");
-+      print_rtl (gcse_file, get_insns ());
-+    }
-+
-+
-+  init_alias_analysis ();
-+
-+  /* Find all the stores that are live to the end of their block.  */
-+  num_stores = compute_store_table ();
-+  if (num_stores == 0)
-+    {
-+      sbitmap_vector_free (reg_set_in_block);
-+      end_alias_analysis ();
-+      return;
-+    }
-+
-+  /* Now compute whats actually available to move.  */
-+  add_noreturn_fake_exit_edges ();
-+  build_store_vectors ();
-+
-+  edge_list = pre_edge_rev_lcm (gcse_file, num_stores, transp, ae_gen,
-+                              st_antloc, ae_kill, &pre_insert_map,
-+                              &pre_delete_map);
-+
-+  /* Now we want to insert the new stores which are going to be needed.  */
-+  for (ptr = first_ls_expr (); ptr != NULL; ptr = next_ls_expr (ptr))
-+    {
-+      FOR_EACH_BB (bb)
-+      if (TEST_BIT (pre_delete_map[bb->index], ptr->index))
-+        delete_store (ptr, bb);
-+
-+      for (x = 0; x < NUM_EDGES (edge_list); x++)
-+      if (TEST_BIT (pre_insert_map[x], ptr->index))
-+        update_flow |= insert_store (ptr, INDEX_EDGE (edge_list, x));
-+    }
-+
-+  if (update_flow)
-+    commit_edge_insertions ();
-+
-+  free_store_memory ();
-+  free_edge_list (edge_list);
-+  remove_fake_edges ();
-+  end_alias_analysis ();
-+}
-+
-+#include "gt-gcse.h"
-diff -ruN gcc-3.3.1/gcc/integrate.c gcc-3.3.1.pp/gcc/integrate.c
---- gcc-3.3.1/gcc/integrate.c  2003-07-15 01:05:43.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/integrate.c       2003-09-05 11:58:59.000000000 +0000
-@@ -401,6 +401,10 @@
-   /* These args would always appear unused, if not for this.  */
-   TREE_USED (copy) = 1;
-+  /* The inlined variable is marked as INLINE not to sweep by propolice */
-+  if (flag_propolice_protection && TREE_CODE (copy) == VAR_DECL)
-+    DECL_INLINE (copy) = 1;
-+
-   /* Set the context for the new declaration.  */
-   if (!DECL_CONTEXT (decl))
-     /* Globals stay global.  */
-@@ -1965,6 +1969,10 @@
-             seq = get_insns ();
-             end_sequence ();
-+#ifdef FRAME_GROWS_DOWNWARD
-+            if (flag_propolice_protection && GET_CODE (seq) == SET)
-+              RTX_INTEGRATED_P (SET_SRC (seq)) = 1;
-+#endif
-             emit_insn_after (seq, map->insns_at_start);
-             return temp;
-           }
-diff -ruN gcc-3.3.1/gcc/integrate.c.orig gcc-3.3.1.pp/gcc/integrate.c.orig
---- gcc-3.3.1/gcc/integrate.c.orig     1970-01-01 00:00:00.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/integrate.c.orig  2003-07-15 01:05:43.000000000 +0000
-@@ -0,0 +1,3213 @@
-+/* Procedure integration for GCC.
-+   Copyright (C) 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998,
-+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
-+   Contributed by Michael Tiemann (tiemann@cygnus.com)
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify it under
-+the terms of the GNU General Public License as published by the Free
-+Software Foundation; either version 2, or (at your option) any later
-+version.
-+
-+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-+WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING.  If not, write to the Free
-+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-+02111-1307, USA.  */
-+
-+#include "config.h"
-+#include "system.h"
-+
-+#include "rtl.h"
-+#include "tree.h"
-+#include "tm_p.h"
-+#include "regs.h"
-+#include "flags.h"
-+#include "debug.h"
-+#include "insn-config.h"
-+#include "expr.h"
-+#include "output.h"
-+#include "recog.h"
-+#include "integrate.h"
-+#include "real.h"
-+#include "except.h"
-+#include "function.h"
-+#include "toplev.h"
-+#include "intl.h"
-+#include "loop.h"
-+#include "params.h"
-+#include "ggc.h"
-+#include "target.h"
-+#include "langhooks.h"
-+
-+/* Similar, but round to the next highest integer that meets the
-+   alignment.  */
-+#define CEIL_ROUND(VALUE,ALIGN)       (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))
-+
-+/* Default max number of insns a function can have and still be inline.
-+   This is overridden on RISC machines.  */
-+#ifndef INTEGRATE_THRESHOLD
-+/* Inlining small functions might save more space then not inlining at
-+   all.  Assume 1 instruction for the call and 1.5 insns per argument.  */
-+#define INTEGRATE_THRESHOLD(DECL) \
-+  (optimize_size \
-+   ? (1 + (3 * list_length (DECL_ARGUMENTS (DECL))) / 2) \
-+   : (8 * (8 + list_length (DECL_ARGUMENTS (DECL)))))
-+#endif
-+\f
-+
-+/* Private type used by {get/has}_func_hard_reg_initial_val.  */
-+typedef struct initial_value_pair GTY(()) {
-+  rtx hard_reg;
-+  rtx pseudo;
-+} initial_value_pair;
-+typedef struct initial_value_struct GTY(()) {
-+  int num_entries;
-+  int max_entries;
-+  initial_value_pair * GTY ((length ("%h.num_entries"))) entries;
-+} initial_value_struct;
-+
-+static void setup_initial_hard_reg_value_integration PARAMS ((struct function *, struct inline_remap *));
-+
-+static rtvec initialize_for_inline    PARAMS ((tree));
-+static void note_modified_parmregs    PARAMS ((rtx, rtx, void *));
-+static void integrate_parm_decls      PARAMS ((tree, struct inline_remap *,
-+                                               rtvec));
-+static tree integrate_decl_tree               PARAMS ((tree,
-+                                               struct inline_remap *));
-+static void subst_constants           PARAMS ((rtx *, rtx,
-+                                               struct inline_remap *, int));
-+static void set_block_origin_self     PARAMS ((tree));
-+static void set_block_abstract_flags  PARAMS ((tree, int));
-+static void process_reg_param         PARAMS ((struct inline_remap *, rtx,
-+                                               rtx));
-+void set_decl_abstract_flags          PARAMS ((tree, int));
-+static void mark_stores                 PARAMS ((rtx, rtx, void *));
-+static void save_parm_insns           PARAMS ((rtx, rtx));
-+static void copy_insn_list              PARAMS ((rtx, struct inline_remap *,
-+                                               rtx));
-+static void copy_insn_notes           PARAMS ((rtx, struct inline_remap *,
-+                                               int));
-+static int compare_blocks               PARAMS ((const PTR, const PTR));
-+static int find_block                   PARAMS ((const PTR, const PTR));
-+
-+/* Used by copy_rtx_and_substitute; this indicates whether the function is
-+   called for the purpose of inlining or some other purpose (i.e. loop
-+   unrolling).  This affects how constant pool references are handled.
-+   This variable contains the FUNCTION_DECL for the inlined function.  */
-+static struct function *inlining = 0;
-+\f
-+/* Returns the Ith entry in the label_map contained in MAP.  If the
-+   Ith entry has not yet been set, return a fresh label.  This function
-+   performs a lazy initialization of label_map, thereby avoiding huge memory
-+   explosions when the label_map gets very large.  */
-+
-+rtx
-+get_label_from_map (map, i)
-+     struct inline_remap *map;
-+     int i;
-+{
-+  rtx x = map->label_map[i];
-+
-+  if (x == NULL_RTX)
-+    x = map->label_map[i] = gen_label_rtx ();
-+
-+  return x;
-+}
-+
-+/* Return false if the function FNDECL cannot be inlined on account of its
-+   attributes, true otherwise.  */
-+bool
-+function_attribute_inlinable_p (fndecl)
-+     tree fndecl;
-+{
-+  if (targetm.attribute_table)
-+    {
-+      tree a;
-+
-+      for (a = DECL_ATTRIBUTES (fndecl); a; a = TREE_CHAIN (a))
-+      {
-+        tree name = TREE_PURPOSE (a);
-+        int i;
-+
-+        for (i = 0; targetm.attribute_table[i].name != NULL; i++)
-+          if (is_attribute_p (targetm.attribute_table[i].name, name))
-+            return (*targetm.function_attribute_inlinable_p) (fndecl);
-+      }
-+    }
-+
-+  return true;
-+}
-+
-+/* Zero if the current function (whose FUNCTION_DECL is FNDECL)
-+   is safe and reasonable to integrate into other functions.
-+   Nonzero means value is a warning msgid with a single %s
-+   for the function's name.  */
-+
-+const char *
-+function_cannot_inline_p (fndecl)
-+     tree fndecl;
-+{
-+  rtx insn;
-+  tree last = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
-+
-+  /* For functions marked as inline increase the maximum size to
-+     MAX_INLINE_INSNS_RTL (--param max-inline-insn-rtl=<n>). For
-+     regular functions use the limit given by INTEGRATE_THRESHOLD.
-+     Note that the RTL inliner is not used by the languages that use
-+     the tree inliner (C, C++).  */
-+
-+  int max_insns = (DECL_INLINE (fndecl))
-+                 ? (MAX_INLINE_INSNS_RTL
-+                    + 8 * list_length (DECL_ARGUMENTS (fndecl)))
-+                 : INTEGRATE_THRESHOLD (fndecl);
-+
-+  int ninsns = 0;
-+  tree parms;
-+
-+  if (DECL_UNINLINABLE (fndecl))
-+    return N_("function cannot be inline");
-+
-+  /* No inlines with varargs.  */
-+  if (last && TREE_VALUE (last) != void_type_node)
-+    return N_("varargs function cannot be inline");
-+
-+  if (current_function_calls_alloca)
-+    return N_("function using alloca cannot be inline");
-+
-+  if (current_function_calls_setjmp)
-+    return N_("function using setjmp cannot be inline");
-+
-+  if (current_function_calls_eh_return)
-+    return N_("function uses __builtin_eh_return");
-+
-+  if (current_function_contains_functions)
-+    return N_("function with nested functions cannot be inline");
-+
-+  if (forced_labels)
-+    return
-+      N_("function with label addresses used in initializers cannot inline");
-+
-+  if (current_function_cannot_inline)
-+    return current_function_cannot_inline;
-+
-+  /* If its not even close, don't even look.  */
-+  if (get_max_uid () > 3 * max_insns)
-+    return N_("function too large to be inline");
-+
-+#if 0
-+  /* Don't inline functions which do not specify a function prototype and
-+     have BLKmode argument or take the address of a parameter.  */
-+  for (parms = DECL_ARGUMENTS (fndecl); parms; parms = TREE_CHAIN (parms))
-+    {
-+      if (TYPE_MODE (TREE_TYPE (parms)) == BLKmode)
-+      TREE_ADDRESSABLE (parms) = 1;
-+      if (last == NULL_TREE && TREE_ADDRESSABLE (parms))
-+      return N_("no prototype, and parameter address used; cannot be inline");
-+    }
-+#endif
-+
-+  /* We can't inline functions that return structures
-+     the old-fashioned PCC way, copying into a static block.  */
-+  if (current_function_returns_pcc_struct)
-+    return N_("inline functions not supported for this return value type");
-+
-+  /* We can't inline functions that return structures of varying size.  */
-+  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
-+     receives a transparent union.  */
-+  for (parms = DECL_ARGUMENTS (fndecl); parms; parms = TREE_CHAIN (parms))
-+    {
-+      if (int_size_in_bytes (TREE_TYPE (parms)) < 0)
-+      return N_("function with varying-size parameter cannot be inline");
-+      else if (TREE_CODE (TREE_TYPE (parms)) == UNION_TYPE
-+             && TYPE_TRANSPARENT_UNION (TREE_TYPE (parms)))
-+      return N_("function with transparent unit parameter cannot be inline");
-+    }
-+
-+  if (get_max_uid () > max_insns)
-+    {
-+      for (ninsns = 0, insn = get_first_nonparm_insn ();
-+         insn && ninsns < max_insns;
-+         insn = NEXT_INSN (insn))
-+      if (INSN_P (insn))
-+        ninsns++;
-+
-+      if (ninsns >= max_insns)
-+      return N_("function too large to be inline");
-+    }
-+
-+  /* We will not inline a function which uses computed goto.  The addresses of
-+     its local labels, which may be tucked into global storage, are of course
-+     not constant across instantiations, which causes unexpected behavior.  */
-+  if (current_function_has_computed_jump)
-+    return N_("function with computed jump cannot inline");
-+
-+  /* We cannot inline a nested function that jumps to a nonlocal label.  */
-+  if (current_function_has_nonlocal_goto)
-+    return N_("function with nonlocal goto cannot be inline");
-+
-+  /* We can't inline functions that return a PARALLEL rtx.  */
-+  if (DECL_RTL_SET_P (DECL_RESULT (fndecl)))
-+    {
-+      rtx result = DECL_RTL (DECL_RESULT (fndecl));
-+      if (GET_CODE (result) == PARALLEL)
-+      return N_("inline functions not supported for this return value type");
-+    }
-+
-+  /* If the function has a target specific attribute attached to it,
-+     then we assume that we should not inline it.  This can be overriden
-+     by the target if it defines TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P.  */
-+  if (!function_attribute_inlinable_p (fndecl))
-+    return N_("function with target specific attribute(s) cannot be inlined");
-+
-+  return NULL;
-+}
-+\f
-+/* Map pseudo reg number into the PARM_DECL for the parm living in the reg.
-+   Zero for a reg that isn't a parm's home.
-+   Only reg numbers less than max_parm_reg are mapped here.  */
-+static tree *parmdecl_map;
-+
-+/* In save_for_inline, nonzero if past the parm-initialization insns.  */
-+static int in_nonparm_insns;
-+\f
-+/* Subroutine for `save_for_inline'.  Performs initialization
-+   needed to save FNDECL's insns and info for future inline expansion.  */
-+
-+static rtvec
-+initialize_for_inline (fndecl)
-+     tree fndecl;
-+{
-+  int i;
-+  rtvec arg_vector;
-+  tree parms;
-+
-+  /* Clear out PARMDECL_MAP.  It was allocated in the caller's frame.  */
-+  memset ((char *) parmdecl_map, 0, max_parm_reg * sizeof (tree));
-+  arg_vector = rtvec_alloc (list_length (DECL_ARGUMENTS (fndecl)));
-+
-+  for (parms = DECL_ARGUMENTS (fndecl), i = 0;
-+       parms;
-+       parms = TREE_CHAIN (parms), i++)
-+    {
-+      rtx p = DECL_RTL (parms);
-+
-+      /* If we have (mem (addressof (mem ...))), use the inner MEM since
-+       otherwise the copy_rtx call below will not unshare the MEM since
-+       it shares ADDRESSOF.  */
-+      if (GET_CODE (p) == MEM && GET_CODE (XEXP (p, 0)) == ADDRESSOF
-+        && GET_CODE (XEXP (XEXP (p, 0), 0)) == MEM)
-+      p = XEXP (XEXP (p, 0), 0);
-+
-+      RTVEC_ELT (arg_vector, i) = p;
-+
-+      if (GET_CODE (p) == REG)
-+      parmdecl_map[REGNO (p)] = parms;
-+      else if (GET_CODE (p) == CONCAT)
-+      {
-+        rtx preal = gen_realpart (GET_MODE (XEXP (p, 0)), p);
-+        rtx pimag = gen_imagpart (GET_MODE (preal), p);
-+
-+        if (GET_CODE (preal) == REG)
-+          parmdecl_map[REGNO (preal)] = parms;
-+        if (GET_CODE (pimag) == REG)
-+          parmdecl_map[REGNO (pimag)] = parms;
-+      }
-+
-+      /* This flag is cleared later
-+       if the function ever modifies the value of the parm.  */
-+      TREE_READONLY (parms) = 1;
-+    }
-+
-+  return arg_vector;
-+}
-+
-+/* Copy NODE (which must be a DECL, but not a PARM_DECL).  The DECL
-+   originally was in the FROM_FN, but now it will be in the
-+   TO_FN.  */
-+
-+tree
-+copy_decl_for_inlining (decl, from_fn, to_fn)
-+     tree decl;
-+     tree from_fn;
-+     tree to_fn;
-+{
-+  tree copy;
-+
-+  /* Copy the declaration.  */
-+  if (TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == RESULT_DECL)
-+    {
-+      tree type;
-+      int invisiref = 0;
-+
-+      /* See if the frontend wants to pass this by invisible reference.  */
-+      if (TREE_CODE (decl) == PARM_DECL
-+        && DECL_ARG_TYPE (decl) != TREE_TYPE (decl)
-+        && POINTER_TYPE_P (DECL_ARG_TYPE (decl))
-+        && TREE_TYPE (DECL_ARG_TYPE (decl)) == TREE_TYPE (decl))
-+      {
-+        invisiref = 1;
-+        type = DECL_ARG_TYPE (decl);
-+      }
-+      else
-+      type = TREE_TYPE (decl);
-+
-+      /* For a parameter, we must make an equivalent VAR_DECL, not a
-+       new PARM_DECL.  */
-+      copy = build_decl (VAR_DECL, DECL_NAME (decl), type);
-+      if (!invisiref)
-+      {
-+        TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
-+        TREE_READONLY (copy) = TREE_READONLY (decl);
-+        TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
-+      }
-+      else
-+      {
-+        TREE_ADDRESSABLE (copy) = 0;
-+        TREE_READONLY (copy) = 1;
-+        TREE_THIS_VOLATILE (copy) = 0;
-+      }
-+    }
-+  else
-+    {
-+      copy = copy_node (decl);
-+      /* The COPY is not abstract; it will be generated in TO_FN.  */
-+      DECL_ABSTRACT (copy) = 0;
-+      (*lang_hooks.dup_lang_specific_decl) (copy);
-+
-+      /* TREE_ADDRESSABLE isn't used to indicate that a label's
-+       address has been taken; it's for internal bookkeeping in
-+       expand_goto_internal.  */
-+      if (TREE_CODE (copy) == LABEL_DECL)
-+      TREE_ADDRESSABLE (copy) = 0;
-+    }
-+
-+  /* Set the DECL_ABSTRACT_ORIGIN so the debugging routines know what
-+     declaration inspired this copy.  */
-+  DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl);
-+
-+  /* The new variable/label has no RTL, yet.  */
-+  SET_DECL_RTL (copy, NULL_RTX);
-+
-+  /* These args would always appear unused, if not for this.  */
-+  TREE_USED (copy) = 1;
-+
-+  /* Set the context for the new declaration.  */
-+  if (!DECL_CONTEXT (decl))
-+    /* Globals stay global.  */
-+    ;
-+  else if (DECL_CONTEXT (decl) != from_fn)
-+    /* Things that weren't in the scope of the function we're inlining
-+       from aren't in the scope we're inlining too, either.  */
-+    ;
-+  else if (TREE_STATIC (decl))
-+    /* Function-scoped static variables should say in the original
-+       function.  */
-+    ;
-+  else
-+    /* Ordinary automatic local variables are now in the scope of the
-+       new function.  */
-+    DECL_CONTEXT (copy) = to_fn;
-+
-+  return copy;
-+}
-+
-+/* Make the insns and PARM_DECLs of the current function permanent
-+   and record other information in DECL_SAVED_INSNS to allow inlining
-+   of this function in subsequent calls.
-+
-+   This routine need not copy any insns because we are not going
-+   to immediately compile the insns in the insn chain.  There
-+   are two cases when we would compile the insns for FNDECL:
-+   (1) when FNDECL is expanded inline, and (2) when FNDECL needs to
-+   be output at the end of other compilation, because somebody took
-+   its address.  In the first case, the insns of FNDECL are copied
-+   as it is expanded inline, so FNDECL's saved insns are not
-+   modified.  In the second case, FNDECL is used for the last time,
-+   so modifying the rtl is not a problem.
-+
-+   We don't have to worry about FNDECL being inline expanded by
-+   other functions which are written at the end of compilation
-+   because flag_no_inline is turned on when we begin writing
-+   functions at the end of compilation.  */
-+
-+void
-+save_for_inline (fndecl)
-+     tree fndecl;
-+{
-+  rtx insn;
-+  rtvec argvec;
-+  rtx first_nonparm_insn;
-+
-+  /* Set up PARMDECL_MAP which maps pseudo-reg number to its PARM_DECL.
-+     Later we set TREE_READONLY to 0 if the parm is modified inside the fn.
-+     Also set up ARG_VECTOR, which holds the unmodified DECL_RTX values
-+     for the parms, prior to elimination of virtual registers.
-+     These values are needed for substituting parms properly.  */
-+  if (! flag_no_inline)
-+    parmdecl_map = (tree *) xmalloc (max_parm_reg * sizeof (tree));
-+
-+  /* Make and emit a return-label if we have not already done so.  */
-+
-+  if (return_label == 0)
-+    {
-+      return_label = gen_label_rtx ();
-+      emit_label (return_label);
-+    }
-+
-+  if (! flag_no_inline)
-+    argvec = initialize_for_inline (fndecl);
-+  else
-+    argvec = NULL;
-+
-+  /* Delete basic block notes created by early run of find_basic_block.
-+     The notes would be later used by find_basic_blocks to reuse the memory
-+     for basic_block structures on already freed obstack.  */
-+  for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
-+    if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK)
-+      delete_related_insns (insn);
-+
-+  /* If there are insns that copy parms from the stack into pseudo registers,
-+     those insns are not copied.  `expand_inline_function' must
-+     emit the correct code to handle such things.  */
-+
-+  insn = get_insns ();
-+  if (GET_CODE (insn) != NOTE)
-+    abort ();
-+
-+  if (! flag_no_inline)
-+    {
-+      /* Get the insn which signals the end of parameter setup code.  */
-+      first_nonparm_insn = get_first_nonparm_insn ();
-+
-+      /* Now just scan the chain of insns to see what happens to our
-+       PARM_DECLs.  If a PARM_DECL is used but never modified, we
-+       can substitute its rtl directly when expanding inline (and
-+       perform constant folding when its incoming value is
-+       constant).  Otherwise, we have to copy its value into a new
-+       register and track the new register's life.  */
-+      in_nonparm_insns = 0;
-+      save_parm_insns (insn, first_nonparm_insn);
-+
-+      cfun->inl_max_label_num = max_label_num ();
-+      cfun->inl_last_parm_insn = cfun->x_last_parm_insn;
-+      cfun->original_arg_vector = argvec;
-+    }
-+  cfun->original_decl_initial = DECL_INITIAL (fndecl);
-+  cfun->no_debugging_symbols = (write_symbols == NO_DEBUG);
-+  DECL_SAVED_INSNS (fndecl) = cfun;
-+
-+  /* Clean up.  */
-+  if (! flag_no_inline)
-+    free (parmdecl_map);
-+}
-+
-+/* Scan the chain of insns to see what happens to our PARM_DECLs.  If a
-+   PARM_DECL is used but never modified, we can substitute its rtl directly
-+   when expanding inline (and perform constant folding when its incoming
-+   value is constant). Otherwise, we have to copy its value into a new
-+   register and track the new register's life.  */
-+
-+static void
-+save_parm_insns (insn, first_nonparm_insn)
-+     rtx insn;
-+     rtx first_nonparm_insn;
-+{
-+  if (insn == NULL_RTX)
-+    return;
-+
-+  for (insn = NEXT_INSN (insn); insn; insn = NEXT_INSN (insn))
-+    {
-+      if (insn == first_nonparm_insn)
-+      in_nonparm_insns = 1;
-+
-+      if (INSN_P (insn))
-+      {
-+        /* Record what interesting things happen to our parameters.  */
-+        note_stores (PATTERN (insn), note_modified_parmregs, NULL);
-+
-+        /* If this is a CALL_PLACEHOLDER insn then we need to look into the
-+           three attached sequences: normal call, sibling call and tail
-+           recursion.  */
-+        if (GET_CODE (insn) == CALL_INSN
-+            && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
-+          {
-+            int i;
-+
-+            for (i = 0; i < 3; i++)
-+              save_parm_insns (XEXP (PATTERN (insn), i),
-+                               first_nonparm_insn);
-+          }
-+      }
-+    }
-+}
-+\f
-+/* Note whether a parameter is modified or not.  */
-+
-+static void
-+note_modified_parmregs (reg, x, data)
-+     rtx reg;
-+     rtx x ATTRIBUTE_UNUSED;
-+     void *data ATTRIBUTE_UNUSED;
-+{
-+  if (GET_CODE (reg) == REG && in_nonparm_insns
-+      && REGNO (reg) < max_parm_reg
-+      && REGNO (reg) >= FIRST_PSEUDO_REGISTER
-+      && parmdecl_map[REGNO (reg)] != 0)
-+    TREE_READONLY (parmdecl_map[REGNO (reg)]) = 0;
-+}
-+
-+/* Unfortunately, we need a global copy of const_equiv map for communication
-+   with a function called from note_stores.  Be *very* careful that this
-+   is used properly in the presence of recursion.  */
-+
-+varray_type global_const_equiv_varray;
-+\f
-+#define FIXED_BASE_PLUS_P(X) \
-+  (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT        \
-+   && GET_CODE (XEXP (X, 0)) == REG                           \
-+   && REGNO (XEXP (X, 0)) >= FIRST_VIRTUAL_REGISTER           \
-+   && REGNO (XEXP (X, 0)) <= LAST_VIRTUAL_REGISTER)
-+
-+/* Called to set up a mapping for the case where a parameter is in a
-+   register.  If it is read-only and our argument is a constant, set up the
-+   constant equivalence.
-+
-+   If LOC is REG_USERVAR_P, the usual case, COPY must also have that flag set
-+   if it is a register.
-+
-+   Also, don't allow hard registers here; they might not be valid when
-+   substituted into insns.  */
-+static void
-+process_reg_param (map, loc, copy)
-+     struct inline_remap *map;
-+     rtx loc, copy;
-+{
-+  if ((GET_CODE (copy) != REG && GET_CODE (copy) != SUBREG)
-+      || (GET_CODE (copy) == REG && REG_USERVAR_P (loc)
-+        && ! REG_USERVAR_P (copy))
-+      || (GET_CODE (copy) == REG
-+        && REGNO (copy) < FIRST_PSEUDO_REGISTER))
-+    {
-+      rtx temp = copy_to_mode_reg (GET_MODE (loc), copy);
-+      REG_USERVAR_P (temp) = REG_USERVAR_P (loc);
-+      if (CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
-+      SET_CONST_EQUIV_DATA (map, temp, copy, CONST_AGE_PARM);
-+      copy = temp;
-+    }
-+  map->reg_map[REGNO (loc)] = copy;
-+}
-+
-+/* Compare two BLOCKs for qsort.  The key we sort on is the
-+   BLOCK_ABSTRACT_ORIGIN of the blocks.  We cannot just subtract the
-+   two pointers, because it may overflow sizeof(int).  */
-+
-+static int
-+compare_blocks (v1, v2)
-+     const PTR v1;
-+     const PTR v2;
-+{
-+  tree b1 = *((const tree *) v1);
-+  tree b2 = *((const tree *) v2);
-+  char *p1 = (char *) BLOCK_ABSTRACT_ORIGIN (b1);
-+  char *p2 = (char *) BLOCK_ABSTRACT_ORIGIN (b2);
-+
-+  if (p1 == p2)
-+    return 0;
-+  return p1 < p2 ? -1 : 1;
-+}
-+
-+/* Compare two BLOCKs for bsearch.  The first pointer corresponds to
-+   an original block; the second to a remapped equivalent.  */
-+
-+static int
-+find_block (v1, v2)
-+     const PTR v1;
-+     const PTR v2;
-+{
-+  const union tree_node *b1 = (const union tree_node *) v1;
-+  tree b2 = *((const tree *) v2);
-+  char *p1 = (char *) b1;
-+  char *p2 = (char *) BLOCK_ABSTRACT_ORIGIN (b2);
-+
-+  if (p1 == p2)
-+    return 0;
-+  return p1 < p2 ? -1 : 1;
-+}
-+
-+/* Integrate the procedure defined by FNDECL.  Note that this function
-+   may wind up calling itself.  Since the static variables are not
-+   reentrant, we do not assign them until after the possibility
-+   of recursion is eliminated.
-+
-+   If IGNORE is nonzero, do not produce a value.
-+   Otherwise store the value in TARGET if it is nonzero and that is convenient.
-+
-+   Value is:
-+   (rtx)-1 if we could not substitute the function
-+   0 if we substituted it and it does not produce a value
-+   else an rtx for where the value is stored.  */
-+
-+rtx
-+expand_inline_function (fndecl, parms, target, ignore, type,
-+                      structure_value_addr)
-+     tree fndecl, parms;
-+     rtx target;
-+     int ignore;
-+     tree type;
-+     rtx structure_value_addr;
-+{
-+  struct function *inlining_previous;
-+  struct function *inl_f = DECL_SAVED_INSNS (fndecl);
-+  tree formal, actual, block;
-+  rtx parm_insns = inl_f->emit->x_first_insn;
-+  rtx insns = (inl_f->inl_last_parm_insn
-+             ? NEXT_INSN (inl_f->inl_last_parm_insn)
-+             : parm_insns);
-+  tree *arg_trees;
-+  rtx *arg_vals;
-+  int max_regno;
-+  int i;
-+  int min_labelno = inl_f->emit->x_first_label_num;
-+  int max_labelno = inl_f->inl_max_label_num;
-+  int nargs;
-+  rtx loc;
-+  rtx stack_save = 0;
-+  rtx temp;
-+  struct inline_remap *map = 0;
-+  rtvec arg_vector = inl_f->original_arg_vector;
-+  rtx static_chain_value = 0;
-+  int inl_max_uid;
-+  int eh_region_offset;
-+
-+  /* The pointer used to track the true location of the memory used
-+     for MAP->LABEL_MAP.  */
-+  rtx *real_label_map = 0;
-+
-+  /* Allow for equivalences of the pseudos we make for virtual fp and ap.  */
-+  max_regno = inl_f->emit->x_reg_rtx_no + 3;
-+  if (max_regno < FIRST_PSEUDO_REGISTER)
-+    abort ();
-+
-+  /* Pull out the decl for the function definition; fndecl may be a
-+     local declaration, which would break DECL_ABSTRACT_ORIGIN.  */
-+  fndecl = inl_f->decl;
-+
-+  nargs = list_length (DECL_ARGUMENTS (fndecl));
-+
-+  if (cfun->preferred_stack_boundary < inl_f->preferred_stack_boundary)
-+    cfun->preferred_stack_boundary = inl_f->preferred_stack_boundary;
-+
-+  /* Check that the parms type match and that sufficient arguments were
-+     passed.  Since the appropriate conversions or default promotions have
-+     already been applied, the machine modes should match exactly.  */
-+
-+  for (formal = DECL_ARGUMENTS (fndecl), actual = parms;
-+       formal;
-+       formal = TREE_CHAIN (formal), actual = TREE_CHAIN (actual))
-+    {
-+      tree arg;
-+      enum machine_mode mode;
-+
-+      if (actual == 0)
-+      return (rtx) (size_t) -1;
-+
-+      arg = TREE_VALUE (actual);
-+      mode = TYPE_MODE (DECL_ARG_TYPE (formal));
-+
-+      if (arg == error_mark_node
-+        || mode != TYPE_MODE (TREE_TYPE (arg))
-+        /* If they are block mode, the types should match exactly.
-+           They don't match exactly if TREE_TYPE (FORMAL) == ERROR_MARK_NODE,
-+           which could happen if the parameter has incomplete type.  */
-+        || (mode == BLKmode
-+            && (TYPE_MAIN_VARIANT (TREE_TYPE (arg))
-+                != TYPE_MAIN_VARIANT (TREE_TYPE (formal)))))
-+      return (rtx) (size_t) -1;
-+    }
-+
-+  /* Extra arguments are valid, but will be ignored below, so we must
-+     evaluate them here for side-effects.  */
-+  for (; actual; actual = TREE_CHAIN (actual))
-+    expand_expr (TREE_VALUE (actual), const0_rtx,
-+               TYPE_MODE (TREE_TYPE (TREE_VALUE (actual))), 0);
-+
-+  /* Expand the function arguments.  Do this first so that any
-+     new registers get created before we allocate the maps.  */
-+
-+  arg_vals = (rtx *) xmalloc (nargs * sizeof (rtx));
-+  arg_trees = (tree *) xmalloc (nargs * sizeof (tree));
-+
-+  for (formal = DECL_ARGUMENTS (fndecl), actual = parms, i = 0;
-+       formal;
-+       formal = TREE_CHAIN (formal), actual = TREE_CHAIN (actual), i++)
-+    {
-+      /* Actual parameter, converted to the type of the argument within the
-+       function.  */
-+      tree arg = convert (TREE_TYPE (formal), TREE_VALUE (actual));
-+      /* Mode of the variable used within the function.  */
-+      enum machine_mode mode = TYPE_MODE (TREE_TYPE (formal));
-+      int invisiref = 0;
-+
-+      arg_trees[i] = arg;
-+      loc = RTVEC_ELT (arg_vector, i);
-+
-+      /* If this is an object passed by invisible reference, we copy the
-+       object into a stack slot and save its address.  If this will go
-+       into memory, we do nothing now.  Otherwise, we just expand the
-+       argument.  */
-+      if (GET_CODE (loc) == MEM && GET_CODE (XEXP (loc, 0)) == REG
-+        && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER)
-+      {
-+        rtx stack_slot = assign_temp (TREE_TYPE (arg), 1, 1, 1);
-+
-+        store_expr (arg, stack_slot, 0);
-+        arg_vals[i] = XEXP (stack_slot, 0);
-+        invisiref = 1;
-+      }
-+      else if (GET_CODE (loc) != MEM)
-+      {
-+        if (GET_MODE (loc) != TYPE_MODE (TREE_TYPE (arg)))
-+          {
-+            int unsignedp = TREE_UNSIGNED (TREE_TYPE (formal));
-+            enum machine_mode pmode = TYPE_MODE (TREE_TYPE (formal));
-+
-+            pmode = promote_mode (TREE_TYPE (formal), pmode,
-+                                  &unsignedp, 0);
-+
-+            if (GET_MODE (loc) != pmode)
-+              abort ();
-+
-+            /* The mode if LOC and ARG can differ if LOC was a variable
-+               that had its mode promoted via PROMOTED_MODE.  */
-+            arg_vals[i] = convert_modes (pmode,
-+                                         TYPE_MODE (TREE_TYPE (arg)),
-+                                         expand_expr (arg, NULL_RTX, mode,
-+                                                      EXPAND_SUM),
-+                                         unsignedp);
-+          }
-+        else
-+          arg_vals[i] = expand_expr (arg, NULL_RTX, mode, EXPAND_SUM);
-+      }
-+      else
-+      arg_vals[i] = 0;
-+
-+      if (arg_vals[i] != 0
-+        && (! TREE_READONLY (formal)
-+            /* If the parameter is not read-only, copy our argument through
-+               a register.  Also, we cannot use ARG_VALS[I] if it overlaps
-+               TARGET in any way.  In the inline function, they will likely
-+               be two different pseudos, and `safe_from_p' will make all
-+               sorts of smart assumptions about their not conflicting.
-+               But if ARG_VALS[I] overlaps TARGET, these assumptions are
-+               wrong, so put ARG_VALS[I] into a fresh register.
-+               Don't worry about invisible references, since their stack
-+               temps will never overlap the target.  */
-+            || (target != 0
-+                && ! invisiref
-+                && (GET_CODE (arg_vals[i]) == REG
-+                    || GET_CODE (arg_vals[i]) == SUBREG
-+                    || GET_CODE (arg_vals[i]) == MEM)
-+                && reg_overlap_mentioned_p (arg_vals[i], target))
-+            /* ??? We must always copy a SUBREG into a REG, because it might
-+               get substituted into an address, and not all ports correctly
-+               handle SUBREGs in addresses.  */
-+            || (GET_CODE (arg_vals[i]) == SUBREG)))
-+      arg_vals[i] = copy_to_mode_reg (GET_MODE (loc), arg_vals[i]);
-+
-+      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))));
-+    }
-+
-+  /* Allocate the structures we use to remap things.  */
-+
-+  map = (struct inline_remap *) xcalloc (1, sizeof (struct inline_remap));
-+  map->fndecl = fndecl;
-+
-+  VARRAY_TREE_INIT (map->block_map, 10, "block_map");
-+  map->reg_map = (rtx *) xcalloc (max_regno, sizeof (rtx));
-+
-+  /* We used to use alloca here, but the size of what it would try to
-+     allocate would occasionally cause it to exceed the stack limit and
-+     cause unpredictable core dumps.  */
-+  real_label_map
-+    = (rtx *) xmalloc ((max_labelno) * sizeof (rtx));
-+  map->label_map = real_label_map;
-+  map->local_return_label = NULL_RTX;
-+
-+  inl_max_uid = (inl_f->emit->x_cur_insn_uid + 1);
-+  map->insn_map = (rtx *) xcalloc (inl_max_uid, sizeof (rtx));
-+  map->min_insnno = 0;
-+  map->max_insnno = inl_max_uid;
-+
-+  map->integrating = 1;
-+  map->compare_src = NULL_RTX;
-+  map->compare_mode = VOIDmode;
-+
-+  /* const_equiv_varray maps pseudos in our routine to constants, so
-+     it needs to be large enough for all our pseudos.  This is the
-+     number we are currently using plus the number in the called
-+     routine, plus 15 for each arg, five to compute the virtual frame
-+     pointer, and five for the return value.  This should be enough
-+     for most cases.  We do not reference entries outside the range of
-+     the map.
-+
-+     ??? These numbers are quite arbitrary and were obtained by
-+     experimentation.  At some point, we should try to allocate the
-+     table after all the parameters are set up so we can more accurately
-+     estimate the number of pseudos we will need.  */
-+
-+  VARRAY_CONST_EQUIV_INIT (map->const_equiv_varray,
-+                         (max_reg_num ()
-+                          + (max_regno - FIRST_PSEUDO_REGISTER)
-+                          + 15 * nargs
-+                          + 10),
-+                         "expand_inline_function");
-+  map->const_age = 0;
-+
-+  /* Record the current insn in case we have to set up pointers to frame
-+     and argument memory blocks.  If there are no insns yet, add a dummy
-+     insn that can be used as an insertion point.  */
-+  map->insns_at_start = get_last_insn ();
-+  if (map->insns_at_start == 0)
-+    map->insns_at_start = emit_note (NULL, NOTE_INSN_DELETED);
-+
-+  map->regno_pointer_align = inl_f->emit->regno_pointer_align;
-+  map->x_regno_reg_rtx = inl_f->emit->x_regno_reg_rtx;
-+
-+  /* Update the outgoing argument size to allow for those in the inlined
-+     function.  */
-+  if (inl_f->outgoing_args_size > current_function_outgoing_args_size)
-+    current_function_outgoing_args_size = inl_f->outgoing_args_size;
-+
-+  /* If the inline function needs to make PIC references, that means
-+     that this function's PIC offset table must be used.  */
-+  if (inl_f->uses_pic_offset_table)
-+    current_function_uses_pic_offset_table = 1;
-+
-+  /* If this function needs a context, set it up.  */
-+  if (inl_f->needs_context)
-+    static_chain_value = lookup_static_chain (fndecl);
-+
-+  if (GET_CODE (parm_insns) == NOTE
-+      && NOTE_LINE_NUMBER (parm_insns) > 0)
-+    {
-+      rtx note = emit_note (NOTE_SOURCE_FILE (parm_insns),
-+                          NOTE_LINE_NUMBER (parm_insns));
-+      if (note)
-+      RTX_INTEGRATED_P (note) = 1;
-+    }
-+
-+  /* Process each argument.  For each, set up things so that the function's
-+     reference to the argument will refer to the argument being passed.
-+     We only replace REG with REG here.  Any simplifications are done
-+     via const_equiv_map.
-+
-+     We make two passes:  In the first, we deal with parameters that will
-+     be placed into registers, since we need to ensure that the allocated
-+     register number fits in const_equiv_map.  Then we store all non-register
-+     parameters into their memory location.  */
-+
-+  /* Don't try to free temp stack slots here, because we may put one of the
-+     parameters into a temp stack slot.  */
-+
-+  for (i = 0; i < nargs; i++)
-+    {
-+      rtx copy = arg_vals[i];
-+
-+      loc = RTVEC_ELT (arg_vector, i);
-+
-+      /* There are three cases, each handled separately.  */
-+      if (GET_CODE (loc) == MEM && GET_CODE (XEXP (loc, 0)) == REG
-+        && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER)
-+      {
-+        /* This must be an object passed by invisible reference (it could
-+           also be a variable-sized object, but we forbid inlining functions
-+           with variable-sized arguments).  COPY is the address of the
-+           actual value (this computation will cause it to be copied).  We
-+           map that address for the register, noting the actual address as
-+           an equivalent in case it can be substituted into the insns.  */
-+
-+        if (GET_CODE (copy) != REG)
-+          {
-+            temp = copy_addr_to_reg (copy);
-+            if (CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
-+              SET_CONST_EQUIV_DATA (map, temp, copy, CONST_AGE_PARM);
-+            copy = temp;
-+          }
-+        map->reg_map[REGNO (XEXP (loc, 0))] = copy;
-+      }
-+      else if (GET_CODE (loc) == MEM)
-+      {
-+        /* This is the case of a parameter that lives in memory.  It
-+           will live in the block we allocate in the called routine's
-+           frame that simulates the incoming argument area.  Do nothing
-+           with the parameter now; we will call store_expr later.  In
-+           this case, however, we must ensure that the virtual stack and
-+           incoming arg rtx values are expanded now so that we can be
-+           sure we have enough slots in the const equiv map since the
-+           store_expr call can easily blow the size estimate.  */
-+        if (DECL_SAVED_INSNS (fndecl)->args_size != 0)
-+          copy_rtx_and_substitute (virtual_incoming_args_rtx, map, 0);
-+      }
-+      else if (GET_CODE (loc) == REG)
-+      process_reg_param (map, loc, copy);
-+      else if (GET_CODE (loc) == CONCAT)
-+      {
-+        rtx locreal = gen_realpart (GET_MODE (XEXP (loc, 0)), loc);
-+        rtx locimag = gen_imagpart (GET_MODE (XEXP (loc, 0)), loc);
-+        rtx copyreal = gen_realpart (GET_MODE (locreal), copy);
-+        rtx copyimag = gen_imagpart (GET_MODE (locimag), copy);
-+
-+        process_reg_param (map, locreal, copyreal);
-+        process_reg_param (map, locimag, copyimag);
-+      }
-+      else
-+      abort ();
-+    }
-+
-+  /* Tell copy_rtx_and_substitute to handle constant pool SYMBOL_REFs
-+     specially.  This function can be called recursively, so we need to
-+     save the previous value.  */
-+  inlining_previous = inlining;
-+  inlining = inl_f;
-+
-+  /* Now do the parameters that will be placed in memory.  */
-+
-+  for (formal = DECL_ARGUMENTS (fndecl), i = 0;
-+       formal; formal = TREE_CHAIN (formal), i++)
-+    {
-+      loc = RTVEC_ELT (arg_vector, i);
-+
-+      if (GET_CODE (loc) == MEM
-+        /* Exclude case handled above.  */
-+        && ! (GET_CODE (XEXP (loc, 0)) == REG
-+              && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER))
-+      {
-+        rtx note = emit_note (DECL_SOURCE_FILE (formal),
-+                              DECL_SOURCE_LINE (formal));
-+        if (note)
-+          RTX_INTEGRATED_P (note) = 1;
-+
-+        /* Compute the address in the area we reserved and store the
-+           value there.  */
-+        temp = copy_rtx_and_substitute (loc, map, 1);
-+        subst_constants (&temp, NULL_RTX, map, 1);
-+        apply_change_group ();
-+        if (! memory_address_p (GET_MODE (temp), XEXP (temp, 0)))
-+          temp = change_address (temp, VOIDmode, XEXP (temp, 0));
-+        store_expr (arg_trees[i], temp, 0);
-+      }
-+    }
-+
-+  /* Deal with the places that the function puts its result.
-+     We are driven by what is placed into DECL_RESULT.
-+
-+     Initially, we assume that we don't have anything special handling for
-+     REG_FUNCTION_RETURN_VALUE_P.  */
-+
-+  map->inline_target = 0;
-+  loc = (DECL_RTL_SET_P (DECL_RESULT (fndecl)) 
-+       ? DECL_RTL (DECL_RESULT (fndecl)) : NULL_RTX);
-+
-+  if (TYPE_MODE (type) == VOIDmode)
-+    /* There is no return value to worry about.  */
-+    ;
-+  else if (GET_CODE (loc) == MEM)
-+    {
-+      if (GET_CODE (XEXP (loc, 0)) == ADDRESSOF)
-+      {
-+        temp = copy_rtx_and_substitute (loc, map, 1);
-+        subst_constants (&temp, NULL_RTX, map, 1);
-+        apply_change_group ();
-+        target = temp;
-+      }
-+      else
-+      {
-+        if (! structure_value_addr
-+            || ! aggregate_value_p (DECL_RESULT (fndecl)))
-+          abort ();
-+
-+        /* Pass the function the address in which to return a structure
-+           value.  Note that a constructor can cause someone to call us
-+           with STRUCTURE_VALUE_ADDR, but the initialization takes place
-+           via the first parameter, rather than the struct return address.
-+
-+           We have two cases: If the address is a simple register
-+           indirect, use the mapping mechanism to point that register to
-+           our structure return address.  Otherwise, store the structure
-+           return value into the place that it will be referenced from.  */
-+
-+        if (GET_CODE (XEXP (loc, 0)) == REG)
-+          {
-+            temp = force_operand (structure_value_addr, NULL_RTX);
-+            temp = force_reg (Pmode, temp);
-+            /* A virtual register might be invalid in an insn, because
-+               it can cause trouble in reload.  Since we don't have access
-+               to the expanders at map translation time, make sure we have
-+               a proper register now.
-+               If a virtual register is actually valid, cse or combine
-+               can put it into the mapped insns.  */
-+            if (REGNO (temp) >= FIRST_VIRTUAL_REGISTER
-+                && REGNO (temp) <= LAST_VIRTUAL_REGISTER)
-+            temp = copy_to_mode_reg (Pmode, temp);
-+            map->reg_map[REGNO (XEXP (loc, 0))] = temp;
-+
-+            if (CONSTANT_P (structure_value_addr)
-+                || GET_CODE (structure_value_addr) == ADDRESSOF
-+                || (GET_CODE (structure_value_addr) == PLUS
-+                    && (XEXP (structure_value_addr, 0)
-+                        == virtual_stack_vars_rtx)
-+                    && (GET_CODE (XEXP (structure_value_addr, 1))
-+                        == CONST_INT)))
-+              {
-+                SET_CONST_EQUIV_DATA (map, temp, structure_value_addr,
-+                                      CONST_AGE_PARM);
-+              }
-+          }
-+        else
-+          {
-+            temp = copy_rtx_and_substitute (loc, map, 1);
-+            subst_constants (&temp, NULL_RTX, map, 0);
-+            apply_change_group ();
-+            emit_move_insn (temp, structure_value_addr);
-+          }
-+      }
-+    }
-+  else if (ignore)
-+    /* We will ignore the result value, so don't look at its structure.
-+       Note that preparations for an aggregate return value
-+       do need to be made (above) even if it will be ignored.  */
-+    ;
-+  else if (GET_CODE (loc) == REG)
-+    {
-+      /* The function returns an object in a register and we use the return
-+       value.  Set up our target for remapping.  */
-+
-+      /* Machine mode function was declared to return.  */
-+      enum machine_mode departing_mode = TYPE_MODE (type);
-+      /* (Possibly wider) machine mode it actually computes
-+       (for the sake of callers that fail to declare it right).
-+       We have to use the mode of the result's RTL, rather than
-+       its type, since expand_function_start may have promoted it.  */
-+      enum machine_mode arriving_mode
-+      = GET_MODE (DECL_RTL (DECL_RESULT (fndecl)));
-+      rtx reg_to_map;
-+
-+      /* Don't use MEMs as direct targets because on some machines
-+       substituting a MEM for a REG makes invalid insns.
-+       Let the combiner substitute the MEM if that is valid.  */
-+      if (target == 0 || GET_CODE (target) != REG
-+        || GET_MODE (target) != departing_mode)
-+      {
-+        /* Don't make BLKmode registers.  If this looks like
-+           a BLKmode object being returned in a register, get
-+           the mode from that, otherwise abort.  */
-+        if (departing_mode == BLKmode)
-+          {
-+            if (REG == GET_CODE (DECL_RTL (DECL_RESULT (fndecl))))
-+              {
-+                departing_mode = GET_MODE (DECL_RTL (DECL_RESULT (fndecl)));
-+                arriving_mode = departing_mode;
-+              }
-+            else
-+              abort ();
-+          }
-+
-+        target = gen_reg_rtx (departing_mode);
-+      }
-+
-+      /* If function's value was promoted before return,
-+       avoid machine mode mismatch when we substitute INLINE_TARGET.
-+       But TARGET is what we will return to the caller.  */
-+      if (arriving_mode != departing_mode)
-+      {
-+        /* Avoid creating a paradoxical subreg wider than
-+           BITS_PER_WORD, since that is illegal.  */
-+        if (GET_MODE_BITSIZE (arriving_mode) > BITS_PER_WORD)
-+          {
-+            if (!TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (departing_mode),
-+                                        GET_MODE_BITSIZE (arriving_mode)))
-+              /* Maybe could be handled by using convert_move () ?  */
-+              abort ();
-+            reg_to_map = gen_reg_rtx (arriving_mode);
-+            target = gen_lowpart (departing_mode, reg_to_map);
-+          }
-+        else
-+          reg_to_map = gen_rtx_SUBREG (arriving_mode, target, 0);
-+      }
-+      else
-+      reg_to_map = target;
-+
-+      /* Usually, the result value is the machine's return register.
-+       Sometimes it may be a pseudo. Handle both cases.  */
-+      if (REG_FUNCTION_VALUE_P (loc))
-+      map->inline_target = reg_to_map;
-+      else
-+      map->reg_map[REGNO (loc)] = reg_to_map;
-+    }
-+  else if (GET_CODE (loc) == CONCAT)
-+    {
-+      enum machine_mode departing_mode = TYPE_MODE (type);
-+      enum machine_mode arriving_mode
-+      = GET_MODE (DECL_RTL (DECL_RESULT (fndecl)));
-+
-+      if (departing_mode != arriving_mode)
-+      abort ();
-+      if (GET_CODE (XEXP (loc, 0)) != REG
-+        || GET_CODE (XEXP (loc, 1)) != REG)
-+      abort ();
-+
-+      /* Don't use MEMs as direct targets because on some machines
-+       substituting a MEM for a REG makes invalid insns.
-+       Let the combiner substitute the MEM if that is valid.  */
-+      if (target == 0 || GET_CODE (target) != REG
-+        || GET_MODE (target) != departing_mode)
-+      target = gen_reg_rtx (departing_mode);
-+
-+      if (GET_CODE (target) != CONCAT)
-+      abort ();
-+
-+      map->reg_map[REGNO (XEXP (loc, 0))] = XEXP (target, 0);
-+      map->reg_map[REGNO (XEXP (loc, 1))] = XEXP (target, 1);
-+    }
-+  else
-+    abort ();
-+
-+  /* Remap the exception handler data pointer from one to the other.  */
-+  temp = get_exception_pointer (inl_f);
-+  if (temp)
-+    map->reg_map[REGNO (temp)] = get_exception_pointer (cfun);
-+
-+  /* Initialize label_map.  get_label_from_map will actually make
-+     the labels.  */
-+  memset ((char *) &map->label_map[min_labelno], 0,
-+       (max_labelno - min_labelno) * sizeof (rtx));
-+
-+  /* Make copies of the decls of the symbols in the inline function, so that
-+     the copies of the variables get declared in the current function.  Set
-+     up things so that lookup_static_chain knows that to interpret registers
-+     in SAVE_EXPRs for TYPE_SIZEs as local.  */
-+  inline_function_decl = fndecl;
-+  integrate_parm_decls (DECL_ARGUMENTS (fndecl), map, arg_vector);
-+  block = integrate_decl_tree (inl_f->original_decl_initial, map);
-+  BLOCK_ABSTRACT_ORIGIN (block) = DECL_ORIGIN (fndecl);
-+  inline_function_decl = 0;
-+
-+  /* Make a fresh binding contour that we can easily remove.  Do this after
-+     expanding our arguments so cleanups are properly scoped.  */
-+  expand_start_bindings_and_block (0, block);
-+
-+  /* Sort the block-map so that it will be easy to find remapped
-+     blocks later.  */
-+  qsort (&VARRAY_TREE (map->block_map, 0),
-+       map->block_map->elements_used,
-+       sizeof (tree),
-+       compare_blocks);
-+
-+  /* Perform postincrements before actually calling the function.  */
-+  emit_queue ();
-+
-+  /* Clean up stack so that variables might have smaller offsets.  */
-+  do_pending_stack_adjust ();
-+
-+  /* Save a copy of the location of const_equiv_varray for
-+     mark_stores, called via note_stores.  */
-+  global_const_equiv_varray = map->const_equiv_varray;
-+
-+  /* If the called function does an alloca, save and restore the
-+     stack pointer around the call.  This saves stack space, but
-+     also is required if this inline is being done between two
-+     pushes.  */
-+  if (inl_f->calls_alloca)
-+    emit_stack_save (SAVE_BLOCK, &stack_save, NULL_RTX);
-+
-+  /* Map pseudos used for initial hard reg values.  */
-+  setup_initial_hard_reg_value_integration (inl_f, map);
-+
-+  /* Now copy the insns one by one.  */
-+  copy_insn_list (insns, map, static_chain_value);
-+
-+  /* Duplicate the EH regions.  This will create an offset from the
-+     region numbers in the function we're inlining to the region
-+     numbers in the calling function.  This must wait until after
-+     copy_insn_list, as we need the insn map to be complete.  */
-+  eh_region_offset = duplicate_eh_regions (inl_f, map);
-+
-+  /* Now copy the REG_NOTES for those insns.  */
-+  copy_insn_notes (insns, map, eh_region_offset);
-+
-+  /* If the insn sequence required one, emit the return label.  */
-+  if (map->local_return_label)
-+    emit_label (map->local_return_label);
-+
-+  /* Restore the stack pointer if we saved it above.  */
-+  if (inl_f->calls_alloca)
-+    emit_stack_restore (SAVE_BLOCK, stack_save, NULL_RTX);
-+
-+  if (! cfun->x_whole_function_mode_p)
-+    /* In statement-at-a-time mode, we just tell the front-end to add
-+       this block to the list of blocks at this binding level.  We
-+       can't do it the way it's done for function-at-a-time mode the
-+       superblocks have not been created yet.  */
-+    (*lang_hooks.decls.insert_block) (block);
-+  else
-+    {
-+      BLOCK_CHAIN (block)
-+      = BLOCK_CHAIN (DECL_INITIAL (current_function_decl));
-+      BLOCK_CHAIN (DECL_INITIAL (current_function_decl)) = block;
-+    }
-+
-+  /* End the scope containing the copied formal parameter variables
-+     and copied LABEL_DECLs.  We pass NULL_TREE for the variables list
-+     here so that expand_end_bindings will not check for unused
-+     variables.  That's already been checked for when the inlined
-+     function was defined.  */
-+  expand_end_bindings (NULL_TREE, 1, 1);
-+
-+  /* Must mark the line number note after inlined functions as a repeat, so
-+     that the test coverage code can avoid counting the call twice.  This
-+     just tells the code to ignore the immediately following line note, since
-+     there already exists a copy of this note before the expanded inline call.
-+     This line number note is still needed for debugging though, so we can't
-+     delete it.  */
-+  if (flag_test_coverage)
-+    emit_note (0, NOTE_INSN_REPEATED_LINE_NUMBER);
-+
-+  emit_line_note (input_filename, lineno);
-+
-+  /* If the function returns a BLKmode object in a register, copy it
-+     out of the temp register into a BLKmode memory object.  */
-+  if (target
-+      && TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))) == BLKmode
-+      && ! aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl))))
-+    target = copy_blkmode_from_reg (0, target, TREE_TYPE (TREE_TYPE (fndecl)));
-+
-+  if (structure_value_addr)
-+    {
-+      target = gen_rtx_MEM (TYPE_MODE (type),
-+                          memory_address (TYPE_MODE (type),
-+                                          structure_value_addr));
-+      set_mem_attributes (target, type, 1);
-+    }
-+
-+  /* Make sure we free the things we explicitly allocated with xmalloc.  */
-+  if (real_label_map)
-+    free (real_label_map);
-+  VARRAY_FREE (map->const_equiv_varray);
-+  free (map->reg_map);
-+  free (map->insn_map);
-+  free (map);
-+  free (arg_vals);
-+  free (arg_trees);
-+
-+  inlining = inlining_previous;
-+
-+  return target;
-+}
-+
-+/* Make copies of each insn in the given list using the mapping
-+   computed in expand_inline_function. This function may call itself for
-+   insns containing sequences.
-+
-+   Copying is done in two passes, first the insns and then their REG_NOTES.
-+
-+   If static_chain_value is nonzero, it represents the context-pointer
-+   register for the function.  */
-+
-+static void
-+copy_insn_list (insns, map, static_chain_value)
-+     rtx insns;
-+     struct inline_remap *map;
-+     rtx static_chain_value;
-+{
-+  int i;
-+  rtx insn;
-+  rtx temp;
-+#ifdef HAVE_cc0
-+  rtx cc0_insn = 0;
-+#endif
-+  rtx static_chain_mem = 0;
-+
-+  /* Copy the insns one by one.  Do this in two passes, first the insns and
-+     then their REG_NOTES.  */
-+
-+  /* This loop is very similar to the loop in copy_loop_body in unroll.c.  */
-+
-+  for (insn = insns; insn; insn = NEXT_INSN (insn))
-+    {
-+      rtx copy, pattern, set;
-+
-+      map->orig_asm_operands_vector = 0;
-+
-+      switch (GET_CODE (insn))
-+      {
-+      case INSN:
-+        pattern = PATTERN (insn);
-+        set = single_set (insn);
-+        copy = 0;
-+        if (GET_CODE (pattern) == USE
-+            && GET_CODE (XEXP (pattern, 0)) == REG
-+            && REG_FUNCTION_VALUE_P (XEXP (pattern, 0)))
-+          /* The (USE (REG n)) at return from the function should
-+             be ignored since we are changing (REG n) into
-+             inline_target.  */
-+          break;
-+
-+        /* Ignore setting a function value that we don't want to use.  */
-+        if (map->inline_target == 0
-+            && set != 0
-+            && GET_CODE (SET_DEST (set)) == REG
-+            && REG_FUNCTION_VALUE_P (SET_DEST (set)))
-+          {
-+            if (volatile_refs_p (SET_SRC (set)))
-+              {
-+                rtx new_set;
-+
-+                /* If we must not delete the source,
-+                   load it into a new temporary.  */
-+                copy = emit_insn (copy_rtx_and_substitute (pattern, map, 0));
-+
-+                new_set = single_set (copy);
-+                if (new_set == 0)
-+                  abort ();
-+
-+                SET_DEST (new_set)
-+                  = gen_reg_rtx (GET_MODE (SET_DEST (new_set)));
-+              }
-+            /* If the source and destination are the same and it
-+               has a note on it, keep the insn.  */
-+            else if (rtx_equal_p (SET_DEST (set), SET_SRC (set))
-+                     && REG_NOTES (insn) != 0)
-+              copy = emit_insn (copy_rtx_and_substitute (pattern, map, 0));
-+            else
-+              break;
-+          }
-+
-+        /* Similarly if an ignored return value is clobbered.  */
-+        else if (map->inline_target == 0
-+                 && GET_CODE (pattern) == CLOBBER
-+                 && GET_CODE (XEXP (pattern, 0)) == REG
-+                 && REG_FUNCTION_VALUE_P (XEXP (pattern, 0)))
-+          break;
-+
-+        /* Look for the address of the static chain slot. The
-+             rtx_equal_p comparisons against the
-+             static_chain_incoming_rtx below may fail if the static
-+             chain is in memory and the address specified is not
-+             "legitimate".  This happens on Xtensa where the static
-+             chain is at a negative offset from argp and where only
-+             positive offsets are legitimate.  When the RTL is
-+             generated, the address is "legitimized" by copying it
-+             into a register, causing the rtx_equal_p comparisons to
-+             fail.  This workaround looks for code that sets a
-+             register to the address of the static chain.  Subsequent
-+             memory references via that register can then be
-+             identified as static chain references.  We assume that
-+             the register is only assigned once, and that the static
-+             chain address is only live in one register at a time.  */
-+
-+        else if (static_chain_value != 0
-+                 && set != 0
-+                 && GET_CODE (static_chain_incoming_rtx) == MEM
-+                 && GET_CODE (SET_DEST (set)) == REG
-+                 && rtx_equal_p (SET_SRC (set),
-+                                 XEXP (static_chain_incoming_rtx, 0)))
-+          {
-+            static_chain_mem =
-+                gen_rtx_MEM (GET_MODE (static_chain_incoming_rtx),
-+                             SET_DEST (set));
-+
-+            /* emit the instruction in case it is used for something
-+               other than setting the static chain; if it's not used,
-+               it can always be removed as dead code */
-+            copy = emit_insn (copy_rtx_and_substitute (pattern, map, 0));
-+          }
-+
-+        /* If this is setting the static chain rtx, omit it.  */
-+        else if (static_chain_value != 0
-+                 && set != 0
-+                 && (rtx_equal_p (SET_DEST (set),
-+                                  static_chain_incoming_rtx)
-+                     || (static_chain_mem
-+                         && rtx_equal_p (SET_DEST (set), static_chain_mem))))
-+          break;
-+
-+        /* If this is setting the static chain pseudo, set it from
-+           the value we want to give it instead.  */
-+        else if (static_chain_value != 0
-+                 && set != 0
-+                 && (rtx_equal_p (SET_SRC (set),
-+                                  static_chain_incoming_rtx)
-+                     || (static_chain_mem
-+                         && rtx_equal_p (SET_SRC (set), static_chain_mem))))
-+          {
-+            rtx newdest = copy_rtx_and_substitute (SET_DEST (set), map, 1);
-+
-+            copy = emit_move_insn (newdest, static_chain_value);
-+            if (GET_CODE (static_chain_incoming_rtx) != MEM)
-+              static_chain_value = 0;
-+          }
-+
-+        /* If this is setting the virtual stack vars register, this must
-+           be the code at the handler for a builtin longjmp.  The value
-+           saved in the setjmp buffer will be the address of the frame
-+           we've made for this inlined instance within our frame.  But we
-+           know the offset of that value so we can use it to reconstruct
-+           our virtual stack vars register from that value.  If we are
-+           copying it from the stack pointer, leave it unchanged.  */
-+        else if (set != 0
-+                 && rtx_equal_p (SET_DEST (set), virtual_stack_vars_rtx))
-+          {
-+            HOST_WIDE_INT offset;
-+            temp = map->reg_map[REGNO (SET_DEST (set))];
-+            temp = VARRAY_CONST_EQUIV (map->const_equiv_varray,
-+                                       REGNO (temp)).rtx;
-+
-+            if (rtx_equal_p (temp, virtual_stack_vars_rtx))
-+              offset = 0;
-+            else if (GET_CODE (temp) == PLUS
-+                     && rtx_equal_p (XEXP (temp, 0), virtual_stack_vars_rtx)
-+                     && GET_CODE (XEXP (temp, 1)) == CONST_INT)
-+              offset = INTVAL (XEXP (temp, 1));
-+            else
-+              abort ();
-+
-+            if (rtx_equal_p (SET_SRC (set), stack_pointer_rtx))
-+              temp = SET_SRC (set);
-+            else
-+              temp = force_operand (plus_constant (SET_SRC (set),
-+                                                   - offset),
-+                                    NULL_RTX);
-+
-+            copy = emit_move_insn (virtual_stack_vars_rtx, temp);
-+          }
-+
-+        else
-+          copy = emit_insn (copy_rtx_and_substitute (pattern, map, 0));
-+        /* REG_NOTES will be copied later.  */
-+
-+#ifdef HAVE_cc0
-+        /* If this insn is setting CC0, it may need to look at
-+           the insn that uses CC0 to see what type of insn it is.
-+           In that case, the call to recog via validate_change will
-+           fail.  So don't substitute constants here.  Instead,
-+           do it when we emit the following insn.
-+
-+           For example, see the pyr.md file.  That machine has signed and
-+           unsigned compares.  The compare patterns must check the
-+           following branch insn to see which what kind of compare to
-+           emit.
-+
-+           If the previous insn set CC0, substitute constants on it as
-+           well.  */
-+        if (sets_cc0_p (PATTERN (copy)) != 0)
-+          cc0_insn = copy;
-+        else
-+          {
-+            if (cc0_insn)
-+              try_constants (cc0_insn, map);
-+            cc0_insn = 0;
-+            try_constants (copy, map);
-+          }
-+#else
-+        try_constants (copy, map);
-+#endif
-+        INSN_SCOPE (copy) = INSN_SCOPE (insn);
-+        break;
-+
-+      case JUMP_INSN:
-+        if (map->integrating && returnjump_p (insn))
-+          {
-+            if (map->local_return_label == 0)
-+              map->local_return_label = gen_label_rtx ();
-+            pattern = gen_jump (map->local_return_label);
-+          }
-+        else
-+          pattern = copy_rtx_and_substitute (PATTERN (insn), map, 0);
-+
-+        copy = emit_jump_insn (pattern);
-+
-+#ifdef HAVE_cc0
-+        if (cc0_insn)
-+          try_constants (cc0_insn, map);
-+        cc0_insn = 0;
-+#endif
-+        try_constants (copy, map);
-+        INSN_SCOPE (copy) = INSN_SCOPE (insn);
-+
-+        /* If this used to be a conditional jump insn but whose branch
-+           direction is now know, we must do something special.  */
-+        if (any_condjump_p (insn) && onlyjump_p (insn) && map->last_pc_value)
-+          {
-+#ifdef HAVE_cc0
-+            /* If the previous insn set cc0 for us, delete it.  */
-+            if (only_sets_cc0_p (PREV_INSN (copy)))
-+              delete_related_insns (PREV_INSN (copy));
-+#endif
-+
-+            /* If this is now a no-op, delete it.  */
-+            if (map->last_pc_value == pc_rtx)
-+              {
-+                delete_related_insns (copy);
-+                copy = 0;
-+              }
-+            else
-+              /* Otherwise, this is unconditional jump so we must put a
-+                 BARRIER after it.  We could do some dead code elimination
-+                 here, but jump.c will do it just as well.  */
-+              emit_barrier ();
-+          }
-+        break;
-+
-+      case CALL_INSN:
-+        /* If this is a CALL_PLACEHOLDER insn then we need to copy the
-+           three attached sequences: normal call, sibling call and tail
-+           recursion.  */
-+        if (GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
-+          {
-+            rtx sequence[3];
-+            rtx tail_label;
-+
-+            for (i = 0; i < 3; i++)
-+              {
-+                rtx seq;
-+
-+                sequence[i] = NULL_RTX;
-+                seq = XEXP (PATTERN (insn), i);
-+                if (seq)
-+                  {
-+                    start_sequence ();
-+                    copy_insn_list (seq, map, static_chain_value);
-+                    sequence[i] = get_insns ();
-+                    end_sequence ();
-+                  }
-+              }
-+
-+            /* Find the new tail recursion label.
-+               It will already be substituted into sequence[2].  */
-+            tail_label = copy_rtx_and_substitute (XEXP (PATTERN (insn), 3),
-+                                                  map, 0);
-+
-+            copy = emit_call_insn (gen_rtx_CALL_PLACEHOLDER (VOIDmode,
-+                                                             sequence[0],
-+                                                             sequence[1],
-+                                                             sequence[2],
-+                                                             tail_label));
-+            break;
-+          }
-+
-+        pattern = copy_rtx_and_substitute (PATTERN (insn), map, 0);
-+        copy = emit_call_insn (pattern);
-+
-+        SIBLING_CALL_P (copy) = SIBLING_CALL_P (insn);
-+        CONST_OR_PURE_CALL_P (copy) = CONST_OR_PURE_CALL_P (insn);
-+        INSN_SCOPE (copy) = INSN_SCOPE (insn);
-+
-+        /* Because the USAGE information potentially contains objects other
-+           than hard registers, we need to copy it.  */
-+
-+        CALL_INSN_FUNCTION_USAGE (copy)
-+          = copy_rtx_and_substitute (CALL_INSN_FUNCTION_USAGE (insn),
-+                                     map, 0);
-+
-+#ifdef HAVE_cc0
-+        if (cc0_insn)
-+          try_constants (cc0_insn, map);
-+        cc0_insn = 0;
-+#endif
-+        try_constants (copy, map);
-+
-+        /* Be lazy and assume CALL_INSNs clobber all hard registers.  */
-+        for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-+          VARRAY_CONST_EQUIV (map->const_equiv_varray, i).rtx = 0;
-+        break;
-+
-+      case CODE_LABEL:
-+        copy = emit_label (get_label_from_map (map,
-+                                               CODE_LABEL_NUMBER (insn)));
-+        LABEL_NAME (copy) = LABEL_NAME (insn);
-+        map->const_age++;
-+        break;
-+
-+      case BARRIER:
-+        copy = emit_barrier ();
-+        break;
-+
-+      case NOTE:
-+        if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)
-+          {
-+            copy = emit_label (get_label_from_map (map,
-+                                                  CODE_LABEL_NUMBER (insn)));
-+            LABEL_NAME (copy) = NOTE_SOURCE_FILE (insn);
-+            map->const_age++;
-+            break;
-+          }
-+
-+        /* NOTE_INSN_FUNCTION_END and NOTE_INSN_FUNCTION_BEG are
-+           discarded because it is important to have only one of
-+           each in the current function.
-+
-+           NOTE_INSN_DELETED notes aren't useful.  */
-+
-+        if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
-+            && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG
-+            && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
-+          {
-+            copy = emit_note (NOTE_SOURCE_FILE (insn),
-+                              NOTE_LINE_NUMBER (insn));
-+            if (copy
-+                && (NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_BEG
-+                    || NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_END)
-+                && NOTE_BLOCK (insn))
-+              {
-+                tree *mapped_block_p;
-+
-+                mapped_block_p
-+                  = (tree *) bsearch (NOTE_BLOCK (insn),
-+                                      &VARRAY_TREE (map->block_map, 0),
-+                                      map->block_map->elements_used,
-+                                      sizeof (tree),
-+                                      find_block);
-+
-+                if (!mapped_block_p)
-+                  abort ();
-+                else
-+                  NOTE_BLOCK (copy) = *mapped_block_p;
-+              }
-+            else if (copy
-+                     && NOTE_LINE_NUMBER (copy) == NOTE_INSN_EXPECTED_VALUE)
-+              NOTE_EXPECTED_VALUE (copy)
-+                = copy_rtx_and_substitute (NOTE_EXPECTED_VALUE (insn),
-+                                           map, 0);
-+          }
-+        else
-+          copy = 0;
-+        break;
-+
-+      default:
-+        abort ();
-+      }
-+
-+      if (copy)
-+      RTX_INTEGRATED_P (copy) = 1;
-+
-+      map->insn_map[INSN_UID (insn)] = copy;
-+    }
-+}
-+
-+/* Copy the REG_NOTES.  Increment const_age, so that only constants
-+   from parameters can be substituted in.  These are the only ones
-+   that are valid across the entire function.  */
-+
-+static void
-+copy_insn_notes (insns, map, eh_region_offset)
-+     rtx insns;
-+     struct inline_remap *map;
-+     int eh_region_offset;
-+{
-+  rtx insn, new_insn;
-+
-+  map->const_age++;
-+  for (insn = insns; insn; insn = NEXT_INSN (insn))
-+    {
-+      if (! INSN_P (insn))
-+      continue;
-+
-+      new_insn = map->insn_map[INSN_UID (insn)];
-+      if (! new_insn)
-+      continue;
-+
-+      if (REG_NOTES (insn))
-+        {
-+        rtx next, note = copy_rtx_and_substitute (REG_NOTES (insn), map, 0);
-+
-+        /* We must also do subst_constants, in case one of our parameters
-+           has const type and constant value.  */
-+        subst_constants (&note, NULL_RTX, map, 0);
-+        apply_change_group ();
-+        REG_NOTES (new_insn) = note;
-+
-+        /* Delete any REG_LABEL notes from the chain.  Remap any
-+             REG_EH_REGION notes.  */
-+        for (; note; note = next)
-+          {
-+            next = XEXP (note, 1);
-+            if (REG_NOTE_KIND (note) == REG_LABEL)
-+              remove_note (new_insn, note);
-+            else if (REG_NOTE_KIND (note) == REG_EH_REGION
-+                     && INTVAL (XEXP (note, 0)) > 0)
-+              XEXP (note, 0) = GEN_INT (INTVAL (XEXP (note, 0))
-+                                        + eh_region_offset);
-+          }
-+        }
-+
-+      if (GET_CODE (insn) == CALL_INSN
-+        && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
-+      {
-+        int i;
-+        for (i = 0; i < 3; i++)
-+          copy_insn_notes (XEXP (PATTERN (insn), i), map, eh_region_offset);
-+      }
-+
-+      if (GET_CODE (insn) == JUMP_INSN
-+        && GET_CODE (PATTERN (insn)) == RESX)
-+      XINT (PATTERN (new_insn), 0) += eh_region_offset;
-+    }
-+}
-+\f
-+/* Given a chain of PARM_DECLs, ARGS, copy each decl into a VAR_DECL,
-+   push all of those decls and give each one the corresponding home.  */
-+
-+static void
-+integrate_parm_decls (args, map, arg_vector)
-+     tree args;
-+     struct inline_remap *map;
-+     rtvec arg_vector;
-+{
-+  tree tail;
-+  int i;
-+
-+  for (tail = args, i = 0; tail; tail = TREE_CHAIN (tail), i++)
-+    {
-+      tree decl = copy_decl_for_inlining (tail, map->fndecl,
-+                                        current_function_decl);
-+      rtx new_decl_rtl
-+      = copy_rtx_and_substitute (RTVEC_ELT (arg_vector, i), map, 1);
-+
-+      /* We really should be setting DECL_INCOMING_RTL to something reasonable
-+       here, but that's going to require some more work.  */
-+      /* DECL_INCOMING_RTL (decl) = ?; */
-+      /* Fully instantiate the address with the equivalent form so that the
-+       debugging information contains the actual register, instead of the
-+       virtual register.   Do this by not passing an insn to
-+       subst_constants.  */
-+      subst_constants (&new_decl_rtl, NULL_RTX, map, 1);
-+      apply_change_group ();
-+      SET_DECL_RTL (decl, new_decl_rtl);
-+    }
-+}
-+
-+/* Given a BLOCK node LET, push decls and levels so as to construct in the
-+   current function a tree of contexts isomorphic to the one that is given.
-+
-+   MAP, if nonzero, is a pointer to an inline_remap map which indicates how
-+   registers used in the DECL_RTL field should be remapped.  If it is zero,
-+   no mapping is necessary.  */
-+
-+static tree
-+integrate_decl_tree (let, map)
-+     tree let;
-+     struct inline_remap *map;
-+{
-+  tree t;
-+  tree new_block;
-+  tree *next;
-+
-+  new_block = make_node (BLOCK);
-+  VARRAY_PUSH_TREE (map->block_map, new_block);
-+  next = &BLOCK_VARS (new_block);
-+
-+  for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t))
-+    {
-+      tree d;
-+
-+      d = copy_decl_for_inlining (t, map->fndecl, current_function_decl);
-+
-+      if (DECL_RTL_SET_P (t))
-+      {
-+        rtx r;
-+
-+        SET_DECL_RTL (d, copy_rtx_and_substitute (DECL_RTL (t), map, 1));
-+
-+        /* Fully instantiate the address with the equivalent form so that the
-+           debugging information contains the actual register, instead of the
-+           virtual register.   Do this by not passing an insn to
-+           subst_constants.  */
-+        r = DECL_RTL (d);
-+        subst_constants (&r, NULL_RTX, map, 1);
-+        SET_DECL_RTL (d, r);
-+
-+        if (GET_CODE (r) == REG)
-+          REGNO_DECL (REGNO (r)) = d;
-+        else if (GET_CODE (r) == CONCAT)
-+          {
-+            REGNO_DECL (REGNO (XEXP (r, 0))) = d;
-+            REGNO_DECL (REGNO (XEXP (r, 1))) = d;
-+          }
-+
-+        apply_change_group ();
-+      }
-+
-+      /* Add this declaration to the list of variables in the new
-+       block.  */
-+      *next = d;
-+      next = &TREE_CHAIN (d);
-+    }
-+
-+  next = &BLOCK_SUBBLOCKS (new_block);
-+  for (t = BLOCK_SUBBLOCKS (let); t; t = BLOCK_CHAIN (t))
-+    {
-+      *next = integrate_decl_tree (t, map);
-+      BLOCK_SUPERCONTEXT (*next) = new_block;
-+      next = &BLOCK_CHAIN (*next);
-+    }
-+
-+  TREE_USED (new_block) = TREE_USED (let);
-+  BLOCK_ABSTRACT_ORIGIN (new_block) = let;
-+
-+  return new_block;
-+}
-+\f
-+/* Create a new copy of an rtx. Recursively copies the operands of the rtx,
-+   except for those few rtx codes that are sharable.
-+
-+   We always return an rtx that is similar to that incoming rtx, with the
-+   exception of possibly changing a REG to a SUBREG or vice versa.  No
-+   rtl is ever emitted.
-+
-+   If FOR_LHS is nonzero, if means we are processing something that will
-+   be the LHS of a SET.  In that case, we copy RTX_UNCHANGING_P even if
-+   inlining since we need to be conservative in how it is set for
-+   such cases.
-+
-+   Handle constants that need to be placed in the constant pool by
-+   calling `force_const_mem'.  */
-+
-+rtx
-+copy_rtx_and_substitute (orig, map, for_lhs)
-+     rtx orig;
-+     struct inline_remap *map;
-+     int for_lhs;
-+{
-+  rtx copy, temp;
-+  int i, j;
-+  RTX_CODE code;
-+  enum machine_mode mode;
-+  const char *format_ptr;
-+  int regno;
-+
-+  if (orig == 0)
-+    return 0;
-+
-+  code = GET_CODE (orig);
-+  mode = GET_MODE (orig);
-+
-+  switch (code)
-+    {
-+    case REG:
-+      /* If the stack pointer register shows up, it must be part of
-+       stack-adjustments (*not* because we eliminated the frame pointer!).
-+       Small hard registers are returned as-is.  Pseudo-registers
-+       go through their `reg_map'.  */
-+      regno = REGNO (orig);
-+      if (regno <= LAST_VIRTUAL_REGISTER
-+        || (map->integrating
-+            && DECL_SAVED_INSNS (map->fndecl)->internal_arg_pointer == orig))
-+      {
-+        /* Some hard registers are also mapped,
-+           but others are not translated.  */
-+        if (map->reg_map[regno] != 0)
-+          return map->reg_map[regno];
-+
-+        /* If this is the virtual frame pointer, make space in current
-+           function's stack frame for the stack frame of the inline function.
-+
-+           Copy the address of this area into a pseudo.  Map
-+           virtual_stack_vars_rtx to this pseudo and set up a constant
-+           equivalence for it to be the address.  This will substitute the
-+           address into insns where it can be substituted and use the new
-+           pseudo where it can't.  */
-+        else if (regno == VIRTUAL_STACK_VARS_REGNUM)
-+          {
-+            rtx loc, seq;
-+            int size = get_func_frame_size (DECL_SAVED_INSNS (map->fndecl));
-+#ifdef FRAME_GROWS_DOWNWARD
-+            int alignment
-+              = (DECL_SAVED_INSNS (map->fndecl)->stack_alignment_needed
-+                 / BITS_PER_UNIT);
-+
-+            /* In this case, virtual_stack_vars_rtx points to one byte
-+               higher than the top of the frame area.  So make sure we
-+               allocate a big enough chunk to keep the frame pointer
-+               aligned like a real one.  */
-+            if (alignment)
-+              size = CEIL_ROUND (size, alignment);
-+#endif
-+            start_sequence ();
-+            loc = assign_stack_temp (BLKmode, size, 1);
-+            loc = XEXP (loc, 0);
-+#ifdef FRAME_GROWS_DOWNWARD
-+            /* In this case, virtual_stack_vars_rtx points to one byte
-+               higher than the top of the frame area.  So compute the offset
-+               to one byte higher than our substitute frame.  */
-+            loc = plus_constant (loc, size);
-+#endif
-+            map->reg_map[regno] = temp
-+              = force_reg (Pmode, force_operand (loc, NULL_RTX));
-+
-+#ifdef STACK_BOUNDARY
-+            mark_reg_pointer (map->reg_map[regno], STACK_BOUNDARY);
-+#endif
-+
-+            SET_CONST_EQUIV_DATA (map, temp, loc, CONST_AGE_PARM);
-+
-+            seq = get_insns ();
-+            end_sequence ();
-+            emit_insn_after (seq, map->insns_at_start);
-+            return temp;
-+          }
-+        else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM
-+                 || (map->integrating
-+                     && (DECL_SAVED_INSNS (map->fndecl)->internal_arg_pointer
-+                         == orig)))
-+          {
-+            /* Do the same for a block to contain any arguments referenced
-+               in memory.  */
-+            rtx loc, seq;
-+            int size = DECL_SAVED_INSNS (map->fndecl)->args_size;
-+
-+            start_sequence ();
-+            loc = assign_stack_temp (BLKmode, size, 1);
-+            loc = XEXP (loc, 0);
-+            /* When arguments grow downward, the virtual incoming
-+               args pointer points to the top of the argument block,
-+               so the remapped location better do the same.  */
-+#ifdef ARGS_GROW_DOWNWARD
-+            loc = plus_constant (loc, size);
-+#endif
-+            map->reg_map[regno] = temp
-+              = force_reg (Pmode, force_operand (loc, NULL_RTX));
-+
-+#ifdef STACK_BOUNDARY
-+            mark_reg_pointer (map->reg_map[regno], STACK_BOUNDARY);
-+#endif
-+
-+            SET_CONST_EQUIV_DATA (map, temp, loc, CONST_AGE_PARM);
-+
-+            seq = get_insns ();
-+            end_sequence ();
-+            emit_insn_after (seq, map->insns_at_start);
-+            return temp;
-+          }
-+        else if (REG_FUNCTION_VALUE_P (orig))
-+          {
-+            /* This is a reference to the function return value.  If
-+               the function doesn't have a return value, error.  If the
-+               mode doesn't agree, and it ain't BLKmode, make a SUBREG.  */
-+            if (map->inline_target == 0)
-+              {
-+                if (rtx_equal_function_value_matters)
-+                  /* This is an ignored return value.  We must not
-+                     leave it in with REG_FUNCTION_VALUE_P set, since
-+                     that would confuse subsequent inlining of the
-+                     current function into a later function.  */
-+                  return gen_rtx_REG (GET_MODE (orig), regno);
-+                else
-+                  /* Must be unrolling loops or replicating code if we
-+                     reach here, so return the register unchanged.  */
-+                  return orig;
-+              }
-+            else if (GET_MODE (map->inline_target) != BLKmode
-+                     && mode != GET_MODE (map->inline_target))
-+              return gen_lowpart (mode, map->inline_target);
-+            else
-+              return map->inline_target;
-+          }
-+#if defined (LEAF_REGISTERS) && defined (LEAF_REG_REMAP)
-+        /* If leaf_renumber_regs_insn() might remap this register to
-+           some other number, make sure we don't share it with the
-+           inlined function, otherwise delayed optimization of the
-+           inlined function may change it in place, breaking our
-+           reference to it.  We may still shared it within the
-+           function, so create an entry for this register in the
-+           reg_map.  */
-+        if (map->integrating && regno < FIRST_PSEUDO_REGISTER
-+            && LEAF_REGISTERS[regno] && LEAF_REG_REMAP (regno) != regno)
-+          {
-+            if (!map->leaf_reg_map[regno][mode])
-+              map->leaf_reg_map[regno][mode] = gen_rtx_REG (mode, regno);
-+            return map->leaf_reg_map[regno][mode]; 
-+          }
-+#endif
-+        else
-+          return orig;
-+
-+        abort ();
-+      }
-+      if (map->reg_map[regno] == NULL)
-+      {
-+        map->reg_map[regno] = gen_reg_rtx (mode);
-+        REG_USERVAR_P (map->reg_map[regno]) = REG_USERVAR_P (orig);
-+        REG_LOOP_TEST_P (map->reg_map[regno]) = REG_LOOP_TEST_P (orig);
-+        RTX_UNCHANGING_P (map->reg_map[regno]) = RTX_UNCHANGING_P (orig);
-+        /* A reg with REG_FUNCTION_VALUE_P true will never reach here.  */
-+
-+        if (REG_POINTER (map->x_regno_reg_rtx[regno]))
-+          mark_reg_pointer (map->reg_map[regno],
-+                            map->regno_pointer_align[regno]);
-+      }
-+      return map->reg_map[regno];
-+
-+    case SUBREG:
-+      copy = copy_rtx_and_substitute (SUBREG_REG (orig), map, for_lhs);
-+      return simplify_gen_subreg (GET_MODE (orig), copy,
-+                                GET_MODE (SUBREG_REG (orig)),
-+                                SUBREG_BYTE (orig));
-+
-+    case ADDRESSOF:
-+      copy = gen_rtx_ADDRESSOF (mode,
-+                              copy_rtx_and_substitute (XEXP (orig, 0),
-+                                                       map, for_lhs),
-+                              0, ADDRESSOF_DECL (orig));
-+      regno = ADDRESSOF_REGNO (orig);
-+      if (map->reg_map[regno])
-+      regno = REGNO (map->reg_map[regno]);
-+      else if (regno > LAST_VIRTUAL_REGISTER)
-+      {
-+        temp = XEXP (orig, 0);
-+        map->reg_map[regno] = gen_reg_rtx (GET_MODE (temp));
-+        REG_USERVAR_P (map->reg_map[regno]) = REG_USERVAR_P (temp);
-+        REG_LOOP_TEST_P (map->reg_map[regno]) = REG_LOOP_TEST_P (temp);
-+        RTX_UNCHANGING_P (map->reg_map[regno]) = RTX_UNCHANGING_P (temp);
-+        /* A reg with REG_FUNCTION_VALUE_P true will never reach here.  */
-+
-+        /* Objects may initially be represented as registers, but
-+           but turned into a MEM if their address is taken by
-+           put_var_into_stack.  Therefore, the register table may have
-+           entries which are MEMs.
-+
-+           We briefly tried to clear such entries, but that ended up
-+           cascading into many changes due to the optimizers not being
-+           prepared for empty entries in the register table.  So we've
-+           decided to allow the MEMs in the register table for now.  */
-+        if (REG_P (map->x_regno_reg_rtx[regno])
-+            && REG_POINTER (map->x_regno_reg_rtx[regno]))
-+          mark_reg_pointer (map->reg_map[regno],
-+                            map->regno_pointer_align[regno]);
-+        regno = REGNO (map->reg_map[regno]);
-+      }
-+      ADDRESSOF_REGNO (copy) = regno;
-+      return copy;
-+
-+    case USE:
-+    case CLOBBER:
-+      /* USE and CLOBBER are ordinary, but we convert (use (subreg foo))
-+       to (use foo) if the original insn didn't have a subreg.
-+       Removing the subreg distorts the VAX movstrhi pattern
-+       by changing the mode of an operand.  */
-+      copy = copy_rtx_and_substitute (XEXP (orig, 0), map, code == CLOBBER);
-+      if (GET_CODE (copy) == SUBREG && GET_CODE (XEXP (orig, 0)) != SUBREG)
-+      copy = SUBREG_REG (copy);
-+      return gen_rtx_fmt_e (code, VOIDmode, copy);
-+
-+    /* We need to handle "deleted" labels that appear in the DECL_RTL
-+       of a LABEL_DECL.  */
-+    case NOTE:
-+      if (NOTE_LINE_NUMBER (orig) != NOTE_INSN_DELETED_LABEL)
-+      break;
-+
-+      /* ... FALLTHRU ...  */
-+    case CODE_LABEL:
-+      LABEL_PRESERVE_P (get_label_from_map (map, CODE_LABEL_NUMBER (orig)))
-+      = LABEL_PRESERVE_P (orig);
-+      return get_label_from_map (map, CODE_LABEL_NUMBER (orig));
-+
-+    case LABEL_REF:
-+      copy
-+      = gen_rtx_LABEL_REF
-+        (mode,
-+         LABEL_REF_NONLOCAL_P (orig) ? XEXP (orig, 0)
-+         : get_label_from_map (map, CODE_LABEL_NUMBER (XEXP (orig, 0))));
-+
-+      LABEL_OUTSIDE_LOOP_P (copy) = LABEL_OUTSIDE_LOOP_P (orig);
-+
-+      /* The fact that this label was previously nonlocal does not mean
-+       it still is, so we must check if it is within the range of
-+       this function's labels.  */
-+      LABEL_REF_NONLOCAL_P (copy)
-+      = (LABEL_REF_NONLOCAL_P (orig)
-+         && ! (CODE_LABEL_NUMBER (XEXP (copy, 0)) >= get_first_label_num ()
-+               && CODE_LABEL_NUMBER (XEXP (copy, 0)) < max_label_num ()));
-+
-+      /* If we have made a nonlocal label local, it means that this
-+       inlined call will be referring to our nonlocal goto handler.
-+       So make sure we create one for this block; we normally would
-+       not since this is not otherwise considered a "call".  */
-+      if (LABEL_REF_NONLOCAL_P (orig) && ! LABEL_REF_NONLOCAL_P (copy))
-+      function_call_count++;
-+
-+      return copy;
-+
-+    case PC:
-+    case CC0:
-+    case CONST_INT:
-+    case CONST_VECTOR:
-+      return orig;
-+
-+    case SYMBOL_REF:
-+      /* Symbols which represent the address of a label stored in the constant
-+       pool must be modified to point to a constant pool entry for the
-+       remapped label.  Otherwise, symbols are returned unchanged.  */
-+      if (CONSTANT_POOL_ADDRESS_P (orig))
-+      {
-+        struct function *f = inlining ? inlining : cfun;
-+        rtx constant = get_pool_constant_for_function (f, orig);
-+        enum machine_mode const_mode = get_pool_mode_for_function (f, orig);
-+        if (inlining)
-+          {
-+            rtx temp = force_const_mem (const_mode,
-+                                        copy_rtx_and_substitute (constant,
-+                                                                 map, 0));
-+
-+#if 0
-+            /* Legitimizing the address here is incorrect.
-+
-+               Since we had a SYMBOL_REF before, we can assume it is valid
-+               to have one in this position in the insn.
-+
-+               Also, change_address may create new registers.  These
-+               registers will not have valid reg_map entries.  This can
-+               cause try_constants() to fail because assumes that all
-+               registers in the rtx have valid reg_map entries, and it may
-+               end up replacing one of these new registers with junk.  */
-+
-+            if (! memory_address_p (GET_MODE (temp), XEXP (temp, 0)))
-+              temp = change_address (temp, GET_MODE (temp), XEXP (temp, 0));
-+#endif
-+
-+            temp = XEXP (temp, 0);
-+
-+#ifdef POINTERS_EXTEND_UNSIGNED
-+            if (GET_MODE (temp) != GET_MODE (orig))
-+              temp = convert_memory_address (GET_MODE (orig), temp);
-+#endif
-+            return temp;
-+          }
-+        else if (GET_CODE (constant) == LABEL_REF)
-+          return XEXP (force_const_mem
-+                       (GET_MODE (orig),
-+                        copy_rtx_and_substitute (constant, map, for_lhs)),
-+                       0);
-+      }
-+
-+      return orig;
-+
-+    case CONST_DOUBLE:
-+      /* We have to make a new copy of this CONST_DOUBLE because don't want
-+       to use the old value of CONST_DOUBLE_MEM.  Also, this may be a
-+       duplicate of a CONST_DOUBLE we have already seen.  */
-+      if (GET_MODE_CLASS (GET_MODE (orig)) == MODE_FLOAT)
-+      {
-+        REAL_VALUE_TYPE d;
-+
-+        REAL_VALUE_FROM_CONST_DOUBLE (d, orig);
-+        return CONST_DOUBLE_FROM_REAL_VALUE (d, GET_MODE (orig));
-+      }
-+      else
-+      return immed_double_const (CONST_DOUBLE_LOW (orig),
-+                                 CONST_DOUBLE_HIGH (orig), VOIDmode);
-+
-+    case CONST:
-+      /* Make new constant pool entry for a constant
-+       that was in the pool of the inline function.  */
-+      if (RTX_INTEGRATED_P (orig))
-+      abort ();
-+      break;
-+
-+    case ASM_OPERANDS:
-+      /* If a single asm insn contains multiple output operands then
-+       it contains multiple ASM_OPERANDS rtx's that share the input
-+       and constraint vecs.  We must make sure that the copied insn
-+       continues to share it.  */
-+      if (map->orig_asm_operands_vector == ASM_OPERANDS_INPUT_VEC (orig))
-+      {
-+        copy = rtx_alloc (ASM_OPERANDS);
-+        RTX_FLAG (copy, volatil) = RTX_FLAG (orig, volatil);
-+        PUT_MODE (copy, GET_MODE (orig));
-+        ASM_OPERANDS_TEMPLATE (copy) = ASM_OPERANDS_TEMPLATE (orig);
-+        ASM_OPERANDS_OUTPUT_CONSTRAINT (copy)
-+          = ASM_OPERANDS_OUTPUT_CONSTRAINT (orig);
-+        ASM_OPERANDS_OUTPUT_IDX (copy) = ASM_OPERANDS_OUTPUT_IDX (orig);
-+        ASM_OPERANDS_INPUT_VEC (copy) = map->copy_asm_operands_vector;
-+        ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy)
-+          = map->copy_asm_constraints_vector;
-+        ASM_OPERANDS_SOURCE_FILE (copy) = ASM_OPERANDS_SOURCE_FILE (orig);
-+        ASM_OPERANDS_SOURCE_LINE (copy) = ASM_OPERANDS_SOURCE_LINE (orig);
-+        return copy;
-+      }
-+      break;
-+
-+    case CALL:
-+      /* This is given special treatment because the first
-+       operand of a CALL is a (MEM ...) which may get
-+       forced into a register for cse.  This is undesirable
-+       if function-address cse isn't wanted or if we won't do cse.  */
-+#ifndef NO_FUNCTION_CSE
-+      if (! (optimize && ! flag_no_function_cse))
-+#endif
-+      {
-+        rtx copy
-+          = gen_rtx_MEM (GET_MODE (XEXP (orig, 0)),
-+                         copy_rtx_and_substitute (XEXP (XEXP (orig, 0), 0),
-+                                                  map, 0));
-+
-+        MEM_COPY_ATTRIBUTES (copy, XEXP (orig, 0));
-+
-+        return
-+          gen_rtx_CALL (GET_MODE (orig), copy, 
-+                        copy_rtx_and_substitute (XEXP (orig, 1), map, 0));
-+      }
-+      break;
-+
-+#if 0
-+      /* Must be ifdefed out for loop unrolling to work.  */
-+    case RETURN:
-+      abort ();
-+#endif
-+
-+    case SET:
-+      /* If this is setting fp or ap, it means that we have a nonlocal goto.
-+       Adjust the setting by the offset of the area we made.
-+       If the nonlocal goto is into the current function,
-+       this will result in unnecessarily bad code, but should work.  */
-+      if (SET_DEST (orig) == virtual_stack_vars_rtx
-+        || SET_DEST (orig) == virtual_incoming_args_rtx)
-+      {
-+        /* In case a translation hasn't occurred already, make one now.  */
-+        rtx equiv_reg;
-+        rtx equiv_loc;
-+        HOST_WIDE_INT loc_offset;
-+
-+        copy_rtx_and_substitute (SET_DEST (orig), map, for_lhs);
-+        equiv_reg = map->reg_map[REGNO (SET_DEST (orig))];
-+        equiv_loc = VARRAY_CONST_EQUIV (map->const_equiv_varray,
-+                                        REGNO (equiv_reg)).rtx;
-+        loc_offset
-+          = GET_CODE (equiv_loc) == REG ? 0 : INTVAL (XEXP (equiv_loc, 1));
-+
-+        return gen_rtx_SET (VOIDmode, SET_DEST (orig),
-+                            force_operand
-+                            (plus_constant
-+                             (copy_rtx_and_substitute (SET_SRC (orig),
-+                                                       map, 0),
-+                              - loc_offset),
-+                             NULL_RTX));
-+      }
-+      else
-+      return gen_rtx_SET (VOIDmode,
-+                          copy_rtx_and_substitute (SET_DEST (orig), map, 1),
-+                          copy_rtx_and_substitute (SET_SRC (orig), map, 0));
-+      break;
-+
-+    case MEM:
-+      if (inlining
-+        && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
-+        && CONSTANT_POOL_ADDRESS_P (XEXP (orig, 0)))
-+      {
-+        enum machine_mode const_mode
-+          = get_pool_mode_for_function (inlining, XEXP (orig, 0));
-+        rtx constant
-+          = get_pool_constant_for_function (inlining, XEXP (orig, 0));
-+
-+        constant = copy_rtx_and_substitute (constant, map, 0);
-+
-+        /* If this was an address of a constant pool entry that itself
-+           had to be placed in the constant pool, it might not be a
-+           valid address.  So the recursive call might have turned it
-+           into a register.  In that case, it isn't a constant any
-+           more, so return it.  This has the potential of changing a
-+           MEM into a REG, but we'll assume that it safe.  */
-+        if (! CONSTANT_P (constant))
-+          return constant;
-+
-+        return validize_mem (force_const_mem (const_mode, constant));
-+      }
-+
-+      copy = gen_rtx_MEM (mode, copy_rtx_and_substitute (XEXP (orig, 0),
-+                                                       map, 0));
-+      MEM_COPY_ATTRIBUTES (copy, orig);
-+
-+      /* If inlining and this is not for the LHS, turn off RTX_UNCHANGING_P
-+       since this may be an indirect reference to a parameter and the
-+       actual may not be readonly.  */
-+      if (inlining && !for_lhs)
-+      RTX_UNCHANGING_P (copy) = 0;
-+
-+      /* If inlining, squish aliasing data that references the subroutine's
-+       parameter list, since that's no longer applicable.  */
-+      if (inlining && MEM_EXPR (copy)
-+        && TREE_CODE (MEM_EXPR (copy)) == INDIRECT_REF
-+        && TREE_CODE (TREE_OPERAND (MEM_EXPR (copy), 0)) == PARM_DECL)
-+      set_mem_expr (copy, NULL_TREE);
-+
-+      return copy;
-+
-+    default:
-+      break;
-+    }
-+
-+  copy = rtx_alloc (code);
-+  PUT_MODE (copy, mode);
-+  RTX_FLAG (copy, in_struct) = RTX_FLAG (orig, in_struct);
-+  RTX_FLAG (copy, volatil) = RTX_FLAG (orig, volatil);
-+  RTX_FLAG (copy, unchanging) = RTX_FLAG (orig, unchanging);
-+
-+  format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
-+
-+  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
-+    {
-+      switch (*format_ptr++)
-+      {
-+      case '0':
-+        /* Copy this through the wide int field; that's safest.  */
-+        X0WINT (copy, i) = X0WINT (orig, i);
-+        break;
-+
-+      case 'e':
-+        XEXP (copy, i)
-+          = copy_rtx_and_substitute (XEXP (orig, i), map, for_lhs);
-+        break;
-+
-+      case 'u':
-+        /* Change any references to old-insns to point to the
-+           corresponding copied insns.  */
-+        XEXP (copy, i) = map->insn_map[INSN_UID (XEXP (orig, i))];
-+        break;
-+
-+      case 'E':
-+        XVEC (copy, i) = XVEC (orig, i);
-+        if (XVEC (orig, i) != NULL && XVECLEN (orig, i) != 0)
-+          {
-+            XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
-+            for (j = 0; j < XVECLEN (copy, i); j++)
-+              XVECEXP (copy, i, j)
-+                = copy_rtx_and_substitute (XVECEXP (orig, i, j),
-+                                           map, for_lhs);
-+          }
-+        break;
-+
-+      case 'w':
-+        XWINT (copy, i) = XWINT (orig, i);
-+        break;
-+
-+      case 'i':
-+        XINT (copy, i) = XINT (orig, i);
-+        break;
-+
-+      case 's':
-+        XSTR (copy, i) = XSTR (orig, i);
-+        break;
-+
-+      case 't':
-+        XTREE (copy, i) = XTREE (orig, i);
-+        break;
-+
-+      default:
-+        abort ();
-+      }
-+    }
-+
-+  if (code == ASM_OPERANDS && map->orig_asm_operands_vector == 0)
-+    {
-+      map->orig_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (orig);
-+      map->copy_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (copy);
-+      map->copy_asm_constraints_vector
-+      = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy);
-+    }
-+
-+  return copy;
-+}
-+\f
-+/* Substitute known constant values into INSN, if that is valid.  */
-+
-+void
-+try_constants (insn, map)
-+     rtx insn;
-+     struct inline_remap *map;
-+{
-+  int i;
-+
-+  map->num_sets = 0;
-+
-+  /* First try just updating addresses, then other things.  This is
-+     important when we have something like the store of a constant
-+     into memory and we can update the memory address but the machine
-+     does not support a constant source.  */
-+  subst_constants (&PATTERN (insn), insn, map, 1);
-+  apply_change_group ();
-+  subst_constants (&PATTERN (insn), insn, map, 0);
-+  apply_change_group ();
-+
-+  /* Show we don't know the value of anything stored or clobbered.  */
-+  note_stores (PATTERN (insn), mark_stores, NULL);
-+  map->last_pc_value = 0;
-+#ifdef HAVE_cc0
-+  map->last_cc0_value = 0;
-+#endif
-+
-+  /* Set up any constant equivalences made in this insn.  */
-+  for (i = 0; i < map->num_sets; i++)
-+    {
-+      if (GET_CODE (map->equiv_sets[i].dest) == REG)
-+      {
-+        int regno = REGNO (map->equiv_sets[i].dest);
-+
-+        MAYBE_EXTEND_CONST_EQUIV_VARRAY (map, regno);
-+        if (VARRAY_CONST_EQUIV (map->const_equiv_varray, regno).rtx == 0
-+            /* Following clause is a hack to make case work where GNU C++
-+               reassigns a variable to make cse work right.  */
-+            || ! rtx_equal_p (VARRAY_CONST_EQUIV (map->const_equiv_varray,
-+                                                  regno).rtx,
-+                              map->equiv_sets[i].equiv))
-+          SET_CONST_EQUIV_DATA (map, map->equiv_sets[i].dest,
-+                                map->equiv_sets[i].equiv, map->const_age);
-+      }
-+      else if (map->equiv_sets[i].dest == pc_rtx)
-+      map->last_pc_value = map->equiv_sets[i].equiv;
-+#ifdef HAVE_cc0
-+      else if (map->equiv_sets[i].dest == cc0_rtx)
-+      map->last_cc0_value = map->equiv_sets[i].equiv;
-+#endif
-+    }
-+}
-+\f
-+/* Substitute known constants for pseudo regs in the contents of LOC,
-+   which are part of INSN.
-+   If INSN is zero, the substitution should always be done (this is used to
-+   update DECL_RTL).
-+   These changes are taken out by try_constants if the result is not valid.
-+
-+   Note that we are more concerned with determining when the result of a SET
-+   is a constant, for further propagation, than actually inserting constants
-+   into insns; cse will do the latter task better.
-+
-+   This function is also used to adjust address of items previously addressed
-+   via the virtual stack variable or virtual incoming arguments registers.
-+
-+   If MEMONLY is nonzero, only make changes inside a MEM.  */
-+
-+static void
-+subst_constants (loc, insn, map, memonly)
-+     rtx *loc;
-+     rtx insn;
-+     struct inline_remap *map;
-+     int memonly;
-+{
-+  rtx x = *loc;
-+  int i, j;
-+  enum rtx_code code;
-+  const char *format_ptr;
-+  int num_changes = num_validated_changes ();
-+  rtx new = 0;
-+  enum machine_mode op0_mode = MAX_MACHINE_MODE;
-+
-+  code = GET_CODE (x);
-+
-+  switch (code)
-+    {
-+    case PC:
-+    case CONST_INT:
-+    case CONST_DOUBLE:
-+    case CONST_VECTOR:
-+    case SYMBOL_REF:
-+    case CONST:
-+    case LABEL_REF:
-+    case ADDRESS:
-+      return;
-+
-+#ifdef HAVE_cc0
-+    case CC0:
-+      if (! memonly)
-+      validate_change (insn, loc, map->last_cc0_value, 1);
-+      return;
-+#endif
-+
-+    case USE:
-+    case CLOBBER:
-+      /* The only thing we can do with a USE or CLOBBER is possibly do
-+       some substitutions in a MEM within it.  */
-+      if (GET_CODE (XEXP (x, 0)) == MEM)
-+      subst_constants (&XEXP (XEXP (x, 0), 0), insn, map, 0);
-+      return;
-+
-+    case REG:
-+      /* Substitute for parms and known constants.  Don't replace
-+       hard regs used as user variables with constants.  */
-+      if (! memonly)
-+      {
-+        int regno = REGNO (x);
-+        struct const_equiv_data *p;
-+
-+        if (! (regno < FIRST_PSEUDO_REGISTER && REG_USERVAR_P (x))
-+            && (size_t) regno < VARRAY_SIZE (map->const_equiv_varray)
-+            && (p = &VARRAY_CONST_EQUIV (map->const_equiv_varray, regno),
-+                p->rtx != 0)
-+            && p->age >= map->const_age)
-+          validate_change (insn, loc, p->rtx, 1);
-+      }
-+      return;
-+
-+    case SUBREG:
-+      /* SUBREG applied to something other than a reg
-+       should be treated as ordinary, since that must
-+       be a special hack and we don't know how to treat it specially.
-+       Consider for example mulsidi3 in m68k.md.
-+       Ordinary SUBREG of a REG needs this special treatment.  */
-+      if (! memonly && GET_CODE (SUBREG_REG (x)) == REG)
-+      {
-+        rtx inner = SUBREG_REG (x);
-+        rtx new = 0;
-+
-+        /* We can't call subst_constants on &SUBREG_REG (x) because any
-+           constant or SUBREG wouldn't be valid inside our SUBEG.  Instead,
-+           see what is inside, try to form the new SUBREG and see if that is
-+           valid.  We handle two cases: extracting a full word in an
-+           integral mode and extracting the low part.  */
-+        subst_constants (&inner, NULL_RTX, map, 0);
-+        new = simplify_gen_subreg (GET_MODE (x), inner,
-+                                   GET_MODE (SUBREG_REG (x)),
-+                                   SUBREG_BYTE (x));
-+
-+        if (new)
-+          validate_change (insn, loc, new, 1);
-+        else
-+          cancel_changes (num_changes);
-+
-+        return;
-+      }
-+      break;
-+
-+    case MEM:
-+      subst_constants (&XEXP (x, 0), insn, map, 0);
-+
-+      /* If a memory address got spoiled, change it back.  */
-+      if (! memonly && insn != 0 && num_validated_changes () != num_changes
-+        && ! memory_address_p (GET_MODE (x), XEXP (x, 0)))
-+      cancel_changes (num_changes);
-+      return;
-+
-+    case SET:
-+      {
-+      /* Substitute constants in our source, and in any arguments to a
-+         complex (e..g, ZERO_EXTRACT) destination, but not in the destination
-+         itself.  */
-+      rtx *dest_loc = &SET_DEST (x);
-+      rtx dest = *dest_loc;
-+      rtx src, tem;
-+      enum machine_mode compare_mode = VOIDmode;
-+
-+      /* If SET_SRC is a COMPARE which subst_constants would turn into
-+         COMPARE of 2 VOIDmode constants, note the mode in which comparison
-+         is to be done.  */
-+      if (GET_CODE (SET_SRC (x)) == COMPARE)
-+        {
-+          src = SET_SRC (x);
-+          if (GET_MODE_CLASS (GET_MODE (src)) == MODE_CC
-+#ifdef HAVE_cc0
-+              || dest == cc0_rtx
-+#endif
-+              )
-+            {
-+              compare_mode = GET_MODE (XEXP (src, 0));
-+              if (compare_mode == VOIDmode)
-+                compare_mode = GET_MODE (XEXP (src, 1));
-+            }
-+        }
-+
-+      subst_constants (&SET_SRC (x), insn, map, memonly);
-+      src = SET_SRC (x);
-+
-+      while (GET_CODE (*dest_loc) == ZERO_EXTRACT
-+             || GET_CODE (*dest_loc) == SUBREG
-+             || GET_CODE (*dest_loc) == STRICT_LOW_PART)
-+        {
-+          if (GET_CODE (*dest_loc) == ZERO_EXTRACT)
-+            {
-+              subst_constants (&XEXP (*dest_loc, 1), insn, map, memonly);
-+              subst_constants (&XEXP (*dest_loc, 2), insn, map, memonly);
-+            }
-+          dest_loc = &XEXP (*dest_loc, 0);
-+        }
-+
-+      /* Do substitute in the address of a destination in memory.  */
-+      if (GET_CODE (*dest_loc) == MEM)
-+        subst_constants (&XEXP (*dest_loc, 0), insn, map, 0);
-+
-+      /* Check for the case of DEST a SUBREG, both it and the underlying
-+         register are less than one word, and the SUBREG has the wider mode.
-+         In the case, we are really setting the underlying register to the
-+         source converted to the mode of DEST.  So indicate that.  */
-+      if (GET_CODE (dest) == SUBREG
-+          && GET_MODE_SIZE (GET_MODE (dest)) <= UNITS_PER_WORD
-+          && GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) <= UNITS_PER_WORD
-+          && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
-+                    <= GET_MODE_SIZE (GET_MODE (dest)))
-+          && (tem = gen_lowpart_if_possible (GET_MODE (SUBREG_REG (dest)),
-+                                             src)))
-+        src = tem, dest = SUBREG_REG (dest);
-+
-+      /* If storing a recognizable value save it for later recording.  */
-+      if ((map->num_sets < MAX_RECOG_OPERANDS)
-+          && (CONSTANT_P (src)
-+              || (GET_CODE (src) == REG
-+                  && (REGNO (src) == VIRTUAL_INCOMING_ARGS_REGNUM
-+                      || REGNO (src) == VIRTUAL_STACK_VARS_REGNUM))
-+              || (GET_CODE (src) == PLUS
-+                  && GET_CODE (XEXP (src, 0)) == REG
-+                  && (REGNO (XEXP (src, 0)) == VIRTUAL_INCOMING_ARGS_REGNUM
-+                      || REGNO (XEXP (src, 0)) == VIRTUAL_STACK_VARS_REGNUM)
-+                  && CONSTANT_P (XEXP (src, 1)))
-+              || GET_CODE (src) == COMPARE
-+#ifdef HAVE_cc0
-+              || dest == cc0_rtx
-+#endif
-+              || (dest == pc_rtx
-+                  && (src == pc_rtx || GET_CODE (src) == RETURN
-+                      || GET_CODE (src) == LABEL_REF))))
-+        {
-+          /* Normally, this copy won't do anything.  But, if SRC is a COMPARE
-+             it will cause us to save the COMPARE with any constants
-+             substituted, which is what we want for later.  */
-+          rtx src_copy = copy_rtx (src);
-+          map->equiv_sets[map->num_sets].equiv = src_copy;
-+          map->equiv_sets[map->num_sets++].dest = dest;
-+          if (compare_mode != VOIDmode
-+              && GET_CODE (src) == COMPARE
-+              && (GET_MODE_CLASS (GET_MODE (src)) == MODE_CC
-+#ifdef HAVE_cc0
-+                  || dest == cc0_rtx
-+#endif
-+                  )
-+              && GET_MODE (XEXP (src, 0)) == VOIDmode
-+              && GET_MODE (XEXP (src, 1)) == VOIDmode)
-+            {
-+              map->compare_src = src_copy;
-+              map->compare_mode = compare_mode;
-+            }
-+        }
-+      }
-+      return;
-+
-+    default:
-+      break;
-+    }
-+
-+  format_ptr = GET_RTX_FORMAT (code);
-+
-+  /* If the first operand is an expression, save its mode for later.  */
-+  if (*format_ptr == 'e')
-+    op0_mode = GET_MODE (XEXP (x, 0));
-+
-+  for (i = 0; i < GET_RTX_LENGTH (code); i++)
-+    {
-+      switch (*format_ptr++)
-+      {
-+      case '0':
-+        break;
-+
-+      case 'e':
-+        if (XEXP (x, i))
-+          subst_constants (&XEXP (x, i), insn, map, memonly);
-+        break;
-+
-+      case 'u':
-+      case 'i':
-+      case 's':
-+      case 'w':
-+      case 'n':
-+      case 't':
-+      case 'B':
-+        break;
-+
-+      case 'E':
-+        if (XVEC (x, i) != NULL && XVECLEN (x, i) != 0)
-+          for (j = 0; j < XVECLEN (x, i); j++)
-+            subst_constants (&XVECEXP (x, i, j), insn, map, memonly);
-+
-+        break;
-+
-+      default:
-+        abort ();
-+      }
-+    }
-+
-+  /* If this is a commutative operation, move a constant to the second
-+     operand unless the second operand is already a CONST_INT.  */
-+  if (! memonly
-+      && (GET_RTX_CLASS (code) == 'c' || code == NE || code == EQ)
-+      && CONSTANT_P (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) != CONST_INT)
-+    {
-+      rtx tem = XEXP (x, 0);
-+      validate_change (insn, &XEXP (x, 0), XEXP (x, 1), 1);
-+      validate_change (insn, &XEXP (x, 1), tem, 1);
-+    }
-+
-+  /* Simplify the expression in case we put in some constants.  */
-+  if (! memonly)
-+    switch (GET_RTX_CLASS (code))
-+      {
-+      case '1':
-+      if (op0_mode == MAX_MACHINE_MODE)
-+        abort ();
-+      new = simplify_unary_operation (code, GET_MODE (x),
-+                                      XEXP (x, 0), op0_mode);
-+      break;
-+
-+      case '<':
-+      {
-+        enum machine_mode op_mode = GET_MODE (XEXP (x, 0));
-+
-+        if (op_mode == VOIDmode)
-+          op_mode = GET_MODE (XEXP (x, 1));
-+        new = simplify_relational_operation (code, op_mode,
-+                                             XEXP (x, 0), XEXP (x, 1));
-+#ifdef FLOAT_STORE_FLAG_VALUE
-+        if (new != 0 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
-+          {
-+            enum machine_mode mode = GET_MODE (x);
-+            if (new == const0_rtx)
-+              new = CONST0_RTX (mode);
-+            else
-+              {
-+                REAL_VALUE_TYPE val;
-+
-+                /* Avoid automatic aggregate initialization.  */
-+                val = FLOAT_STORE_FLAG_VALUE (mode);
-+                new = CONST_DOUBLE_FROM_REAL_VALUE (val, mode);
-+              }
-+          }
-+#endif
-+        break;
-+      }
-+
-+      case '2':
-+      case 'c':
-+      new = simplify_binary_operation (code, GET_MODE (x),
-+                                       XEXP (x, 0), XEXP (x, 1));
-+      break;
-+
-+      case 'b':
-+      case '3':
-+      if (op0_mode == MAX_MACHINE_MODE)
-+        abort ();
-+
-+      if (code == IF_THEN_ELSE)
-+        {
-+          rtx op0 = XEXP (x, 0);
-+
-+          if (GET_RTX_CLASS (GET_CODE (op0)) == '<'
-+              && GET_MODE (op0) == VOIDmode
-+              && ! side_effects_p (op0)
-+              && XEXP (op0, 0) == map->compare_src
-+              && GET_MODE (XEXP (op0, 1)) == VOIDmode)
-+            {
-+              /* We have compare of two VOIDmode constants for which
-+                 we recorded the comparison mode.  */
-+              rtx temp =
-+                simplify_relational_operation (GET_CODE (op0),
-+                                               map->compare_mode,
-+                                               XEXP (op0, 0),
-+                                               XEXP (op0, 1));
-+
-+              if (temp == const0_rtx)
-+                new = XEXP (x, 2);
-+              else if (temp == const1_rtx)
-+                new = XEXP (x, 1);
-+            }
-+        }
-+      if (!new)
-+        new = simplify_ternary_operation (code, GET_MODE (x), op0_mode,
-+                                          XEXP (x, 0), XEXP (x, 1),
-+                                          XEXP (x, 2));
-+      break;
-+      }
-+
-+  if (new)
-+    validate_change (insn, loc, new, 1);
-+}
-+
-+/* Show that register modified no longer contain known constants.  We are
-+   called from note_stores with parts of the new insn.  */
-+
-+static void
-+mark_stores (dest, x, data)
-+     rtx dest;
-+     rtx x ATTRIBUTE_UNUSED;
-+     void *data ATTRIBUTE_UNUSED;
-+{
-+  int regno = -1;
-+  enum machine_mode mode = VOIDmode;
-+
-+  /* DEST is always the innermost thing set, except in the case of
-+     SUBREGs of hard registers.  */
-+
-+  if (GET_CODE (dest) == REG)
-+    regno = REGNO (dest), mode = GET_MODE (dest);
-+  else if (GET_CODE (dest) == SUBREG && GET_CODE (SUBREG_REG (dest)) == REG)
-+    {
-+      regno = REGNO (SUBREG_REG (dest));
-+      if (regno < FIRST_PSEUDO_REGISTER)
-+      regno += subreg_regno_offset (REGNO (SUBREG_REG (dest)),
-+                                    GET_MODE (SUBREG_REG (dest)),
-+                                    SUBREG_BYTE (dest),
-+                                    GET_MODE (dest));
-+      mode = GET_MODE (SUBREG_REG (dest));
-+    }
-+
-+  if (regno >= 0)
-+    {
-+      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 (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;
-+    }
-+}
-+\f
-+/* Given a pointer to some BLOCK node, if the BLOCK_ABSTRACT_ORIGIN for the
-+   given BLOCK node is NULL, set the BLOCK_ABSTRACT_ORIGIN for the node so
-+   that it points to the node itself, thus indicating that the node is its
-+   own (abstract) origin.  Additionally, if the BLOCK_ABSTRACT_ORIGIN for
-+   the given node is NULL, recursively descend the decl/block tree which
-+   it is the root of, and for each other ..._DECL or BLOCK node contained
-+   therein whose DECL_ABSTRACT_ORIGINs or BLOCK_ABSTRACT_ORIGINs are also
-+   still NULL, set *their* DECL_ABSTRACT_ORIGIN or BLOCK_ABSTRACT_ORIGIN
-+   values to point to themselves.  */
-+
-+static void
-+set_block_origin_self (stmt)
-+     tree stmt;
-+{
-+  if (BLOCK_ABSTRACT_ORIGIN (stmt) == NULL_TREE)
-+    {
-+      BLOCK_ABSTRACT_ORIGIN (stmt) = stmt;
-+
-+      {
-+      tree local_decl;
-+
-+      for (local_decl = BLOCK_VARS (stmt);
-+           local_decl != NULL_TREE;
-+           local_decl = TREE_CHAIN (local_decl))
-+        set_decl_origin_self (local_decl);    /* Potential recursion.  */
-+      }
-+
-+      {
-+      tree subblock;
-+
-+      for (subblock = BLOCK_SUBBLOCKS (stmt);
-+           subblock != NULL_TREE;
-+           subblock = BLOCK_CHAIN (subblock))
-+        set_block_origin_self (subblock);     /* Recurse.  */
-+      }
-+    }
-+}
-+
-+/* Given a pointer to some ..._DECL node, if the DECL_ABSTRACT_ORIGIN for
-+   the given ..._DECL node is NULL, set the DECL_ABSTRACT_ORIGIN for the
-+   node to so that it points to the node itself, thus indicating that the
-+   node represents its own (abstract) origin.  Additionally, if the
-+   DECL_ABSTRACT_ORIGIN for the given node is NULL, recursively descend
-+   the decl/block tree of which the given node is the root of, and for
-+   each other ..._DECL or BLOCK node contained therein whose
-+   DECL_ABSTRACT_ORIGINs or BLOCK_ABSTRACT_ORIGINs are also still NULL,
-+   set *their* DECL_ABSTRACT_ORIGIN or BLOCK_ABSTRACT_ORIGIN values to
-+   point to themselves.  */
-+
-+void
-+set_decl_origin_self (decl)
-+     tree decl;
-+{
-+  if (DECL_ABSTRACT_ORIGIN (decl) == NULL_TREE)
-+    {
-+      DECL_ABSTRACT_ORIGIN (decl) = decl;
-+      if (TREE_CODE (decl) == FUNCTION_DECL)
-+      {
-+        tree arg;
-+
-+        for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg))
-+          DECL_ABSTRACT_ORIGIN (arg) = arg;
-+        if (DECL_INITIAL (decl) != NULL_TREE
-+            && DECL_INITIAL (decl) != error_mark_node)
-+          set_block_origin_self (DECL_INITIAL (decl));
-+      }
-+    }
-+}
-+\f
-+/* Given a pointer to some BLOCK node, and a boolean value to set the
-+   "abstract" flags to, set that value into the BLOCK_ABSTRACT flag for
-+   the given block, and for all local decls and all local sub-blocks
-+   (recursively) which are contained therein.  */
-+
-+static void
-+set_block_abstract_flags (stmt, setting)
-+     tree stmt;
-+     int setting;
-+{
-+  tree local_decl;
-+  tree subblock;
-+
-+  BLOCK_ABSTRACT (stmt) = setting;
-+
-+  for (local_decl = BLOCK_VARS (stmt);
-+       local_decl != NULL_TREE;
-+       local_decl = TREE_CHAIN (local_decl))
-+    set_decl_abstract_flags (local_decl, setting);
-+
-+  for (subblock = BLOCK_SUBBLOCKS (stmt);
-+       subblock != NULL_TREE;
-+       subblock = BLOCK_CHAIN (subblock))
-+    set_block_abstract_flags (subblock, setting);
-+}
-+
-+/* Given a pointer to some ..._DECL node, and a boolean value to set the
-+   "abstract" flags to, set that value into the DECL_ABSTRACT flag for the
-+   given decl, and (in the case where the decl is a FUNCTION_DECL) also
-+   set the abstract flags for all of the parameters, local vars, local
-+   blocks and sub-blocks (recursively) to the same setting.  */
-+
-+void
-+set_decl_abstract_flags (decl, setting)
-+     tree decl;
-+     int setting;
-+{
-+  DECL_ABSTRACT (decl) = setting;
-+  if (TREE_CODE (decl) == FUNCTION_DECL)
-+    {
-+      tree arg;
-+
-+      for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg))
-+      DECL_ABSTRACT (arg) = setting;
-+      if (DECL_INITIAL (decl) != NULL_TREE
-+        && DECL_INITIAL (decl) != error_mark_node)
-+      set_block_abstract_flags (DECL_INITIAL (decl), setting);
-+    }
-+}
-+\f
-+/* Output the assembly language code for the function FNDECL
-+   from its DECL_SAVED_INSNS.  Used for inline functions that are output
-+   at end of compilation instead of where they came in the source.  */
-+
-+static GTY(()) struct function *old_cfun;
-+
-+void
-+output_inline_function (fndecl)
-+     tree fndecl;
-+{
-+  enum debug_info_type old_write_symbols = write_symbols;
-+  const struct gcc_debug_hooks *const old_debug_hooks = debug_hooks;
-+  struct function *f = DECL_SAVED_INSNS (fndecl);
-+
-+  old_cfun = cfun;
-+  cfun = f;
-+  current_function_decl = fndecl;
-+
-+  set_new_last_label_num (f->inl_max_label_num);
-+
-+  /* We're not deferring this any longer.  */
-+  DECL_DEFER_OUTPUT (fndecl) = 0;
-+
-+  /* If requested, suppress debugging information.  */
-+  if (f->no_debugging_symbols)
-+    {
-+      write_symbols = NO_DEBUG;
-+      debug_hooks = &do_nothing_debug_hooks;
-+    }
-+
-+  /* Make sure warnings emitted by the optimizers (e.g. control reaches
-+     end of non-void function) is not wildly incorrect.  */
-+  input_filename = DECL_SOURCE_FILE (fndecl);
-+  lineno = DECL_SOURCE_LINE (fndecl);
-+
-+  /* Compile this function all the way down to assembly code.  As a
-+     side effect this destroys the saved RTL representation, but
-+     that's okay, because we don't need to inline this anymore.  */
-+  rest_of_compilation (fndecl);
-+  DECL_INLINE (fndecl) = 0;
-+
-+  cfun = old_cfun;
-+  current_function_decl = old_cfun ? old_cfun->decl : 0;
-+  write_symbols = old_write_symbols;
-+  debug_hooks = old_debug_hooks;
-+}
-+
-+\f
-+/* Functions to keep track of the values hard regs had at the start of
-+   the function.  */
-+
-+rtx
-+get_hard_reg_initial_reg (fun, reg)
-+     struct function *fun;
-+     rtx reg;
-+{
-+  struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
-+  int i;
-+
-+  if (ivs == 0)
-+    return NULL_RTX;
-+
-+  for (i = 0; i < ivs->num_entries; i++)
-+    if (rtx_equal_p (ivs->entries[i].pseudo, reg))
-+      return ivs->entries[i].hard_reg;
-+
-+  return NULL_RTX;
-+}
-+
-+rtx
-+has_func_hard_reg_initial_val (fun, reg)
-+     struct function *fun;
-+     rtx reg;
-+{
-+  struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
-+  int i;
-+
-+  if (ivs == 0)
-+    return NULL_RTX;
-+
-+  for (i = 0; i < ivs->num_entries; i++)
-+    if (rtx_equal_p (ivs->entries[i].hard_reg, reg))
-+      return ivs->entries[i].pseudo;
-+
-+  return NULL_RTX;
-+}
-+
-+rtx
-+get_func_hard_reg_initial_val (fun, reg)
-+     struct function *fun;
-+     rtx reg;
-+{
-+  struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
-+  rtx rv = has_func_hard_reg_initial_val (fun, reg);
-+
-+  if (rv)
-+    return rv;
-+
-+  if (ivs == 0)
-+    {
-+      fun->hard_reg_initial_vals = (void *) ggc_alloc (sizeof (initial_value_struct));
-+      ivs = fun->hard_reg_initial_vals;
-+      ivs->num_entries = 0;
-+      ivs->max_entries = 5;
-+      ivs->entries = (initial_value_pair *) ggc_alloc (5 * sizeof (initial_value_pair));
-+    }
-+
-+  if (ivs->num_entries >= ivs->max_entries)
-+    {
-+      ivs->max_entries += 5;
-+      ivs->entries = 
-+      (initial_value_pair *) ggc_realloc (ivs->entries,
-+                                          ivs->max_entries
-+                                          * sizeof (initial_value_pair));
-+    }
-+
-+  ivs->entries[ivs->num_entries].hard_reg = reg;
-+  ivs->entries[ivs->num_entries].pseudo = gen_reg_rtx (GET_MODE (reg));
-+
-+  return ivs->entries[ivs->num_entries++].pseudo;
-+}
-+
-+rtx
-+get_hard_reg_initial_val (mode, regno)
-+     enum machine_mode mode;
-+     int regno;
-+{
-+  return get_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
-+}
-+
-+rtx
-+has_hard_reg_initial_val (mode, regno)
-+     enum machine_mode mode;
-+     int regno;
-+{
-+  return has_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
-+}
-+
-+static void
-+setup_initial_hard_reg_value_integration (inl_f, remap)
-+     struct function *inl_f;
-+     struct inline_remap *remap;
-+{
-+  struct initial_value_struct *ivs = inl_f->hard_reg_initial_vals;
-+  int i;
-+
-+  if (ivs == 0)
-+    return;
-+
-+  for (i = 0; i < ivs->num_entries; i ++)
-+    remap->reg_map[REGNO (ivs->entries[i].pseudo)]
-+      = get_func_hard_reg_initial_val (cfun, ivs->entries[i].hard_reg);
-+}
-+
-+
-+void
-+emit_initial_value_sets ()
-+{
-+  struct initial_value_struct *ivs = cfun->hard_reg_initial_vals;
-+  int i;
-+  rtx seq;
-+
-+  if (ivs == 0)
-+    return;
-+
-+  start_sequence ();
-+  for (i = 0; i < ivs->num_entries; i++)
-+    emit_move_insn (ivs->entries[i].pseudo, ivs->entries[i].hard_reg);
-+  seq = get_insns ();
-+  end_sequence ();
-+
-+  emit_insn_after (seq, get_insns ());
-+}
-+
-+/* If the backend knows where to allocate pseudos for hard
-+   register initial values, register these allocations now.  */
-+void
-+allocate_initial_values (reg_equiv_memory_loc)
-+     rtx *reg_equiv_memory_loc ATTRIBUTE_UNUSED;
-+{
-+#ifdef ALLOCATE_INITIAL_VALUE
-+  struct initial_value_struct *ivs = cfun->hard_reg_initial_vals;
-+  int i;
-+
-+  if (ivs == 0)
-+    return;
-+
-+  for (i = 0; i < ivs->num_entries; i++)
-+    {
-+      int regno = REGNO (ivs->entries[i].pseudo);
-+      rtx x = ALLOCATE_INITIAL_VALUE (ivs->entries[i].hard_reg);
-+
-+      if (x == NULL_RTX || REG_N_SETS (REGNO (ivs->entries[i].pseudo)) > 1)
-+      ; /* Do nothing.  */
-+      else if (GET_CODE (x) == MEM)
-+      reg_equiv_memory_loc[regno] = x;
-+      else if (GET_CODE (x) == REG)
-+      {
-+        reg_renumber[regno] = REGNO (x);
-+        /* Poke the regno right into regno_reg_rtx
-+           so that even fixed regs are accepted.  */
-+        REGNO (ivs->entries[i].pseudo) = REGNO (x);
-+      }
-+      else abort ();
-+    }
-+#endif
-+}
-+
-+#include "gt-integrate.h"
-diff -ruN gcc-3.3.1/gcc/libgcc-std.ver gcc-3.3.1.pp/gcc/libgcc-std.ver
---- gcc-3.3.1/gcc/libgcc-std.ver       2003-07-13 21:25:09.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/libgcc-std.ver    2003-09-05 11:58:59.000000000 +0000
-@@ -174,6 +174,10 @@
-   _Unwind_SjLj_RaiseException
-   _Unwind_SjLj_ForcedUnwind
-   _Unwind_SjLj_Resume
-+
-+  # stack smash handler symbols
-+  __guard
-+  __stack_smash_handler
- }
- %inherit GCC_3.3 GCC_3.0
-diff -ruN gcc-3.3.1/gcc/libgcc2.c gcc-3.3.1.pp/gcc/libgcc2.c
---- gcc-3.3.1/gcc/libgcc2.c    2002-10-23 10:47:24.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/libgcc2.c 2003-09-05 11:58:59.000000000 +0000
-@@ -1993,3 +1993,102 @@
- #endif /* NEED_ATEXIT */
- #endif /* L_exit */
-+\f
-+#ifdef L_stack_smash_handler
-+#include <stdio.h>
-+#include <string.h>
-+#include <fcntl.h>
-+#include <unistd.h>
-+
-+#ifdef _POSIX_SOURCE
-+#include <signal.h>
-+#endif
-+
-+#if defined(HAVE_SYSLOG)
-+#include <sys/types.h>
-+#include <sys/socket.h>
-+#include <sys/un.h>
-+
-+#include <sys/syslog.h>
-+#ifndef _PATH_LOG
-+#define _PATH_LOG "/dev/log"
-+#endif
-+#endif
-+
-+long __guard[8] = {0,0,0,0,0,0,0,0};
-+static void __guard_setup (void) __attribute__ ((constructor)) ;
-+static void __guard_setup (void)
-+{
-+  int fd;
-+  if (__guard[0]!=0) return;
-+  fd = open ("/dev/urandom", 0);
-+  if (fd != -1) {
-+    ssize_t size = read (fd, (char*)&__guard, sizeof(__guard));
-+    close (fd) ;
-+    if (size == sizeof(__guard)) return;
-+  }
-+  /* If a random generator can't be used, the protector switches the guard
-+     to the "terminator canary" */
-+  ((char*)__guard)[0] = 0; ((char*)__guard)[1] = 0;
-+  ((char*)__guard)[2] = '\n'; ((char*)__guard)[3] = 255;
-+}
-+void __stack_smash_handler (char func[], int damaged ATTRIBUTE_UNUSED)
-+{
-+#if defined (__GNU_LIBRARY__)
-+  extern char * __progname;
-+#endif
-+  const char message[] = ": stack smashing attack in function ";
-+  int bufsz = 256, len;
-+  char buf[bufsz];
-+#if defined(HAVE_SYSLOG)
-+  int LogFile;
-+  struct sockaddr_un SyslogAddr;  /* AF_UNIX address of local logger */
-+#endif
-+#ifdef _POSIX_SOURCE
-+  {
-+    sigset_t mask;
-+    sigfillset(&mask);
-+    sigdelset(&mask, SIGABRT);        /* Block all signal handlers */
-+    sigprocmask(SIG_BLOCK, &mask, NULL); /* except SIGABRT */
-+  }
-+#endif
-+
-+  strcpy(buf, "<2>"); len=3;  /* send LOG_CRIT */
-+#if defined (__GNU_LIBRARY__)
-+  strncat(buf, __progname, bufsz-len-1); len = strlen(buf);
-+#endif
-+  if (bufsz>len) {strncat(buf, message, bufsz-len-1); len = strlen(buf);}
-+  if (bufsz>len) {strncat(buf, func, bufsz-len-1); len = strlen(buf);}
-+
-+  /* print error message */
-+  write (STDERR_FILENO, buf+3, len-3);
-+#if defined(HAVE_SYSLOG)
-+  if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) != -1) {
-+
-+    /*
-+     * Send "found" message to the "/dev/log" path
-+     */
-+    SyslogAddr.sun_family = AF_UNIX;
-+    (void)strncpy(SyslogAddr.sun_path, _PATH_LOG,
-+                sizeof(SyslogAddr.sun_path) - 1);
-+    SyslogAddr.sun_path[sizeof(SyslogAddr.sun_path) - 1] = '\0';
-+    sendto(LogFile, buf, len, 0, (struct sockaddr *)&SyslogAddr,
-+         sizeof(SyslogAddr));
-+  }
-+#endif
-+
-+#ifdef _POSIX_SOURCE
-+  { /* Make sure the default handler is associated with SIGABRT */
-+    struct sigaction sa;
-+    
-+    memset(&sa, 0, sizeof(struct sigaction));
-+    sigfillset(&sa.sa_mask);  /* Block all signals */
-+    sa.sa_flags = 0;
-+    sa.sa_handler = SIG_DFL;
-+    sigaction(SIGABRT, &sa, NULL);
-+    (void)kill(getpid(), SIGABRT);
-+  }
-+#endif
-+  _exit(127);
-+}
-+#endif
-diff -ruN gcc-3.3.1/gcc/loop.c gcc-3.3.1.pp/gcc/loop.c
---- gcc-3.3.1/gcc/loop.c       2003-07-11 06:47:05.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/loop.c    2003-09-05 11:58:59.000000000 +0000
-@@ -6516,6 +6516,14 @@
-   if (GET_CODE (*mult_val) == USE)
-     *mult_val = XEXP (*mult_val, 0);
-+#ifndef FRAME_GROWS_DOWNWARD
-+  if (flag_propolice_protection
-+      && GET_CODE (*add_val) == PLUS
-+      && (XEXP (*add_val, 0) == frame_pointer_rtx
-+        || XEXP (*add_val, 1) == frame_pointer_rtx))
-+    return 0;
-+#endif
-+
-   if (is_addr)
-     *pbenefit += address_cost (orig_x, addr_mode) - reg_address_cost;
-   else
-diff -ruN gcc-3.3.1/gcc/optabs.c gcc-3.3.1.pp/gcc/optabs.c
---- gcc-3.3.1/gcc/optabs.c     2003-07-19 00:25:25.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/optabs.c  2003-09-05 11:58:59.000000000 +0000
-@@ -703,6 +703,26 @@
-   if (target)
-     target = protect_from_queue (target, 1);
-+  if (flag_propolice_protection
-+      && binoptab->code == PLUS
-+      && op0 == virtual_stack_vars_rtx
-+      && GET_CODE(op1) == CONST_INT)
-+    {
-+      int icode = (int) binoptab->handlers[(int) mode].insn_code;
-+      if (target)
-+      temp = target;
-+      else
-+      temp = gen_reg_rtx (mode);
-+
-+      if (! (*insn_data[icode].operand[0].predicate) (temp, mode)
-+        || GET_CODE (temp) != REG)
-+      temp = gen_reg_rtx (mode);
-+
-+      emit_insn (gen_rtx_SET (VOIDmode, temp,
-+                            gen_rtx_PLUS (GET_MODE (op0), op0, op1)));
-+      return temp;
-+    }
-+
-   if (flag_force_mem)
-     {
-       op0 = force_not_mem (op0);
-diff -ruN gcc-3.3.1/gcc/optabs.c.orig gcc-3.3.1.pp/gcc/optabs.c.orig
---- gcc-3.3.1/gcc/optabs.c.orig        1970-01-01 00:00:00.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/optabs.c.orig     2003-07-19 00:25:25.000000000 +0000
-@@ -0,0 +1,5511 @@
-+/* Expand the basic unary and binary arithmetic operations, for GNU compiler.
-+   Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-+   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify it under
-+the terms of the GNU General Public License as published by the Free
-+Software Foundation; either version 2, or (at your option) any later
-+version.
-+
-+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-+WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING.  If not, write to the Free
-+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-+02111-1307, USA.  */
-+
-+
-+#include "config.h"
-+#include "system.h"
-+#include "toplev.h"
-+
-+/* Include insn-config.h before expr.h so that HAVE_conditional_move
-+   is properly defined.  */
-+#include "insn-config.h"
-+#include "rtl.h"
-+#include "tree.h"
-+#include "tm_p.h"
-+#include "flags.h"
-+#include "function.h"
-+#include "except.h"
-+#include "expr.h"
-+#include "optabs.h"
-+#include "libfuncs.h"
-+#include "recog.h"
-+#include "reload.h"
-+#include "ggc.h"
-+#include "real.h"
-+#include "basic-block.h"
-+
-+/* Each optab contains info on how this target machine
-+   can perform a particular operation
-+   for all sizes and kinds of operands.
-+
-+   The operation to be performed is often specified
-+   by passing one of these optabs as an argument.
-+
-+   See expr.h for documentation of these optabs.  */
-+
-+optab optab_table[OTI_MAX];
-+
-+rtx libfunc_table[LTI_MAX];
-+
-+/* Tables of patterns for extending one integer mode to another.  */
-+enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
-+
-+/* Tables of patterns for converting between fixed and floating point.  */
-+enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
-+enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
-+enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
-+
-+/* Contains the optab used for each rtx code.  */
-+optab code_to_optab[NUM_RTX_CODE + 1];
-+
-+/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
-+   gives the gen_function to make a branch to test that condition.  */
-+
-+rtxfun bcc_gen_fctn[NUM_RTX_CODE];
-+
-+/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
-+   gives the insn code to make a store-condition insn
-+   to test that condition.  */
-+
-+enum insn_code setcc_gen_code[NUM_RTX_CODE];
-+
-+#ifdef HAVE_conditional_move
-+/* Indexed by the machine mode, gives the insn code to make a conditional
-+   move insn.  This is not indexed by the rtx-code like bcc_gen_fctn and
-+   setcc_gen_code to cut down on the number of named patterns.  Consider a day
-+   when a lot more rtx codes are conditional (eg: for the ARM).  */
-+
-+enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
-+#endif
-+
-+/* The insn generating function can not take an rtx_code argument.
-+   TRAP_RTX is used as an rtx argument.  Its code is replaced with
-+   the code to be used in the trap insn and all other fields are ignored.  */
-+static GTY(()) rtx trap_rtx;
-+
-+static int add_equal_note     PARAMS ((rtx, rtx, enum rtx_code, rtx, rtx));
-+static rtx widen_operand      PARAMS ((rtx, enum machine_mode,
-+                                     enum machine_mode, int, int));
-+static int expand_cmplxdiv_straight PARAMS ((rtx, rtx, rtx, rtx,
-+                                         rtx, rtx, enum machine_mode,
-+                                         int, enum optab_methods,
-+                                         enum mode_class, optab));
-+static int expand_cmplxdiv_wide PARAMS ((rtx, rtx, rtx, rtx,
-+                                     rtx, rtx, enum machine_mode,
-+                                     int, enum optab_methods,
-+                                     enum mode_class, optab));
-+static void prepare_cmp_insn PARAMS ((rtx *, rtx *, enum rtx_code *, rtx,
-+                                    enum machine_mode *, int *,
-+                                    enum can_compare_purpose));
-+static enum insn_code can_fix_p       PARAMS ((enum machine_mode, enum machine_mode,
-+                                     int, int *));
-+static enum insn_code can_float_p PARAMS ((enum machine_mode,
-+                                         enum machine_mode,
-+                                         int));
-+static rtx ftruncify  PARAMS ((rtx));
-+static optab new_optab        PARAMS ((void));
-+static inline optab init_optab        PARAMS ((enum rtx_code));
-+static inline optab init_optabv       PARAMS ((enum rtx_code));
-+static void init_libfuncs PARAMS ((optab, int, int, const char *, int));
-+static void init_integral_libfuncs PARAMS ((optab, const char *, int));
-+static void init_floating_libfuncs PARAMS ((optab, const char *, int));
-+static void emit_cmp_and_jump_insn_1 PARAMS ((rtx, rtx, enum machine_mode,
-+                                          enum rtx_code, int, rtx));
-+static void prepare_float_lib_cmp PARAMS ((rtx *, rtx *, enum rtx_code *,
-+                                       enum machine_mode *, int *));
-+static rtx expand_vector_binop PARAMS ((enum machine_mode, optab,
-+                                      rtx, rtx, rtx, int,
-+                                      enum optab_methods));
-+static rtx expand_vector_unop PARAMS ((enum machine_mode, optab, rtx, rtx,
-+                                     int));
-+
-+#ifndef HAVE_conditional_trap
-+#define HAVE_conditional_trap 0
-+#define gen_conditional_trap(a,b) (abort (), NULL_RTX)
-+#endif
-+\f
-+/* Add a REG_EQUAL note to the last insn in INSNS.  TARGET is being set to
-+   the result of operation CODE applied to OP0 (and OP1 if it is a binary
-+   operation).
-+
-+   If the last insn does not set TARGET, don't do anything, but return 1.
-+
-+   If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
-+   don't add the REG_EQUAL note but return 0.  Our caller can then try
-+   again, ensuring that TARGET is not one of the operands.  */
-+
-+static int
-+add_equal_note (insns, target, code, op0, op1)
-+     rtx insns;
-+     rtx target;
-+     enum rtx_code code;
-+     rtx op0, op1;
-+{
-+  rtx last_insn, insn, set;
-+  rtx note;
-+
-+  if (! insns
-+      || ! INSN_P (insns)
-+      || NEXT_INSN (insns) == NULL_RTX)
-+    abort ();
-+
-+  if (GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
-+      && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
-+    return 1;
-+
-+  if (GET_CODE (target) == ZERO_EXTRACT)
-+    return 1;
-+
-+  for (last_insn = insns;
-+       NEXT_INSN (last_insn) != NULL_RTX;
-+       last_insn = NEXT_INSN (last_insn))
-+    ;
-+
-+  set = single_set (last_insn);
-+  if (set == NULL_RTX)
-+    return 1;
-+
-+  if (! rtx_equal_p (SET_DEST (set), target)
-+      /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
-+       SUBREG.  */
-+      && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
-+        || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
-+                          target)))
-+    return 1;
-+
-+  /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
-+     besides the last insn.  */
-+  if (reg_overlap_mentioned_p (target, op0)
-+      || (op1 && reg_overlap_mentioned_p (target, op1)))
-+    {
-+      insn = PREV_INSN (last_insn);
-+      while (insn != NULL_RTX)
-+      {
-+        if (reg_set_p (target, insn))
-+          return 0;
-+
-+        insn = PREV_INSN (insn);
-+      }
-+    }
-+
-+  if (GET_RTX_CLASS (code) == '1')
-+    note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
-+  else
-+    note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
-+
-+  set_unique_reg_note (last_insn, REG_EQUAL, note);
-+
-+  return 1;
-+}
-+\f
-+/* Widen OP to MODE and return the rtx for the widened operand.  UNSIGNEDP
-+   says whether OP is signed or unsigned.  NO_EXTEND is nonzero if we need
-+   not actually do a sign-extend or zero-extend, but can leave the 
-+   higher-order bits of the result rtx undefined, for example, in the case
-+   of logical operations, but not right shifts.  */
-+
-+static rtx
-+widen_operand (op, mode, oldmode, unsignedp, no_extend)
-+     rtx op;
-+     enum machine_mode mode, oldmode;
-+     int unsignedp;
-+     int no_extend;
-+{
-+  rtx result;
-+
-+  /* If we don't have to extend and this is a constant, return it.  */
-+  if (no_extend && GET_MODE (op) == VOIDmode)
-+    return op;
-+
-+  /* If we must extend do so.  If OP is a SUBREG for a promoted object, also
-+     extend since it will be more efficient to do so unless the signedness of
-+     a promoted object differs from our extension.  */
-+  if (! no_extend
-+      || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
-+        && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
-+    return convert_modes (mode, oldmode, op, unsignedp);
-+
-+  /* If MODE is no wider than a single word, we return a paradoxical
-+     SUBREG.  */
-+  if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
-+    return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
-+
-+  /* Otherwise, get an object of MODE, clobber it, and set the low-order
-+     part to OP.  */
-+
-+  result = gen_reg_rtx (mode);
-+  emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
-+  emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
-+  return result;
-+}
-+\f
-+/* Generate code to perform a straightforward complex divide.  */
-+
-+static int
-+expand_cmplxdiv_straight (real0, real1, imag0, imag1, realr, imagr, submode,
-+                        unsignedp, methods, class, binoptab)
-+     rtx real0, real1, imag0, imag1, realr, imagr;
-+     enum machine_mode submode;
-+     int unsignedp;
-+     enum optab_methods methods;
-+     enum mode_class class;
-+     optab binoptab;
-+{
-+  rtx divisor;
-+  rtx real_t, imag_t;
-+  rtx temp1, temp2;
-+  rtx res;
-+  optab this_add_optab = add_optab;
-+  optab this_sub_optab = sub_optab;
-+  optab this_neg_optab = neg_optab;
-+  optab this_mul_optab = smul_optab;
-+            
-+  if (binoptab == sdivv_optab)
-+    {
-+      this_add_optab = addv_optab;
-+      this_sub_optab = subv_optab;
-+      this_neg_optab = negv_optab;
-+      this_mul_optab = smulv_optab;
-+    }
-+
-+  /* Don't fetch these from memory more than once.  */
-+  real0 = force_reg (submode, real0);
-+  real1 = force_reg (submode, real1);
-+
-+  if (imag0 != 0)
-+    imag0 = force_reg (submode, imag0);
-+
-+  imag1 = force_reg (submode, imag1);
-+
-+  /* Divisor: c*c + d*d.  */
-+  temp1 = expand_binop (submode, this_mul_optab, real1, real1,
-+                      NULL_RTX, unsignedp, methods);
-+
-+  temp2 = expand_binop (submode, this_mul_optab, imag1, imag1,
-+                      NULL_RTX, unsignedp, methods);
-+
-+  if (temp1 == 0 || temp2 == 0)
-+    return 0;
-+
-+  divisor = expand_binop (submode, this_add_optab, temp1, temp2,
-+                        NULL_RTX, unsignedp, methods);
-+  if (divisor == 0)
-+    return 0;
-+
-+  if (imag0 == 0)
-+    {
-+      /* Mathematically, ((a)(c-id))/divisor.  */
-+      /* Computationally, (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)).  */
-+
-+      /* Calculate the dividend.  */
-+      real_t = expand_binop (submode, this_mul_optab, real0, real1,
-+                           NULL_RTX, unsignedp, methods);
-+                
-+      imag_t = expand_binop (submode, this_mul_optab, real0, imag1,
-+                           NULL_RTX, unsignedp, methods);
-+
-+      if (real_t == 0 || imag_t == 0)
-+      return 0;
-+
-+      imag_t = expand_unop (submode, this_neg_optab, imag_t,
-+                          NULL_RTX, unsignedp);
-+    }
-+  else
-+    {
-+      /* Mathematically, ((a+ib)(c-id))/divider.  */
-+      /* Calculate the dividend.  */
-+      temp1 = expand_binop (submode, this_mul_optab, real0, real1,
-+                          NULL_RTX, unsignedp, methods);
-+
-+      temp2 = expand_binop (submode, this_mul_optab, imag0, imag1,
-+                          NULL_RTX, unsignedp, methods);
-+
-+      if (temp1 == 0 || temp2 == 0)
-+      return 0;
-+
-+      real_t = expand_binop (submode, this_add_optab, temp1, temp2,
-+                           NULL_RTX, unsignedp, methods);
-+                
-+      temp1 = expand_binop (submode, this_mul_optab, imag0, real1,
-+                          NULL_RTX, unsignedp, methods);
-+
-+      temp2 = expand_binop (submode, this_mul_optab, real0, imag1,
-+                          NULL_RTX, unsignedp, methods);
-+
-+      if (temp1 == 0 || temp2 == 0)
-+      return 0;
-+
-+      imag_t = expand_binop (submode, this_sub_optab, temp1, temp2,
-+                           NULL_RTX, unsignedp, methods);
-+
-+      if (real_t == 0 || imag_t == 0)
-+      return 0;
-+    }
-+
-+  if (class == MODE_COMPLEX_FLOAT)
-+    res = expand_binop (submode, binoptab, real_t, divisor,
-+                      realr, unsignedp, methods);
-+  else
-+    res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
-+                       real_t, divisor, realr, unsignedp);
-+
-+  if (res == 0)
-+    return 0;
-+
-+  if (res != realr)
-+    emit_move_insn (realr, res);
-+
-+  if (class == MODE_COMPLEX_FLOAT)
-+    res = expand_binop (submode, binoptab, imag_t, divisor,
-+                      imagr, unsignedp, methods);
-+  else
-+    res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
-+                       imag_t, divisor, imagr, unsignedp);
-+
-+  if (res == 0)
-+    return 0;
-+
-+  if (res != imagr)
-+    emit_move_insn (imagr, res);
-+
-+  return 1;
-+}
-+\f
-+/* Generate code to perform a wide-input-range-acceptable complex divide.  */
-+
-+static int
-+expand_cmplxdiv_wide (real0, real1, imag0, imag1, realr, imagr, submode,
-+                    unsignedp, methods, class, binoptab)
-+     rtx real0, real1, imag0, imag1, realr, imagr;
-+     enum machine_mode submode;
-+     int unsignedp;
-+     enum optab_methods methods;
-+     enum mode_class class;
-+     optab binoptab;
-+{
-+  rtx ratio, divisor;
-+  rtx real_t, imag_t;
-+  rtx temp1, temp2, lab1, lab2;
-+  enum machine_mode mode;
-+  rtx res;
-+  optab this_add_optab = add_optab;
-+  optab this_sub_optab = sub_optab;
-+  optab this_neg_optab = neg_optab;
-+  optab this_mul_optab = smul_optab;
-+
-+  if (binoptab == sdivv_optab)
-+    {
-+      this_add_optab = addv_optab;
-+      this_sub_optab = subv_optab;
-+      this_neg_optab = negv_optab;
-+      this_mul_optab = smulv_optab;
-+    }
-+            
-+  /* Don't fetch these from memory more than once.  */
-+  real0 = force_reg (submode, real0);
-+  real1 = force_reg (submode, real1);
-+
-+  if (imag0 != 0)
-+    imag0 = force_reg (submode, imag0);
-+
-+  imag1 = force_reg (submode, imag1);
-+
-+  /* XXX What's an "unsigned" complex number?  */
-+  if (unsignedp)
-+    {
-+      temp1 = real1;
-+      temp2 = imag1;
-+    }
-+  else
-+    {
-+      temp1 = expand_abs (submode, real1, NULL_RTX, unsignedp, 1);
-+      temp2 = expand_abs (submode, imag1, NULL_RTX, unsignedp, 1);
-+    }
-+
-+  if (temp1 == 0 || temp2 == 0)
-+    return 0;
-+
-+  mode = GET_MODE (temp1);
-+  lab1 = gen_label_rtx ();
-+  emit_cmp_and_jump_insns (temp1, temp2, LT, NULL_RTX,
-+                         mode, unsignedp, lab1);
-+
-+  /* |c| >= |d|; use ratio d/c to scale dividend and divisor.  */
-+
-+  if (class == MODE_COMPLEX_FLOAT)
-+    ratio = expand_binop (submode, binoptab, imag1, real1,
-+                        NULL_RTX, unsignedp, methods);
-+  else
-+    ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
-+                         imag1, real1, NULL_RTX, unsignedp);
-+
-+  if (ratio == 0)
-+    return 0;
-+
-+  /* Calculate divisor.  */
-+
-+  temp1 = expand_binop (submode, this_mul_optab, imag1, ratio,
-+                      NULL_RTX, unsignedp, methods);
-+
-+  if (temp1 == 0)
-+    return 0;
-+
-+  divisor = expand_binop (submode, this_add_optab, temp1, real1,
-+                        NULL_RTX, unsignedp, methods);
-+
-+  if (divisor == 0)
-+    return 0;
-+
-+  /* Calculate dividend.  */
-+
-+  if (imag0 == 0)
-+    {
-+      real_t = real0;
-+
-+      /* Compute a / (c+id) as a / (c+d(d/c)) + i (-a(d/c)) / (c+d(d/c)).  */
-+
-+      imag_t = expand_binop (submode, this_mul_optab, real0, ratio,
-+                           NULL_RTX, unsignedp, methods);
-+
-+      if (imag_t == 0)
-+      return 0;
-+
-+      imag_t = expand_unop (submode, this_neg_optab, imag_t,
-+                          NULL_RTX, unsignedp);
-+
-+      if (real_t == 0 || imag_t == 0)
-+      return 0;
-+    }
-+  else
-+    {
-+      /* Compute (a+ib)/(c+id) as
-+       (a+b(d/c))/(c+d(d/c) + i(b-a(d/c))/(c+d(d/c)).  */
-+
-+      temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
-+                          NULL_RTX, unsignedp, methods);
-+
-+      if (temp1 == 0)
-+      return 0;
-+
-+      real_t = expand_binop (submode, this_add_optab, temp1, real0,
-+                           NULL_RTX, unsignedp, methods);
-+
-+      temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
-+                          NULL_RTX, unsignedp, methods);
-+
-+      if (temp1 == 0)
-+      return 0;
-+
-+      imag_t = expand_binop (submode, this_sub_optab, imag0, temp1,
-+                           NULL_RTX, unsignedp, methods);
-+
-+      if (real_t == 0 || imag_t == 0)
-+      return 0;
-+    }
-+
-+  if (class == MODE_COMPLEX_FLOAT)
-+    res = expand_binop (submode, binoptab, real_t, divisor,
-+                      realr, unsignedp, methods);
-+  else
-+    res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
-+                       real_t, divisor, realr, unsignedp);
-+
-+  if (res == 0)
-+    return 0;
-+
-+  if (res != realr)
-+    emit_move_insn (realr, res);
-+
-+  if (class == MODE_COMPLEX_FLOAT)
-+    res = expand_binop (submode, binoptab, imag_t, divisor,
-+                      imagr, unsignedp, methods);
-+  else
-+    res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
-+                       imag_t, divisor, imagr, unsignedp);
-+
-+  if (res == 0)
-+    return 0;
-+
-+  if (res != imagr)
-+    emit_move_insn (imagr, res);
-+
-+  lab2 = gen_label_rtx ();
-+  emit_jump_insn (gen_jump (lab2));
-+  emit_barrier ();
-+
-+  emit_label (lab1);
-+
-+  /* |d| > |c|; use ratio c/d to scale dividend and divisor.  */
-+
-+  if (class == MODE_COMPLEX_FLOAT)
-+    ratio = expand_binop (submode, binoptab, real1, imag1,
-+                        NULL_RTX, unsignedp, methods);
-+  else
-+    ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
-+                         real1, imag1, NULL_RTX, unsignedp);
-+
-+  if (ratio == 0)
-+    return 0;
-+
-+  /* Calculate divisor.  */
-+
-+  temp1 = expand_binop (submode, this_mul_optab, real1, ratio,
-+                      NULL_RTX, unsignedp, methods);
-+
-+  if (temp1 == 0)
-+    return 0;
-+
-+  divisor = expand_binop (submode, this_add_optab, temp1, imag1,
-+                        NULL_RTX, unsignedp, methods);
-+
-+  if (divisor == 0)
-+    return 0;
-+
-+  /* Calculate dividend.  */
-+
-+  if (imag0 == 0)
-+    {
-+      /* Compute a / (c+id) as a(c/d) / (c(c/d)+d) + i (-a) / (c(c/d)+d).  */
-+
-+      real_t = expand_binop (submode, this_mul_optab, real0, ratio,
-+                           NULL_RTX, unsignedp, methods);
-+
-+      imag_t = expand_unop (submode, this_neg_optab, real0,
-+                          NULL_RTX, unsignedp);
-+
-+      if (real_t == 0 || imag_t == 0)
-+      return 0;
-+    }
-+  else
-+    {
-+      /* Compute (a+ib)/(c+id) as
-+       (a(c/d)+b)/(c(c/d)+d) + i (b(c/d)-a)/(c(c/d)+d).  */
-+
-+      temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
-+                          NULL_RTX, unsignedp, methods);
-+
-+      if (temp1 == 0)
-+      return 0;
-+
-+      real_t = expand_binop (submode, this_add_optab, temp1, imag0,
-+                           NULL_RTX, unsignedp, methods);
-+
-+      temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
-+                          NULL_RTX, unsignedp, methods);
-+
-+      if (temp1 == 0)
-+      return 0;
-+
-+      imag_t = expand_binop (submode, this_sub_optab, temp1, real0,
-+                           NULL_RTX, unsignedp, methods);
-+
-+      if (real_t == 0 || imag_t == 0)
-+      return 0;
-+    }
-+
-+  if (class == MODE_COMPLEX_FLOAT)
-+    res = expand_binop (submode, binoptab, real_t, divisor,
-+                      realr, unsignedp, methods);
-+  else
-+    res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
-+                       real_t, divisor, realr, unsignedp);
-+
-+  if (res == 0)
-+    return 0;
-+
-+  if (res != realr)
-+    emit_move_insn (realr, res);
-+
-+  if (class == MODE_COMPLEX_FLOAT)
-+    res = expand_binop (submode, binoptab, imag_t, divisor,
-+                      imagr, unsignedp, methods);
-+  else
-+    res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
-+                       imag_t, divisor, imagr, unsignedp);
-+
-+  if (res == 0)
-+    return 0;
-+
-+  if (res != imagr)
-+    emit_move_insn (imagr, res);
-+
-+  emit_label (lab2);
-+
-+  return 1;
-+}
-+\f
-+/* Wrapper around expand_binop which takes an rtx code to specify
-+   the operation to perform, not an optab pointer.  All other
-+   arguments are the same.  */
-+rtx
-+expand_simple_binop (mode, code, op0, op1, target, unsignedp, methods)
-+     enum machine_mode mode;
-+     enum rtx_code code;
-+     rtx op0, op1;
-+     rtx target;
-+     int unsignedp;
-+     enum optab_methods methods;
-+{
-+  optab binop = code_to_optab[(int) code];
-+  if (binop == 0)
-+    abort ();
-+
-+  return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
-+}
-+
-+/* Generate code to perform an operation specified by BINOPTAB
-+   on operands OP0 and OP1, with result having machine-mode MODE.
-+
-+   UNSIGNEDP is for the case where we have to widen the operands
-+   to perform the operation.  It says to use zero-extension.
-+
-+   If TARGET is nonzero, the value
-+   is generated there, if it is convenient to do so.
-+   In all cases an rtx is returned for the locus of the value;
-+   this may or may not be TARGET.  */
-+
-+rtx
-+expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
-+     enum machine_mode mode;
-+     optab binoptab;
-+     rtx op0, op1;
-+     rtx target;
-+     int unsignedp;
-+     enum optab_methods methods;
-+{
-+  enum optab_methods next_methods
-+    = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
-+       ? OPTAB_WIDEN : methods);
-+  enum mode_class class;
-+  enum machine_mode wider_mode;
-+  rtx temp;
-+  int commutative_op = 0;
-+  int shift_op = (binoptab->code == ASHIFT
-+                || binoptab->code == ASHIFTRT
-+                || binoptab->code == LSHIFTRT
-+                || binoptab->code == ROTATE
-+                || binoptab->code == ROTATERT);
-+  rtx entry_last = get_last_insn ();
-+  rtx last;
-+
-+  class = GET_MODE_CLASS (mode);
-+
-+  op0 = protect_from_queue (op0, 0);
-+  op1 = protect_from_queue (op1, 0);
-+  if (target)
-+    target = protect_from_queue (target, 1);
-+
-+  if (flag_force_mem)
-+    {
-+      op0 = force_not_mem (op0);
-+      op1 = force_not_mem (op1);
-+    }
-+
-+  /* If subtracting an integer constant, convert this into an addition of
-+     the negated constant.  */
-+
-+  if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
-+    {
-+      op1 = negate_rtx (mode, op1);
-+      binoptab = add_optab;
-+    }
-+
-+  /* If we are inside an appropriately-short loop and one operand is an
-+     expensive constant, force it into a register.  */
-+  if (CONSTANT_P (op0) && preserve_subexpressions_p ()
-+      && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
-+    op0 = force_reg (mode, op0);
-+
-+  if (CONSTANT_P (op1) && preserve_subexpressions_p ()
-+      && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
-+    op1 = force_reg (mode, op1);
-+
-+  /* Record where to delete back to if we backtrack.  */
-+  last = get_last_insn ();
-+
-+  /* If operation is commutative,
-+     try to make the first operand a register.
-+     Even better, try to make it the same as the target.
-+     Also try to make the last operand a constant.  */
-+  if (GET_RTX_CLASS (binoptab->code) == 'c'
-+      || binoptab == smul_widen_optab
-+      || binoptab == umul_widen_optab
-+      || binoptab == smul_highpart_optab
-+      || binoptab == umul_highpart_optab)
-+    {
-+      commutative_op = 1;
-+
-+      if (((target == 0 || GET_CODE (target) == REG)
-+         ? ((GET_CODE (op1) == REG
-+             && GET_CODE (op0) != REG)
-+            || target == op1)
-+         : rtx_equal_p (op1, target))
-+        || GET_CODE (op0) == CONST_INT)
-+      {
-+        temp = op1;
-+        op1 = op0;
-+        op0 = temp;
-+      }
-+    }
-+
-+  /* If we can do it with a three-operand insn, do so.  */
-+
-+  if (methods != OPTAB_MUST_WIDEN
-+      && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
-+    {
-+      int icode = (int) binoptab->handlers[(int) mode].insn_code;
-+      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
-+      enum machine_mode mode1 = insn_data[icode].operand[2].mode;
-+      rtx pat;
-+      rtx xop0 = op0, xop1 = op1;
-+
-+      if (target)
-+      temp = target;
-+      else
-+      temp = gen_reg_rtx (mode);
-+
-+      /* If it is a commutative operator and the modes would match
-+       if we would swap the operands, we can save the conversions.  */
-+      if (commutative_op)
-+      {
-+        if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
-+            && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
-+          {
-+            rtx tmp;
-+
-+            tmp = op0; op0 = op1; op1 = tmp;
-+            tmp = xop0; xop0 = xop1; xop1 = tmp;
-+          }
-+      }
-+
-+      /* In case the insn wants input operands in modes different from
-+       those of the actual operands, convert the operands.  It would
-+       seem that we don't need to convert CONST_INTs, but we do, so
-+       that they're properly zero-extended, sign-extended or truncated
-+       for their mode.  */
-+
-+      if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
-+      xop0 = convert_modes (mode0,
-+                            GET_MODE (op0) != VOIDmode
-+                            ? GET_MODE (op0)
-+                            : mode,
-+                            xop0, unsignedp);
-+
-+      if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
-+      xop1 = convert_modes (mode1,
-+                            GET_MODE (op1) != VOIDmode
-+                            ? GET_MODE (op1)
-+                            : mode,
-+                            xop1, unsignedp);
-+
-+      /* Now, if insn's predicates don't allow our operands, put them into
-+       pseudo regs.  */
-+
-+      if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0)
-+        && mode0 != VOIDmode)
-+      xop0 = copy_to_mode_reg (mode0, xop0);
-+
-+      if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1)
-+        && mode1 != VOIDmode)
-+      xop1 = copy_to_mode_reg (mode1, xop1);
-+
-+      if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
-+      temp = gen_reg_rtx (mode);
-+
-+      pat = GEN_FCN (icode) (temp, xop0, xop1);
-+      if (pat)
-+      {
-+        /* If PAT is composed of more than one insn, try to add an appropriate
-+           REG_EQUAL note to it.  If we can't because TEMP conflicts with an
-+           operand, call ourselves again, this time without a target.  */
-+        if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
-+            && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
-+          {
-+            delete_insns_since (last);
-+            return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
-+                                 unsignedp, methods);
-+          }
-+
-+        emit_insn (pat);
-+        return temp;
-+      }
-+      else
-+      delete_insns_since (last);
-+    }
-+
-+  /* If this is a multiply, see if we can do a widening operation that
-+     takes operands of this mode and makes a wider mode.  */
-+
-+  if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
-+      && (((unsignedp ? umul_widen_optab : smul_widen_optab)
-+         ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
-+        != CODE_FOR_nothing))
-+    {
-+      temp = expand_binop (GET_MODE_WIDER_MODE (mode),
-+                         unsignedp ? umul_widen_optab : smul_widen_optab,
-+                         op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
-+
-+      if (temp != 0)
-+      {
-+        if (GET_MODE_CLASS (mode) == MODE_INT)
-+          return gen_lowpart (mode, temp);
-+        else
-+          return convert_to_mode (mode, temp, unsignedp);
-+      }
-+    }
-+
-+  /* Look for a wider mode of the same class for which we think we
-+     can open-code the operation.  Check for a widening multiply at the
-+     wider mode as well.  */
-+
-+  if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
-+      && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
-+    for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
-+       wider_mode = GET_MODE_WIDER_MODE (wider_mode))
-+      {
-+      if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
-+          || (binoptab == smul_optab
-+              && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
-+              && (((unsignedp ? umul_widen_optab : smul_widen_optab)
-+                   ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
-+                  != CODE_FOR_nothing)))
-+        {
-+          rtx xop0 = op0, xop1 = op1;
-+          int no_extend = 0;
-+
-+          /* For certain integer operations, we need not actually extend
-+             the narrow operands, as long as we will truncate
-+             the results to the same narrowness.  */
-+
-+          if ((binoptab == ior_optab || binoptab == and_optab
-+               || binoptab == xor_optab
-+               || binoptab == add_optab || binoptab == sub_optab
-+               || binoptab == smul_optab || binoptab == ashl_optab)
-+              && class == MODE_INT)
-+            no_extend = 1;
-+
-+          xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
-+
-+          /* The second operand of a shift must always be extended.  */
-+          xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
-+                                no_extend && binoptab != ashl_optab);
-+
-+          temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
-+                               unsignedp, OPTAB_DIRECT);
-+          if (temp)
-+            {
-+              if (class != MODE_INT)
-+                {
-+                  if (target == 0)
-+                    target = gen_reg_rtx (mode);
-+                  convert_move (target, temp, 0);
-+                  return target;
-+                }
-+              else
-+                return gen_lowpart (mode, temp);
-+            }
-+          else
-+            delete_insns_since (last);
-+        }
-+      }
-+
-+  /* These can be done a word at a time.  */
-+  if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
-+      && class == MODE_INT
-+      && GET_MODE_SIZE (mode) > UNITS_PER_WORD
-+      && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
-+    {
-+      int i;
-+      rtx insns;
-+      rtx equiv_value;
-+
-+      /* If TARGET is the same as one of the operands, the REG_EQUAL note
-+       won't be accurate, so use a new target.  */
-+      if (target == 0 || target == op0 || target == op1)
-+      target = gen_reg_rtx (mode);
-+
-+      start_sequence ();
-+
-+      /* Do the actual arithmetic.  */
-+      for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
-+      {
-+        rtx target_piece = operand_subword (target, i, 1, mode);
-+        rtx x = expand_binop (word_mode, binoptab,
-+                              operand_subword_force (op0, i, mode),
-+                              operand_subword_force (op1, i, mode),
-+                              target_piece, unsignedp, next_methods);
-+
-+        if (x == 0)
-+          break;
-+
-+        if (target_piece != x)
-+          emit_move_insn (target_piece, x);
-+      }
-+
-+      insns = get_insns ();
-+      end_sequence ();
-+
-+      if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
-+      {
-+        if (binoptab->code != UNKNOWN)
-+          equiv_value
-+            = gen_rtx_fmt_ee (binoptab->code, mode,
-+                              copy_rtx (op0), copy_rtx (op1));
-+        else
-+          equiv_value = 0;
-+
-+        emit_no_conflict_block (insns, target, op0, op1, equiv_value);
-+        return target;
-+      }
-+    }
-+
-+  /* Synthesize double word shifts from single word shifts.  */
-+  if ((binoptab == lshr_optab || binoptab == ashl_optab
-+       || binoptab == ashr_optab)
-+      && class == MODE_INT
-+      && GET_CODE (op1) == CONST_INT
-+      && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
-+      && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
-+      && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
-+      && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
-+    {
-+      rtx insns, inter, equiv_value;
-+      rtx into_target, outof_target;
-+      rtx into_input, outof_input;
-+      int shift_count, left_shift, outof_word;
-+
-+      /* If TARGET is the same as one of the operands, the REG_EQUAL note
-+       won't be accurate, so use a new target.  */
-+      if (target == 0 || target == op0 || target == op1)
-+      target = gen_reg_rtx (mode);
-+
-+      start_sequence ();
-+
-+      shift_count = INTVAL (op1);
-+
-+      /* OUTOF_* is the word we are shifting bits away from, and
-+       INTO_* is the word that we are shifting bits towards, thus
-+       they differ depending on the direction of the shift and
-+       WORDS_BIG_ENDIAN.  */
-+
-+      left_shift = binoptab == ashl_optab;
-+      outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
-+
-+      outof_target = operand_subword (target, outof_word, 1, mode);
-+      into_target = operand_subword (target, 1 - outof_word, 1, mode);
-+
-+      outof_input = operand_subword_force (op0, outof_word, mode);
-+      into_input = operand_subword_force (op0, 1 - outof_word, mode);
-+
-+      if (shift_count >= BITS_PER_WORD)
-+      {
-+        inter = expand_binop (word_mode, binoptab,
-+                             outof_input,
-+                             GEN_INT (shift_count - BITS_PER_WORD),
-+                             into_target, unsignedp, next_methods);
-+
-+        if (inter != 0 && inter != into_target)
-+          emit_move_insn (into_target, inter);
-+
-+        /* For a signed right shift, we must fill the word we are shifting
-+           out of with copies of the sign bit.  Otherwise it is zeroed.  */
-+        if (inter != 0 && binoptab != ashr_optab)
-+          inter = CONST0_RTX (word_mode);
-+        else if (inter != 0)
-+          inter = expand_binop (word_mode, binoptab,
-+                                outof_input,
-+                                GEN_INT (BITS_PER_WORD - 1),
-+                                outof_target, unsignedp, next_methods);
-+
-+        if (inter != 0 && inter != outof_target)
-+          emit_move_insn (outof_target, inter);
-+      }
-+      else
-+      {
-+        rtx carries;
-+        optab reverse_unsigned_shift, unsigned_shift;
-+
-+        /* For a shift of less then BITS_PER_WORD, to compute the carry,
-+           we must do a logical shift in the opposite direction of the
-+           desired shift.  */
-+
-+        reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
-+
-+        /* For a shift of less than BITS_PER_WORD, to compute the word
-+           shifted towards, we need to unsigned shift the orig value of
-+           that word.  */
-+
-+        unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
-+
-+        carries = expand_binop (word_mode, reverse_unsigned_shift,
-+                                outof_input,
-+                                GEN_INT (BITS_PER_WORD - shift_count),
-+                                0, unsignedp, next_methods);
-+
-+        if (carries == 0)
-+          inter = 0;
-+        else
-+          inter = expand_binop (word_mode, unsigned_shift, into_input,
-+                                op1, 0, unsignedp, next_methods);
-+
-+        if (inter != 0)
-+          inter = expand_binop (word_mode, ior_optab, carries, inter,
-+                                into_target, unsignedp, next_methods);
-+
-+        if (inter != 0 && inter != into_target)
-+          emit_move_insn (into_target, inter);
-+
-+        if (inter != 0)
-+          inter = expand_binop (word_mode, binoptab, outof_input,
-+                                op1, outof_target, unsignedp, next_methods);
-+        
-+        if (inter != 0 && inter != outof_target)
-+          emit_move_insn (outof_target, inter);
-+      }
-+
-+      insns = get_insns ();
-+      end_sequence ();
-+
-+      if (inter != 0)
-+      {
-+        if (binoptab->code != UNKNOWN)
-+          equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
-+        else
-+          equiv_value = 0;
-+
-+        emit_no_conflict_block (insns, target, op0, op1, equiv_value);
-+        return target;
-+      }
-+    }
-+
-+  /* Synthesize double word rotates from single word shifts.  */
-+  if ((binoptab == rotl_optab || binoptab == rotr_optab)
-+      && class == MODE_INT
-+      && GET_CODE (op1) == CONST_INT
-+      && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
-+      && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
-+      && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
-+    {
-+      rtx insns, equiv_value;
-+      rtx into_target, outof_target;
-+      rtx into_input, outof_input;
-+      rtx inter;
-+      int shift_count, left_shift, outof_word;
-+
-+      /* If TARGET is the same as one of the operands, the REG_EQUAL note
-+       won't be accurate, so use a new target.  */
-+      if (target == 0 || target == op0 || target == op1)
-+      target = gen_reg_rtx (mode);
-+
-+      start_sequence ();
-+
-+      shift_count = INTVAL (op1);
-+
-+      /* OUTOF_* is the word we are shifting bits away from, and
-+       INTO_* is the word that we are shifting bits towards, thus
-+       they differ depending on the direction of the shift and
-+       WORDS_BIG_ENDIAN.  */
-+
-+      left_shift = (binoptab == rotl_optab);
-+      outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
-+
-+      outof_target = operand_subword (target, outof_word, 1, mode);
-+      into_target = operand_subword (target, 1 - outof_word, 1, mode);
-+
-+      outof_input = operand_subword_force (op0, outof_word, mode);
-+      into_input = operand_subword_force (op0, 1 - outof_word, mode);
-+
-+      if (shift_count == BITS_PER_WORD)
-+      {
-+        /* This is just a word swap.  */
-+        emit_move_insn (outof_target, into_input);
-+        emit_move_insn (into_target, outof_input);
-+        inter = const0_rtx;
-+      }
-+      else
-+      {
-+        rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
-+        rtx first_shift_count, second_shift_count;
-+        optab reverse_unsigned_shift, unsigned_shift;
-+
-+        reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
-+                                  ? lshr_optab : ashl_optab);
-+
-+        unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
-+                          ? ashl_optab : lshr_optab);
-+
-+        if (shift_count > BITS_PER_WORD)
-+          {
-+            first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
-+            second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
-+          }
-+        else
-+          {
-+            first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
-+            second_shift_count = GEN_INT (shift_count);
-+          }
-+
-+        into_temp1 = expand_binop (word_mode, unsigned_shift,
-+                                   outof_input, first_shift_count,
-+                                   NULL_RTX, unsignedp, next_methods);
-+        into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
-+                                   into_input, second_shift_count,
-+                                   NULL_RTX, unsignedp, next_methods);
-+
-+        if (into_temp1 != 0 && into_temp2 != 0)
-+          inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
-+                                into_target, unsignedp, next_methods);
-+        else
-+          inter = 0;
-+
-+        if (inter != 0 && inter != into_target)
-+          emit_move_insn (into_target, inter);
-+
-+        outof_temp1 = expand_binop (word_mode, unsigned_shift,
-+                                    into_input, first_shift_count,
-+                                    NULL_RTX, unsignedp, next_methods);
-+        outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
-+                                    outof_input, second_shift_count,
-+                                    NULL_RTX, unsignedp, next_methods);
-+
-+        if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
-+          inter = expand_binop (word_mode, ior_optab,
-+                                outof_temp1, outof_temp2,
-+                                outof_target, unsignedp, next_methods);
-+
-+        if (inter != 0 && inter != outof_target)
-+          emit_move_insn (outof_target, inter);
-+      }
-+
-+      insns = get_insns ();
-+      end_sequence ();
-+
-+      if (inter != 0)
-+      {
-+        if (binoptab->code != UNKNOWN)
-+          equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
-+        else
-+          equiv_value = 0;
-+
-+        /* We can't make this a no conflict block if this is a word swap,
-+           because the word swap case fails if the input and output values
-+           are in the same register.  */
-+        if (shift_count != BITS_PER_WORD)
-+          emit_no_conflict_block (insns, target, op0, op1, equiv_value);
-+        else
-+          emit_insn (insns);
-+
-+
-+        return target;
-+      }
-+    }
-+
-+  /* These can be done a word at a time by propagating carries.  */
-+  if ((binoptab == add_optab || binoptab == sub_optab)
-+      && class == MODE_INT
-+      && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
-+      && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
-+    {
-+      unsigned int i;
-+      optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
-+      const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
-+      rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
-+      rtx xop0, xop1, xtarget;
-+
-+      /* We can handle either a 1 or -1 value for the carry.  If STORE_FLAG
-+       value is one of those, use it.  Otherwise, use 1 since it is the
-+       one easiest to get.  */
-+#if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
-+      int normalizep = STORE_FLAG_VALUE;
-+#else
-+      int normalizep = 1;
-+#endif
-+
-+      /* Prepare the operands.  */
-+      xop0 = force_reg (mode, op0);
-+      xop1 = force_reg (mode, op1);
-+
-+      xtarget = gen_reg_rtx (mode);
-+
-+      if (target == 0 || GET_CODE (target) != REG)
-+      target = xtarget;
-+
-+      /* Indicate for flow that the entire target reg is being set.  */
-+      if (GET_CODE (target) == REG)
-+      emit_insn (gen_rtx_CLOBBER (VOIDmode, xtarget));
-+
-+      /* Do the actual arithmetic.  */
-+      for (i = 0; i < nwords; i++)
-+      {
-+        int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
-+        rtx target_piece = operand_subword (xtarget, index, 1, mode);
-+        rtx op0_piece = operand_subword_force (xop0, index, mode);
-+        rtx op1_piece = operand_subword_force (xop1, index, mode);
-+        rtx x;
-+
-+        /* Main add/subtract of the input operands.  */
-+        x = expand_binop (word_mode, binoptab,
-+                          op0_piece, op1_piece,
-+                          target_piece, unsignedp, next_methods);
-+        if (x == 0)
-+          break;
-+
-+        if (i + 1 < nwords)
-+          {
-+            /* Store carry from main add/subtract.  */
-+            carry_out = gen_reg_rtx (word_mode);
-+            carry_out = emit_store_flag_force (carry_out,
-+                                               (binoptab == add_optab
-+                                                ? LT : GT),
-+                                               x, op0_piece,
-+                                               word_mode, 1, normalizep);
-+          }
-+
-+        if (i > 0)
-+          {
-+            rtx newx;
-+            
-+            /* Add/subtract previous carry to main result.  */
-+            newx = expand_binop (word_mode,
-+                                 normalizep == 1 ? binoptab : otheroptab,
-+                                 x, carry_in,
-+                                 NULL_RTX, 1, next_methods);
-+
-+            if (i + 1 < nwords)
-+              {
-+                /* Get out carry from adding/subtracting carry in.  */
-+                rtx carry_tmp = gen_reg_rtx (word_mode);
-+                carry_tmp = emit_store_flag_force (carry_tmp,
-+                                                   (binoptab == add_optab
-+                                                    ? LT : GT),
-+                                                   newx, x,
-+                                                   word_mode, 1, normalizep);
-+
-+                /* Logical-ior the two poss. carry together.  */
-+                carry_out = expand_binop (word_mode, ior_optab,
-+                                          carry_out, carry_tmp,
-+                                          carry_out, 0, next_methods);
-+                if (carry_out == 0)
-+                  break;
-+              }
-+            emit_move_insn (target_piece, newx);
-+          }
-+
-+        carry_in = carry_out;
-+      }       
-+
-+      if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
-+      {
-+        if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
-+          {
-+            rtx temp = emit_move_insn (target, xtarget);
-+
-+            set_unique_reg_note (temp,
-+                                 REG_EQUAL,
-+                                 gen_rtx_fmt_ee (binoptab->code, mode,
-+                                                 copy_rtx (xop0),
-+                                                 copy_rtx (xop1)));
-+          }
-+        else
-+          target = xtarget;
-+
-+        return target;
-+      }
-+
-+      else
-+      delete_insns_since (last);
-+    }
-+
-+  /* If we want to multiply two two-word values and have normal and widening
-+     multiplies of single-word values, we can do this with three smaller
-+     multiplications.  Note that we do not make a REG_NO_CONFLICT block here
-+     because we are not operating on one word at a time. 
-+
-+     The multiplication proceeds as follows:
-+                               _______________________
-+                              [__op0_high_|__op0_low__]
-+                               _______________________
-+        *                     [__op1_high_|__op1_low__]
-+        _______________________________________________
-+                               _______________________
-+    (1)                               [__op0_low__*__op1_low__]
-+                   _______________________
-+    (2a)          [__op0_low__*__op1_high_]
-+                   _______________________
-+    (2b)          [__op0_high_*__op1_low__]
-+         _______________________
-+    (3) [__op0_high_*__op1_high_]
-+
-+
-+    This gives a 4-word result.  Since we are only interested in the
-+    lower 2 words, partial result (3) and the upper words of (2a) and
-+    (2b) don't need to be calculated.  Hence (2a) and (2b) can be
-+    calculated using non-widening multiplication.
-+
-+    (1), however, needs to be calculated with an unsigned widening
-+    multiplication.  If this operation is not directly supported we
-+    try using a signed widening multiplication and adjust the result.
-+    This adjustment works as follows:
-+
-+      If both operands are positive then no adjustment is needed.
-+
-+      If the operands have different signs, for example op0_low < 0 and
-+      op1_low >= 0, the instruction treats the most significant bit of
-+      op0_low as a sign bit instead of a bit with significance
-+      2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
-+      with 2**BITS_PER_WORD - op0_low, and two's complements the
-+      result.  Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
-+      the result.
-+
-+      Similarly, if both operands are negative, we need to add
-+      (op0_low + op1_low) * 2**BITS_PER_WORD.
-+
-+      We use a trick to adjust quickly.  We logically shift op0_low right
-+      (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
-+      op0_high (op1_high) before it is used to calculate 2b (2a).  If no
-+      logical shift exists, we do an arithmetic right shift and subtract
-+      the 0 or -1.  */
-+
-+  if (binoptab == smul_optab
-+      && class == MODE_INT
-+      && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
-+      && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
-+      && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
-+      && ((umul_widen_optab->handlers[(int) mode].insn_code
-+         != CODE_FOR_nothing)
-+        || (smul_widen_optab->handlers[(int) mode].insn_code
-+            != CODE_FOR_nothing)))
-+    {
-+      int low = (WORDS_BIG_ENDIAN ? 1 : 0);
-+      int high = (WORDS_BIG_ENDIAN ? 0 : 1);
-+      rtx op0_high = operand_subword_force (op0, high, mode);
-+      rtx op0_low = operand_subword_force (op0, low, mode);
-+      rtx op1_high = operand_subword_force (op1, high, mode);
-+      rtx op1_low = operand_subword_force (op1, low, mode);
-+      rtx product = 0;
-+      rtx op0_xhigh = NULL_RTX;
-+      rtx op1_xhigh = NULL_RTX;
-+
-+      /* If the target is the same as one of the inputs, don't use it.  This
-+       prevents problems with the REG_EQUAL note.  */
-+      if (target == op0 || target == op1
-+        || (target != 0 && GET_CODE (target) != REG))
-+      target = 0;
-+
-+      /* Multiply the two lower words to get a double-word product.
-+       If unsigned widening multiplication is available, use that;
-+       otherwise use the signed form and compensate.  */
-+
-+      if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
-+      {
-+        product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
-+                                target, 1, OPTAB_DIRECT);
-+
-+        /* If we didn't succeed, delete everything we did so far.  */
-+        if (product == 0)
-+          delete_insns_since (last);
-+        else
-+          op0_xhigh = op0_high, op1_xhigh = op1_high;
-+      }
-+
-+      if (product == 0
-+        && smul_widen_optab->handlers[(int) mode].insn_code
-+             != CODE_FOR_nothing)
-+      {
-+        rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
-+        product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
-+                                target, 1, OPTAB_DIRECT);
-+        op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
-+                                  NULL_RTX, 1, next_methods);
-+        if (op0_xhigh)
-+          op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
-+                                    op0_xhigh, op0_xhigh, 0, next_methods);
-+        else
-+          {
-+            op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
-+                                      NULL_RTX, 0, next_methods);
-+            if (op0_xhigh)
-+              op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
-+                                        op0_xhigh, op0_xhigh, 0,
-+                                        next_methods);
-+          }
-+
-+        op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
-+                                  NULL_RTX, 1, next_methods);
-+        if (op1_xhigh)
-+          op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
-+                                    op1_xhigh, op1_xhigh, 0, next_methods);
-+        else
-+          {
-+            op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
-+                                      NULL_RTX, 0, next_methods);
-+            if (op1_xhigh)
-+              op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
-+                                        op1_xhigh, op1_xhigh, 0,
-+                                        next_methods);
-+          }
-+      }
-+
-+      /* If we have been able to directly compute the product of the
-+       low-order words of the operands and perform any required adjustments
-+       of the operands, we proceed by trying two more multiplications
-+       and then computing the appropriate sum.
-+
-+       We have checked above that the required addition is provided.
-+       Full-word addition will normally always succeed, especially if
-+       it is provided at all, so we don't worry about its failure.  The
-+       multiplication may well fail, however, so we do handle that.  */
-+
-+      if (product && op0_xhigh && op1_xhigh)
-+      {
-+        rtx product_high = operand_subword (product, high, 1, mode);
-+        rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
-+                                 NULL_RTX, 0, OPTAB_DIRECT);
-+
-+        if (!REG_P (product_high))
-+          product_high = force_reg (word_mode, product_high);
-+
-+        if (temp != 0)
-+          temp = expand_binop (word_mode, add_optab, temp, product_high,
-+                               product_high, 0, next_methods);
-+
-+        if (temp != 0 && temp != product_high)
-+          emit_move_insn (product_high, temp);
-+
-+        if (temp != 0)
-+          temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh, 
-+                               NULL_RTX, 0, OPTAB_DIRECT);
-+
-+        if (temp != 0)
-+          temp = expand_binop (word_mode, add_optab, temp,
-+                               product_high, product_high,
-+                               0, next_methods);
-+
-+        if (temp != 0 && temp != product_high)
-+          emit_move_insn (product_high, temp);
-+
-+        emit_move_insn (operand_subword (product, high, 1, mode), product_high);
-+
-+        if (temp != 0)
-+          {
-+            if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
-+              {
-+                temp = emit_move_insn (product, product);
-+                set_unique_reg_note (temp,
-+                                     REG_EQUAL,
-+                                     gen_rtx_fmt_ee (MULT, mode,
-+                                                     copy_rtx (op0),
-+                                                     copy_rtx (op1)));
-+              }
-+
-+            return product;
-+          }
-+      }
-+
-+      /* If we get here, we couldn't do it for some reason even though we
-+       originally thought we could.  Delete anything we've emitted in
-+       trying to do it.  */
-+
-+      delete_insns_since (last);
-+    }
-+
-+  /* Open-code the vector operations if we have no hardware support
-+     for them.  */
-+  if (class == MODE_VECTOR_INT || class == MODE_VECTOR_FLOAT)
-+    return expand_vector_binop (mode, binoptab, op0, op1, target,
-+                              unsignedp, methods);
-+
-+  /* We need to open-code the complex type operations: '+, -, * and /' */
-+
-+  /* At this point we allow operations between two similar complex
-+     numbers, and also if one of the operands is not a complex number
-+     but rather of MODE_FLOAT or MODE_INT. However, the caller
-+     must make sure that the MODE of the non-complex operand matches
-+     the SUBMODE of the complex operand.  */
-+
-+  if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
-+    {
-+      rtx real0 = 0, imag0 = 0;
-+      rtx real1 = 0, imag1 = 0;
-+      rtx realr, imagr, res;
-+      rtx seq;
-+      rtx equiv_value;
-+      int ok = 0;
-+
-+      /* Find the correct mode for the real and imaginary parts */
-+      enum machine_mode submode = GET_MODE_INNER(mode);
-+
-+      if (submode == BLKmode)
-+      abort ();
-+
-+      if (! target)
-+      target = gen_reg_rtx (mode);
-+
-+      start_sequence ();
-+
-+      realr = gen_realpart (submode, target);
-+      imagr = gen_imagpart (submode, target);
-+
-+      if (GET_MODE (op0) == mode)
-+      {
-+        real0 = gen_realpart (submode, op0);
-+        imag0 = gen_imagpart (submode, op0);
-+      }
-+      else
-+      real0 = op0;
-+
-+      if (GET_MODE (op1) == mode)
-+      {
-+        real1 = gen_realpart (submode, op1);
-+        imag1 = gen_imagpart (submode, op1);
-+      }
-+      else
-+      real1 = op1;
-+
-+      if (real0 == 0 || real1 == 0 || ! (imag0 != 0 || imag1 != 0))
-+      abort ();
-+
-+      switch (binoptab->code)
-+      {
-+      case PLUS:
-+        /* (a+ib) + (c+id) = (a+c) + i(b+d) */
-+      case MINUS:
-+        /* (a+ib) - (c+id) = (a-c) + i(b-d) */
-+        res = expand_binop (submode, binoptab, real0, real1,
-+                            realr, unsignedp, methods);
-+
-+        if (res == 0)
-+          break;
-+        else if (res != realr)
-+          emit_move_insn (realr, res);
-+
-+        if (imag0 != 0 && imag1 != 0)
-+          res = expand_binop (submode, binoptab, imag0, imag1,
-+                              imagr, unsignedp, methods);
-+        else if (imag0 != 0)
-+          res = imag0;
-+        else if (binoptab->code == MINUS)
-+            res = expand_unop (submode,
-+                                binoptab == subv_optab ? negv_optab : neg_optab,
-+                                imag1, imagr, unsignedp);
-+        else
-+          res = imag1;
-+
-+        if (res == 0)
-+          break;
-+        else if (res != imagr)
-+          emit_move_insn (imagr, res);
-+
-+        ok = 1;
-+        break;
-+
-+      case MULT:
-+        /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
-+
-+        if (imag0 != 0 && imag1 != 0)
-+          {
-+            rtx temp1, temp2;
-+
-+            /* Don't fetch these from memory more than once.  */
-+            real0 = force_reg (submode, real0);
-+            real1 = force_reg (submode, real1);
-+            imag0 = force_reg (submode, imag0);
-+            imag1 = force_reg (submode, imag1);
-+
-+            temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
-+                                  unsignedp, methods);
-+
-+            temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
-+                                  unsignedp, methods);
-+
-+            if (temp1 == 0 || temp2 == 0)
-+              break;
-+
-+            res = (expand_binop
-+                     (submode,
-+                      binoptab == smulv_optab ? subv_optab : sub_optab,
-+                      temp1, temp2, realr, unsignedp, methods));
-+
-+            if (res == 0)
-+              break;
-+            else if (res != realr)
-+              emit_move_insn (realr, res);
-+
-+            temp1 = expand_binop (submode, binoptab, real0, imag1,
-+                                  NULL_RTX, unsignedp, methods);
-+
-+            temp2 = expand_binop (submode, binoptab, real1, imag0,
-+                                  NULL_RTX, unsignedp, methods);
-+
-+            if (temp1 == 0 || temp2 == 0)
-+              break;
-+
-+            res = (expand_binop
-+                     (submode,
-+                      binoptab == smulv_optab ? addv_optab : add_optab,
-+                      temp1, temp2, imagr, unsignedp, methods));
-+
-+            if (res == 0)
-+              break;
-+            else if (res != imagr)
-+              emit_move_insn (imagr, res);
-+
-+            ok = 1;
-+          }
-+        else
-+          {
-+            /* Don't fetch these from memory more than once.  */
-+            real0 = force_reg (submode, real0);
-+            real1 = force_reg (submode, real1);
-+
-+            res = expand_binop (submode, binoptab, real0, real1,
-+                                realr, unsignedp, methods);
-+            if (res == 0)
-+              break;
-+            else if (res != realr)
-+              emit_move_insn (realr, res);
-+
-+            if (imag0 != 0)
-+              res = expand_binop (submode, binoptab,
-+                                  real1, imag0, imagr, unsignedp, methods);
-+            else
-+              res = expand_binop (submode, binoptab,
-+                                  real0, imag1, imagr, unsignedp, methods);
-+
-+            if (res == 0)
-+              break;
-+            else if (res != imagr)
-+              emit_move_insn (imagr, res);
-+
-+            ok = 1;
-+          }
-+        break;
-+
-+      case DIV:
-+        /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
-+        
-+        if (imag1 == 0)
-+          {
-+            /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
-+
-+            /* Don't fetch these from memory more than once.  */
-+            real1 = force_reg (submode, real1);
-+
-+            /* Simply divide the real and imaginary parts by `c' */
-+            if (class == MODE_COMPLEX_FLOAT)
-+              res = expand_binop (submode, binoptab, real0, real1,
-+                                  realr, unsignedp, methods);
-+            else
-+              res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
-+                                   real0, real1, realr, unsignedp);
-+
-+            if (res == 0)
-+              break;
-+            else if (res != realr)
-+              emit_move_insn (realr, res);
-+
-+            if (class == MODE_COMPLEX_FLOAT)
-+              res = expand_binop (submode, binoptab, imag0, real1,
-+                                  imagr, unsignedp, methods);
-+            else
-+              res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
-+                                   imag0, real1, imagr, unsignedp);
-+
-+            if (res == 0)
-+              break;
-+            else if (res != imagr)
-+              emit_move_insn (imagr, res);
-+
-+            ok = 1;
-+          }
-+        else
-+          {
-+            switch (flag_complex_divide_method)
-+              {
-+              case 0:
-+                ok = expand_cmplxdiv_straight (real0, real1, imag0, imag1,
-+                                               realr, imagr, submode,
-+                                               unsignedp, methods,
-+                                               class, binoptab);
-+                break;
-+
-+              case 1:
-+                ok = expand_cmplxdiv_wide (real0, real1, imag0, imag1,
-+                                           realr, imagr, submode,
-+                                           unsignedp, methods,
-+                                           class, binoptab);
-+                break;
-+
-+              default:
-+                abort ();
-+              }
-+          }
-+        break;
-+        
-+      default:
-+        abort ();
-+      }
-+
-+      seq = get_insns ();
-+      end_sequence ();
-+
-+      if (ok)
-+      {
-+        if (binoptab->code != UNKNOWN)
-+          equiv_value
-+            = gen_rtx_fmt_ee (binoptab->code, mode,
-+                              copy_rtx (op0), copy_rtx (op1));
-+        else
-+          equiv_value = 0;
-+        
-+        emit_no_conflict_block (seq, target, op0, op1, equiv_value);
-+      
-+        return target;
-+      }
-+    }
-+
-+  /* It can't be open-coded in this mode.
-+     Use a library call if one is available and caller says that's ok.  */
-+
-+  if (binoptab->handlers[(int) mode].libfunc
-+      && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
-+    {
-+      rtx insns;
-+      rtx op1x = op1;
-+      enum machine_mode op1_mode = mode;
-+      rtx value;
-+
-+      start_sequence ();
-+
-+      if (shift_op)
-+      {
-+        op1_mode = word_mode;
-+        /* Specify unsigned here,
-+           since negative shift counts are meaningless.  */
-+        op1x = convert_to_mode (word_mode, op1, 1);
-+      }
-+
-+      if (GET_MODE (op0) != VOIDmode
-+        && GET_MODE (op0) != mode)
-+      op0 = convert_to_mode (mode, op0, unsignedp);
-+
-+      /* Pass 1 for NO_QUEUE so we don't lose any increments
-+       if the libcall is cse'd or moved.  */
-+      value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
-+                                     NULL_RTX, LCT_CONST, mode, 2,
-+                                     op0, mode, op1x, op1_mode);
-+
-+      insns = get_insns ();
-+      end_sequence ();
-+
-+      target = gen_reg_rtx (mode);
-+      emit_libcall_block (insns, target, value,
-+                        gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
-+
-+      return target;
-+    }
-+
-+  delete_insns_since (last);
-+
-+  /* It can't be done in this mode.  Can we do it in a wider mode?  */
-+
-+  if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
-+       || methods == OPTAB_MUST_WIDEN))
-+    {
-+      /* Caller says, don't even try.  */
-+      delete_insns_since (entry_last);
-+      return 0;
-+    }
-+
-+  /* Compute the value of METHODS to pass to recursive calls.
-+     Don't allow widening to be tried recursively.  */
-+
-+  methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
-+
-+  /* Look for a wider mode of the same class for which it appears we can do
-+     the operation.  */
-+
-+  if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
-+    {
-+      for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
-+         wider_mode = GET_MODE_WIDER_MODE (wider_mode))
-+      {
-+        if ((binoptab->handlers[(int) wider_mode].insn_code
-+             != CODE_FOR_nothing)
-+            || (methods == OPTAB_LIB
-+                && binoptab->handlers[(int) wider_mode].libfunc))
-+          {
-+            rtx xop0 = op0, xop1 = op1;
-+            int no_extend = 0;
-+
-+            /* For certain integer operations, we need not actually extend
-+               the narrow operands, as long as we will truncate
-+               the results to the same narrowness.  */
-+
-+            if ((binoptab == ior_optab || binoptab == and_optab
-+                 || binoptab == xor_optab
-+                 || binoptab == add_optab || binoptab == sub_optab
-+                 || binoptab == smul_optab || binoptab == ashl_optab)
-+                && class == MODE_INT)
-+              no_extend = 1;
-+
-+            xop0 = widen_operand (xop0, wider_mode, mode,
-+                                  unsignedp, no_extend);
-+
-+            /* The second operand of a shift must always be extended.  */
-+            xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
-+                                  no_extend && binoptab != ashl_optab);
-+
-+            temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
-+                                 unsignedp, methods);
-+            if (temp)
-+              {
-+                if (class != MODE_INT)
-+                  {
-+                    if (target == 0)
-+                      target = gen_reg_rtx (mode);
-+                    convert_move (target, temp, 0);
-+                    return target;
-+                  }
-+                else
-+                  return gen_lowpart (mode, temp);
-+              }
-+            else
-+              delete_insns_since (last);
-+          }
-+      }
-+    }
-+
-+  delete_insns_since (entry_last);
-+  return 0;
-+}
-+
-+/* Like expand_binop, but for open-coding vectors binops.  */
-+
-+static rtx
-+expand_vector_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
-+     enum machine_mode mode;
-+     optab binoptab;
-+     rtx op0, op1;
-+     rtx target;
-+     int unsignedp;
-+     enum optab_methods methods;
-+{
-+  enum machine_mode submode, tmode;
-+  int size, elts, subsize, subbitsize, i;
-+  rtx t, a, b, res, seq;
-+  enum mode_class class;
-+
-+  class = GET_MODE_CLASS (mode);
-+
-+  size = GET_MODE_SIZE (mode);
-+  submode = GET_MODE_INNER (mode);
-+
-+  /* Search for the widest vector mode with the same inner mode that is
-+     still narrower than MODE and that allows to open-code this operator.
-+     Note, if we find such a mode and the handler later decides it can't
-+     do the expansion, we'll be called recursively with the narrower mode.  */
-+  for (tmode = GET_CLASS_NARROWEST_MODE (class);
-+       GET_MODE_SIZE (tmode) < GET_MODE_SIZE (mode);
-+       tmode = GET_MODE_WIDER_MODE (tmode))
-+    {
-+      if (GET_MODE_INNER (tmode) == GET_MODE_INNER (mode)
-+        && binoptab->handlers[(int) tmode].insn_code != CODE_FOR_nothing)
-+      submode = tmode;
-+    }
-+
-+  switch (binoptab->code)
-+    {
-+    case AND:
-+    case IOR:
-+    case XOR:
-+      tmode = int_mode_for_mode (mode);
-+      if (tmode != BLKmode)
-+      submode = tmode;
-+    case PLUS:
-+    case MINUS:
-+    case MULT:
-+    case DIV:
-+      subsize = GET_MODE_SIZE (submode);
-+      subbitsize = GET_MODE_BITSIZE (submode);
-+      elts = size / subsize;
-+
-+      /* If METHODS is OPTAB_DIRECT, we don't insist on the exact mode,
-+       but that we operate on more than one element at a time.  */
-+      if (subsize == GET_MODE_UNIT_SIZE (mode) && methods == OPTAB_DIRECT)
-+      return 0;
-+
-+      start_sequence ();
-+
-+      /* Errors can leave us with a const0_rtx as operand.  */
-+      if (GET_MODE (op0) != mode)
-+      op0 = copy_to_mode_reg (mode, op0);
-+      if (GET_MODE (op1) != mode)
-+      op1 = copy_to_mode_reg (mode, op1);
-+
-+      if (!target)
-+      target = gen_reg_rtx (mode);
-+
-+      for (i = 0; i < elts; ++i)
-+      {
-+        /* If this is part of a register, and not the first item in the
-+           word, we can't store using a SUBREG - that would clobber
-+           previous results.
-+           And storing with a SUBREG is only possible for the least
-+           significant part, hence we can't do it for big endian
-+           (unless we want to permute the evaluation order.  */
-+        if (GET_CODE (target) == REG
-+            && (BYTES_BIG_ENDIAN
-+                ? subsize < UNITS_PER_WORD
-+                : ((i * subsize) % UNITS_PER_WORD) != 0))
-+          t = NULL_RTX;
-+        else
-+          t = simplify_gen_subreg (submode, target, mode, i * subsize);
-+        if (CONSTANT_P (op0))
-+          a = simplify_gen_subreg (submode, op0, mode, i * subsize);
-+        else
-+          a = extract_bit_field (op0, subbitsize, i * subbitsize, unsignedp,
-+                                 NULL_RTX, submode, submode, size);
-+        if (CONSTANT_P (op1))
-+          b = simplify_gen_subreg (submode, op1, mode, i * subsize);
-+        else
-+          b = extract_bit_field (op1, subbitsize, i * subbitsize, unsignedp,
-+                                 NULL_RTX, submode, submode, size);
-+
-+        if (binoptab->code == DIV)
-+          {
-+            if (class == MODE_VECTOR_FLOAT)
-+              res = expand_binop (submode, binoptab, a, b, t,
-+                                  unsignedp, methods);
-+            else
-+              res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
-+                                   a, b, t, unsignedp);
-+          }
-+        else
-+          res = expand_binop (submode, binoptab, a, b, t,
-+                              unsignedp, methods);
-+
-+        if (res == 0)
-+          break;
-+
-+        if (t)
-+          emit_move_insn (t, res);
-+        else
-+          store_bit_field (target, subbitsize, i * subbitsize, submode, res,
-+                           size);
-+      }
-+      break;
-+
-+    default:
-+      abort ();
-+    }
-+
-+  seq = get_insns ();
-+  end_sequence ();
-+  emit_insn (seq);
-+
-+  return target;
-+}
-+
-+/* Like expand_unop but for open-coding vector unops.  */
-+
-+static rtx
-+expand_vector_unop (mode, unoptab, op0, target, unsignedp)
-+     enum machine_mode mode;
-+     optab unoptab;
-+     rtx op0;
-+     rtx target;
-+     int unsignedp;
-+{
-+  enum machine_mode submode, tmode;
-+  int size, elts, subsize, subbitsize, i;
-+  rtx t, a, res, seq;
-+
-+  size = GET_MODE_SIZE (mode);
-+  submode = GET_MODE_INNER (mode);
-+
-+  /* Search for the widest vector mode with the same inner mode that is
-+     still narrower than MODE and that allows to open-code this operator.
-+     Note, if we find such a mode and the handler later decides it can't
-+     do the expansion, we'll be called recursively with the narrower mode.  */
-+  for (tmode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (mode));
-+       GET_MODE_SIZE (tmode) < GET_MODE_SIZE (mode);
-+       tmode = GET_MODE_WIDER_MODE (tmode))
-+    {
-+      if (GET_MODE_INNER (tmode) == GET_MODE_INNER (mode)
-+        && unoptab->handlers[(int) tmode].insn_code != CODE_FOR_nothing)
-+      submode = tmode;
-+    }
-+  /* If there is no negate operation, try doing a subtract from zero.  */
-+  if (unoptab == neg_optab && GET_MODE_CLASS (submode) == MODE_INT
-+      /* Avoid infinite recursion when an
-+       error has left us with the wrong mode.  */
-+      && GET_MODE (op0) == mode)
-+    {    
-+      rtx temp;
-+      temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
-+                           target, unsignedp, OPTAB_DIRECT);
-+      if (temp)
-+      return temp;
-+    }
-+
-+  if (unoptab == one_cmpl_optab)
-+    {
-+      tmode = int_mode_for_mode (mode);
-+      if (tmode != BLKmode)
-+      submode = tmode;
-+    }
-+
-+  subsize = GET_MODE_SIZE (submode);
-+  subbitsize = GET_MODE_BITSIZE (submode);
-+  elts = size / subsize;
-+
-+  /* Errors can leave us with a const0_rtx as operand.  */
-+  if (GET_MODE (op0) != mode)
-+    op0 = copy_to_mode_reg (mode, op0);
-+
-+  if (!target)
-+    target = gen_reg_rtx (mode);
-+
-+  start_sequence ();
-+
-+  for (i = 0; i < elts; ++i)
-+    {
-+      /* If this is part of a register, and not the first item in the
-+       word, we can't store using a SUBREG - that would clobber
-+       previous results.
-+       And storing with a SUBREG is only possible for the least
-+       significant part, hence we can't do it for big endian
-+       (unless we want to permute the evaluation order.  */
-+      if (GET_CODE (target) == REG
-+        && (BYTES_BIG_ENDIAN
-+            ?  subsize < UNITS_PER_WORD
-+            : ((i * subsize) % UNITS_PER_WORD) != 0))
-+      t = NULL_RTX;
-+      else
-+      t = simplify_gen_subreg (submode, target, mode, i * subsize);
-+      if (CONSTANT_P (op0))
-+      a = simplify_gen_subreg (submode, op0, mode, i * subsize);
-+      else
-+      a = extract_bit_field (op0, subbitsize, i * subbitsize, unsignedp,
-+                             t, submode, submode, size);
-+
-+      res = expand_unop (submode, unoptab, a, t, unsignedp);
-+
-+      if (t)
-+      emit_move_insn (t, res);
-+      else
-+      store_bit_field (target, subbitsize, i * subbitsize, submode, res,
-+                       size);
-+    }
-+
-+  seq = get_insns ();
-+  end_sequence ();
-+  emit_insn (seq);
-+
-+  return target;
-+}
-+\f
-+/* Expand a binary operator which has both signed and unsigned forms.
-+   UOPTAB is the optab for unsigned operations, and SOPTAB is for
-+   signed operations.
-+
-+   If we widen unsigned operands, we may use a signed wider operation instead
-+   of an unsigned wider operation, since the result would be the same.  */
-+
-+rtx
-+sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
-+     enum machine_mode mode;
-+     optab uoptab, soptab;
-+     rtx op0, op1, target;
-+     int unsignedp;
-+     enum optab_methods methods;
-+{
-+  rtx temp;
-+  optab direct_optab = unsignedp ? uoptab : soptab;
-+  struct optab wide_soptab;
-+
-+  /* Do it without widening, if possible.  */
-+  temp = expand_binop (mode, direct_optab, op0, op1, target,
-+                     unsignedp, OPTAB_DIRECT);
-+  if (temp || methods == OPTAB_DIRECT)
-+    return temp;
-+
-+  /* Try widening to a signed int.  Make a fake signed optab that
-+     hides any signed insn for direct use.  */
-+  wide_soptab = *soptab;
-+  wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
-+  wide_soptab.handlers[(int) mode].libfunc = 0;
-+
-+  temp = expand_binop (mode, &wide_soptab, op0, op1, target,
-+                     unsignedp, OPTAB_WIDEN);
-+
-+  /* For unsigned operands, try widening to an unsigned int.  */
-+  if (temp == 0 && unsignedp)
-+    temp = expand_binop (mode, uoptab, op0, op1, target,
-+                       unsignedp, OPTAB_WIDEN);
-+  if (temp || methods == OPTAB_WIDEN)
-+    return temp;
-+
-+  /* Use the right width lib call if that exists.  */
-+  temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
-+  if (temp || methods == OPTAB_LIB)
-+    return temp;
-+
-+  /* Must widen and use a lib call, use either signed or unsigned.  */
-+  temp = expand_binop (mode, &wide_soptab, op0, op1, target,
-+                     unsignedp, methods);
-+  if (temp != 0)
-+    return temp;
-+  if (unsignedp)
-+    return expand_binop (mode, uoptab, op0, op1, target,
-+                       unsignedp, methods);
-+  return 0;
-+}
-+\f
-+/* Generate code to perform an operation specified by BINOPTAB
-+   on operands OP0 and OP1, with two results to TARG1 and TARG2.
-+   We assume that the order of the operands for the instruction
-+   is TARG0, OP0, OP1, TARG1, which would fit a pattern like
-+   [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
-+
-+   Either TARG0 or TARG1 may be zero, but what that means is that
-+   the result is not actually wanted.  We will generate it into
-+   a dummy pseudo-reg and discard it.  They may not both be zero.
-+
-+   Returns 1 if this operation can be performed; 0 if not.  */
-+
-+int
-+expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
-+     optab binoptab;
-+     rtx op0, op1;
-+     rtx targ0, targ1;
-+     int unsignedp;
-+{
-+  enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
-+  enum mode_class class;
-+  enum machine_mode wider_mode;
-+  rtx entry_last = get_last_insn ();
-+  rtx last;
-+
-+  class = GET_MODE_CLASS (mode);
-+
-+  op0 = protect_from_queue (op0, 0);
-+  op1 = protect_from_queue (op1, 0);
-+
-+  if (flag_force_mem)
-+    {
-+      op0 = force_not_mem (op0);
-+      op1 = force_not_mem (op1);
-+    }
-+
-+  /* If we are inside an appropriately-short loop and one operand is an
-+     expensive constant, force it into a register.  */
-+  if (CONSTANT_P (op0) && preserve_subexpressions_p ()
-+      && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
-+    op0 = force_reg (mode, op0);
-+
-+  if (CONSTANT_P (op1) && preserve_subexpressions_p ()
-+      && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
-+    op1 = force_reg (mode, op1);
-+
-+  if (targ0)
-+    targ0 = protect_from_queue (targ0, 1);
-+  else
-+    targ0 = gen_reg_rtx (mode);
-+  if (targ1)
-+    targ1 = protect_from_queue (targ1, 1);
-+  else
-+    targ1 = gen_reg_rtx (mode);
-+
-+  /* Record where to go back to if we fail.  */
-+  last = get_last_insn ();
-+
-+  if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
-+    {
-+      int icode = (int) binoptab->handlers[(int) mode].insn_code;
-+      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
-+      enum machine_mode mode1 = insn_data[icode].operand[2].mode;
-+      rtx pat;
-+      rtx xop0 = op0, xop1 = op1;
-+
-+      /* In case the insn wants input operands in modes different from
-+       those of the actual operands, convert the operands.  It would
-+       seem that we don't need to convert CONST_INTs, but we do, so
-+       that they're properly zero-extended, sign-extended or truncated
-+       for their mode.  */
-+
-+      if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
-+      xop0 = convert_modes (mode0,
-+                            GET_MODE (op0) != VOIDmode
-+                            ? GET_MODE (op0)
-+                            : mode,
-+                            xop0, unsignedp);
-+
-+      if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
-+      xop1 = convert_modes (mode1,
-+                            GET_MODE (op1) != VOIDmode
-+                            ? GET_MODE (op1)
-+                            : mode,
-+                            xop1, unsignedp);
-+
-+      /* Now, if insn doesn't accept these operands, put them into pseudos.  */
-+      if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
-+      xop0 = copy_to_mode_reg (mode0, xop0);
-+
-+      if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1))
-+      xop1 = copy_to_mode_reg (mode1, xop1);
-+
-+      /* We could handle this, but we should always be called with a pseudo
-+       for our targets and all insns should take them as outputs.  */
-+      if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
-+        || ! (*insn_data[icode].operand[3].predicate) (targ1, mode))
-+      abort ();
-+      
-+      pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
-+      if (pat)
-+      {
-+        emit_insn (pat);
-+        return 1;
-+      }
-+      else
-+      delete_insns_since (last);
-+    }
-+
-+  /* It can't be done in this mode.  Can we do it in a wider mode?  */
-+
-+  if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
-+    {
-+      for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
-+         wider_mode = GET_MODE_WIDER_MODE (wider_mode))
-+      {
-+        if (binoptab->handlers[(int) wider_mode].insn_code
-+            != CODE_FOR_nothing)
-+          {
-+            rtx t0 = gen_reg_rtx (wider_mode);
-+            rtx t1 = gen_reg_rtx (wider_mode);
-+            rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
-+            rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
-+
-+            if (expand_twoval_binop (binoptab, cop0, cop1,
-+                                     t0, t1, unsignedp))
-+              {
-+                convert_move (targ0, t0, unsignedp);
-+                convert_move (targ1, t1, unsignedp);
-+                return 1;
-+              }
-+            else
-+              delete_insns_since (last);
-+          }
-+      }
-+    }
-+
-+  delete_insns_since (entry_last);
-+  return 0;
-+}
-+\f
-+/* Wrapper around expand_unop which takes an rtx code to specify
-+   the operation to perform, not an optab pointer.  All other
-+   arguments are the same.  */
-+rtx
-+expand_simple_unop (mode, code, op0, target, unsignedp)
-+     enum machine_mode mode;
-+     enum rtx_code code;
-+     rtx op0;
-+     rtx target;
-+     int unsignedp;
-+{
-+  optab unop = code_to_optab[(int) code];
-+  if (unop == 0)
-+    abort ();
-+
-+  return expand_unop (mode, unop, op0, target, unsignedp);
-+}
-+
-+/* Generate code to perform an operation specified by UNOPTAB
-+   on operand OP0, with result having machine-mode MODE.
-+
-+   UNSIGNEDP is for the case where we have to widen the operands
-+   to perform the operation.  It says to use zero-extension.
-+
-+   If TARGET is nonzero, the value
-+   is generated there, if it is convenient to do so.
-+   In all cases an rtx is returned for the locus of the value;
-+   this may or may not be TARGET.  */
-+
-+rtx
-+expand_unop (mode, unoptab, op0, target, unsignedp)
-+     enum machine_mode mode;
-+     optab unoptab;
-+     rtx op0;
-+     rtx target;
-+     int unsignedp;
-+{
-+  enum mode_class class;
-+  enum machine_mode wider_mode;
-+  rtx temp;
-+  rtx last = get_last_insn ();
-+  rtx pat;
-+
-+  class = GET_MODE_CLASS (mode);
-+
-+  op0 = protect_from_queue (op0, 0);
-+
-+  if (flag_force_mem)
-+    {
-+      op0 = force_not_mem (op0);
-+    }
-+
-+  if (target)
-+    target = protect_from_queue (target, 1);
-+
-+  if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
-+    {
-+      int icode = (int) unoptab->handlers[(int) mode].insn_code;
-+      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
-+      rtx xop0 = op0;
-+
-+      if (target)
-+      temp = target;
-+      else
-+      temp = gen_reg_rtx (mode);
-+
-+      if (GET_MODE (xop0) != VOIDmode
-+        && GET_MODE (xop0) != mode0)
-+      xop0 = convert_to_mode (mode0, xop0, unsignedp);
-+
-+      /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
-+
-+      if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
-+      xop0 = copy_to_mode_reg (mode0, xop0);
-+
-+      if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
-+      temp = gen_reg_rtx (mode);
-+
-+      pat = GEN_FCN (icode) (temp, xop0);
-+      if (pat)
-+      {
-+        if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
-+            && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
-+          {
-+            delete_insns_since (last);
-+            return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
-+          }
-+
-+        emit_insn (pat);
-+        
-+        return temp;
-+      }
-+      else
-+      delete_insns_since (last);
-+    }
-+
-+  /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
-+
-+  if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
-+    for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
-+       wider_mode = GET_MODE_WIDER_MODE (wider_mode))
-+      {
-+      if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
-+        {
-+          rtx xop0 = op0;
-+
-+          /* For certain operations, we need not actually extend
-+             the narrow operand, as long as we will truncate the
-+             results to the same narrowness.  */
-+
-+          xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
-+                                (unoptab == neg_optab
-+                                 || unoptab == one_cmpl_optab)
-+                                && class == MODE_INT);
-+            
-+          temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
-+                              unsignedp);
-+
-+          if (temp)
-+            {
-+              if (class != MODE_INT)
-+                {
-+                  if (target == 0)
-+                    target = gen_reg_rtx (mode);
-+                  convert_move (target, temp, 0);
-+                  return target;
-+                }
-+              else
-+                return gen_lowpart (mode, temp);
-+            }
-+          else
-+            delete_insns_since (last);
-+        }
-+      }
-+
-+  /* These can be done a word at a time.  */
-+  if (unoptab == one_cmpl_optab
-+      && class == MODE_INT
-+      && GET_MODE_SIZE (mode) > UNITS_PER_WORD
-+      && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
-+    {
-+      int i;
-+      rtx insns;
-+
-+      if (target == 0 || target == op0)
-+      target = gen_reg_rtx (mode);
-+
-+      start_sequence ();
-+
-+      /* Do the actual arithmetic.  */
-+      for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
-+      {
-+        rtx target_piece = operand_subword (target, i, 1, mode);
-+        rtx x = expand_unop (word_mode, unoptab,
-+                             operand_subword_force (op0, i, mode),
-+                             target_piece, unsignedp);
-+
-+        if (target_piece != x)
-+          emit_move_insn (target_piece, x);
-+      }
-+
-+      insns = get_insns ();
-+      end_sequence ();
-+
-+      emit_no_conflict_block (insns, target, op0, NULL_RTX,
-+                            gen_rtx_fmt_e (unoptab->code, mode,
-+                                           copy_rtx (op0)));
-+      return target;
-+    }
-+
-+  /* Open-code the complex negation operation.  */
-+  else if (unoptab->code == NEG
-+         && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
-+    {
-+      rtx target_piece;
-+      rtx x;
-+      rtx seq;
-+
-+      /* Find the correct mode for the real and imaginary parts */
-+      enum machine_mode submode = GET_MODE_INNER (mode);
-+
-+      if (submode == BLKmode)
-+      abort ();
-+
-+      if (target == 0)
-+      target = gen_reg_rtx (mode);
-+      
-+      start_sequence ();
-+
-+      target_piece = gen_imagpart (submode, target);
-+      x = expand_unop (submode, unoptab,
-+                     gen_imagpart (submode, op0),
-+                     target_piece, unsignedp);
-+      if (target_piece != x)
-+      emit_move_insn (target_piece, x);
-+
-+      target_piece = gen_realpart (submode, target);
-+      x = expand_unop (submode, unoptab,
-+                     gen_realpart (submode, op0),
-+                     target_piece, unsignedp);
-+      if (target_piece != x)
-+      emit_move_insn (target_piece, x);
-+
-+      seq = get_insns ();
-+      end_sequence ();
-+
-+      emit_no_conflict_block (seq, target, op0, 0,
-+                            gen_rtx_fmt_e (unoptab->code, mode,
-+                                           copy_rtx (op0)));
-+      return target;
-+    }
-+
-+  /* Now try a library call in this mode.  */
-+  if (unoptab->handlers[(int) mode].libfunc)
-+    {
-+      rtx insns;
-+      rtx value;
-+
-+      start_sequence ();
-+
-+      /* Pass 1 for NO_QUEUE so we don't lose any increments
-+       if the libcall is cse'd or moved.  */
-+      value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
-+                                     NULL_RTX, LCT_CONST, mode, 1, op0, mode);
-+      insns = get_insns ();
-+      end_sequence ();
-+
-+      target = gen_reg_rtx (mode);
-+      emit_libcall_block (insns, target, value,
-+                        gen_rtx_fmt_e (unoptab->code, mode, op0));
-+
-+      return target;
-+    }
-+
-+  if (class == MODE_VECTOR_FLOAT || class == MODE_VECTOR_INT)
-+    return expand_vector_unop (mode, unoptab, op0, target, unsignedp);
-+
-+  /* It can't be done in this mode.  Can we do it in a wider mode?  */
-+
-+  if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
-+    {
-+      for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
-+         wider_mode = GET_MODE_WIDER_MODE (wider_mode))
-+      {
-+        if ((unoptab->handlers[(int) wider_mode].insn_code
-+             != CODE_FOR_nothing)
-+            || unoptab->handlers[(int) wider_mode].libfunc)
-+          {
-+            rtx xop0 = op0;
-+
-+            /* For certain operations, we need not actually extend
-+               the narrow operand, as long as we will truncate the
-+               results to the same narrowness.  */
-+
-+            xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
-+                                  (unoptab == neg_optab
-+                                   || unoptab == one_cmpl_optab)
-+                                  && class == MODE_INT);
-+            
-+            temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
-+                                unsignedp);
-+
-+            if (temp)
-+              {
-+                if (class != MODE_INT)
-+                  {
-+                    if (target == 0)
-+                      target = gen_reg_rtx (mode);
-+                    convert_move (target, temp, 0);
-+                    return target;
-+                  }
-+                else
-+                  return gen_lowpart (mode, temp);
-+              }
-+            else
-+              delete_insns_since (last);
-+          }
-+      }
-+    }
-+
-+  /* If there is no negate operation, try doing a subtract from zero.
-+     The US Software GOFAST library needs this.  */
-+  if (unoptab->code == NEG)
-+    {    
-+      rtx temp;
-+      temp = expand_binop (mode,
-+                           unoptab == negv_optab ? subv_optab : sub_optab,
-+                           CONST0_RTX (mode), op0,
-+                           target, unsignedp, OPTAB_LIB_WIDEN);
-+      if (temp)
-+      return temp;
-+    }
-+      
-+  return 0;
-+}
-+\f
-+/* Emit code to compute the absolute value of OP0, with result to
-+   TARGET if convenient.  (TARGET may be 0.)  The return value says
-+   where the result actually is to be found.
-+
-+   MODE is the mode of the operand; the mode of the result is
-+   different but can be deduced from MODE.
-+
-+ */
-+
-+rtx
-+expand_abs (mode, op0, target, result_unsignedp, safe)
-+     enum machine_mode mode;
-+     rtx op0;
-+     rtx target;
-+     int result_unsignedp;
-+     int safe;
-+{
-+  rtx temp, op1;
-+
-+  if (! flag_trapv)
-+    result_unsignedp = 1;
-+
-+  /* First try to do it with a special abs instruction.  */
-+  temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
-+                      op0, target, 0);
-+  if (temp != 0)
-+    return temp;
-+
-+  /* If we have a MAX insn, we can do this as MAX (x, -x).  */
-+  if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
-+    {
-+      rtx last = get_last_insn ();
-+
-+      temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
-+      if (temp != 0)
-+      temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
-+                           OPTAB_WIDEN);
-+
-+      if (temp != 0)
-+      return temp;
-+
-+      delete_insns_since (last);
-+    }
-+
-+  /* If this machine has expensive jumps, we can do integer absolute
-+     value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
-+     where W is the width of MODE.  */
-+
-+  if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
-+    {
-+      rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
-+                                 size_int (GET_MODE_BITSIZE (mode) - 1),
-+                                 NULL_RTX, 0);
-+
-+      temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
-+                         OPTAB_LIB_WIDEN);
-+      if (temp != 0)
-+      temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
-+                             temp, extended, target, 0, OPTAB_LIB_WIDEN);
-+
-+      if (temp != 0)
-+      return temp;
-+    }
-+
-+  /* If that does not win, use conditional jump and negate.  */
-+
-+  /* It is safe to use the target if it is the same
-+     as the source if this is also a pseudo register */
-+  if (op0 == target && GET_CODE (op0) == REG
-+      && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
-+    safe = 1;
-+
-+  op1 = gen_label_rtx ();
-+  if (target == 0 || ! safe
-+      || GET_MODE (target) != mode
-+      || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
-+      || (GET_CODE (target) == REG
-+        && REGNO (target) < FIRST_PSEUDO_REGISTER))
-+    target = gen_reg_rtx (mode);
-+
-+  emit_move_insn (target, op0);
-+  NO_DEFER_POP;
-+
-+  /* If this mode is an integer too wide to compare properly,
-+     compare word by word.  Rely on CSE to optimize constant cases.  */
-+  if (GET_MODE_CLASS (mode) == MODE_INT
-+      && ! can_compare_p (GE, mode, ccp_jump))
-+    do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx, 
-+                                NULL_RTX, op1);
-+  else
-+    do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
-+                           NULL_RTX, NULL_RTX, op1);
-+
-+  op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
-+                     target, target, 0);
-+  if (op0 != target)
-+    emit_move_insn (target, op0);
-+  emit_label (op1);
-+  OK_DEFER_POP;
-+  return target;
-+}
-+\f
-+/* Emit code to compute the absolute value of OP0, with result to
-+   TARGET if convenient.  (TARGET may be 0.)  The return value says
-+   where the result actually is to be found.
-+
-+   MODE is the mode of the operand; the mode of the result is
-+   different but can be deduced from MODE.
-+
-+   UNSIGNEDP is relevant for complex integer modes.  */
-+
-+rtx
-+expand_complex_abs (mode, op0, target, unsignedp)
-+     enum machine_mode mode;
-+     rtx op0;
-+     rtx target;
-+     int unsignedp;
-+{
-+  enum mode_class class = GET_MODE_CLASS (mode);
-+  enum machine_mode wider_mode;
-+  rtx temp;
-+  rtx entry_last = get_last_insn ();
-+  rtx last;
-+  rtx pat;
-+  optab this_abs_optab;
-+
-+  /* Find the correct mode for the real and imaginary parts.  */
-+  enum machine_mode submode = GET_MODE_INNER (mode);
-+
-+  if (submode == BLKmode)
-+    abort ();
-+
-+  op0 = protect_from_queue (op0, 0);
-+
-+  if (flag_force_mem)
-+    {
-+      op0 = force_not_mem (op0);
-+    }
-+
-+  last = get_last_insn ();
-+
-+  if (target)
-+    target = protect_from_queue (target, 1);
-+
-+  this_abs_optab = ! unsignedp && flag_trapv
-+                   && (GET_MODE_CLASS(mode) == MODE_INT)
-+                   ? absv_optab : abs_optab;
-+
-+  if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
-+    {
-+      int icode = (int) this_abs_optab->handlers[(int) mode].insn_code;
-+      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
-+      rtx xop0 = op0;
-+
-+      if (target)
-+      temp = target;
-+      else
-+      temp = gen_reg_rtx (submode);
-+
-+      if (GET_MODE (xop0) != VOIDmode
-+        && GET_MODE (xop0) != mode0)
-+      xop0 = convert_to_mode (mode0, xop0, unsignedp);
-+
-+      /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
-+
-+      if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
-+      xop0 = copy_to_mode_reg (mode0, xop0);
-+
-+      if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
-+      temp = gen_reg_rtx (submode);
-+
-+      pat = GEN_FCN (icode) (temp, xop0);
-+      if (pat)
-+      {
-+        if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
-+            && ! add_equal_note (pat, temp, this_abs_optab->code, xop0, 
-+                                 NULL_RTX))
-+          {
-+            delete_insns_since (last);
-+            return expand_unop (mode, this_abs_optab, op0, NULL_RTX, 
-+                                unsignedp);
-+          }
-+
-+        emit_insn (pat);
-+        
-+        return temp;
-+      }
-+      else
-+      delete_insns_since (last);
-+    }
-+
-+  /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
-+
-+  for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
-+       wider_mode = GET_MODE_WIDER_MODE (wider_mode))
-+    {
-+      if (this_abs_optab->handlers[(int) wider_mode].insn_code 
-+        != CODE_FOR_nothing)
-+      {
-+        rtx xop0 = op0;
-+
-+        xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
-+        temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
-+
-+        if (temp)
-+          {
-+            if (class != MODE_COMPLEX_INT)
-+              {
-+                if (target == 0)
-+                  target = gen_reg_rtx (submode);
-+                convert_move (target, temp, 0);
-+                return target;
-+              }
-+            else
-+              return gen_lowpart (submode, temp);
-+          }
-+        else
-+          delete_insns_since (last);
-+      }
-+    }
-+
-+  /* Open-code the complex absolute-value operation
-+     if we can open-code sqrt.  Otherwise it's not worth while.  */
-+  if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
-+      && ! flag_trapv)
-+    {
-+      rtx real, imag, total;
-+
-+      real = gen_realpart (submode, op0);
-+      imag = gen_imagpart (submode, op0);
-+
-+      /* Square both parts.  */
-+      real = expand_mult (submode, real, real, NULL_RTX, 0);
-+      imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
-+
-+      /* Sum the parts.  */
-+      total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
-+                          0, OPTAB_LIB_WIDEN);
-+
-+      /* Get sqrt in TARGET.  Set TARGET to where the result is.  */
-+      target = expand_unop (submode, sqrt_optab, total, target, 0);
-+      if (target == 0)
-+      delete_insns_since (last);
-+      else
-+      return target;
-+    }
-+
-+  /* Now try a library call in this mode.  */
-+  if (this_abs_optab->handlers[(int) mode].libfunc)
-+    {
-+      rtx insns;
-+      rtx value;
-+
-+      start_sequence ();
-+
-+      /* Pass 1 for NO_QUEUE so we don't lose any increments
-+       if the libcall is cse'd or moved.  */
-+      value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
-+                                     NULL_RTX, LCT_CONST, submode, 1, op0, mode);
-+      insns = get_insns ();
-+      end_sequence ();
-+
-+      target = gen_reg_rtx (submode);
-+      emit_libcall_block (insns, target, value,
-+                        gen_rtx_fmt_e (this_abs_optab->code, mode, op0));
-+
-+      return target;
-+    }
-+
-+  /* It can't be done in this mode.  Can we do it in a wider mode?  */
-+
-+  for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
-+       wider_mode = GET_MODE_WIDER_MODE (wider_mode))
-+    {
-+      if ((this_abs_optab->handlers[(int) wider_mode].insn_code
-+         != CODE_FOR_nothing)
-+        || this_abs_optab->handlers[(int) wider_mode].libfunc)
-+      {
-+        rtx xop0 = op0;
-+
-+        xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
-+
-+        temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
-+
-+        if (temp)
-+          {
-+            if (class != MODE_COMPLEX_INT)
-+              {
-+                if (target == 0)
-+                  target = gen_reg_rtx (submode);
-+                convert_move (target, temp, 0);
-+                return target;
-+              }
-+            else
-+              return gen_lowpart (submode, temp);
-+          }
-+        else
-+          delete_insns_since (last);
-+      }
-+    }
-+
-+  delete_insns_since (entry_last);
-+  return 0;
-+}
-+\f
-+/* Generate an instruction whose insn-code is INSN_CODE,
-+   with two operands: an output TARGET and an input OP0.
-+   TARGET *must* be nonzero, and the output is always stored there.
-+   CODE is an rtx code such that (CODE OP0) is an rtx that describes
-+   the value that is stored into TARGET.  */
-+
-+void
-+emit_unop_insn (icode, target, op0, code)
-+     int icode;
-+     rtx target;
-+     rtx op0;
-+     enum rtx_code code;
-+{
-+  rtx temp;
-+  enum machine_mode mode0 = insn_data[icode].operand[1].mode;
-+  rtx pat;
-+
-+  temp = target = protect_from_queue (target, 1);
-+
-+  op0 = protect_from_queue (op0, 0);
-+
-+  /* Sign and zero extension from memory is often done specially on
-+     RISC machines, so forcing into a register here can pessimize
-+     code.  */
-+  if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
-+    op0 = force_not_mem (op0);
-+
-+  /* Now, if insn does not accept our operands, put them into pseudos.  */
-+
-+  if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
-+    op0 = copy_to_mode_reg (mode0, op0);
-+
-+  if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
-+      || (flag_force_mem && GET_CODE (temp) == MEM))
-+    temp = gen_reg_rtx (GET_MODE (temp));
-+
-+  pat = GEN_FCN (icode) (temp, op0);
-+
-+  if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
-+    add_equal_note (pat, temp, code, op0, NULL_RTX);
-+  
-+  emit_insn (pat);
-+
-+  if (temp != target)
-+    emit_move_insn (target, temp);
-+}
-+\f
-+/* Emit code to perform a series of operations on a multi-word quantity, one
-+   word at a time.
-+
-+   Such a block is preceded by a CLOBBER of the output, consists of multiple
-+   insns, each setting one word of the output, and followed by a SET copying
-+   the output to itself.
-+
-+   Each of the insns setting words of the output receives a REG_NO_CONFLICT
-+   note indicating that it doesn't conflict with the (also multi-word)
-+   inputs.  The entire block is surrounded by REG_LIBCALL and REG_RETVAL
-+   notes.
-+
-+   INSNS is a block of code generated to perform the operation, not including
-+   the CLOBBER and final copy.  All insns that compute intermediate values
-+   are first emitted, followed by the block as described above.  
-+
-+   TARGET, OP0, and OP1 are the output and inputs of the operations,
-+   respectively.  OP1 may be zero for a unary operation.
-+
-+   EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
-+   on the last insn.
-+
-+   If TARGET is not a register, INSNS is simply emitted with no special
-+   processing.  Likewise if anything in INSNS is not an INSN or if
-+   there is a libcall block inside INSNS.
-+
-+   The final insn emitted is returned.  */
-+
-+rtx
-+emit_no_conflict_block (insns, target, op0, op1, equiv)
-+     rtx insns;
-+     rtx target;
-+     rtx op0, op1;
-+     rtx equiv;
-+{
-+  rtx prev, next, first, last, insn;
-+
-+  if (GET_CODE (target) != REG || reload_in_progress)
-+    return emit_insn (insns);
-+  else
-+    for (insn = insns; insn; insn = NEXT_INSN (insn))
-+      if (GET_CODE (insn) != INSN
-+        || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
-+      return emit_insn (insns);
-+
-+  /* First emit all insns that do not store into words of the output and remove
-+     these from the list.  */
-+  for (insn = insns; insn; insn = next)
-+    {
-+      rtx set = 0, note;
-+      int i;
-+
-+      next = NEXT_INSN (insn);
-+
-+      /* Some ports (cris) create an libcall regions at their own.  We must
-+       avoid any potential nesting of LIBCALLs.  */
-+      if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
-+      remove_note (insn, note);
-+      if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
-+      remove_note (insn, note);
-+
-+      if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
-+        || GET_CODE (PATTERN (insn)) == CLOBBER)
-+      set = PATTERN (insn);
-+      else if (GET_CODE (PATTERN (insn)) == PARALLEL)
-+      {
-+        for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
-+          if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
-+            {
-+              set = XVECEXP (PATTERN (insn), 0, i);
-+              break;
-+            }
-+      }
-+
-+      if (set == 0)
-+      abort ();
-+
-+      if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
-+      {
-+        if (PREV_INSN (insn))
-+          NEXT_INSN (PREV_INSN (insn)) = next;
-+        else
-+          insns = next;
-+
-+        if (next)
-+          PREV_INSN (next) = PREV_INSN (insn);
-+
-+        add_insn (insn);
-+      }
-+    }
-+
-+  prev = get_last_insn ();
-+
-+  /* Now write the CLOBBER of the output, followed by the setting of each
-+     of the words, followed by the final copy.  */
-+  if (target != op0 && target != op1)
-+    emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
-+
-+  for (insn = insns; insn; insn = next)
-+    {
-+      next = NEXT_INSN (insn);
-+      add_insn (insn);
-+
-+      if (op1 && GET_CODE (op1) == REG)
-+      REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
-+                                            REG_NOTES (insn));
-+
-+      if (op0 && GET_CODE (op0) == REG)
-+      REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
-+                                            REG_NOTES (insn));
-+    }
-+
-+  if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
-+      != CODE_FOR_nothing)
-+    {
-+      last = emit_move_insn (target, target);
-+      if (equiv)
-+      set_unique_reg_note (last, REG_EQUAL, equiv);
-+    }
-+  else
-+    {
-+      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 ();
-+  else
-+    first = NEXT_INSN (prev);
-+
-+  /* Encapsulate the block so it gets manipulated as a unit.  */
-+  REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
-+                                       REG_NOTES (first));
-+  REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
-+
-+  return last;
-+}
-+\f
-+/* Emit code to make a call to a constant function or a library call.
-+
-+   INSNS is a list containing all insns emitted in the call.
-+   These insns leave the result in RESULT.  Our block is to copy RESULT
-+   to TARGET, which is logically equivalent to EQUIV.
-+
-+   We first emit any insns that set a pseudo on the assumption that these are
-+   loading constants into registers; doing so allows them to be safely cse'ed
-+   between blocks.  Then we emit all the other insns in the block, followed by
-+   an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
-+   note with an operand of EQUIV.
-+
-+   Moving assignments to pseudos outside of the block is done to improve
-+   the generated code, but is not required to generate correct code,
-+   hence being unable to move an assignment is not grounds for not making
-+   a libcall block.  There are two reasons why it is safe to leave these
-+   insns inside the block: First, we know that these pseudos cannot be
-+   used in generated RTL outside the block since they are created for
-+   temporary purposes within the block.  Second, CSE will not record the
-+   values of anything set inside a libcall block, so we know they must
-+   be dead at the end of the block.
-+
-+   Except for the first group of insns (the ones setting pseudos), the
-+   block is delimited by REG_RETVAL and REG_LIBCALL notes.  */
-+
-+void
-+emit_libcall_block (insns, target, result, equiv)
-+     rtx insns;
-+     rtx target;
-+     rtx result;
-+     rtx equiv;
-+{
-+  rtx final_dest = target;
-+  rtx prev, next, first, last, insn;
-+
-+  /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
-+     into a MEM later.  Protect the libcall block from this change.  */
-+  if (! REG_P (target) || REG_USERVAR_P (target))
-+    target = gen_reg_rtx (GET_MODE (target));
-+  
-+  /* If we're using non-call exceptions, a libcall corresponding to an
-+     operation that may trap may also trap.  */
-+  if (flag_non_call_exceptions && may_trap_p (equiv))
-+    {
-+      for (insn = insns; insn; insn = NEXT_INSN (insn))
-+      if (GET_CODE (insn) == CALL_INSN)
-+        {
-+          rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
-+          
-+          if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
-+            remove_note (insn, note);
-+        }
-+    }
-+  else
-+  /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
-+     reg note to indicate that this call cannot throw or execute a nonlocal
-+     goto (unless there is already a REG_EH_REGION note, in which case
-+     we update it).  */
-+    for (insn = insns; insn; insn = NEXT_INSN (insn))
-+      if (GET_CODE (insn) == CALL_INSN)
-+      {
-+        rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
-+      
-+        if (note != 0)
-+          XEXP (note, 0) = GEN_INT (-1);
-+        else
-+          REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
-+                                                REG_NOTES (insn));
-+      }
-+
-+  /* First emit all insns that set pseudos.  Remove them from the list as
-+     we go.  Avoid insns that set pseudos which were referenced in previous
-+     insns.  These can be generated by move_by_pieces, for example,
-+     to update an address.  Similarly, avoid insns that reference things
-+     set in previous insns.  */
-+
-+  for (insn = insns; insn; insn = next)
-+    {
-+      rtx set = single_set (insn);
-+      rtx note;
-+
-+      /* Some ports (cris) create an libcall regions at their own.  We must
-+       avoid any potential nesting of LIBCALLs.  */
-+      if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
-+      remove_note (insn, note);
-+      if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
-+      remove_note (insn, note);
-+
-+      next = NEXT_INSN (insn);
-+
-+      if (set != 0 && GET_CODE (SET_DEST (set)) == REG
-+        && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
-+        && (insn == insns
-+            || ((! INSN_P(insns)
-+                 || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
-+                && ! reg_used_between_p (SET_DEST (set), insns, insn)
-+                && ! modified_in_p (SET_SRC (set), insns)
-+                && ! modified_between_p (SET_SRC (set), insns, insn))))
-+      {
-+        if (PREV_INSN (insn))
-+          NEXT_INSN (PREV_INSN (insn)) = next;
-+        else
-+          insns = next;
-+
-+        if (next)
-+          PREV_INSN (next) = PREV_INSN (insn);
-+
-+        add_insn (insn);
-+      }
-+    }
-+
-+  prev = get_last_insn ();
-+
-+  /* Write the remaining insns followed by the final copy.  */
-+
-+  for (insn = insns; insn; insn = next)
-+    {
-+      next = NEXT_INSN (insn);
-+
-+      add_insn (insn);
-+    }
-+
-+  last = emit_move_insn (target, result);
-+  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 (final_dest != target)
-+    emit_move_insn (final_dest, target);
-+
-+  if (prev == 0)
-+    first = get_insns ();
-+  else
-+    first = NEXT_INSN (prev);
-+
-+  /* Encapsulate the block so it gets manipulated as a unit.  */
-+  if (!flag_non_call_exceptions || !may_trap_p (equiv))
-+    {
-+      /* We can't attach the REG_LIBCALL and REG_RETVAL notes
-+       when the encapsulated region would not be in one basic block,
-+       i.e. when there is a control_flow_insn_p insn between FIRST and LAST.
-+       */
-+      bool attach_libcall_retval_notes = true;
-+      next = NEXT_INSN (last);
-+      for (insn = first; insn != next; insn = NEXT_INSN (insn))
-+      if (control_flow_insn_p (insn))
-+        {
-+          attach_libcall_retval_notes = false;
-+          break;
-+        }
-+
-+      if (attach_libcall_retval_notes)
-+      {
-+        REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
-+                                               REG_NOTES (first));
-+        REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
-+                                              REG_NOTES (last));
-+      }
-+    }
-+}
-+\f
-+/* Generate code to store zero in X.  */
-+
-+void
-+emit_clr_insn (x)
-+     rtx x;
-+{
-+  emit_move_insn (x, const0_rtx);
-+}
-+
-+/* Generate code to store 1 in X
-+   assuming it contains zero beforehand.  */
-+
-+void
-+emit_0_to_1_insn (x)
-+     rtx x;
-+{
-+  emit_move_insn (x, const1_rtx);
-+}
-+
-+/* Nonzero if we can perform a comparison of mode MODE straightforwardly.
-+   PURPOSE describes how this comparison will be used.  CODE is the rtx
-+   comparison code we will be using.
-+
-+   ??? Actually, CODE is slightly weaker than that.  A target is still
-+   required to implement all of the normal bcc operations, but not 
-+   required to implement all (or any) of the unordered bcc operations.  */
-+  
-+int
-+can_compare_p (code, mode, purpose)
-+     enum rtx_code code;
-+     enum machine_mode mode;
-+     enum can_compare_purpose purpose;
-+{
-+  do
-+    {
-+      if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
-+      {
-+        if (purpose == ccp_jump)
-+          return bcc_gen_fctn[(int) code] != NULL;
-+        else if (purpose == ccp_store_flag)
-+          return setcc_gen_code[(int) code] != CODE_FOR_nothing;
-+        else
-+          /* There's only one cmov entry point, and it's allowed to fail.  */
-+          return 1;
-+      }
-+      if (purpose == ccp_jump
-+        && cbranch_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
-+      return 1;
-+      if (purpose == ccp_cmov
-+        && cmov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
-+      return 1;
-+      if (purpose == ccp_store_flag
-+        && cstore_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
-+      return 1;
-+
-+      mode = GET_MODE_WIDER_MODE (mode);
-+    }
-+  while (mode != VOIDmode);
-+
-+  return 0;
-+}
-+
-+/* This function is called when we are going to emit a compare instruction that
-+   compares the values found in *PX and *PY, using the rtl operator COMPARISON.
-+
-+   *PMODE is the mode of the inputs (in case they are const_int).
-+   *PUNSIGNEDP nonzero says that the operands are unsigned;
-+   this matters if they need to be widened.
-+
-+   If they have mode BLKmode, then SIZE specifies the size of both operands.
-+
-+   This function performs all the setup necessary so that the caller only has
-+   to emit a single comparison insn.  This setup can involve doing a BLKmode
-+   comparison or emitting a library call to perform the comparison if no insn
-+   is available to handle it.
-+   The values which are passed in through pointers can be modified; the caller
-+   should perform the comparison on the modified values.  */
-+
-+static void
-+prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, purpose)
-+     rtx *px, *py;
-+     enum rtx_code *pcomparison;
-+     rtx size;
-+     enum machine_mode *pmode;
-+     int *punsignedp;
-+     enum can_compare_purpose purpose;
-+{
-+  enum machine_mode mode = *pmode;
-+  rtx x = *px, y = *py;
-+  int unsignedp = *punsignedp;
-+  enum mode_class class;
-+
-+  class = GET_MODE_CLASS (mode);
-+
-+  /* They could both be VOIDmode if both args are immediate constants,
-+     but we should fold that at an earlier stage.
-+     With no special code here, this will call abort,
-+     reminding the programmer to implement such folding.  */
-+
-+  if (mode != BLKmode && flag_force_mem)
-+    {
-+      x = force_not_mem (x);
-+      y = force_not_mem (y);
-+    }
-+
-+  /* 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) > COSTS_N_INSNS (1))
-+    x = force_reg (mode, x);
-+
-+  if (CONSTANT_P (y) && preserve_subexpressions_p ()
-+      && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
-+    y = force_reg (mode, y);
-+
-+#ifdef HAVE_cc0
-+  /* Abort if we have a non-canonical comparison.  The RTL documentation
-+     states that canonical comparisons are required only for targets which
-+     have cc0.  */
-+  if (CONSTANT_P (x) && ! CONSTANT_P (y))
-+    abort ();
-+#endif
-+
-+  /* Don't let both operands fail to indicate the mode.  */
-+  if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
-+    x = force_reg (mode, x);
-+
-+  /* Handle all BLKmode compares.  */
-+
-+  if (mode == BLKmode)
-+    {
-+      rtx result;
-+      enum machine_mode result_mode;
-+      rtx opalign ATTRIBUTE_UNUSED
-+      = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
-+
-+      emit_queue ();
-+      x = protect_from_queue (x, 0);
-+      y = protect_from_queue (y, 0);
-+
-+      if (size == 0)
-+      abort ();
-+#ifdef HAVE_cmpstrqi
-+      if (HAVE_cmpstrqi
-+        && GET_CODE (size) == CONST_INT
-+        && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
-+      {
-+        result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
-+        result = gen_reg_rtx (result_mode);
-+        emit_insn (gen_cmpstrqi (result, x, y, size, opalign));
-+      }
-+      else
-+#endif
-+#ifdef HAVE_cmpstrhi
-+      if (HAVE_cmpstrhi
-+        && GET_CODE (size) == CONST_INT
-+        && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
-+      {
-+        result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
-+        result = gen_reg_rtx (result_mode);
-+        emit_insn (gen_cmpstrhi (result, x, y, size, opalign));
-+      }
-+      else
-+#endif
-+#ifdef HAVE_cmpstrsi
-+      if (HAVE_cmpstrsi)
-+      {
-+        result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
-+        result = gen_reg_rtx (result_mode);
-+        size = protect_from_queue (size, 0);
-+        emit_insn (gen_cmpstrsi (result, x, y,
-+                                 convert_to_mode (SImode, size, 1),
-+                                 opalign));
-+      }
-+      else
-+#endif
-+      {
-+#ifdef TARGET_MEM_FUNCTIONS
-+        result = emit_library_call_value (memcmp_libfunc, NULL_RTX, LCT_PURE_MAKE_BLOCK,
-+                                          TYPE_MODE (integer_type_node), 3,
-+                                          XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
-+                                          convert_to_mode (TYPE_MODE (sizetype), size,
-+                                                           TREE_UNSIGNED (sizetype)),
-+                                          TYPE_MODE (sizetype));
-+#else
-+        result = emit_library_call_value (bcmp_libfunc, NULL_RTX, LCT_PURE_MAKE_BLOCK,
-+                                          TYPE_MODE (integer_type_node), 3,
-+                                          XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
-+                                          convert_to_mode (TYPE_MODE (integer_type_node),
-+                                                           size,
-+                                                           TREE_UNSIGNED (integer_type_node)),
-+                                          TYPE_MODE (integer_type_node));
-+#endif
-+
-+        result_mode = TYPE_MODE (integer_type_node);
-+      }
-+      *px = result;
-+      *py = const0_rtx;
-+      *pmode = result_mode;
-+      return;
-+    }
-+
-+  *px = x;
-+  *py = y;
-+  if (can_compare_p (*pcomparison, mode, purpose))
-+    return;
-+
-+  /* Handle a lib call just for the mode we are using.  */
-+
-+  if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
-+    {
-+      rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
-+      rtx result;
-+
-+      /* If we want unsigned, and this mode has a distinct unsigned
-+       comparison routine, use that.  */
-+      if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
-+      libfunc = ucmp_optab->handlers[(int) mode].libfunc;
-+
-+      result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
-+                                      word_mode, 2, x, mode, y, mode);
-+
-+      /* Integer comparison returns a result that must be compared against 1,
-+       so that even if we do an unsigned compare afterward,
-+       there is still a value that can represent the result "less than".  */
-+      *px = result;
-+      *py = const1_rtx;
-+      *pmode = word_mode;
-+      return;
-+    }
-+
-+  if (class == MODE_FLOAT)
-+    prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
-+
-+  else
-+    abort ();
-+}
-+
-+/* Before emitting an insn with code ICODE, make sure that X, which is going
-+   to be used for operand OPNUM of the insn, is converted from mode MODE to
-+   WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
-+   that it is accepted by the operand predicate.  Return the new value.  */
-+
-+rtx
-+prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
-+     int icode;
-+     rtx x;
-+     int opnum;
-+     enum machine_mode mode, wider_mode;
-+     int unsignedp;
-+{
-+  x = protect_from_queue (x, 0);
-+
-+  if (mode != wider_mode)
-+    x = convert_modes (wider_mode, mode, x, unsignedp);
-+
-+  if (! (*insn_data[icode].operand[opnum].predicate)
-+      (x, insn_data[icode].operand[opnum].mode))
-+    {
-+      if (no_new_pseudos)
-+      return NULL_RTX;
-+      x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
-+    }
-+
-+  return x;
-+}
-+
-+/* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
-+   we can do the comparison.
-+   The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
-+   be NULL_RTX which indicates that only a comparison is to be generated.  */
-+
-+static void
-+emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
-+     rtx x, y;
-+     enum machine_mode mode;
-+     enum rtx_code comparison;
-+     int unsignedp;
-+     rtx label;
-+{
-+  rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
-+  enum mode_class class = GET_MODE_CLASS (mode);
-+  enum machine_mode wider_mode = mode;
-+
-+  /* Try combined insns first.  */
-+  do
-+    {
-+      enum insn_code icode;
-+      PUT_MODE (test, wider_mode);
-+
-+      if (label)
-+      {         
-+        icode = cbranch_optab->handlers[(int) wider_mode].insn_code;
-+        
-+        if (icode != CODE_FOR_nothing
-+            && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
-+          {
-+            x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
-+            y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
-+            emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
-+            return;
-+          }
-+      }
-+
-+      /* Handle some compares against zero.  */
-+      icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
-+      if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
-+      {
-+        x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
-+        emit_insn (GEN_FCN (icode) (x));
-+        if (label)
-+          emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
-+        return;
-+      }
-+
-+      /* Handle compares for which there is a directly suitable insn.  */
-+
-+      icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
-+      if (icode != CODE_FOR_nothing)
-+      {
-+        x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
-+        y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
-+        emit_insn (GEN_FCN (icode) (x, y));
-+        if (label)
-+          emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
-+        return;
-+      }
-+
-+      if (class != MODE_INT && class != MODE_FLOAT
-+        && class != MODE_COMPLEX_FLOAT)
-+      break;
-+
-+      wider_mode = GET_MODE_WIDER_MODE (wider_mode);
-+    }
-+  while (wider_mode != VOIDmode);
-+
-+  abort ();
-+}
-+
-+/* Generate code to compare X with Y so that the condition codes are
-+   set and to jump to LABEL if the condition is true.  If X is a
-+   constant and Y is not a constant, then the comparison is swapped to
-+   ensure that the comparison RTL has the canonical form.
-+
-+   UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
-+   need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
-+   the proper branch condition code.
-+
-+   If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
-+
-+   MODE is the mode of the inputs (in case they are const_int).
-+
-+   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
-+   be passed unchanged to emit_cmp_insn, then potentially converted into an
-+   unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */
-+
-+void
-+emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, label)
-+     rtx x, y;
-+     enum rtx_code comparison;
-+     rtx size;
-+     enum machine_mode mode;
-+     int unsignedp;
-+     rtx label;
-+{
-+  rtx op0 = x, op1 = y;
-+
-+  /* Swap operands and condition to ensure canonical RTL.  */
-+  if (swap_commutative_operands_p (x, y))
-+    {
-+      /* If we're not emitting a branch, this means some caller
-+         is out of sync.  */
-+      if (! label)
-+      abort ();
-+
-+      op0 = y, op1 = x;
-+      comparison = swap_condition (comparison);
-+    }
-+
-+#ifdef HAVE_cc0
-+  /* If OP0 is still a constant, then both X and Y must be constants.  Force
-+     X into a register to avoid aborting in emit_cmp_insn due to non-canonical
-+     RTL.  */
-+  if (CONSTANT_P (op0))
-+    op0 = force_reg (mode, op0);
-+#endif
-+
-+  emit_queue ();
-+  if (unsignedp)
-+    comparison = unsigned_condition (comparison);
-+
-+  prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
-+                  ccp_jump);
-+  emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
-+}
-+
-+/* Like emit_cmp_and_jump_insns, but generate only the comparison.  */
-+
-+void
-+emit_cmp_insn (x, y, comparison, size, mode, unsignedp)
-+     rtx x, y;
-+     enum rtx_code comparison;
-+     rtx size;
-+     enum machine_mode mode;
-+     int unsignedp;
-+{
-+  emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
-+}
-+\f
-+/* Emit a library call comparison between floating point X and Y.
-+   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
-+
-+static void
-+prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp)
-+     rtx *px, *py;
-+     enum rtx_code *pcomparison;
-+     enum machine_mode *pmode;
-+     int *punsignedp;
-+{
-+  enum rtx_code comparison = *pcomparison;
-+  rtx tmp;
-+  rtx x = *px = protect_from_queue (*px, 0);
-+  rtx y = *py = protect_from_queue (*py, 0);
-+  enum machine_mode mode = GET_MODE (x);
-+  rtx libfunc = 0;
-+  rtx result;
-+
-+  if (mode == HFmode)
-+    switch (comparison)
-+      {
-+      case EQ:
-+      libfunc = eqhf2_libfunc;
-+      break;
-+
-+      case NE:
-+      libfunc = nehf2_libfunc;
-+      break;
-+
-+      case GT:
-+      libfunc = gthf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = LT;
-+          libfunc = lthf2_libfunc;
-+        }
-+      break;
-+
-+      case GE:
-+      libfunc = gehf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = LE;
-+          libfunc = lehf2_libfunc;
-+        }
-+      break;
-+
-+      case LT:
-+      libfunc = lthf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = GT;
-+          libfunc = gthf2_libfunc;
-+        }
-+      break;
-+
-+      case LE:
-+      libfunc = lehf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = GE;
-+          libfunc = gehf2_libfunc;
-+        }
-+      break;
-+
-+      case UNORDERED:
-+      libfunc = unordhf2_libfunc;
-+      break;
-+
-+      default:
-+      break;
-+      }
-+  else if (mode == SFmode)
-+    switch (comparison)
-+      {
-+      case EQ:
-+      libfunc = eqsf2_libfunc;
-+      break;
-+
-+      case NE:
-+      libfunc = nesf2_libfunc;
-+      break;
-+
-+      case GT:
-+      libfunc = gtsf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = LT;
-+          libfunc = ltsf2_libfunc;
-+        }
-+      break;
-+
-+      case GE:
-+      libfunc = gesf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = LE;
-+          libfunc = lesf2_libfunc;
-+        }
-+      break;
-+
-+      case LT:
-+      libfunc = ltsf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = GT;
-+          libfunc = gtsf2_libfunc;
-+        }
-+      break;
-+
-+      case LE:
-+      libfunc = lesf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = GE;
-+          libfunc = gesf2_libfunc;
-+        }
-+      break;
-+
-+      case UNORDERED:
-+      libfunc = unordsf2_libfunc;
-+      break;
-+
-+      default:
-+      break;
-+      }
-+  else if (mode == DFmode)
-+    switch (comparison)
-+      {
-+      case EQ:
-+      libfunc = eqdf2_libfunc;
-+      break;
-+
-+      case NE:
-+      libfunc = nedf2_libfunc;
-+      break;
-+
-+      case GT:
-+      libfunc = gtdf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = LT;
-+          libfunc = ltdf2_libfunc;
-+        }
-+      break;
-+
-+      case GE:
-+      libfunc = gedf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = LE;
-+          libfunc = ledf2_libfunc;
-+        }
-+      break;
-+
-+      case LT:
-+      libfunc = ltdf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = GT;
-+          libfunc = gtdf2_libfunc;
-+        }
-+      break;
-+
-+      case LE:
-+      libfunc = ledf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = GE;
-+          libfunc = gedf2_libfunc;
-+        }
-+      break;
-+
-+      case UNORDERED:
-+      libfunc = unorddf2_libfunc;
-+      break;
-+
-+      default:
-+      break;
-+      }
-+  else if (mode == XFmode)
-+    switch (comparison)
-+      {
-+      case EQ:
-+      libfunc = eqxf2_libfunc;
-+      break;
-+
-+      case NE:
-+      libfunc = nexf2_libfunc;
-+      break;
-+
-+      case GT:
-+      libfunc = gtxf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = LT;
-+          libfunc = ltxf2_libfunc;
-+        }
-+      break;
-+
-+      case GE:
-+      libfunc = gexf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = LE;
-+          libfunc = lexf2_libfunc;
-+        }
-+      break;
-+
-+      case LT:
-+      libfunc = ltxf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = GT;
-+          libfunc = gtxf2_libfunc;
-+        }
-+      break;
-+
-+      case LE:
-+      libfunc = lexf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = GE;
-+          libfunc = gexf2_libfunc;
-+        }
-+      break;
-+
-+      case UNORDERED:
-+      libfunc = unordxf2_libfunc;
-+      break;
-+
-+      default:
-+      break;
-+      }
-+  else if (mode == TFmode)
-+    switch (comparison)
-+      {
-+      case EQ:
-+      libfunc = eqtf2_libfunc;
-+      break;
-+
-+      case NE:
-+      libfunc = netf2_libfunc;
-+      break;
-+
-+      case GT:
-+      libfunc = gttf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = LT;
-+          libfunc = lttf2_libfunc;
-+        }
-+      break;
-+
-+      case GE:
-+      libfunc = getf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = LE;
-+          libfunc = letf2_libfunc;
-+        }
-+      break;
-+
-+      case LT:
-+      libfunc = lttf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = GT;
-+          libfunc = gttf2_libfunc;
-+        }
-+      break;
-+
-+      case LE:
-+      libfunc = letf2_libfunc;
-+      if (libfunc == NULL_RTX)
-+        {
-+          tmp = x; x = y; y = tmp;
-+          *pcomparison = GE;
-+          libfunc = getf2_libfunc;
-+        }
-+      break;
-+
-+      case UNORDERED:
-+      libfunc = unordtf2_libfunc;
-+      break;
-+
-+      default:
-+      break;
-+      }
-+  else
-+    {
-+      enum machine_mode wider_mode;
-+
-+      for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
-+         wider_mode = GET_MODE_WIDER_MODE (wider_mode))
-+      {
-+        if ((cmp_optab->handlers[(int) wider_mode].insn_code
-+             != CODE_FOR_nothing)
-+            || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
-+          {
-+            x = protect_from_queue (x, 0);
-+            y = protect_from_queue (y, 0);
-+            *px = convert_to_mode (wider_mode, x, 0);
-+            *py = convert_to_mode (wider_mode, y, 0);
-+            prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
-+            return;
-+          }
-+      }
-+      abort ();
-+    }
-+
-+  if (libfunc == 0)
-+    abort ();
-+
-+  result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
-+                                  word_mode, 2, x, mode, y, mode);
-+  *px = result;
-+  *py = const0_rtx;
-+  *pmode = word_mode;
-+  if (comparison == UNORDERED)
-+    *pcomparison = NE;
-+#ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
-+  else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
-+    *pcomparison = NE;
-+#endif
-+  *punsignedp = 0;
-+}
-+\f
-+/* Generate code to indirectly jump to a location given in the rtx LOC.  */
-+
-+void
-+emit_indirect_jump (loc)
-+     rtx loc;
-+{
-+  if (! ((*insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate)
-+       (loc, Pmode)))
-+    loc = copy_to_mode_reg (Pmode, loc);
-+
-+  emit_jump_insn (gen_indirect_jump (loc));
-+  emit_barrier ();
-+}
-+\f
-+#ifdef HAVE_conditional_move
-+
-+/* Emit a conditional move instruction if the machine supports one for that
-+   condition and machine mode.
-+
-+   OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
-+   the mode to use should they be constants.  If it is VOIDmode, they cannot
-+   both be constants.
-+
-+   OP2 should be stored in TARGET if the comparison is true, otherwise OP3
-+   should be stored there.  MODE is the mode to use should they be constants.
-+   If it is VOIDmode, they cannot both be constants.
-+
-+   The result is either TARGET (perhaps modified) or NULL_RTX if the operation
-+   is not supported.  */
-+
-+rtx
-+emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
-+                     unsignedp)
-+     rtx target;
-+     enum rtx_code code;
-+     rtx op0, op1;
-+     enum machine_mode cmode;
-+     rtx op2, op3;
-+     enum machine_mode mode;
-+     int unsignedp;
-+{
-+  rtx tem, subtarget, comparison, insn;
-+  enum insn_code icode;
-+  enum rtx_code reversed;
-+
-+  /* If one operand is constant, make it the second one.  Only do this
-+     if the other operand is not constant as well.  */
-+
-+  if (swap_commutative_operands_p (op0, op1))
-+    {
-+      tem = op0;
-+      op0 = op1;
-+      op1 = tem;
-+      code = swap_condition (code);
-+    }
-+
-+  /* get_condition will prefer to generate LT and GT even if the old
-+     comparison was against zero, so undo that canonicalization here since
-+     comparisons against zero are cheaper.  */
-+  if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
-+    code = LE, op1 = const0_rtx;
-+  else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
-+    code = GE, op1 = const0_rtx;
-+
-+  if (cmode == VOIDmode)
-+    cmode = GET_MODE (op0);
-+
-+  if (swap_commutative_operands_p (op2, op3)
-+      && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
-+          != UNKNOWN))
-+    {
-+      tem = op2;
-+      op2 = op3;
-+      op3 = tem;
-+      code = reversed;
-+    }
-+
-+  if (mode == VOIDmode)
-+    mode = GET_MODE (op2);
-+
-+  icode = movcc_gen_code[mode];
-+
-+  if (icode == CODE_FOR_nothing)
-+    return 0;
-+
-+  if (flag_force_mem)
-+    {
-+      op2 = force_not_mem (op2);
-+      op3 = force_not_mem (op3);
-+    }
-+
-+  if (target)
-+    target = protect_from_queue (target, 1);
-+  else
-+    target = gen_reg_rtx (mode);
-+
-+  subtarget = target;
-+
-+  emit_queue ();
-+
-+  op2 = protect_from_queue (op2, 0);
-+  op3 = protect_from_queue (op3, 0);
-+
-+  /* If the insn doesn't accept these operands, put them in pseudos.  */
-+
-+  if (! (*insn_data[icode].operand[0].predicate)
-+      (subtarget, insn_data[icode].operand[0].mode))
-+    subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
-+
-+  if (! (*insn_data[icode].operand[2].predicate)
-+      (op2, insn_data[icode].operand[2].mode))
-+    op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
-+
-+  if (! (*insn_data[icode].operand[3].predicate)
-+      (op3, insn_data[icode].operand[3].mode))
-+    op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
-+
-+  /* Everything should now be in the suitable form, so emit the compare insn
-+     and then the conditional move.  */
-+
-+  comparison 
-+    = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
-+
-+  /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
-+  /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
-+     return NULL and let the caller figure out how best to deal with this
-+     situation.  */
-+  if (GET_CODE (comparison) != code)
-+    return NULL_RTX;
-+  
-+  insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
-+
-+  /* If that failed, then give up.  */
-+  if (insn == 0)
-+    return 0;
-+
-+  emit_insn (insn);
-+
-+  if (subtarget != target)
-+    convert_move (target, subtarget, 0);
-+
-+  return target;
-+}
-+
-+/* Return nonzero if a conditional move of mode MODE is supported.
-+
-+   This function is for combine so it can tell whether an insn that looks
-+   like a conditional move is actually supported by the hardware.  If we
-+   guess wrong we lose a bit on optimization, but that's it.  */
-+/* ??? sparc64 supports conditionally moving integers values based on fp
-+   comparisons, and vice versa.  How do we handle them?  */
-+
-+int
-+can_conditionally_move_p (mode)
-+     enum machine_mode mode;
-+{
-+  if (movcc_gen_code[mode] != CODE_FOR_nothing)
-+    return 1;
-+
-+  return 0;
-+}
-+
-+#endif /* HAVE_conditional_move */
-+\f
-+/* These functions generate an insn body and return it
-+   rather than emitting the insn.
-+
-+   They do not protect from queued increments,
-+   because they may be used 1) in protect_from_queue itself
-+   and 2) in other passes where there is no queue.  */
-+
-+/* Generate and return an insn body to add Y to X.  */
-+
-+rtx
-+gen_add2_insn (x, y)
-+     rtx x, y;
-+{
-+  int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 
-+
-+  if (! ((*insn_data[icode].operand[0].predicate)
-+       (x, insn_data[icode].operand[0].mode))
-+      || ! ((*insn_data[icode].operand[1].predicate)
-+          (x, insn_data[icode].operand[1].mode))
-+      || ! ((*insn_data[icode].operand[2].predicate)
-+          (y, insn_data[icode].operand[2].mode)))
-+    abort ();
-+
-+  return (GEN_FCN (icode) (x, x, y));
-+}
-+
-+/* Generate and return an insn body to add r1 and c,
-+   storing the result in r0.  */
-+rtx
-+gen_add3_insn (r0, r1, c)
-+     rtx r0, r1, c;
-+{
-+  int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
-+
-+  if (icode == CODE_FOR_nothing
-+      || ! ((*insn_data[icode].operand[0].predicate)
-+          (r0, insn_data[icode].operand[0].mode))
-+      || ! ((*insn_data[icode].operand[1].predicate)
-+          (r1, insn_data[icode].operand[1].mode))
-+      || ! ((*insn_data[icode].operand[2].predicate)
-+          (c, insn_data[icode].operand[2].mode)))
-+    return NULL_RTX;
-+
-+  return (GEN_FCN (icode) (r0, r1, c));
-+}
-+
-+int
-+have_add2_insn (x, y)
-+     rtx x, y;
-+{
-+  int icode;
-+
-+  if (GET_MODE (x) == VOIDmode)
-+    abort ();
-+
-+  icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 
-+
-+  if (icode == CODE_FOR_nothing)
-+    return 0;
-+
-+  if (! ((*insn_data[icode].operand[0].predicate)
-+       (x, insn_data[icode].operand[0].mode))
-+      || ! ((*insn_data[icode].operand[1].predicate)
-+          (x, insn_data[icode].operand[1].mode))
-+      || ! ((*insn_data[icode].operand[2].predicate)
-+          (y, insn_data[icode].operand[2].mode)))
-+    return 0;
-+
-+  return 1;
-+}
-+
-+/* Generate and return an insn body to subtract Y from X.  */
-+
-+rtx
-+gen_sub2_insn (x, y)
-+     rtx x, y;
-+{
-+  int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 
-+
-+  if (! ((*insn_data[icode].operand[0].predicate)
-+       (x, insn_data[icode].operand[0].mode))
-+      || ! ((*insn_data[icode].operand[1].predicate)
-+          (x, insn_data[icode].operand[1].mode))
-+      || ! ((*insn_data[icode].operand[2].predicate)
-+          (y, insn_data[icode].operand[2].mode)))
-+    abort ();
-+
-+  return (GEN_FCN (icode) (x, x, y));
-+}
-+
-+/* Generate and return an insn body to subtract r1 and c,
-+   storing the result in r0.  */
-+rtx
-+gen_sub3_insn (r0, r1, c)
-+     rtx r0, r1, c;
-+{
-+  int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;
-+
-+  if (icode == CODE_FOR_nothing
-+      || ! ((*insn_data[icode].operand[0].predicate)
-+          (r0, insn_data[icode].operand[0].mode))
-+      || ! ((*insn_data[icode].operand[1].predicate)
-+          (r1, insn_data[icode].operand[1].mode))
-+      || ! ((*insn_data[icode].operand[2].predicate)
-+          (c, insn_data[icode].operand[2].mode)))
-+    return NULL_RTX;
-+
-+  return (GEN_FCN (icode) (r0, r1, c));
-+}
-+
-+int
-+have_sub2_insn (x, y)
-+     rtx x, y;
-+{
-+  int icode;
-+
-+  if (GET_MODE (x) == VOIDmode)
-+    abort ();
-+
-+  icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 
-+
-+  if (icode == CODE_FOR_nothing)
-+    return 0;
-+
-+  if (! ((*insn_data[icode].operand[0].predicate)
-+       (x, insn_data[icode].operand[0].mode))
-+      || ! ((*insn_data[icode].operand[1].predicate)
-+          (x, insn_data[icode].operand[1].mode))
-+      || ! ((*insn_data[icode].operand[2].predicate)
-+          (y, insn_data[icode].operand[2].mode)))
-+    return 0;
-+
-+  return 1;
-+}
-+
-+/* Generate the body of an instruction to copy Y into X.
-+   It may be a list of insns, if one insn isn't enough.  */
-+
-+rtx
-+gen_move_insn (x, y)
-+     rtx x, y;
-+{
-+  enum machine_mode mode = GET_MODE (x);
-+  enum insn_code insn_code;
-+  rtx seq;
-+
-+  if (mode == VOIDmode)
-+    mode = GET_MODE (y); 
-+
-+  insn_code = mov_optab->handlers[(int) mode].insn_code;
-+
-+  /* Handle MODE_CC modes:  If we don't have a special move insn for this mode,
-+     find a mode to do it in.  If we have a movcc, use it.  Otherwise,
-+     find the MODE_INT mode of the same width.  */
-+
-+  if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
-+    {
-+      enum machine_mode tmode = VOIDmode;
-+      rtx x1 = x, y1 = y;
-+
-+      if (mode != CCmode
-+        && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
-+      tmode = CCmode;
-+      else
-+      for (tmode = QImode; tmode != VOIDmode;
-+           tmode = GET_MODE_WIDER_MODE (tmode))
-+        if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
-+          break;
-+
-+      if (tmode == VOIDmode)
-+      abort ();
-+
-+      /* Get X and Y in TMODE.  We can't use gen_lowpart here because it
-+       may call change_address which is not appropriate if we were
-+       called when a reload was in progress.  We don't have to worry
-+       about changing the address since the size in bytes is supposed to
-+       be the same.  Copy the MEM to change the mode and move any
-+       substitutions from the old MEM to the new one.  */
-+
-+      if (reload_in_progress)
-+      {
-+        x = gen_lowpart_common (tmode, x1);
-+        if (x == 0 && GET_CODE (x1) == MEM)
-+          {
-+            x = adjust_address_nv (x1, tmode, 0);
-+            copy_replacements (x1, x);
-+          }
-+
-+        y = gen_lowpart_common (tmode, y1);
-+        if (y == 0 && GET_CODE (y1) == MEM)
-+          {
-+            y = adjust_address_nv (y1, tmode, 0);
-+            copy_replacements (y1, y);
-+          }
-+      }
-+      else
-+      {
-+        x = gen_lowpart (tmode, x);
-+        y = gen_lowpart (tmode, y);
-+      }
-+        
-+      insn_code = mov_optab->handlers[(int) tmode].insn_code;
-+      return (GEN_FCN (insn_code) (x, y));
-+    }
-+
-+  start_sequence ();
-+  emit_move_insn_1 (x, y);
-+  seq = get_insns ();
-+  end_sequence ();
-+  return seq;
-+}
-+\f
-+/* Return the insn code used to extend FROM_MODE to TO_MODE.
-+   UNSIGNEDP specifies zero-extension instead of sign-extension.  If
-+   no such operation exists, CODE_FOR_nothing will be returned.  */
-+
-+enum insn_code
-+can_extend_p (to_mode, from_mode, unsignedp)
-+     enum machine_mode to_mode, from_mode;
-+     int unsignedp;
-+{
-+#ifdef HAVE_ptr_extend
-+  if (unsignedp < 0)
-+    return CODE_FOR_ptr_extend;
-+  else
-+#endif
-+    return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
-+}
-+
-+/* Generate the body of an insn to extend Y (with mode MFROM)
-+   into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
-+
-+rtx
-+gen_extend_insn (x, y, mto, mfrom, unsignedp)
-+     rtx x, y;
-+     enum machine_mode mto, mfrom;
-+     int unsignedp;
-+{
-+  return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y));
-+}
-+\f
-+/* can_fix_p and can_float_p say whether the target machine
-+   can directly convert a given fixed point type to
-+   a given floating point type, or vice versa.
-+   The returned value is the CODE_FOR_... value to use,
-+   or CODE_FOR_nothing if these modes cannot be directly converted.
-+
-+   *TRUNCP_PTR is set to 1 if it is necessary to output
-+   an explicit FTRUNC insn before the fix insn; otherwise 0.  */
-+
-+static enum insn_code
-+can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
-+     enum machine_mode fltmode, fixmode;
-+     int unsignedp;
-+     int *truncp_ptr;
-+{
-+  *truncp_ptr = 0;
-+  if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]
-+      != CODE_FOR_nothing)
-+    return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0];
-+
-+  if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
-+    {
-+      *truncp_ptr = 1;
-+      return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0];
-+    }
-+  return CODE_FOR_nothing;
-+}
-+
-+static enum insn_code
-+can_float_p (fltmode, fixmode, unsignedp)
-+     enum machine_mode fixmode, fltmode;
-+     int unsignedp;
-+{
-+  return floattab[(int) fltmode][(int) fixmode][unsignedp != 0];
-+}
-+\f
-+/* Generate code to convert FROM to floating point
-+   and store in TO.  FROM must be fixed point and not VOIDmode.
-+   UNSIGNEDP nonzero means regard FROM as unsigned.
-+   Normally this is done by correcting the final value
-+   if it is negative.  */
-+
-+void
-+expand_float (to, from, unsignedp)
-+     rtx to, from;
-+     int unsignedp;
-+{
-+  enum insn_code icode;
-+  rtx target = to;
-+  enum machine_mode fmode, imode;
-+
-+  /* Crash now, because we won't be able to decide which mode to use.  */
-+  if (GET_MODE (from) == VOIDmode)
-+    abort ();
-+
-+  /* Look for an insn to do the conversion.  Do it in the specified
-+     modes if possible; otherwise convert either input, output or both to
-+     wider mode.  If the integer mode is wider than the mode of FROM,
-+     we can do the conversion signed even if the input is unsigned.  */
-+
-+  for (fmode = GET_MODE (to); fmode != VOIDmode;
-+       fmode = GET_MODE_WIDER_MODE (fmode))
-+    for (imode = GET_MODE (from); imode != VOIDmode;
-+       imode = GET_MODE_WIDER_MODE (imode))
-+      {
-+      int doing_unsigned = unsignedp;
-+
-+      if (fmode != GET_MODE (to)
-+          && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
-+        continue;
-+
-+      icode = can_float_p (fmode, imode, unsignedp);
-+      if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
-+        icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
-+
-+      if (icode != CODE_FOR_nothing)
-+        {
-+          to = protect_from_queue (to, 1);
-+          from = protect_from_queue (from, 0);
-+
-+          if (imode != GET_MODE (from))
-+            from = convert_to_mode (imode, from, unsignedp);
-+
-+          if (fmode != GET_MODE (to))
-+            target = gen_reg_rtx (fmode);
-+
-+          emit_unop_insn (icode, target, from,
-+                          doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
-+
-+          if (target != to)
-+            convert_move (to, target, 0);
-+          return;
-+        }
-+      }
-+
-+  /* Unsigned integer, and no way to convert directly.
-+     Convert as signed, then conditionally adjust the result.  */
-+  if (unsignedp)
-+    {
-+      rtx label = gen_label_rtx ();
-+      rtx temp;
-+      REAL_VALUE_TYPE offset;
-+
-+      emit_queue ();
-+
-+      to = protect_from_queue (to, 1);
-+      from = protect_from_queue (from, 0);
-+
-+      if (flag_force_mem)
-+      from = force_not_mem (from);
-+
-+      /* Look for a usable floating mode FMODE wider than the source and at
-+       least as wide as the target.  Using FMODE will avoid rounding woes
-+       with unsigned values greater than the signed maximum value.  */
-+
-+      for (fmode = GET_MODE (to);  fmode != VOIDmode;
-+         fmode = GET_MODE_WIDER_MODE (fmode))
-+      if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
-+          && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
-+        break;
-+
-+      if (fmode == VOIDmode)
-+      {
-+        /* There is no such mode.  Pretend the target is wide enough.  */
-+        fmode = GET_MODE (to);
-+
-+        /* Avoid double-rounding when TO is narrower than FROM.  */
-+        if ((significand_size (fmode) + 1)
-+            < GET_MODE_BITSIZE (GET_MODE (from)))
-+          {
-+            rtx temp1;
-+            rtx neglabel = gen_label_rtx ();
-+
-+            /* Don't use TARGET if it isn't a register, is a hard register, 
-+               or is the wrong mode.  */
-+            if (GET_CODE (target) != REG
-+                || REGNO (target) < FIRST_PSEUDO_REGISTER
-+                || GET_MODE (target) != fmode)
-+              target = gen_reg_rtx (fmode);
-+
-+            imode = GET_MODE (from);
-+            do_pending_stack_adjust ();
-+
-+            /* Test whether the sign bit is set.  */
-+            emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
-+                                     0, neglabel);
-+
-+            /* The sign bit is not set.  Convert as signed.  */
-+            expand_float (target, from, 0);
-+            emit_jump_insn (gen_jump (label));
-+            emit_barrier ();
-+
-+            /* The sign bit is set.
-+               Convert to a usable (positive signed) value by shifting right
-+               one bit, while remembering if a nonzero bit was shifted
-+               out; i.e., compute  (from & 1) | (from >> 1).  */
-+
-+            emit_label (neglabel);
-+            temp = expand_binop (imode, and_optab, from, const1_rtx,
-+                                 NULL_RTX, 1, OPTAB_LIB_WIDEN);
-+            temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
-+                                  NULL_RTX, 1);
-+            temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1, 
-+                                 OPTAB_LIB_WIDEN);
-+            expand_float (target, temp, 0);
-+
-+            /* Multiply by 2 to undo the shift above.  */
-+            temp = expand_binop (fmode, add_optab, target, target,
-+                                 target, 0, OPTAB_LIB_WIDEN);
-+            if (temp != target)
-+              emit_move_insn (target, temp);
-+
-+            do_pending_stack_adjust ();
-+            emit_label (label);
-+            goto done;
-+          }
-+      }
-+
-+      /* If we are about to do some arithmetic to correct for an
-+       unsigned operand, do it in a pseudo-register.  */
-+
-+      if (GET_MODE (to) != fmode
-+        || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
-+      target = gen_reg_rtx (fmode);
-+
-+      /* Convert as signed integer to floating.  */
-+      expand_float (target, from, 0);
-+
-+      /* If FROM is negative (and therefore TO is negative),
-+       correct its value by 2**bitwidth.  */
-+
-+      do_pending_stack_adjust ();
-+      emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
-+                             0, label);
-+
-+      
-+      real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
-+      temp = expand_binop (fmode, add_optab, target,
-+                         CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
-+                         target, 0, OPTAB_LIB_WIDEN);
-+      if (temp != target)
-+      emit_move_insn (target, temp);
-+
-+      do_pending_stack_adjust ();
-+      emit_label (label);
-+      goto done;
-+    }
-+
-+  /* No hardware instruction available; call a library routine to convert from
-+     SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode.  */
-+    {
-+      rtx libfcn;
-+      rtx insns;
-+      rtx value;
-+
-+      to = protect_from_queue (to, 1);
-+      from = protect_from_queue (from, 0);
-+
-+      if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
-+      from = convert_to_mode (SImode, from, unsignedp);
-+
-+      if (flag_force_mem)
-+      from = force_not_mem (from);
-+
-+      if (GET_MODE (to) == SFmode)
-+      {
-+        if (GET_MODE (from) == SImode)
-+          libfcn = floatsisf_libfunc;
-+        else if (GET_MODE (from) == DImode)
-+          libfcn = floatdisf_libfunc;
-+        else if (GET_MODE (from) == TImode)
-+          libfcn = floattisf_libfunc;
-+        else
-+          abort ();
-+      }
-+      else if (GET_MODE (to) == DFmode)
-+      {
-+        if (GET_MODE (from) == SImode)
-+          libfcn = floatsidf_libfunc;
-+        else if (GET_MODE (from) == DImode)
-+          libfcn = floatdidf_libfunc;
-+        else if (GET_MODE (from) == TImode)
-+          libfcn = floattidf_libfunc;
-+        else
-+          abort ();
-+      }
-+      else if (GET_MODE (to) == XFmode)
-+      {
-+        if (GET_MODE (from) == SImode)
-+          libfcn = floatsixf_libfunc;
-+        else if (GET_MODE (from) == DImode)
-+          libfcn = floatdixf_libfunc;
-+        else if (GET_MODE (from) == TImode)
-+          libfcn = floattixf_libfunc;
-+        else
-+          abort ();
-+      }
-+      else if (GET_MODE (to) == TFmode)
-+      {
-+        if (GET_MODE (from) == SImode)
-+          libfcn = floatsitf_libfunc;
-+        else if (GET_MODE (from) == DImode)
-+          libfcn = floatditf_libfunc;
-+        else if (GET_MODE (from) == TImode)
-+          libfcn = floattitf_libfunc;
-+        else
-+          abort ();
-+      }
-+      else
-+      abort ();
-+
-+      start_sequence ();
-+
-+      value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
-+                                     GET_MODE (to), 1, from,
-+                                     GET_MODE (from));
-+      insns = get_insns ();
-+      end_sequence ();
-+
-+      emit_libcall_block (insns, target, value,
-+                        gen_rtx_FLOAT (GET_MODE (to), from));
-+    }
-+
-+ done:
-+
-+  /* Copy result to requested destination
-+     if we have been computing in a temp location.  */
-+
-+  if (target != to)
-+    {
-+      if (GET_MODE (target) == GET_MODE (to))
-+      emit_move_insn (to, target);
-+      else
-+      convert_move (to, target, 0);
-+    }
-+}
-+\f
-+/* expand_fix: generate code to convert FROM to fixed point
-+   and store in TO.  FROM must be floating point.  */
-+
-+static rtx
-+ftruncify (x)
-+     rtx x;
-+{
-+  rtx temp = gen_reg_rtx (GET_MODE (x));
-+  return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
-+}
-+
-+void
-+expand_fix (to, from, unsignedp)
-+     rtx to, from;
-+     int unsignedp;
-+{
-+  enum insn_code icode;
-+  rtx target = to;
-+  enum machine_mode fmode, imode;
-+  int must_trunc = 0;
-+  rtx libfcn = 0;
-+
-+  /* We first try to find a pair of modes, one real and one integer, at
-+     least as wide as FROM and TO, respectively, in which we can open-code
-+     this conversion.  If the integer mode is wider than the mode of TO,
-+     we can do the conversion either signed or unsigned.  */
-+
-+  for (fmode = GET_MODE (from); fmode != VOIDmode;
-+       fmode = GET_MODE_WIDER_MODE (fmode))
-+    for (imode = GET_MODE (to); imode != VOIDmode;
-+       imode = GET_MODE_WIDER_MODE (imode))
-+      {
-+      int doing_unsigned = unsignedp;
-+
-+      icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
-+      if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
-+        icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
-+
-+      if (icode != CODE_FOR_nothing)
-+        {
-+          to = protect_from_queue (to, 1);
-+          from = protect_from_queue (from, 0);
-+
-+          if (fmode != GET_MODE (from))
-+            from = convert_to_mode (fmode, from, 0);
-+
-+          if (must_trunc)
-+            from = ftruncify (from);
-+
-+          if (imode != GET_MODE (to))
-+            target = gen_reg_rtx (imode);
-+
-+          emit_unop_insn (icode, target, from,
-+                          doing_unsigned ? UNSIGNED_FIX : FIX);
-+          if (target != to)
-+            convert_move (to, target, unsignedp);
-+          return;
-+        }
-+      }
-+
-+  /* For an unsigned conversion, there is one more way to do it.
-+     If we have a signed conversion, we generate code that compares
-+     the real value to the largest representable positive number.  If if
-+     is smaller, the conversion is done normally.  Otherwise, subtract
-+     one plus the highest signed number, convert, and add it back.
-+
-+     We only need to check all real modes, since we know we didn't find
-+     anything with a wider integer mode.  */
-+
-+  if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
-+    for (fmode = GET_MODE (from); fmode != VOIDmode;
-+       fmode = GET_MODE_WIDER_MODE (fmode))
-+      /* Make sure we won't lose significant bits doing this.  */
-+      if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
-+        && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
-+                                          &must_trunc))
+       /* Don't count call-insns, (set (reg 0) (call ...)), as a set.
+        The hard function value register is used only once, to copy to
+diff -urN gcc-3.3.1/gcc/explow.c gcc-3.3.1-pp/gcc/explow.c
+--- gcc-3.3.1/gcc/explow.c     2003-04-07 22:58:12.000000000 +0000
++++ gcc-3.3.1-pp/gcc/explow.c  2003-09-12 13:40:28.000000000 +0000
+@@ -86,7 +86,8 @@
+   rtx tem;
+   int all_constant = 0;
+-  if (c == 0)
++  if (c == 0
++      && !(flag_propolice_protection && x == virtual_stack_vars_rtx))
+     return x;
+  restart:
+@@ -187,7 +188,8 @@
+       break;
+     }
+-  if (c != 0)
++  if (c != 0
++      || (flag_propolice_protection && x == virtual_stack_vars_rtx))
+     x = gen_rtx_PLUS (mode, x, GEN_INT (c));
+   if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
+@@ -531,6 +533,21 @@
+        in certain cases.  This is not necessary since the code
+        below can handle all possible cases, but machine-dependent
+        transformations can make better code.  */
++      if (flag_propolice_protection)
 +      {
-+        int bitsize;
-+        REAL_VALUE_TYPE offset;
-+        rtx limit, lab1, lab2, insn;
-+
-+        bitsize = GET_MODE_BITSIZE (GET_MODE (to));
-+        real_2expN (&offset, bitsize - 1);
-+        limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
-+        lab1 = gen_label_rtx ();
-+        lab2 = gen_label_rtx ();
-+
-+        emit_queue ();
-+        to = protect_from_queue (to, 1);
-+        from = protect_from_queue (from, 0);
-+
-+        if (flag_force_mem)
-+          from = force_not_mem (from);
-+
-+        if (fmode != GET_MODE (from))
-+          from = convert_to_mode (fmode, from, 0);
-+
-+        /* See if we need to do the subtraction.  */
-+        do_pending_stack_adjust ();
-+        emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
-+                                 0, lab1);
-+
-+        /* If not, do the signed "fix" and branch around fixup code.  */
-+        expand_fix (to, from, 0);
-+        emit_jump_insn (gen_jump (lab2));
-+        emit_barrier ();
-+
-+        /* Otherwise, subtract 2**(N-1), convert to signed number,
-+           then add 2**(N-1).  Do the addition using XOR since this
-+           will often generate better code.  */
-+        emit_label (lab1);
-+        target = expand_binop (GET_MODE (from), sub_optab, from, limit,
-+                               NULL_RTX, 0, OPTAB_LIB_WIDEN);
-+        expand_fix (to, target, 0);
-+        target = expand_binop (GET_MODE (to), xor_optab, to,
-+                               gen_int_mode
-+                               ((HOST_WIDE_INT) 1 << (bitsize - 1),
-+                                GET_MODE (to)),
-+                               to, 1, OPTAB_LIB_WIDEN);
-+
-+        if (target != to)
-+          emit_move_insn (to, target);
-+
-+        emit_label (lab2);
-+
-+        if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
-+            != CODE_FOR_nothing)
++#define FRAMEADDR_P(X) (GET_CODE (X) == PLUS                          \
++                      && XEXP (X, 0) == virtual_stack_vars_rtx        \
++                      && GET_CODE (XEXP (X, 1)) == CONST_INT)
++        rtx y;
++        if (FRAMEADDR_P (x)) goto win;
++        for (y=x; y!=0 && GET_CODE (y)==PLUS; y = XEXP (y, 0))
 +          {
-+            /* Make a place for a REG_NOTE and add it.  */
-+            insn = emit_move_insn (to, to);
-+            set_unique_reg_note (insn,
-+                                 REG_EQUAL,
-+                                 gen_rtx_fmt_e (UNSIGNED_FIX,
-+                                                GET_MODE (to),
-+                                                copy_rtx (from)));
++            if (FRAMEADDR_P (XEXP (y, 0)))
++              XEXP (y, 0) = force_reg (GET_MODE (XEXP (y, 0)), XEXP (y, 0));
++            if (FRAMEADDR_P (XEXP (y, 1)))
++              XEXP (y, 1) = force_reg (GET_MODE (XEXP (y, 1)), XEXP (y, 1));
 +          }
-+
-+        return;
 +      }
+       LEGITIMIZE_ADDRESS (x, oldx, mode, win);
+       /* PLUS and MULT can appear in special ways
+diff -urN gcc-3.3.1/gcc/expr.c gcc-3.3.1-pp/gcc/expr.c
+--- gcc-3.3.1/gcc/expr.c       2003-07-24 19:11:20.000000000 +0000
++++ gcc-3.3.1-pp/gcc/expr.c    2003-09-12 13:40:28.000000000 +0000
+@@ -45,6 +45,7 @@
+ #include "langhooks.h"
+ #include "intl.h"
+ #include "tm_p.h"
++#include "protector.h"
+ /* Decide whether a function's arguments should be processed
+    from first to last or from last to first.
+@@ -1518,7 +1519,7 @@
+       if (USE_LOAD_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_from)
+       {
+-        data.from_addr = copy_addr_to_reg (plus_constant (from_addr, len));
++        data.from_addr = copy_addr_to_reg (plus_constant (from_addr, len-GET_MODE_SIZE (mode)));
+         data.autinc_from = 1;
+         data.explicit_inc_from = -1;
+       }
+@@ -1532,7 +1533,7 @@
+       data.from_addr = copy_addr_to_reg (from_addr);
+       if (USE_STORE_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_to)
+       {
+-        data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len));
++        data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len-GET_MODE_SIZE (mode)));
+         data.autinc_to = 1;
+         data.explicit_inc_to = -1;
+       }
+@@ -1649,11 +1650,13 @@
+       from1 = adjust_address (data->from, mode, data->offset);
+       if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
+-      emit_insn (gen_add2_insn (data->to_addr,
+-                                GEN_INT (-(HOST_WIDE_INT)size)));
++      if (data->explicit_inc_to < -1)
++        emit_insn (gen_add2_insn (data->to_addr,
++                                  GEN_INT (-(HOST_WIDE_INT)size)));
+       if (HAVE_PRE_DECREMENT && data->explicit_inc_from < 0)
+-      emit_insn (gen_add2_insn (data->from_addr,
+-                                GEN_INT (-(HOST_WIDE_INT)size)));
++      if (data->explicit_inc_from < -1)
++        emit_insn (gen_add2_insn (data->from_addr,
++                                  GEN_INT (-(HOST_WIDE_INT)size)));
+       if (data->to)
+       emit_insn ((*genfun) (to1, from1));
+@@ -2826,7 +2829,7 @@
+       if (USE_STORE_PRE_DECREMENT (mode) && data->reverse && ! data->autinc_to)
+       {
+-        data->to_addr = copy_addr_to_reg (plus_constant (to_addr, data->len));
++        data->to_addr = copy_addr_to_reg (plus_constant (to_addr, data->len-GET_MODE_SIZE (mode)));
+         data->autinc_to = 1;
+         data->explicit_inc_to = -1;
+       }
+@@ -2897,8 +2900,9 @@
+       to1 = adjust_address (data->to, mode, data->offset);
+       if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
+-      emit_insn (gen_add2_insn (data->to_addr,
+-                                GEN_INT (-(HOST_WIDE_INT) size)));
++      if (data->explicit_inc_to < -1)
++        emit_insn (gen_add2_insn (data->to_addr,
++                                  GEN_INT (-(HOST_WIDE_INT) size)));
+       cst = (*data->constfun) (data->constfundata, data->offset, mode);
+       emit_insn ((*genfun) (to1, cst));
+@@ -5894,7 +5898,9 @@
+         && GET_CODE (XEXP (value, 0)) == PLUS
+         && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
+         && REGNO (XEXP (XEXP (value, 0), 0)) >= FIRST_VIRTUAL_REGISTER
+-        && REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER)
++        && REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER
++        && (!flag_propolice_protection
++            || XEXP (XEXP (value, 0), 0) != virtual_stack_vars_rtx))
+       {
+         rtx temp = expand_simple_binop (GET_MODE (value), code,
+                                         XEXP (XEXP (value, 0), 0), op2,
+@@ -8070,7 +8076,8 @@
+       /* If adding to a sum including a constant,
+        associate it to put the constant outside.  */
+       if (GET_CODE (op1) == PLUS
+-        && CONSTANT_P (XEXP (op1, 1)))
++        && CONSTANT_P (XEXP (op1, 1))
++        && !(flag_propolice_protection && (contains_fp (op0) || contains_fp (op1))))
+       {
+         rtx constant_term = const0_rtx;
+diff -urN gcc-3.3.1/gcc/flags.h gcc-3.3.1-pp/gcc/flags.h
+--- gcc-3.3.1/gcc/flags.h      2003-06-20 21:18:41.000000000 +0000
++++ gcc-3.3.1-pp/gcc/flags.h   2003-09-12 13:40:28.000000000 +0000
+@@ -690,4 +690,12 @@
+ #define HONOR_SIGN_DEPENDENT_ROUNDING(MODE) \
+   (MODE_HAS_SIGN_DEPENDENT_ROUNDING (MODE) && !flag_unsafe_math_optimizations)
++/* Nonzero means use propolice as a stack protection method */
 +
-+  /* We can't do it with an insn, so use a library call.  But first ensure
-+     that the mode of TO is at least as wide as SImode, since those are the
-+     only library calls we know about.  */
-+
-+  if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
-+    {
-+      target = gen_reg_rtx (SImode);
++extern int flag_propolice_protection;
 +
-+      expand_fix (target, from, unsignedp);
-+    }
-+  else if (GET_MODE (from) == SFmode)
-+    {
-+      if (GET_MODE (to) == SImode)
-+      libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
-+      else if (GET_MODE (to) == DImode)
-+      libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
-+      else if (GET_MODE (to) == TImode)
-+      libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
-+      else
-+      abort ();
-+    }
-+  else if (GET_MODE (from) == DFmode)
-+    {
-+      if (GET_MODE (to) == SImode)
-+      libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
-+      else if (GET_MODE (to) == DImode)
-+      libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
-+      else if (GET_MODE (to) == TImode)
-+      libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
-+      else
-+      abort ();
-+    }
-+  else if (GET_MODE (from) == XFmode)
-+    {
-+      if (GET_MODE (to) == SImode)
-+      libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
-+      else if (GET_MODE (to) == DImode)
-+      libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
-+      else if (GET_MODE (to) == TImode)
-+      libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
-+      else
-+      abort ();
-+    }
-+  else if (GET_MODE (from) == TFmode)
-+    {
-+      if (GET_MODE (to) == SImode)
-+      libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
-+      else if (GET_MODE (to) == DImode)
-+      libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
-+      else if (GET_MODE (to) == TImode)
-+      libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
-+      else
-+      abort ();
-+    }
-+  else
-+    abort ();
++/* Warn when not issuing stack smashing protection for some reason */
 +
-+  if (libfcn)
-+    {
-+      rtx insns;
-+      rtx value;
++extern int warn_stack_protector;
 +
-+      to = protect_from_queue (to, 1);
-+      from = protect_from_queue (from, 0);
+ #endif /* ! GCC_FLAGS_H */
+diff -urN gcc-3.3.1/gcc/function.c gcc-3.3.1-pp/gcc/function.c
+--- gcc-3.3.1/gcc/function.c   2003-04-10 22:26:04.000000000 +0000
++++ gcc-3.3.1-pp/gcc/function.c        2003-09-12 13:40:28.000000000 +0000
+@@ -59,6 +59,7 @@
+ #include "tm_p.h"
+ #include "integrate.h"
+ #include "langhooks.h"
++#include "protector.h"
+ #ifndef TRAMPOLINE_ALIGNMENT
+ #define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
+@@ -142,6 +143,10 @@
+ /* Array of INSN_UIDs to hold the INSN_UIDs for each sibcall epilogue
+    in this function.  */
+ static GTY(()) varray_type sibcall_epilogue;
 +
-+      if (flag_force_mem)
-+      from = force_not_mem (from);
++/* Current boundary mark for character arrays.  */
++int temp_boundary_mark = 0;
 +
-+      start_sequence ();
\f
+ /* In order to evaluate some expressions, such as function calls returning
+    structures in memory, we need to temporarily allocate stack locations.
+@@ -195,6 +200,8 @@
+   /* The size of the slot, including extra space for alignment.  This
+      info is for combine_temp_slots.  */
+   HOST_WIDE_INT full_size;
++  /* Boundary mark of a character array and the others. This info is for propolice */
++  int boundary_mark;
+ };
\f
+ /* This structure is used to record MEMs or pseudos used to replace VAR, any
+@@ -629,6 +636,7 @@
+    whose lifetime is controlled by CLEANUP_POINT_EXPRs.  KEEP is 3
+    if we are to allocate something at an inner level to be treated as
+    a variable in the block (e.g., a SAVE_EXPR).
++   KEEP is 5 if we allocate a place to return structure.
+    TYPE is the type that will be used for the stack slot.  */
+@@ -642,6 +650,8 @@
+   unsigned int align;
+   struct temp_slot *p, *best_p = 0;
+   rtx slot;
++  int char_array = (flag_propolice_protection
++                  && keep == 1 && search_string_def (type));
+   /* If SIZE is -1 it means that somebody tried to allocate a temporary
+      of a variable size.  */
+@@ -667,7 +677,8 @@
+       && ! p->in_use
+       && objects_must_conflict_p (p->type, type)
+       && (best_p == 0 || best_p->size > p->size
+-          || (best_p->size == p->size && best_p->align > p->align)))
++          || (best_p->size == p->size && best_p->align > p->align))
++      && (! char_array || p->boundary_mark != 0))
+       {
+       if (p->align == align && p->size == size)
+         {
+@@ -702,6 +713,7 @@
+             p->address = 0;
+             p->rtl_expr = 0;
+             p->type = best_p->type;
++            p->boundary_mark = best_p->boundary_mark;
+             p->next = temp_slots;
+             temp_slots = p;
+@@ -762,6 +774,7 @@
+       p->full_size = frame_offset - frame_offset_old;
+ #endif
+       p->address = 0;
++      p->boundary_mark = char_array?++temp_boundary_mark:0;
+       p->next = temp_slots;
+       temp_slots = p;
+     }
+@@ -932,14 +945,16 @@
+           int delete_q = 0;
+           if (! q->in_use && GET_MODE (q->slot) == BLKmode)
+             {
+-              if (p->base_offset + p->full_size == q->base_offset)
++              if (p->base_offset + p->full_size == q->base_offset &&
++                  p->boundary_mark == q->boundary_mark)
+                 {
+                   /* Q comes after P; combine Q into P.  */
+                   p->size += q->size;
+                   p->full_size += q->full_size;
+                   delete_q = 1;
+                 }
+-              else if (q->base_offset + q->full_size == p->base_offset)
++              else if (q->base_offset + q->full_size == p->base_offset &&
++                       p->boundary_mark == q->boundary_mark)
+                 {
+                   /* P comes after Q; combine P into Q.  */
+                   q->size += p->size;
+@@ -1497,7 +1512,9 @@
+     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);
++    new = function ?
++      assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode), 0, func):
++      assign_stack_local_for_pseudo_reg (decl_mode, GET_MODE_SIZE (decl_mode), 0);
+   PUT_CODE (reg, MEM);
+   PUT_MODE (reg, decl_mode);
+@@ -3961,7 +3978,8 @@
+                constant with that register.  */
+             temp = gen_reg_rtx (Pmode);
+             XEXP (x, 0) = new;
+-            if (validate_change (object, &XEXP (x, 1), temp, 0))
++            if (validate_change (object, &XEXP (x, 1), temp, 0)
++                && ! flag_propolice_protection)
+               emit_insn_before (gen_move_insn (temp, new_offset), object);
+             else
+               {
+diff -urN gcc-3.3.1/gcc/gcse.c gcc-3.3.1-pp/gcc/gcse.c
+--- gcc-3.3.1/gcc/gcse.c       2003-07-14 09:21:22.000000000 +0000
++++ gcc-3.3.1-pp/gcc/gcse.c    2003-09-12 13:40:28.000000000 +0000
+@@ -4211,7 +4211,7 @@
+       /* Find an assignment that sets reg_used and is available
+        at the start of the block.  */
+       set = find_avail_set (regno, insn);
+-      if (! set)
++      if (! set || set->expr->volatil)
+       continue;
+       pat = set->expr;
+diff -urN gcc-3.3.1/gcc/integrate.c gcc-3.3.1-pp/gcc/integrate.c
+--- gcc-3.3.1/gcc/integrate.c  2003-07-15 01:05:43.000000000 +0000
++++ gcc-3.3.1-pp/gcc/integrate.c       2003-09-12 13:40:28.000000000 +0000
+@@ -401,6 +401,10 @@
+   /* These args would always appear unused, if not for this.  */
+   TREE_USED (copy) = 1;
++  /* The inlined variable is marked as INLINE not to sweep by propolice */
++  if (flag_propolice_protection && TREE_CODE (copy) == VAR_DECL)
++    DECL_INLINE (copy) = 1;
 +
-+      value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
-+                                     GET_MODE (to), 1, from,
-+                                     GET_MODE (from));
-+      insns = get_insns ();
-+      end_sequence ();
+   /* Set the context for the new declaration.  */
+   if (!DECL_CONTEXT (decl))
+     /* Globals stay global.  */
+@@ -1965,6 +1969,10 @@
+             seq = get_insns ();
+             end_sequence ();
++#ifdef FRAME_GROWS_DOWNWARD
++            if (flag_propolice_protection && GET_CODE (seq) == SET)
++              RTX_INTEGRATED_P (SET_SRC (seq)) = 1;
++#endif
+             emit_insn_after (seq, map->insns_at_start);
+             return temp;
+           }
+diff -urN gcc-3.3.1/gcc/libgcc-std.ver gcc-3.3.1-pp/gcc/libgcc-std.ver
+--- gcc-3.3.1/gcc/libgcc-std.ver       2003-07-13 21:25:09.000000000 +0000
++++ gcc-3.3.1-pp/gcc/libgcc-std.ver    2003-09-12 13:40:28.000000000 +0000
+@@ -174,6 +174,10 @@
+   _Unwind_SjLj_RaiseException
+   _Unwind_SjLj_ForcedUnwind
+   _Unwind_SjLj_Resume
 +
-+      emit_libcall_block (insns, target, value,
-+                        gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
-+                                       GET_MODE (to), from));
-+    }
-+      
-+  if (target != to)
-+    {
-+      if (GET_MODE (to) == GET_MODE (target))
-+        emit_move_insn (to, target);
-+      else
-+        convert_move (to, target, 0);
-+    }
-+}
++  # stack smash handler symbols
++  __guard
++  __stack_smash_handler
+ }
+ %inherit GCC_3.3 GCC_3.0
+diff -urN gcc-3.3.1/gcc/libgcc2.c gcc-3.3.1-pp/gcc/libgcc2.c
+--- gcc-3.3.1/gcc/libgcc2.c    2002-10-23 10:47:24.000000000 +0000
++++ gcc-3.3.1-pp/gcc/libgcc2.c 2003-09-12 13:40:28.000000000 +0000
+@@ -1993,3 +1993,102 @@
+ #endif /* NEED_ATEXIT */
+ #endif /* L_exit */
 +\f
-+/* Report whether we have an instruction to perform the operation
-+   specified by CODE on operands of mode MODE.  */
-+int
-+have_insn_for (code, mode)
-+     enum rtx_code code;
-+     enum machine_mode mode;
-+{
-+  return (code_to_optab[(int) code] != 0
-+        && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
-+            != CODE_FOR_nothing));
-+}
-+
-+/* Create a blank optab.  */
-+static optab
-+new_optab ()
-+{
-+  int i;
-+  optab op = (optab) ggc_alloc (sizeof (struct optab));
-+  for (i = 0; i < NUM_MACHINE_MODES; i++)
-+    {
-+      op->handlers[i].insn_code = CODE_FOR_nothing;
-+      op->handlers[i].libfunc = 0;
-+    }
-+
-+  return op;
-+}
-+
-+/* Same, but fill in its code as CODE, and write it into the
-+   code_to_optab table.  */
-+static inline optab
-+init_optab (code)
-+     enum rtx_code code;
-+{
-+  optab op = new_optab ();
-+  op->code = code;
-+  code_to_optab[(int) code] = op;
-+  return op;
-+}
-+
-+/* Same, but fill in its code as CODE, and do _not_ write it into
-+   the code_to_optab table.  */
-+static inline optab
-+init_optabv (code)
-+     enum rtx_code code;
-+{
-+  optab op = new_optab ();
-+  op->code = code;
-+  return op;
-+}
-+
-+/* Initialize the libfunc fields of an entire group of entries in some
-+   optab.  Each entry is set equal to a string consisting of a leading
-+   pair of underscores followed by a generic operation name followed by
-+   a mode name (downshifted to lower case) followed by a single character
-+   representing the number of operands for the given operation (which is
-+   usually one of the characters '2', '3', or '4').
-+
-+   OPTABLE is the table in which libfunc fields are to be initialized.
-+   FIRST_MODE is the first machine mode index in the given optab to
-+     initialize.
-+   LAST_MODE is the last machine mode index in the given optab to
-+     initialize.
-+   OPNAME is the generic (string) name of the operation.
-+   SUFFIX is the character which specifies the number of operands for
-+     the given generic operation.
-+*/
-+
-+static void
-+init_libfuncs (optable, first_mode, last_mode, opname, suffix)
-+     optab optable;
-+     int first_mode;
-+     int last_mode;
-+     const char *opname;
-+     int suffix;
-+{
-+  int mode;
-+  unsigned opname_len = strlen (opname);
-+
-+  for (mode = first_mode; (int) mode <= (int) last_mode;
-+       mode = (enum machine_mode) ((int) mode + 1))
-+    {
-+      const char *mname = GET_MODE_NAME (mode);
-+      unsigned mname_len = strlen (mname);
-+      char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
-+      char *p;
-+      const char *q;
-+
-+      p = libfunc_name;
-+      *p++ = '_';
-+      *p++ = '_';
-+      for (q = opname; *q; )
-+      *p++ = *q++;
-+      for (q = mname; *q; q++)
-+      *p++ = TOLOWER (*q);
-+      *p++ = suffix;
-+      *p = '\0';
-+
-+      optable->handlers[(int) mode].libfunc
-+      = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (libfunc_name,
-+                                                     p - libfunc_name));
-+    }
-+}
-+
-+/* Initialize the libfunc fields of an entire group of entries in some
-+   optab which correspond to all integer mode operations.  The parameters
-+   have the same meaning as similarly named ones for the `init_libfuncs'
-+   routine.  (See above).  */
-+
-+static void
-+init_integral_libfuncs (optable, opname, suffix)
-+     optab optable;
-+     const char *opname;
-+     int suffix;
-+{
-+  init_libfuncs (optable, SImode, TImode, opname, suffix);
-+}
-+
-+/* Initialize the libfunc fields of an entire group of entries in some
-+   optab which correspond to all real mode operations.  The parameters
-+   have the same meaning as similarly named ones for the `init_libfuncs'
-+   routine.  (See above).  */
-+
-+static void
-+init_floating_libfuncs (optable, opname, suffix)
-+     optab optable;
-+     const char *opname;
-+     int suffix;
-+{
-+  init_libfuncs (optable, SFmode, TFmode, opname, suffix);
-+}
-+
-+rtx
-+init_one_libfunc (name)
-+     const char *name;
-+{
-+  /* Create a FUNCTION_DECL that can be passed to
-+     targetm.encode_section_info.  */
-+  /* ??? We don't have any type information except for this is
-+     a function.  Pretend this is "int foo()".  */
-+  tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
-+                        build_function_type (integer_type_node, NULL_TREE));
-+  DECL_ARTIFICIAL (decl) = 1;
-+  DECL_EXTERNAL (decl) = 1;
-+  TREE_PUBLIC (decl) = 1;
-+
-+  /* Return the symbol_ref from the mem rtx.  */
-+  return XEXP (DECL_RTL (decl), 0);
-+}
-+
-+/* Call this once to initialize the contents of the optabs
-+   appropriately for the current target machine.  */
-+
-+void
-+init_optabs ()
-+{
-+  unsigned int i, j, k;
-+
-+  /* Start by initializing all tables to contain CODE_FOR_nothing.  */
-+
-+  for (i = 0; i < ARRAY_SIZE (fixtab); i++)
-+    for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++)
-+      for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++)
-+      fixtab[i][j][k] = CODE_FOR_nothing;
-+
-+  for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++)
-+    for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++)
-+      for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++)
-+      fixtrunctab[i][j][k] = CODE_FOR_nothing;
-+
-+  for (i = 0; i < ARRAY_SIZE (floattab); i++)
-+    for (j = 0; j < ARRAY_SIZE (floattab[0]); j++)
-+      for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++)
-+      floattab[i][j][k] = CODE_FOR_nothing;
-+
-+  for (i = 0; i < ARRAY_SIZE (extendtab); i++)
-+    for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++)
-+      for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++)
-+      extendtab[i][j][k] = CODE_FOR_nothing;
-+
-+  for (i = 0; i < NUM_RTX_CODE; i++)
-+    setcc_gen_code[i] = CODE_FOR_nothing;
++#ifdef L_stack_smash_handler
++#include <stdio.h>
++#include <string.h>
++#include <fcntl.h>
++#include <unistd.h>
 +
-+#ifdef HAVE_conditional_move
-+  for (i = 0; i < NUM_MACHINE_MODES; i++)
-+    movcc_gen_code[i] = CODE_FOR_nothing;
++#ifdef _POSIX_SOURCE
++#include <signal.h>
 +#endif
 +
-+  add_optab = init_optab (PLUS);
-+  addv_optab = init_optabv (PLUS);
-+  sub_optab = init_optab (MINUS);
-+  subv_optab = init_optabv (MINUS);
-+  smul_optab = init_optab (MULT);
-+  smulv_optab = init_optabv (MULT);
-+  smul_highpart_optab = init_optab (UNKNOWN);
-+  umul_highpart_optab = init_optab (UNKNOWN);
-+  smul_widen_optab = init_optab (UNKNOWN);
-+  umul_widen_optab = init_optab (UNKNOWN);
-+  sdiv_optab = init_optab (DIV);
-+  sdivv_optab = init_optabv (DIV);
-+  sdivmod_optab = init_optab (UNKNOWN);
-+  udiv_optab = init_optab (UDIV);
-+  udivmod_optab = init_optab (UNKNOWN);
-+  smod_optab = init_optab (MOD);
-+  umod_optab = init_optab (UMOD);
-+  ftrunc_optab = init_optab (UNKNOWN);
-+  and_optab = init_optab (AND);
-+  ior_optab = init_optab (IOR);
-+  xor_optab = init_optab (XOR);
-+  ashl_optab = init_optab (ASHIFT);
-+  ashr_optab = init_optab (ASHIFTRT);
-+  lshr_optab = init_optab (LSHIFTRT);
-+  rotl_optab = init_optab (ROTATE);
-+  rotr_optab = init_optab (ROTATERT);
-+  smin_optab = init_optab (SMIN);
-+  smax_optab = init_optab (SMAX);
-+  umin_optab = init_optab (UMIN);
-+  umax_optab = init_optab (UMAX);
-+
-+  /* These three have codes assigned exclusively for the sake of
-+     have_insn_for.  */
-+  mov_optab = init_optab (SET);
-+  movstrict_optab = init_optab (STRICT_LOW_PART);
-+  cmp_optab = init_optab (COMPARE);
-+
-+  ucmp_optab = init_optab (UNKNOWN);
-+  tst_optab = init_optab (UNKNOWN);
-+  neg_optab = init_optab (NEG);
-+  negv_optab = init_optabv (NEG);
-+  abs_optab = init_optab (ABS);
-+  absv_optab = init_optabv (ABS);
-+  one_cmpl_optab = init_optab (NOT);
-+  ffs_optab = init_optab (FFS);
-+  sqrt_optab = init_optab (SQRT);
-+  sin_optab = init_optab (UNKNOWN);
-+  cos_optab = init_optab (UNKNOWN);
-+  exp_optab = init_optab (UNKNOWN);
-+  log_optab = init_optab (UNKNOWN);
-+  strlen_optab = init_optab (UNKNOWN);
-+  cbranch_optab = init_optab (UNKNOWN);
-+  cmov_optab = init_optab (UNKNOWN);
-+  cstore_optab = init_optab (UNKNOWN);
-+  push_optab = init_optab (UNKNOWN);
-+
-+  for (i = 0; i < NUM_MACHINE_MODES; i++)
-+    {
-+      movstr_optab[i] = CODE_FOR_nothing;
-+      clrstr_optab[i] = CODE_FOR_nothing;
++#if defined(HAVE_SYSLOG)
++#include <sys/types.h>
++#include <sys/socket.h>
++#include <sys/un.h>
 +
-+#ifdef HAVE_SECONDARY_RELOADS
-+      reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
++#include <sys/syslog.h>
++#ifndef _PATH_LOG
++#define _PATH_LOG "/dev/log"
 +#endif
-+    }
-+
-+  /* Fill in the optabs with the insns we support.  */
-+  init_all_optabs ();
-+
-+#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
-+  /* This flag says the same insns that convert to a signed fixnum
-+     also convert validly to an unsigned one.  */
-+  for (i = 0; i < NUM_MACHINE_MODES; i++)
-+    for (j = 0; j < NUM_MACHINE_MODES; j++)
-+      fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
 +#endif
 +
-+  /* Initialize the optabs with the names of the library functions.  */
-+  init_integral_libfuncs (add_optab, "add", '3');
-+  init_floating_libfuncs (add_optab, "add", '3');
-+  init_integral_libfuncs (addv_optab, "addv", '3');
-+  init_floating_libfuncs (addv_optab, "add", '3');
-+  init_integral_libfuncs (sub_optab, "sub", '3');
-+  init_floating_libfuncs (sub_optab, "sub", '3');
-+  init_integral_libfuncs (subv_optab, "subv", '3');
-+  init_floating_libfuncs (subv_optab, "sub", '3');
-+  init_integral_libfuncs (smul_optab, "mul", '3');
-+  init_floating_libfuncs (smul_optab, "mul", '3');
-+  init_integral_libfuncs (smulv_optab, "mulv", '3');
-+  init_floating_libfuncs (smulv_optab, "mul", '3');
-+  init_integral_libfuncs (sdiv_optab, "div", '3');
-+  init_floating_libfuncs (sdiv_optab, "div", '3');
-+  init_integral_libfuncs (sdivv_optab, "divv", '3');
-+  init_integral_libfuncs (udiv_optab, "udiv", '3');
-+  init_integral_libfuncs (sdivmod_optab, "divmod", '4');
-+  init_integral_libfuncs (udivmod_optab, "udivmod", '4');
-+  init_integral_libfuncs (smod_optab, "mod", '3');
-+  init_integral_libfuncs (umod_optab, "umod", '3');
-+  init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
-+  init_integral_libfuncs (and_optab, "and", '3');
-+  init_integral_libfuncs (ior_optab, "ior", '3');
-+  init_integral_libfuncs (xor_optab, "xor", '3');
-+  init_integral_libfuncs (ashl_optab, "ashl", '3');
-+  init_integral_libfuncs (ashr_optab, "ashr", '3');
-+  init_integral_libfuncs (lshr_optab, "lshr", '3');
-+  init_integral_libfuncs (smin_optab, "min", '3');
-+  init_floating_libfuncs (smin_optab, "min", '3');
-+  init_integral_libfuncs (smax_optab, "max", '3');
-+  init_floating_libfuncs (smax_optab, "max", '3');
-+  init_integral_libfuncs (umin_optab, "umin", '3');
-+  init_integral_libfuncs (umax_optab, "umax", '3');
-+  init_integral_libfuncs (neg_optab, "neg", '2');
-+  init_floating_libfuncs (neg_optab, "neg", '2');
-+  init_integral_libfuncs (negv_optab, "negv", '2');
-+  init_floating_libfuncs (negv_optab, "neg", '2');
-+  init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
-+  init_integral_libfuncs (ffs_optab, "ffs", '2');
-+
-+  /* Comparison libcalls for integers MUST come in pairs, signed/unsigned.  */
-+  init_integral_libfuncs (cmp_optab, "cmp", '2');
-+  init_integral_libfuncs (ucmp_optab, "ucmp", '2');
-+  init_floating_libfuncs (cmp_optab, "cmp", '2');
-+
-+#ifdef MULSI3_LIBCALL
-+  smul_optab->handlers[(int) SImode].libfunc
-+    = init_one_libfunc (MULSI3_LIBCALL);
-+#endif
-+#ifdef MULDI3_LIBCALL
-+  smul_optab->handlers[(int) DImode].libfunc
-+    = init_one_libfunc (MULDI3_LIBCALL);
++long __guard[8] = {0,0,0,0,0,0,0,0};
++static void __guard_setup (void) __attribute__ ((constructor)) ;
++static void __guard_setup (void)
++{
++  int fd;
++  if (__guard[0]!=0) return;
++  fd = open ("/dev/urandom", 0);
++  if (fd != -1) {
++    ssize_t size = read (fd, (char*)&__guard, sizeof(__guard));
++    close (fd) ;
++    if (size == sizeof(__guard)) return;
++  }
++  /* If a random generator can't be used, the protector switches the guard
++     to the "terminator canary" */
++  ((char*)__guard)[0] = 0; ((char*)__guard)[1] = 0;
++  ((char*)__guard)[2] = '\n'; ((char*)__guard)[3] = 255;
++}
++void __stack_smash_handler (char func[], int damaged ATTRIBUTE_UNUSED)
++{
++#if defined (__GNU_LIBRARY__)
++  extern char * __progname;
 +#endif
-+
-+#ifdef DIVSI3_LIBCALL
-+  sdiv_optab->handlers[(int) SImode].libfunc
-+    = init_one_libfunc (DIVSI3_LIBCALL);
++  const char message[] = ": stack smashing attack in function ";
++  int bufsz = 256, len;
++  char buf[bufsz];
++#if defined(HAVE_SYSLOG)
++  int LogFile;
++  struct sockaddr_un SyslogAddr;  /* AF_UNIX address of local logger */
 +#endif
-+#ifdef DIVDI3_LIBCALL
-+  sdiv_optab->handlers[(int) DImode].libfunc
-+    = init_one_libfunc (DIVDI3_LIBCALL);
++#ifdef _POSIX_SOURCE
++  {
++    sigset_t mask;
++    sigfillset(&mask);
++    sigdelset(&mask, SIGABRT);        /* Block all signal handlers */
++    sigprocmask(SIG_BLOCK, &mask, NULL); /* except SIGABRT */
++  }
 +#endif
 +
-+#ifdef UDIVSI3_LIBCALL
-+  udiv_optab->handlers[(int) SImode].libfunc
-+    = init_one_libfunc (UDIVSI3_LIBCALL);
-+#endif
-+#ifdef UDIVDI3_LIBCALL
-+  udiv_optab->handlers[(int) DImode].libfunc
-+    = init_one_libfunc (UDIVDI3_LIBCALL);
++  strcpy(buf, "<2>"); len=3;  /* send LOG_CRIT */
++#if defined (__GNU_LIBRARY__)
++  strncat(buf, __progname, bufsz-len-1); len = strlen(buf);
 +#endif
++  if (bufsz>len) {strncat(buf, message, bufsz-len-1); len = strlen(buf);}
++  if (bufsz>len) {strncat(buf, func, bufsz-len-1); len = strlen(buf);}
 +
-+#ifdef MODSI3_LIBCALL
-+  smod_optab->handlers[(int) SImode].libfunc
-+    = init_one_libfunc (MODSI3_LIBCALL);
-+#endif
-+#ifdef MODDI3_LIBCALL
-+  smod_optab->handlers[(int) DImode].libfunc
-+    = init_one_libfunc (MODDI3_LIBCALL);
-+#endif
++  /* print error message */
++  write (STDERR_FILENO, buf+3, len-3);
++#if defined(HAVE_SYSLOG)
++  if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) != -1) {
 +
-+#ifdef UMODSI3_LIBCALL
-+  umod_optab->handlers[(int) SImode].libfunc
-+    = init_one_libfunc (UMODSI3_LIBCALL);
-+#endif
-+#ifdef UMODDI3_LIBCALL
-+  umod_optab->handlers[(int) DImode].libfunc
-+    = init_one_libfunc (UMODDI3_LIBCALL);
++    /*
++     * Send "found" message to the "/dev/log" path
++     */
++    SyslogAddr.sun_family = AF_UNIX;
++    (void)strncpy(SyslogAddr.sun_path, _PATH_LOG,
++                sizeof(SyslogAddr.sun_path) - 1);
++    SyslogAddr.sun_path[sizeof(SyslogAddr.sun_path) - 1] = '\0';
++    sendto(LogFile, buf, len, 0, (struct sockaddr *)&SyslogAddr,
++         sizeof(SyslogAddr));
++  }
 +#endif
 +
-+  /* Use cabs for DC complex abs, since systems generally have cabs.
-+     Don't define any libcall for SCmode, so that cabs will be used.  */
-+  abs_optab->handlers[(int) DCmode].libfunc
-+    = init_one_libfunc ("cabs");
-+
-+  /* The ffs function operates on `int'.  */
-+  ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
-+    = init_one_libfunc ("ffs");
-+
-+  extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
-+  extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
-+  extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
-+  extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
-+  extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
-+
-+  truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
-+  truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
-+  trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
-+  truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
-+  trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
-+
-+  abort_libfunc = init_one_libfunc ("abort");
-+  memcpy_libfunc = init_one_libfunc ("memcpy");
-+  memmove_libfunc = init_one_libfunc ("memmove");
-+  bcopy_libfunc = init_one_libfunc ("bcopy");
-+  memcmp_libfunc = init_one_libfunc ("memcmp");
-+  bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
-+  memset_libfunc = init_one_libfunc ("memset");
-+  bzero_libfunc = init_one_libfunc ("bzero");
-+
-+  unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
-+                                          ? "_Unwind_SjLj_Resume"
-+                                          : "_Unwind_Resume");
-+#ifndef DONT_USE_BUILTIN_SETJMP
-+  setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
-+  longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
-+#else
-+  setjmp_libfunc = init_one_libfunc ("setjmp");
-+  longjmp_libfunc = init_one_libfunc ("longjmp");
-+#endif
-+  unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
-+  unwind_sjlj_unregister_libfunc
-+    = init_one_libfunc ("_Unwind_SjLj_Unregister");
-+
-+  eqhf2_libfunc = init_one_libfunc ("__eqhf2");
-+  nehf2_libfunc = init_one_libfunc ("__nehf2");
-+  gthf2_libfunc = init_one_libfunc ("__gthf2");
-+  gehf2_libfunc = init_one_libfunc ("__gehf2");
-+  lthf2_libfunc = init_one_libfunc ("__lthf2");
-+  lehf2_libfunc = init_one_libfunc ("__lehf2");
-+  unordhf2_libfunc = init_one_libfunc ("__unordhf2");
-+
-+  eqsf2_libfunc = init_one_libfunc ("__eqsf2");
-+  nesf2_libfunc = init_one_libfunc ("__nesf2");
-+  gtsf2_libfunc = init_one_libfunc ("__gtsf2");
-+  gesf2_libfunc = init_one_libfunc ("__gesf2");
-+  ltsf2_libfunc = init_one_libfunc ("__ltsf2");
-+  lesf2_libfunc = init_one_libfunc ("__lesf2");
-+  unordsf2_libfunc = init_one_libfunc ("__unordsf2");
-+
-+  eqdf2_libfunc = init_one_libfunc ("__eqdf2");
-+  nedf2_libfunc = init_one_libfunc ("__nedf2");
-+  gtdf2_libfunc = init_one_libfunc ("__gtdf2");
-+  gedf2_libfunc = init_one_libfunc ("__gedf2");
-+  ltdf2_libfunc = init_one_libfunc ("__ltdf2");
-+  ledf2_libfunc = init_one_libfunc ("__ledf2");
-+  unorddf2_libfunc = init_one_libfunc ("__unorddf2");
-+
-+  eqxf2_libfunc = init_one_libfunc ("__eqxf2");
-+  nexf2_libfunc = init_one_libfunc ("__nexf2");
-+  gtxf2_libfunc = init_one_libfunc ("__gtxf2");
-+  gexf2_libfunc = init_one_libfunc ("__gexf2");
-+  ltxf2_libfunc = init_one_libfunc ("__ltxf2");
-+  lexf2_libfunc = init_one_libfunc ("__lexf2");
-+  unordxf2_libfunc = init_one_libfunc ("__unordxf2");
-+
-+  eqtf2_libfunc = init_one_libfunc ("__eqtf2");
-+  netf2_libfunc = init_one_libfunc ("__netf2");
-+  gttf2_libfunc = init_one_libfunc ("__gttf2");
-+  getf2_libfunc = init_one_libfunc ("__getf2");
-+  lttf2_libfunc = init_one_libfunc ("__lttf2");
-+  letf2_libfunc = init_one_libfunc ("__letf2");
-+  unordtf2_libfunc = init_one_libfunc ("__unordtf2");
-+
-+  floatsisf_libfunc = init_one_libfunc ("__floatsisf");
-+  floatdisf_libfunc = init_one_libfunc ("__floatdisf");
-+  floattisf_libfunc = init_one_libfunc ("__floattisf");
-+
-+  floatsidf_libfunc = init_one_libfunc ("__floatsidf");
-+  floatdidf_libfunc = init_one_libfunc ("__floatdidf");
-+  floattidf_libfunc = init_one_libfunc ("__floattidf");
-+
-+  floatsixf_libfunc = init_one_libfunc ("__floatsixf");
-+  floatdixf_libfunc = init_one_libfunc ("__floatdixf");
-+  floattixf_libfunc = init_one_libfunc ("__floattixf");
-+
-+  floatsitf_libfunc = init_one_libfunc ("__floatsitf");
-+  floatditf_libfunc = init_one_libfunc ("__floatditf");
-+  floattitf_libfunc = init_one_libfunc ("__floattitf");
-+
-+  fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
-+  fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
-+  fixsfti_libfunc = init_one_libfunc ("__fixsfti");
-+
-+  fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
-+  fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
-+  fixdfti_libfunc = init_one_libfunc ("__fixdfti");
-+
-+  fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
-+  fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
-+  fixxfti_libfunc = init_one_libfunc ("__fixxfti");
-+
-+  fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
-+  fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
-+  fixtfti_libfunc = init_one_libfunc ("__fixtfti");
-+
-+  fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
-+  fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
-+  fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");
-+
-+  fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
-+  fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
-+  fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
-+
-+  fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
-+  fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
-+  fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");
-+
-+  fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
-+  fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
-+  fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");
-+
-+  /* For function entry/exit instrumentation.  */
-+  profile_function_entry_libfunc
-+    = init_one_libfunc ("__cyg_profile_func_enter");
-+  profile_function_exit_libfunc
-+    = init_one_libfunc ("__cyg_profile_func_exit");
-+
-+  if (HAVE_conditional_trap)
-+    trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
-+
-+#ifdef INIT_TARGET_OPTABS
-+  /* Allow the target to add more libcalls or rename some, etc.  */
-+  INIT_TARGET_OPTABS;
++#ifdef _POSIX_SOURCE
++  { /* Make sure the default handler is associated with SIGABRT */
++    struct sigaction sa;
++    
++    memset(&sa, 0, sizeof(struct sigaction));
++    sigfillset(&sa.sa_mask);  /* Block all signals */
++    sa.sa_flags = 0;
++    sa.sa_handler = SIG_DFL;
++    sigaction(SIGABRT, &sa, NULL);
++    (void)kill(getpid(), SIGABRT);
++  }
 +#endif
++  _exit(127);
 +}
-+\f
-+/* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
-+   CODE.  Return 0 on failure.  */
-+
-+rtx
-+gen_cond_trap (code, op1, op2, tcode)
-+     enum rtx_code code ATTRIBUTE_UNUSED;
-+     rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
-+{
-+  enum machine_mode mode = GET_MODE (op1);
-+  enum insn_code icode;
-+  rtx insn;
-+
-+  if (!HAVE_conditional_trap)
-+    return 0;
-+
-+  if (mode == VOIDmode)
-+    return 0;
-+
-+  icode = cmp_optab->handlers[(int) mode].insn_code;
-+  if (icode == CODE_FOR_nothing)
++#endif
+diff -urN gcc-3.3.1/gcc/loop.c gcc-3.3.1-pp/gcc/loop.c
+--- gcc-3.3.1/gcc/loop.c       2003-07-11 06:47:05.000000000 +0000
++++ gcc-3.3.1-pp/gcc/loop.c    2003-09-12 13:40:28.000000000 +0000
+@@ -6516,6 +6516,14 @@
+   if (GET_CODE (*mult_val) == USE)
+     *mult_val = XEXP (*mult_val, 0);
++#ifndef FRAME_GROWS_DOWNWARD
++  if (flag_propolice_protection
++      && GET_CODE (*add_val) == PLUS
++      && (XEXP (*add_val, 0) == frame_pointer_rtx
++        || XEXP (*add_val, 1) == frame_pointer_rtx))
 +    return 0;
++#endif
 +
-+  start_sequence ();
-+  op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
-+  op2 = prepare_operand (icode, op2, 1, mode, mode, 0);
-+  if (!op1 || !op2)
+   if (is_addr)
+     *pbenefit += address_cost (orig_x, addr_mode) - reg_address_cost;
+   else
+diff -urN gcc-3.3.1/gcc/optabs.c gcc-3.3.1-pp/gcc/optabs.c
+--- gcc-3.3.1/gcc/optabs.c     2003-07-19 00:25:25.000000000 +0000
++++ gcc-3.3.1-pp/gcc/optabs.c  2003-09-12 13:40:28.000000000 +0000
+@@ -703,6 +703,26 @@
+   if (target)
+     target = protect_from_queue (target, 1);
++  if (flag_propolice_protection
++      && binoptab->code == PLUS
++      && op0 == virtual_stack_vars_rtx
++      && GET_CODE(op1) == CONST_INT)
 +    {
-+      end_sequence ();
-+      return 0;
-+    }
-+  emit_insn (GEN_FCN (icode) (op1, op2));
++      int icode = (int) binoptab->handlers[(int) mode].insn_code;
++      if (target)
++      temp = target;
++      else
++      temp = gen_reg_rtx (mode);
 +
-+  PUT_CODE (trap_rtx, code);
-+  insn = gen_conditional_trap (trap_rtx, tcode);
-+  if (insn)
-+    {
-+      emit_insn (insn);
-+      insn = get_insns ();
-+    }
-+  end_sequence ();
++      if (! (*insn_data[icode].operand[0].predicate) (temp, mode)
++        || GET_CODE (temp) != REG)
++      temp = gen_reg_rtx (mode);
 +
-+  return insn;
-+}
++      emit_insn (gen_rtx_SET (VOIDmode, temp,
++                            gen_rtx_PLUS (GET_MODE (op0), op0, op1)));
++      return temp;
++    }
 +
-+#include "gt-optabs.h"
-diff -ruN gcc-3.3.1/gcc/protector.c gcc-3.3.1.pp/gcc/protector.c
+   if (flag_force_mem)
+     {
+       op0 = force_not_mem (op0);
+diff -urN gcc-3.3.1/gcc/protector.c gcc-3.3.1-pp/gcc/protector.c
 --- gcc-3.3.1/gcc/protector.c  1970-01-01 00:00:00.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/protector.c       2003-09-05 11:59:47.000000000 +0000
++++ gcc-3.3.1-pp/gcc/protector.c       2003-09-12 13:40:28.000000000 +0000
 @@ -0,0 +1,2489 @@
 +/* RTL buffer overflow protection function for GNU C compiler
 +   Copyright (C) 1987, 88, 89, 92-7, 1998 Free Software Foundation, Inc.
@@ -39740,9 +3110,9 @@ diff -ruN gcc-3.3.1/gcc/protector.c gcc-3.3.1.pp/gcc/protector.c
 +  return FALSE;
 +}
 +#endif
-diff -ruN gcc-3.3.1/gcc/protector.h gcc-3.3.1.pp/gcc/protector.h
+diff -urN gcc-3.3.1/gcc/protector.h gcc-3.3.1-pp/gcc/protector.h
 --- gcc-3.3.1/gcc/protector.h  1970-01-01 00:00:00.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/protector.h       2003-09-05 11:59:47.000000000 +0000
++++ gcc-3.3.1-pp/gcc/protector.h       2003-09-12 13:40:28.000000000 +0000
 @@ -0,0 +1,48 @@
 +/* RTL buffer overflow protection function for GNU C compiler
 +   Copyright (C) 1987, 88, 89, 92-7, 1998 Free Software Foundation, Inc.
@@ -39792,9 +3162,9 @@ diff -ruN gcc-3.3.1/gcc/protector.h gcc-3.3.1.pp/gcc/protector.h
 +extern rtx assign_stack_local_for_pseudo_reg PARAMS ((enum machine_mode, HOST_WIDE_INT, int));
 +
 +#endif
-diff -ruN gcc-3.3.1/gcc/reload1.c gcc-3.3.1.pp/gcc/reload1.c
+diff -urN gcc-3.3.1/gcc/reload1.c gcc-3.3.1-pp/gcc/reload1.c
 --- gcc-3.3.1/gcc/reload1.c    2003-06-07 05:30:09.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/reload1.c 2003-09-05 11:58:59.000000000 +0000
++++ gcc-3.3.1-pp/gcc/reload1.c 2003-09-12 13:40:28.000000000 +0000
 @@ -42,6 +42,7 @@
  #include "toplev.h"
  #include "except.h"
@@ -39812,9 +3182,9 @@ diff -ruN gcc-3.3.1/gcc/reload1.c gcc-3.3.1.pp/gcc/reload1.c
                                  inherent_size == total_size ? 0 : -1);
          if (BYTES_BIG_ENDIAN)
            /* Cancel the  big-endian correction done in assign_stack_local.
-diff -ruN gcc-3.3.1/gcc/simplify-rtx.c gcc-3.3.1.pp/gcc/simplify-rtx.c
+diff -urN gcc-3.3.1/gcc/simplify-rtx.c gcc-3.3.1-pp/gcc/simplify-rtx.c
 --- gcc-3.3.1/gcc/simplify-rtx.c       2003-07-03 07:38:22.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/simplify-rtx.c    2003-09-05 11:58:59.000000000 +0000
++++ gcc-3.3.1-pp/gcc/simplify-rtx.c    2003-09-12 13:40:28.000000000 +0000
 @@ -1670,7 +1670,8 @@
    int n_ops = 2, input_ops = 2, input_consts = 0, n_consts;
    int first, negate, changed;
@@ -39905,9 +3275,9 @@ diff -ruN gcc-3.3.1/gcc/simplify-rtx.c gcc-3.3.1.pp/gcc/simplify-rtx.c
    /* Put a non-negated operand first.  If there aren't any, make all
       operands positive and negate the whole thing later.  */
  
-diff -ruN gcc-3.3.1/gcc/toplev.c gcc-3.3.1.pp/gcc/toplev.c
+diff -urN gcc-3.3.1/gcc/toplev.c gcc-3.3.1-pp/gcc/toplev.c
 --- gcc-3.3.1/gcc/toplev.c     2003-07-18 06:59:16.000000000 +0000
-+++ gcc-3.3.1.pp/gcc/toplev.c  2003-09-05 11:58:59.000000000 +0000
++++ gcc-3.3.1-pp/gcc/toplev.c  2003-09-12 13:40:28.000000000 +0000
 @@ -904,6 +904,13 @@
     minimum function alignment.  Zero means no alignment is forced.  */
  int force_align_functions_log;
This page took 1.753228 seconds and 4 git commands to generate.