add a gcc variant based on gcc 4.3.3 with codesourcery enhancements
authorFelix Fietkau <nbd@openwrt.org>
Mon, 19 Oct 2009 02:09:52 +0000 (02:09 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Mon, 19 Oct 2009 02:09:52 +0000 (02:09 +0000)
SVN-Revision: 18059

16 files changed:
toolchain/gcc/Config.in
toolchain/gcc/Config.version
toolchain/gcc/Makefile
toolchain/gcc/patches/4.3.3+cs/000-codesourcery_2009q1_203.patch [new file with mode: 0644]
toolchain/gcc/patches/4.3.3+cs/105-libtool.patch [new file with mode: 0644]
toolchain/gcc/patches/4.3.3+cs/106-fix_linker_error.patch [new file with mode: 0644]
toolchain/gcc/patches/4.3.3+cs/301-missing-execinfo_h.patch [new file with mode: 0644]
toolchain/gcc/patches/4.3.3+cs/302-c99-snprintf.patch [new file with mode: 0644]
toolchain/gcc/patches/4.3.3+cs/305-libmudflap-susv3-legacy.patch [new file with mode: 0644]
toolchain/gcc/patches/4.3.3+cs/410-fix_pr37436.patch [new file with mode: 0644]
toolchain/gcc/patches/4.3.3+cs/420-fix_pr26515.patch [new file with mode: 0644]
toolchain/gcc/patches/4.3.3+cs/810-arm-softfloat-libgcc.patch [new file with mode: 0644]
toolchain/gcc/patches/4.3.3+cs/910-mbsd_multi.patch [new file with mode: 0644]
toolchain/gcc/patches/4.3.3+cs/993-arm_insn-opinit-RTX_CODE-fixup.patch [new file with mode: 0644]
toolchain/gcc/patches/4.3.3+cs/998-gcc-4.3.0-fix-header.00.patch [new file with mode: 0644]
toolchain/gcc/patches/4.3.3+cs/999-coldfire.patch [new file with mode: 0644]

index a543b2825ebb5b5e718b1731c27fdf48d54c9db9..2c0f93e79a3bfa813e5b08607439139ab858af42 100644 (file)
@@ -39,6 +39,10 @@ if !LINUX_2_4
 
        config GCC_VERSION_LLVM
                bool "llvm-gcc 4.2"
+
+       config GCC_VERSION_4_3_3_CS
+               bool "gcc 4.3.3 with CodeSourcery enhancements"
+
 endif
 
 endchoice
index 291d345af91a1f57580ead31ce58d32af930469d..12987f402056ed8ea429f98c34015605448629cb 100644 (file)
@@ -4,6 +4,7 @@ config GCC_VERSION
        default "4.1.2"     if GCC_VERSION_4_1_2
        default "4.2.4"     if GCC_VERSION_4_2_4
        default "4.3.3"     if GCC_VERSION_4_3_3
+       default "4.3.3+cs"     if GCC_VERSION_4_3_3_CS
        default "4.3.4"     if GCC_VERSION_4_3_4
        default "4.4.0"     if GCC_VERSION_4_4_0
        default "4.4.1"     if GCC_VERSION_4_4_1
@@ -37,6 +38,7 @@ config GCC_VERSION_4_2
 config GCC_VERSION_4_3
        bool
        default y       if GCC_VERSION_4_3_3
+       default y       if GCC_VERSION_4_3_3_CS
        default y       if GCC_VERSION_4_3_4
 
 config GCC_VERSION_4_4
index 40804d5e0f83636661c3aa0207c11c70de6d5077..fdcee3f2176d14f12a4dd1948ceb7dd22a9143b3 100644 (file)
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=gcc
-PKG_VERSION:=$(call qstrip,$(CONFIG_GCC_VERSION))
-GCC_VERSION:=$(PKG_VERSION)
+GCC_VERSION:=$(call qstrip,$(CONFIG_GCC_VERSION))
+PKG_VERSION:=$(firstword $(subst +, ,$(GCC_VERSION)))
 GCC_DIR:=$(PKG_NAME)-$(PKG_VERSION)
 
 ifdef CONFIG_GCC_VERSION_LLVM
   PKG_SOURCE_VERSION:=c98c494b72ff875884c0c7286be67f16f9f6d7ab
   PKG_REV:=83504
   GCC_DIR:=llvm-gcc-4.2-r$(PKG_REV)
-  GCC_VERSION:=4.2.1
+  PKG_VERSION:=4.2.1
   PKG_SOURCE:=$(GCC_DIR).tar.gz
   PKG_SOURCE_PROTO:=git
   PKG_SOURCE_URL:=git://repo.or.cz/llvm-gcc-4.2.git
@@ -56,7 +56,7 @@ else
   endif
 endif
 
-PATCH_DIR=./patches/$(PKG_VERSION)
+PATCH_DIR=./patches/$(GCC_VERSION)
 
 include $(INCLUDE_DIR)/toolchain-build.mk
 
@@ -85,7 +85,8 @@ GCC_CONFIGURE:= \
                $(SOFT_FLOAT_CONFIG_OPTION) \
                $(call qstrip,$(CONFIG_EXTRA_GCC_CONFIG_OPTIONS)) \
                $(if $(CONFIG_mips64)$(CONFIG_mips64el),--with-arch=mips64 --with-abi=64) \
-               $(if $(CONFIG_GCC_VERSION_LLVM),--enable-llvm=$(BUILD_DIR_BASE)/host/llvm)
+               $(if $(CONFIG_GCC_VERSION_LLVM),--enable-llvm=$(BUILD_DIR_BASE)/host/llvm) \
+               $(if $(CONFIG_GCC_VERSION_4_3_3_CS),--enable-poison-system-directories)
 
 ifneq ($(CONFIG_GCC_VERSION_4_3)$(CONFIG_GCC_VERSION_4_4),)
   GCC_BUILD_TARGET_LIBGCC:=y
@@ -191,7 +192,7 @@ define Stage1/Install
                $(if $(GCC_BUILD_TARGET_LIBGCC),install-target-libgcc)
        
        # XXX: glibc insists on linking against libgcc_eh
-       ( cd $(TOOLCHAIN_DIR)/usr/lib/gcc/$(REAL_GNU_TARGET_NAME)/$(GCC_VERSION) ; \
+       ( cd $(TOOLCHAIN_DIR)/usr/lib/gcc/$(REAL_GNU_TARGET_NAME)/$(PKG_VERSION) ; \
                [ -e libgcc_eh.a ] || ln -sf libgcc.a libgcc_eh.a ; \
                cp libgcc.a libgcc_initial.a; \
        )
diff --git a/toolchain/gcc/patches/4.3.3+cs/000-codesourcery_2009q1_203.patch b/toolchain/gcc/patches/4.3.3+cs/000-codesourcery_2009q1_203.patch
new file mode 100644 (file)
index 0000000..4e93370
--- /dev/null
@@ -0,0 +1,57486 @@
+--- /dev/null
++++ b/ChangeLog.csl
+@@ -0,0 +1,7077 @@
++2009-05-21  Paul Brook  <paul@codesourcery.com>
++
++      Issue #5545
++      gcc/
++      * config/arm/arm.md (ifcompare_neg_move): Disable when
++      TARGET_NO_SINGLE_COND_EXEC.
++
++2009-05-20  Joseph Myers  <joseph@codesourcery.com>
++
++      Issue #5399
++
++      gcc/
++      * config/mips/mips.md (sqrt<mode>2): Condition on
++      <sqrt_condition>.
++
++2009-05-20  Maciej W. Rozycki  <macro@codesourcery.com>
++
++      Issue #5448
++      gcc/
++      * config/mips/predicates.md (const_call_insn_operand): Correct the
++      condition used for -call_nonpic support.
++
++      * release-notes-csl.xml (Compiler performance bug fix): New.
++
++2009-05-12  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      * ChangeLog.csl: Add changelog for the previous commit.
++      gcc/
++      * configure: Regenerate with proper autoconf version.
++
++2009-05-12  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      gcc/
++      * common.opt (feglibc): New dummy option.
++      * opts.c (common_handle_option): Handle it.
++      * config.gcc: Handle 'eglibc' vendor.
++      * config/t-eglibc: Define multilibs for testing EGLIBC features.
++      * configure.ac (--with-eglibc-configs, EGLICB_CONFIGS): New option and
++      variable.
++      * configure: Regenerate.
++      * Makefile.in (EGLIBC_CONFIGS): Handle
++
++2009-05-08  Nathan Sidwell  <nathan@codesourcery.com>
++
++      Issue 5335
++      gcc/
++      * class.c (resolve_address_of_overloaded_function): Use
++      OVL_CURRENT for error.
++      (instantiate_type): Allow FUNCTION_DECL when ms_extensions are
++      active.  Don't copy the rhs node.  Delete COMPOUND_EXPR code.
++      * typeck.c (build_compound_expr): Check RHS has known type.
++
++      gcc/testsuite/
++      * g++.dg/ext/ms-1.C: New.
++      * g++.old-deja/g++.other/overload11.C: Adjust.
++
++      * release-notes-csl.xml: Add two notes.
++
++2009-04-22  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.dg/tls/alias-1.c: Fix check for TLS.
++
++2009-04-22  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Issue #5106
++      Issue #4768
++
++      gcc/testsuite/
++      * gcc.dg/falign-labels-1.c (dg-options): Don't set for m68k and fido.
++
++2009-04-21  Andrew Jenner  <andrew@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.dg/pr34856.c: Handle powerpc*-*-elf.
++
++2009-04-21  Andrew Jenner  <andrew@codesourcery.com>
++
++      gcc/testsuite/
++      * lib/target-supports.exp: Handle powerpc-*-elf.
++
++2009-04-21  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.target/m68k/tls-ld.c, gcc.target/m68k/tls-le.c,
++      * gcc.target/m68k/tls-ld-xgot-xtls.c, gcc.target/m68k/tls-gd-xgot.c,
++      * gcc.target/m68k/tls-ie-xgot.c, gcc.target/m68k/tls-ld-xgot.c,
++      * gcc.target/m68k/tls-ld-xtls.c, gcc.target/m68k/tls-le-xtls.c,
++      * gcc.target/m68k/tls-gd.c, gcc.target/m68k/tls-ie.c: Remove -mcpu=5475
++      setting, run only for *-linux-* target.
++
++2009-04-15  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      Revert (moved to scripts):
++
++      2009-04-10  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Issue #693
++
++      gcc/
++      * config/arm/linux-eabi.h (TARGET_UNWIND_TABLES_DEFAULT): Define
++      to true.
++
++2009-04-13  Kazu Hirata  <kazu@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.dg/promote-short-3.c: XFAIL on fido.
++
++2009-04-10  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.dg/promote-short-3.c: Correct XFAIL syntax.
++
++2009-04-10  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Issue #693
++
++      gcc/
++      * config/arm/linux-eabi.h (TARGET_UNWIND_TABLES_DEFAULT): Define
++      to true.
++
++2009-04-09  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #5174
++      Backport from mainline:
++
++      gcc/
++      * doc/invoke.texi (Optimize Options): Add cross-reference to
++      -Q --help=optimizers examples.
++
++2009-04-09  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.dg/promote-short-3.c: XFAIL test for x86, m68k, sh, and mips.
++
++2009-04-09  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Issue #5186
++
++      gcc/
++      * tree-ssa-loop-promote.c (rebuild_with_promotion_1): Load a memory
++      reference prior to promoting it.
++
++      gcc/testsuite/
++      * gcc.dg/promote-short-9.c: New test.
++
++2009-04-08  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Issue #5171
++
++      gcc/
++      * tree-ssa-loop-promote.c (collection_promotion_candidates):
++      Delay allocation and initialization of new promote_info until we
++      know we have a candidate loop index.
++
++2009-04-06  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      Backport from upstream:
++
++      gcc/
++      2008-04-24  Uros Bizjak  <ubizjak@gmail.com>
++
++      PR rtl-optimization/36006
++      * expmed.c (store_fixed_bit_field): Copy op0 rtx before moving
++      temp to op0 in order to avoid invalid rtx sharing.
++
++      gcc/testsuite/
++      2008-04-24  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
++
++      PR rtl-optimization/36006
++      * gfortran.dg/pr36006-1.f90: New test.
++      * gfortran.dg/pr36006-2.f90: Ditto.
++
++2009-04-06  Paul Brook  <paul@codesourcery.com>
++
++      Issue #5117
++      Partial backport from FSF.
++
++      gcc/
++      * tree-ssa-pre.c (create_expression_by_pieces): Convert to sizetype
++      for POINTER_PLUS_EXPR.
++
++2009-04-04  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/
++      * gcc.c (do_self_spec): Handle switches with arguments.
++
++2009-04-04  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/
++      * testsuite/gcc.dg/pr34263.c: Add -fno-unroll-loops.
++
++2009-04-04  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.md (insv): Do not share operands[0].
++
++2009-04-04  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #5104
++      PR tree-optimization/39604
++
++      * release-notes-csl.xml (Corruption of block-scope variables):
++      New note.
++
++      gcc/testsuite
++      * g++.dg/tree-ssa/sink-1.C: New.
++
++      gcc/
++      * tree_ssa-sink.c (sink_code_in_bb): Do not sink statements out
++      of a lexical block containing variable definitions.
++
++2009-03-31  Andrew Jenner  <andrew@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.dg/arm-g2.c: Add dg-skip-if for MontaVista.
++      * gcc.dg/arm-scd42-2.c: Ditto.
++
++2009-03-31  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/
++      * common.opt (fpromote-loop-indices): Add Optimization keyword.
++
++2009-03-31  Kazu Hirata  <kazu@codesourcery.com>
++
++      Issue #5105
++      gcc/testsuite/
++      * gcc.target/m68k/pr36134.c: Use dg-skip-if to skip the testcase
++      if there is a conflict with -mcpu=.  Use -mcpu=5208.
++
++2009-03-30  Andrew Jenner  <andrew@codesourcery.com>
++
++      gcc/
++      * config.gcc: Accept montavista*-, not just montavista-.
++      * config/mips/t-montavista-linux: Add Octeon multilibs.
++
++2009-03-25  Andrew Stubbs  <ams@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.dg/pragma-isr-trapa2.c: Skip test for FPU-less architectures.
++
++2009-03-24  Andrew Stubbs  <ams@codesourcery.com>
++
++      Backport from upstream:
++      gcc/testsuite/
++      2008-02-25  Kaz Kojima  <kkojima@gcc.gnu.org>
++      * gcc.dg/tree-ssa/ssa-pre-10.c: Use -fno-finite-math-only on
++      sh* targets.
++
++2009-03-22  Mark Mitchell  <mark@codesourcery.com>
++
++      Backport:
++      
++      libstdc++-v3/
++      * testsuite/25_algorithms/search_n/iterator.cc: Condition
++      iterations for simulators.
++      * testsuite/25_algorithms/heap/moveable.cc: Likewise.
++      * testsuite/21_strings/basic_string/inserters_extractors/char/28277.cc
++      Condition stream width for simulators.
++      * testsuite/27_io/basic_ostream/inserters_character/char/28277-3.cc:
++      Likewise.
++      * testsuite/27_io/basic_ostream/inserters_character/char/28277-4.cc:
++      Likewise.
++      * testsuite/ext/vstring/inserters_extractors/char/28277.cc: Likewise.
++
++2009-03-20  Mark Mitchell  <mark@codesourcery.com>
++
++      Issue #4403
++
++      * release-notes-csl.xsml: Document compile-time performance
++      improvement.
++
++2009-03-19  Joseph Myers  <joseph@codesourcery.com>
++
++      Issue #2062
++      Issue #4730
++
++      gcc/
++      * config/arm/t-cs-linux: Add MULTILIB_MATCHES for ARMv4T -mcpu
++      options and for -mfpu=neon-fp16.  Add armv7-a-hard multilib.
++
++2009-03-19  Daniel Gutson  <dgutson@codesourcery.com>
++
++      Issue #4459
++
++      gcc/
++      * config/arm/t-cs-linux: Replaced armv7 by armv7-a in MULTILIB_OPTIONS
++      and added mfpu=neon, plus the required MULTILIB_ALIASES.
++
++      * release-notes.xml: Document.
++
++2009-03-19  Andrew Stubbs  <ams@codesourcery.com>
++
++      gcc/
++      * config.gcc (sh-*-*): Add support for --enable-extra-sgxx-multilibs.
++
++2009-03-18  Daniel Gutson  <dgutson@codesourcery.com>
++
++      Issue #4753
++
++      gcc/
++      * doc/invoke.texi: Added entries for cpus ARM Cortex-M0 and Cortex-M1.
++
++2009-03-18  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #4882
++
++      * release-notes-csl.xml (Better code for accessing global variables):
++      Copy-edit.  Reference updated GCC manual discussion.
++
++      Applied simultaneously to mainline:
++      gcc/
++      * doc/invoke.texi (Code Gen Options): Expand discussion of
++      -fno-common.
++
++2009-03-18  Kazu Hirata  <kazu@codesourcery.com>
++
++      gcc/
++      * config/sparc/sparc.c (sparc_emit_float_lib_cmp): Pass a libcall
++      SYMBOL_REF to hard_libcall_value.
++
++2009-03-17  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #4755
++
++      gcc/
++      * config/arm/arm.c (arm_emit_fp16_const): New function.
++      * config/arm/arm-protos.h (arm_emit_fp16_const): Declare it.
++      * config/arm/arm.md (consttable_2): Replace logic for HFmode values
++      with assertion that they can't appear here.
++      (consttable_4): Add HFmode case and use the new function for it.
++
++2009-03-17  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #4755
++
++      Revert:
++
++      2009-01-23  Sandra Loosemore  <sandra@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (dump_minipool): Use size of mode, not padded size,
++      in switch that controls whether to emit padding.
++
++      2009-02-05  Sandra Loosemore  <sandra@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (struct minipool_fixup): Split mode field into
++      value_mode and ref_mode.
++      (add_minipool_forward_ref): Use value_mode of fixup.
++      (add_minipool_backward_ref): Likewise.
++      (push_minipool_fix): Pass both value_mode and ref_mode as parameters,
++      and store them in the fixup.
++      (note_invalid_constants): Adjust arguments to push_minipool_fix.
++      (arm_reorg): Use ref_mode of fixup.
++
++2009-03-17  Daniel Gutson  <dgutson@codesourcery.com>
++
++      Issue #4753
++
++      gcc/
++      * config/arm/t-cs-eabi (MULTILIB_MATCHES): Added cortex-m0 as a synonym of march=armv6-m.
++      * config/arm/arm-cores.def: Added core cortex-m0.
++      * config/arm/arm-tune.md ("tune"): Aded cortexm0.
++      * config/arm/t-arm-elf (MULTILIB_MATCHES): Added cortex-m0 as a synonym of march=armv6-m.
++      * config/arm/t-uclinux-eabi (MULTILIB_MATCHES): Added cortex-m0 as a synonym of march=armv6-m.
++
++      * release-notes.csl: Document. 
++
++2009-03-16  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/
++      * config/arm/neon-testgen.ml: Use dg-add-options arm_neon.
++
++      gcc/testsuite/
++      * gcc/target/arm/neon/: Regenerated test cases.
++
++      * gcc.target/arm/neon-dse-1.c, gcc.target/arm/neon/polytypes.c,
++      gcc.target/arm/neon-vmla-1.c, gcc.target/arm/neon-vmls-1.c,
++      gcc.target/arm/neon-cond-1.c, gcc.dg/torture/arm-fp16-ops-8.c,
++      gcc.dg/torture/arm-fp16-ops-7.c, g++.dg/ext/arm-fp16/arm-fp16-ops-7.C,
++      g++.dg/ext/arm-fp16/arm-fp16-ops-8.C, g++.dg/abi/mangle-neon.C: Use
++      dg-add-options arm_neon.
++
++      * gcc.target/arm/fp16-compile-vcvt.c, gcc.dg/torture/arm-fp16-ops-5.c,
++      gcc.dg/torture/arm-fp16-ops-6.c, g++.dg/ext/arm-fp16/arm-fp16-ops-5.C,
++      g++.dg/ext/arm-fp16/arm-fp16-ops-6.C: Use dg-add-options arm_neon_fp16
++      and arm_neon_fp16_ok.
++
++      * gcc.dg/vect/vect.exp, g++.dg/vect/vect.exp,
++      gfortran.dg/vect/vect.exp: Use add_options_for_arm_neon.
++
++      * lib/target-supports.exp (add_options_for_arm_neon): New.
++      (check_effective_target_arm_neon_ok_nocache): New, from
++      check_effective_target_arm_neon_ok.  Check multiple possibilities.
++      (check_effective_target_arm_neon_ok): Use
++      check_effective_target_arm_neon_ok_nocache.
++      (add_options_for_arm_neon_fp16)
++      (check_effective_target_arm_neon_fp16_ok)
++      check_effective_target_arm_neon_fp16_ok_nocache): New.
++      (check_effective_target_arm_neon_hw): Use add_options_for_arm_neon.
++
++2009-03-16  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/testsuite/
++      * lib/target-supports.exp (check_effective_target_arm_neon_ok):
++      Correct arm_neon.h typo.
++
++2009-03-16  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #4878
++
++      * release-notes-csl.xml (VFP ABI support): New note.
++
++2008-03-15  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/
++      2008-02-11  David Ung  <davidu@mips.com>
++
++      * config/mips/mips.c (mips_output_division): When
++      GENERATE_DIVIDE_TRAPS, generate the trap instrutions
++      against zero before the actual divide.  This is friendlier
++      to out-of-order cpus like the 74k.
++
++2009-03-13  Joseph Myers  <joseph@codesourcery.com>
++
++      Issue #2062
++
++      gcc/
++      * config/arm/t-linux-eabi: Add MULTILIB_MATCHES for ARMv4T -mcpu
++      options.
++
++2009-03-13  Mark Mitchell  <mark@codesourcery.com>
++
++      Issue #3999
++      
++      * release-notes-csl.xml: Document.
++      gcc/
++      * config/arm/neon.md (*mul<mode>3add<mode>_neon): New pattern.
++      (*mul<mode>3neg<mode>add<mode>_neon): Likewise.
++      gcc/testsuite
++      * gcc.dg/target/arm/neon-vmla-1.c: New.
++      * gcc.dg/target/arm/neon-vmls-1.c: Likewise.
++
++2009-03-13  Catherine Moore  <clm@codesourcery.com>
++
++       gcc/
++       * config/i386/x-mingw32 (host-mingw32.o): Replace
++       diagnostic.h with $(DIAGNOSTIC_H).
++
++2009-03-12  Joseph Myers  <joseph@codesourcery.com>
++
++      Issue #4730
++
++      gcc/
++      * config/arm/t-cs-eabi: Add MULTILIB_MATCHES for -mhard-float.
++
++2009-03-12  Joseph Myers  <joseph@codesourcery.com>
++
++      Issue #4730
++      Issue #4850
++
++      gcc/
++      * config/arm/t-cs-eabi: Add VFP ABI multilib.  Add
++      MULTILIB_MATCHES for -march=armv5t and -mfpu=neon-fp16.
++
++2009-03-12  Daniel Gutson  <dgutson@codesourcery.com>
++
++      Issue #4459
++
++      gcc/
++      * config/arm/t-cs-eabi: Replaced Thumb2 VFP multilibs by ARM VFP3 NEON.
++      * release-notes-csl.xml: Document.
++
++2009-03-11  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Backport from mainline:
++
++      gcc/
++      2009-03-10  Richard Guenther  <rguenther@suse.de>
++                  Nathan Froyd  <froydnj@codesourcery.com>
++
++      PR middle-end/37850
++      * libgcc2.c (__mulMODE3): Use explicit assignments to form the
++      result.
++      (__divMODE3): Likewise.
++
++2009-03-11  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Backport from mainline:
++
++      gcc/testsuite/
++      2009-03-11  Nathan Froyd  <froydnj@codesourcery.com>
++
++      * gcc.dg/vect/vect-82.c: Combine dg-do and
++      dg-require-effective-target into dg-skip-if.
++      * gcc.dg/vect/vect-83.c: Likewise.
++
++2009-03-10  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Issue #4569
++
++      * release-notes-csl.xml (Loop optimization improvements): New note.
++
++2009-03-09  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Issue #4569
++
++      gcc/
++      * tree-ssa-loop-promote.c: New file.
++      * common.opt (fpromote-loop-indices): New option.
++      * timevar.def (TV_TREE_LOOP_PROMOTE): New timevar.
++      * Makefile.in (tree-ssa-loop-promote.o): New rule.
++      (OBJS-comon): Include it.
++      * tree-pass.h (pass_promote_short_indices): Declare.
++      * passes.c (init_optimization_passes): Add it.
++      * pointer-set.h (pointer_set_n_elements, pointer_set_clear,
++      pointer_map_n_elements, pointer_map_clear): Declare.
++      * pointer-set.c (pointer_set_n_elements, pointer_set_clear,
++      pointer_map_n_elements, pointer_map_clear): Define.
++
++      gcc/doc/
++      * invoke.texi (-fpromote-loop-indices): New entry.
++
++      gcc/testsuite/
++      * gcc.dg/promote-short-1.c: New file.
++      * gcc.dg/promote-short-2.c: New file.
++      * gcc.dg/promote-short-3.c: New file.
++      * gcc.dg/promote-short-4.c: New file.
++      * gcc.dg/promote-short-5.c: New file.
++      * gcc.dg/promote-short-6.c: New file.
++      * gcc.dg/promote-short-7.c: New file.
++      * gcc.dg/promote-short-8.c: New file.
++
++2009-03-07  Mark Mitchell  <mark@codesourcery.com>
++
++      * release-notes-csl.xml: Mention use of -fno-common by default on
++      bare--metal targets.
++
++2009-03-07  Joseph Myers  <joseph@codesourcery.com>
++
++      Issue #4730
++
++      Merge from ARM/hard_vfp_4_4_branch:
++
++      gcc/testsuite/
++      2009-03-06  Richard Earnshaw  <rearnsha@arm.com>
++      * lib/target-supports.exp (check_effective_target_hard_vfp_ok): Make
++      this a linkage test.
++      * gcc.target/arm/aapcs/aapcs.exp: New framework for testing AAPCS
++      argument marshalling.
++      * abitest.h: New file.
++      * vfp1.c, vfp2.c, vfp3.c, vfp4.c, vfp5.c, vfp6.c, vfp7.c: New tests.
++      * vfp8.c, vfp9.c, vfp10.c, vfp11.c, vfp12.c, vfp13.c, vfp14.c: New.
++
++2009-03-06  Joseph Myers  <joseph@codesourcery.com>
++
++      Issue #4730
++
++      gcc/
++      * doc/invoke.texi (-mfloat-abi=@var{name}): Remove statement about
++      -mfloat-abi=hard not being supported for VFP.
++
++2009-03-06  Mark Mitchell  <mark@codesourcery.com>
++
++      gcc/
++      * configure.ac (--with-specs): New option.
++      * configure: Regenerated.
++      * gcc.c (driver_self_specs): Include CONFIGURE_SPECS.
++      * Makefile.in (DRIVER_DEFINES): Add -DCONFIGURE_SPECS.
++
++2009-03-05  Mark Mitchell  <mark@codesourcery.com>
++
++      Backport:
++
++      gcc/testsuite/
++      2009-01-07  Janis Johnson  <janis187@us.ibm.com>
++      * g++.dg/torture/pr38586.C: Ignore a possible warning.
++      
++2009-03-05  Joseph Myers  <joseph@codesourcery.com>
++
++      Issue #4730
++
++      gcc/
++      * config/arm/arm.c (arm_handle_pcs_attribute): New.
++      (arm_get_pcs_model): Pass attribute arguments to
++      arm_pcs_from_attribute.
++      (arm_init_cumulative_args): Use base AAPCS for conversions from
++      floating-point types to DImode.
++      (arm_attribute_table): Add pcs attribute.
++      (arm_handle_pcs_attribute): New.
++      * config/arm/bpabi.h (DECLARE_LIBRARY_RENAMES): When renaming
++      conversions from floating-point types to DImode, also declare them
++      to use base AAPCS and declare functions they call to use base
++      AAPCS and their RTABI names.
++
++      gcc/testsuite/
++      * gcc.target/arm/eabi1.c: Do not skip for non-base ABI variants.
++      (PCS): Define macro to use base AAPCS.
++      (decl_float, __aeabi_d2f, __aeabi_f2d): Use PCS macro.
++
++2009-03-05  Mark Mitchell  <mark@codesourcery.com>
++
++      Backport:
++      
++      gcc/testsuite/
++      2008-11-24  DJ Delorie  <dj@redhat.com>
++      * gcc.c-torture/execute/pr36321.c: Don't rely on argv[0] being set.
++
++2009-03-05  Joseph Myers  <joseph@codesourcery.com>
++
++      Issue #4730
++
++      gcc/
++      * config/arm/arm.c (aapcs_vfp_sub_candidate): Use V2SImode and
++      V4SImode as representatives of all 64-bit and 128-bit vector
++      types.  Allow vector types without vector modes.
++      (aapcs_vfp_is_call_or_return_candidate): Handle vector types
++      without vector modes like BLKmode.
++      (aapcs_vfp_allocate): Handle TImode for non-TARGET_NEON like
++      BLKmode.  Avoid unsupported vector modes or TImode moves for
++      non-TARGET_NEON.
++      (aapcs_vfp_allocate_return_reg): Likewise.
++      (arm_vector_mode_supported_p): Only support V2SImode, V4HImode and
++      V8QImode if TARGET_NEON || TARGET_IWMMXT.
++
++2009-03-04  Daniel Gutson  <dgutson@codesourcery.com>
++
++      Issue #4462
++
++      gcc/
++      * config/arm/t-cs-linux: Removed marvell-f multilibs.
++
++      * release-notes-csl.xml: Document. 
++
++2009-03-04  Joseph Myers  <joseph@codesourcery.com>
++
++      Issue #4730
++
++      gcc/
++      * config/arm/arm.c (arm_return_in_memory): Handle returning
++      vectors of suitable size in registers also for AAPCS case.
++
++2009-03-04  Joseph Myers  <joseph@codesourcery.com>
++
++      Issue #3681
++
++      Backport:
++
++      gcc/
++      2009-03-03  Joseph Myers  <joseph@codesourcery.com>
++      * emit-rtl.c (adjust_address_1): Reduce offset to a signed value
++      that fits within Pmode.
++
++      gcc/testsuite/
++      2009-03-03  Joseph Myers  <joseph@codesourcery.com>
++      * gcc.c-torture/compile/20090303-1.c,
++      gcc.c-torture/compile/20090303-2.c: New tests.
++
++2009-03-03  Andrew Stubbs  <ams@codesourcery.com>
++
++      gcc/
++      * config/sh/t-sgxxlite-linux (MULTILIB_EXCEPTIONS): Allow big endian
++      SH4A multilib.
++
++2009-03-01  Mark Mitchell  <mark@codesourcery.com>
++
++      Issue #4768
++
++      * release-notes-csl.xml: Document.
++      gcc/
++      * final.c (shorten_branches): Do not align labels for jump tables.
++      (final_scan_insn): Use JUMP_TABLE_DATA_P.
++
++2009-03-02  Daniel Gutson  <dgutson@codesourcery.com>
++
++      Issue #4462
++
++      gcc/
++      * config/arm/t-cs-eabi: Replaced marvell-f with armv5t multilibs.
++
++      * release-notes-csl.xml: Document.
++
++2009-03-02  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Issue #4344
++
++      gcc/
++      * tree.h (struct tree_type): Enlarge precision field.  Rearrange
++      fields to position things within bytes.  Move packed_flag to...
++      (struct tree_base): ...here.  Decrease spare field accordingly.
++      (TYPE_PACKED): Adjust to reflect new packed_flag location.
++      * config/arm/arm-modes.def (XI): Define it as a real INT_MODE.
++
++      gcc/testsuite/
++      * gcc.target/arm/neon-dse-2.c: New test.
++
++2009-02-27  Daniel Gutson  <dgutson@codesourcery.com>
++
++        Issue #4459
++
++        gcc/
++        * config/arm/linux-eabi.h (LINK_SPEC): BE8_LINK_SPEC added.
++        * config/arm/arm-cores.def: Comment added.
++        * config/arm/bpapi.h (BE8_LINK_SPEC): New define.
++        (LINK_SPEC): BE_LINK_SPEC added.
++
++        * release-notes-csl.xml: Add note.
++
++2009-02-27  Joseph Myers  <joseph@codesourcery.com>
++
++      Issue #4730
++
++      gcc/
++      * config/arm/arm.c (aapcs_layout_arg): Handle coprocessor argument
++      candidates after a previous argument failed to be allocated to
++      coprocessor registers the same way as the first failing argument.
++
++2009-02-26  Joseph Myers  <joseph@codesourcery.com>
++
++      Issue #4730
++
++      gcc/
++      * config/arm/arm.c (arm_libcall_value, arm_init_cumulative_args):
++      Use base ABI for conversion libfuncs between HFmode and SFmode.
++
++2009-02-26  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Issue #4344
++
++      gcc/testsuite/
++      * gcc.target/arm/neon-dse-1.c: New test.
++
++2009-02-25  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Issue #4344
++
++      * release-notes-csl.xml (Internal compiler error with large
++      NEON types): New note.
++
++      gcc/
++      * dse.c (struct store_info): Change positions_needed to an
++      unsigned HOST_WIDEST_INT.
++
++      Backport portions of:
++      2008-12-23  Jakub Jelinek  <jakub@redhat.com>
++
++      gcc/
++      * dse.c (struct store_info): Change begin and end fields to
++      HOST_WIDE_INT.
++        (set_position_unneeded, set_all_positions_unneeded,
++        any_positions_needed_p, all_positions_needed_p): New static inline
++        functions.
++        (set_usage_bits): Don't look at stores where
++        offset + width >= MAX_OFFSET.
++        (check_mem_read_rtx): Use all_positions_needed_p function.
++      
++      Backport from mainline:
++      gcc/
++      2008-04-11  H.J. Lu  <hongjiu.lu@intel.com>
++
++      * dse.c (lowpart_bitmask): New.
++
++2009-02-26  Joseph Myers  <joseph@codesourcery.com>
++
++      Issue #4730
++
++      Merge from ARM/hard_vfp_4_4_branch:
++
++      gcc/
++      2009-01-13  Richard Earnshaw <rearnsha@arm.com>
++
++      * doc/tm.texi (TARGET_LIBCALL_VALUE): Add missing end statement.
++
++      2008-12-09  Richard Earnshaw <rearnsha@arm.com>
++
++      ARM Hard-VFP calling convention
++      * target-def.h (TARGET_LIBCALL_VALUE): New hook.
++      * target.h (gcc_target): Add libcall_value to table of call hooks.
++      * targhooks.h (default_libcall_value): Default implementation.
++      * targhooks.c (default_libcall_value): Likewise.
++      * doc/tm.texi (TARGET_LIBCALL_VALUE): Document it.
++      * optabs.c (expand_unop): Use it.
++      * expr.h (hard_libcall_value): Pass the function RTX through.
++      * calls.c (emit_library_call_value_1): Update call to 
++      hard_libcall_value.
++      * explow.c (hard_libcall_value): Use new target hook.
++      * testsuite/lib/target-supports.exp
++      (check_effective_target_arm_hard_vfp_ok): New hook.
++      (check_effective_target_arm_neon_ok): Improve test for neon
++      availability.
++      * testsuite/gcc.target/arm/eabi1.c: Only run test in base variant.
++      * config/arm/arm.c: Include cgraph.h
++      (TARGET_FUNCTION_VALUE): Override default hook.
++      (arm_pcs_default): New variable.
++      (arm_override_options): Don't fault hard calling convention with VFP.
++      Add support for AAPCS variants.
++      (arm_function_value): Make static.  Handle AAPCS variants.
++      (arm_libcall_value): New function.
++      (arm_apply_result_size): Handle VFP registers in results.
++      (arm_return_in_memory): Rework all AAPCS variants; handle hard-vfp
++      conventions.
++      (pcs_attribute_args): New variable.
++      (arm_pcs_from_attribute): New function.
++      (arm_get_pcs_model): New function.
++      (aapcs_vfp_cum_init): New function.
++      (aapcs_vfp_sub_candidate): New function.
++      (aapcs_vfp_is_return_candidate): New function.
++      (aapcs_vfp_is_call_candidate): New function.
++      (aapcs_vfp_allocate): New function.
++      (aapcs_vfp_allocate_return_reg): New function.
++      (aapcs_vfp_advance): New function.
++      (aapcs_cp_arg_layout): New variable.
++      (aapcs_select_call_coproc): New function.
++      (aapcs_select_return_coproc): New function.
++      (aapcs_allocate_return_reg): New function.
++      (aapcs_libcall_value): New function.
++      (aapcs_layout_arg): New function.
++      (arm_init_cumulative_args): Initialize AAPCS args data.
++      (arm_function_arg): Handle AAPCS variants using new interface.
++      (arm_arg_parital_bytes): Likewise.
++      (arm_function_arg_advance): New function.
++      (arm_function_ok_for_sibcall): Ensure that sibling calls agree on
++      calling conventions.
++      (arm_setup_incoming_varargs): Handle new AAPCS args data.
++      * arm.h (NUM_VFP_ARG_REGS): Define.
++      (LIBCALL_VALUE): Update.
++      (FUNCTION_VALUE): Delete.
++      (FUNCTION_VALUE_REGNO_P): Add VFP regs.
++      (arm_pcs): New enum.
++      (CUMULATIVE_ARGS): New data to support AAPCS argument marshalling.
++      (FUNCTION_ARG_ADVANCE): Call arm_function_arg_advance.
++      (FUNCTION_ARG_REGNO_P): Add VFP regs.
++      * arm-protos.h (arm_function_arg_advance): Add.
++      (aapcs_libcall_value): Add.
++      (arm_function_value): Delete.
++
++2009-02-25  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport from FSF:
++
++      gcc/
++      2008-05-08  Kai Tietz  <kai.tietz@onevision.com>
++      * config/arm/arm.c (arm_return_in_memory): Add fntype argumen.
++      * config/arm/arm.h (RETURN_IN_MEMORY): Replace RETURN_IN_MEMORY
++      by TARGET_RETURN_IN_MEMORY.
++      * config/arm/arm-protos.h (arm_return_in_memory): Add fntype argument.
++
++      2008-05-15  Diego Novillo  <dnovillo@google.com>
++      * config/arm/arm.c (arm_return_in_memory): Fix return type.
++      * config/arm/arm-protos.h (arm_return_in_memory): Likewise.
++
++      2008-06-19  Chung-Lin Tang  <ctang@marvell.com>
++      * arm-protos.h (arm_return_in_memory): Remove public
++      arm_return_in_memory() prototype.
++      * arm.c (arm_return_in_memory): Add static prototype, add target
++      hook macro, change definition and comments.
++      * arm.h (TARGET_RETURN_IN_MEMORY): Remove.
++
++2009-02-24  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #2369
++      Committed upstream at the same time.
++
++      gcc/
++      * doc/invoke.texi (Link Options): Document an easier way to pass
++      options that take arguments to the GNU linker using -Xlinker and
++      -Wl.
++
++2009-02-24  Andrew Stubbs  <ams@codesourcery.com>
++
++      gcc/
++      * config/sh/lib1funcs.asm (ic_invalidate): icbi is not valid in a
++      delay slot.
++
++2009-02-24  Andrew Stubbs  <ams@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.target/sh/sh4a-memmovua.c: Include string.h instead of stdlib.h.
++
++2009-02-24  Andrew Stubbs  <ams@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.target/sh/sh4a-bitmovua.c (y0): Rename to y_0 to avoid a clash
++      with the built-in y0, and the subsequent warning.
++      (y1): Likewise, rename to y_1.
++
++2009-02-21  Mark Mitchell  <mark@codesourcery.com>
++
++      Issue #4694
++      Backport:
++      libiberty/
++      2008-07-31  Jakub Jelinek  <jakub@redhat.com>
++      * mkstemps.c (mkstemps): Keep looping even for EISDIR.
++      2008-07-31  Denys Vlasenko  <dvlasenk@redhat.com>
++      * mkstemps.c (mkstemps): If open failed with errno other than
++      EEXIST, return immediately.
++      * make-temp-file.c: Include errno.h.
++      (make_temp_file): If mkstemps failed, print an error message
++      before aborting.
++
++2009-02-19  Kazu Hirata  <kazu@codesourcery.com>
++
++      Issue #4152
++      * release-notes-csl.xml: Mention the bug fix below.
++
++      Backport:
++      2008-07-30  Andrew Jenner  <andrew@codesourcery.com>
++
++      * config/arm/arm.c (arm_compute_static_chain_stack_bytes): New
++      function.
++      (arm_compute_initial_elimination_offset): Use it.
++      (arm_compute_save_reg_mask): Include static chain save slot when
++      calculating alignment.
++      (arm_get_frame_offsets): Ditto.
++      (thumb1_compute_save_reg_mask): Ensure we have a low register saved
++      that we can use to decrement the stack when the stack decrement
++      could be too big for an immediate value in a single insn.
++      (thumb1_expand_prologue): Avoid using r12 for stack decrement.
++
++2009-02-19  Catherine Moore  <clm@codesourcery.com>
++
++      Issue #2953
++      
++      gcc/
++      * debug.h (set_name):  Declare.
++      * dwarf2out.c (dwarf2out_set_name): Declare.
++      (dwarf2_debug_hooks): Add set_name.
++      (find_AT_string): New.
++      (add_AT_string): Call find_AT_string.
++      (dwarf2out_set_name): New.
++      * cp/decl.c (grokdeclarator): Call set_name.
++      * vmsdbgout.c (vmsdbg_debug_hooks): Add set_name_debug_nothing.
++      * debug.c (do_nothing_debug_hooks): Likewise.
++      * dbxout.c (dbx_debug_hooks): Likewise.
++      * sdbout.c (sdb_debug_hooks): Likewise.  
++
++      * release-notes-csl.xml: Add note.
++
++2009-02-19  Kazu Hirata  <kazu@codesourcery.com>
++
++      Issue #4613
++      gcc/
++      * config/arm/arm.c (arm_rtx_costs_1): Teach that the cost of MLS
++      is the same as its underlying multiplication.
++      * config/arm/arm.md (two splitters): New.
++      * config/arm/predicates.md (binary_operator): New.
++
++      * release-notes-csl.xml: Add a release note fragment for this
++      optimization.
++
++2009-02-17  Andrew Jenner  <andrew@codesourcery.com>
++            Maciej Rozycki  <macro@codesourcery.com>
++
++        gcc/
++        * unwind.inc (_Unwind_RaiseException): Use return value of
++        uw_init_context.
++        * unwind-dw2.c (uw_init_context): Make macro an expression instead of
++        a statement.
++        (uw_init_context_1): Add return value.
++        * unwind-sjlj.c (uw_init_context): Add return value.
++
++2009-02-17  Kazu Hirata  <kazu@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_rtx_costs_1): Treat a minus with a shift
++      the same as a minus without a shift.
++
++2009-02-16  Joseph Myers  <joseph@codesourcery.com>
++
++      Issue #4622
++
++      gcc/
++      * tree-predcom.c (ref_at_iteration): Return NULL_TREE if loop
++      header is an empty block.
++
++      gcc/testsuite/
++      * g++.dg/torture/predcom-1.C: New test.
++
++2009-02-16  Julian Brown  <julian@codesourcery.com>
++
++      Issue #3747
++      gcc/
++      * config/arm/t-linux-eabi (LIB2FUNCS_STATIC_EXTRA): Add
++      config/arm/linux-atomic.c.
++      * config/arm/linux-atomic.c: New.
++
++2009-02-12  Nathan Sidwell  <nathan@codesourcery.com>
++
++      Issue #4620
++      gcc/
++      * config/rs6000/rs6000.c (rs6000_init_builtins): Set TYPE_NAME of
++      our distinct integral and vector types.
++      gcc/testsuite/
++      * g++.dg/ext/altivec-17.C: New.
++
++      * release-notes-csl.xml: Add note.
++
++2009-02-10  Mark Mitchell  <mark@codesourcery.com>
++
++      libjava/classpath/
++      * m4/acinclude.m4 (CLASSPATH_TOOLEXECLIBDIR): Match libjava.
++      * configure.ac (--enable-version-specific-runtime-libs): Support.
++      * Makefile.in, */Makefile.in: Regenerated.
++
++      libjava/
++      * Makefile.am (pkgconfigdir): Use toolexeclibdir, not $(libdir).
++      * configure.ac (dbexecdir): Likewise.
++      * configure: Regenerated.
++
++      libjava/
++      * Makefile.am (jardir): Set to a target-specific location.
++      gcc/java/
++      * Make-lang.in: Adjust to match.
++
++2009-02-09  Mark Mitchell  <mark@codesourcery.com>
++
++      Backport:
++      libffi/
++      2008-05-09  Julian Brown  <julian@codesourcery.com>
++      * Makefile.am (LTLDFLAGS): New.
++      (libffi_la_LDFLAGS): Use above.
++      * Makefile.in: Regenerate.
++      boehm-gc/
++      2009-02-09  Mark Mitchell  <mark@codesourcery.com>
++      * Makefile.am (LTLDFLAGS): New variable.
++      (LINK): Use it.
++      * Makefile.in: Regenerated.
++      libjava/
++      2009-02-09  Mark Mitchell  <mark@codesourcery.com>
++      * Makefile.am (LTLDFLAGS): Define.
++      (GCJLINK): Use it.
++      (LIBLINK): Likewise.
++      * Makefile.in: Regenerated.
++      2009-02-09  Mark Mitchell  <mark@codesourcery.com>
++      * configure.ac: Define enable_sjlj_exceptions
++      appropriately under the ARM EH ABI.
++      * configure: Regenerated.
++      PR other/5303
++      * addr2name.awk: Remove.
++      * Makefile.am (bin_SCRIPTS): Remove addr2name.awk.
++      * Makefile.in: Regenerated.
++
++2009-02-05  Sandra Loosemore  <sandra@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (struct minipool_fixup): Split mode field into
++      value_mode and ref_mode.
++      (add_minipool_forward_ref): Use value_mode of fixup.
++      (add_minipool_backward_ref): Likewise.
++      (push_minipool_fix): Pass both value_mode and ref_mode as parameters,
++      and store them in the fixup.
++      (note_invalid_constants): Adjust arguments to push_minipool_fix.
++      (arm_reorg): Use ref_mode of fixup.
++
++2009-02-04  Andrew Jenner  <andrew@codesourcery.com>
++
++        gcc/
++        * config.gcc: Handle arm-montavista-linux-gnueabi,
++        mips-montavista-linux-gnu, mips64octeon*-montavista-elf* and
++        powerpc-montavista-linux-gnu.
++        * config/rs6000/t-montavista-linux: New file.
++        * config/rs6000/montavista-linux.h: New file.
++        * config/arm/t-montavista-linux: New file.
++        * config/arm/montavista-linux.h: New file.
++        * config/mips/t-montavista-linux: New file.
++        * config/mips/t-montavista-elf: New file.
++        * config/mips/montavista-linux.h: New file.
++
++        libgcc/
++        * config.host: Handle mips64octeon-montavista-elf*.
++
++2009-02-04  Catherine Moore  <clm@codesourcery.com>
++
++      Backport:
++
++      2009-02-02  Catherine Moore  <clm@codesourcery.com>
++
++      * sde.h (SUBTARGET_ARM_SPEC): Don;t assemble -fpic code as
++      -mabicalls.
++
++2009-02-03  Kazu Hirata  <kazu@codesourcery.com>
++
++      * release-notes-csl.xml: Add a release note for improved
++      multiplication.c
++
++2009-02-03  Kazu Hirata  <kazu@codesourcery.com>
++
++      gcc/
++      * expmed.c (synth_mult): When trying out a shift, pass the result
++      of a signed shift.
++
++2009-02-03  Andrew Stubbs  <ams@codesourcery.com>
++
++      gcc/
++      * config.gcc (sh-*): Add --enable-extra-sgxxlite-multilibs option to
++      enable uclibc multilibs.
++      * config/sh/cs-sgxxlite-linux.h: New file.
++      * config/sh/t-sgxxlite-linux: New file.
++
++2009-02-03  Andrew Stubbs  <ams@codesourcery.com>
++
++      gcc/
++      * config/sh/linux-unwind.h: Disable when inhibit_libc is defined.
++
++2009-02-03  Andrew Stubbs  <ams@codesourcery.com>
++
++      gcc/
++      * config.gcc (sh-*-*): Add sysroot-suffix.h to tm_file.
++      Add t-sysroot-suffix to tmake_file.
++
++2009-02-03  Kazu Hirata  <kazu@codesourcery.com>
++
++      config/
++      * mh-mingw: Add a comment.
++
++      libiberty/
++      * cygpath.c (msvcrt_dll): Change the return type to HMODULE.
++      (msvcrt_fopen): Use HMODULE for the return value from msvcrt_dll.
++
++2009-02-03  Andrew Stubbs  <ams@codesourcery.com>
++
++      gcc/
++      * configure.ac: Add new AC_SUBST for TM_ENDIAN_CONFIG,
++      TM_MULTILIB_CONFIG and TM_MULTILIB_EXCEPTIONS_CONFIG.
++      * configure: Regenerate.
++      * Makefile.in: Add variables TM_ENDIAN_CONFIG, TM_MULTILIB_CONFIG
++      and TM_MULTILIB_EXCEPTIONS_CONFIG.
++      * config.gcc (sh-*-*): Switch to using TM_ENDIAN_CONFIG,
++      TM_MULTILIB_CONFIG, and TM_MULTILIB_EXCEPTIONS_CONFIG.
++      Don't add default cpu to multilib list unnecessarily, but do enable
++      the relevant compiler option..
++      Add support for --with-multilib-list=none, and
++      --with-multilib-list=!<somelib> to supress unwanted multilibs.
++      Remove use_fixproto=yes.
++      * config/sh/t-sh (DEFAULT_ENDIAN, OTHER_ENDIAN): New variables.
++      (MULTILIB_ENDIAN, MULTILIB_CPUS): Delete variables.
++      (MULTILIB_OPTIONS): Redefine using OTHER_ENDIAN and
++      TM_MULTILIB_CONFIG.
++      (MULTILIB_EXCEPTIONS): Add TM_MULTILIB_EXCEPTIONS_CONFIG.
++      (MULTILIB_OSDIRNAMES): New variable.
++      * config/sh/t-1e: Delete file.
++      * config/sh/t-mlib-sh1: Delete file.
++      * config/sh/t-mlib-sh2: Delete file.
++      * config/sh/t-mlib-sh2a: Delete file.
++      * config/sh/t-mlib-sh2a-nofpu: Delete file.
++      * config/sh/t-mlib-sh2a-single: Delete file.
++      * config/sh/t-mlib-sh2a-single-only: Delete file.
++      * config/sh/t-mlib-sh2e: Delete file.
++      * config/sh/t-mlib-sh3e: Delete file.
++      * config/sh/t-mlib-sh4: Delete file.
++      * config/sh/t-mlib-sh4-nofpu: Delete file.
++      * config/sh/t-mlib-sh4-single: Delete file.
++      * config/sh/t-mlib-sh4-single-only: Delete file.
++      * config/sh/t-mlib-sh4a: Delete file.
++      * config/sh/t-mlib-sh4a-nofpu: Delete file.
++      * config/sh/t-mlib-sh4a-single: Delete file.
++      * config/sh/t-mlib-sh4a-single-only: Delete file.
++      * config/sh/t-mlib-sh4al: Delete file.
++      * config/sh/t-mlib-sh5-32media: Delete file.
++      * config/sh/t-mlib-sh5-32media-nofpu: Delete file.
++      * config/sh/t-mlib-sh5-64media: Delete file.
++      * config/sh/t-mlib-sh5-64media-nofpu: Delete file.
++      * config/sh/t-mlib-sh5-compact: Delete file.
++      * config/sh/t-mlib-sh5-compact-nofpu: Delete file.
++      * config/sh/t-linux: Don't override MULTILIB_EXCEPTIONS.
++
++2009-02-03  Andrew Stubbs  <ams@codesourcery.com>
++
++      gcc/
++      * config/print-sysroot-suffix.sh: Add support for MULTILIB_ALIASES.
++      * config/t-sysroot-suffix: Pass MULTILIB_ALIASES.
++
++2009-02-03  Andrew Stubbs  <ams@codesourcery.com>
++
++      gcc/
++      * config/arm/print-sysroot-suffix.sh: Move to ...
++      * config/print-sysroot-suffix.sh: ... here.
++      Remove all MULTILIB_ALIASES to make it suitable for upstream
++      submission.
++      * config/arm/t-sysroot-suffix: Move to ...
++      * config/t-sysroot-suffix: ... here.
++      Modify path to print-sysroot-suffix.sh.
++      Remove all MULTILIB_ALIASES.
++      * config.gcc: Modify paths to print-sysroot-suffix.sh.
++
++2009-01-30  Andrew Stubbs  <ams@codesourcery.com>
++
++      gcc/libstdc++-v3/
++      * config/cpu/sh/atomicity.h: Put the SH4A specific functions in the
++      __gnu_cxx namespace.  Remove "static inline".
++
++2009-01-29  Kazu Hirata  <kazu@codesourcery.com>
++
++      * expmed.c (shiftsub_cost): Rename to shiftsub0_cost.
++      (shiftsub1_cost): New.
++      (init_expmed): Compute shiftsub1_cost.
++      (synth_mult): Optimize multiplications by constants of the form
++      -(2^^m-1) for some constant positive integer m.
++
++2009-01-27  Nathan Sidwell  <nathan@codesourcery.com>
++
++      Issue #4428
++      gcc/
++      * config/mips/mips.md (jump): Deal with $gp restoration in delay
++      slot for o32 and o64 ABIs.
++
++      gcc/testsuite/
++      * gcc.target/mips/branch-2.c: New.
++
++      * release-notes-csl.xml: Add note.
++
++2009-01-26  Kazu Hirata  <kazu@codesourcery.com>
++
++      * release-notes-csl.xml: Mention performance improvements for ARM.
++
++      Backport from mainline:
++      2009-01-13  Richard Earnshaw  <rearnsha@arm.com>
++
++      * arm.c (struct processors): Pass for speed down into cost helper
++      functions.
++      (const_ok_for_op): Handle COMPARE and inequality nodes.
++      (arm_rtx_costs_1): Rewrite.
++      (arm_size_rtx_costs): Update prototype.
++      (arm_rtx_costs): Pass speed down to helper functions.
++      (arm_slowmul_rtx_costs): Rework cost calculations.
++      (arm_fastmul_rtx_costs, arm_xscale_rtx_costs): Likewise.
++      (arm_9e_rtx_costs): Likewise.
++
++2009-01-26  Julian Brown  <julian@codesourcery.com>
++
++      Issue #4515
++
++      gcc/
++      * config/arm/ieee754-df.S (cmpdf2): Avoid writing below SP.
++      * config/arm/ieee754-sf.S (cmpsf2): Likewise.
++
++2009-01-23  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #3989
++
++      * release-notes-csl.xml (Thumb half-precision floating point bug fix):
++      New note.
++
++      gcc/
++      * config/arm/arm.c (dump_minipool): Use size of mode, not padded size,
++      in switch that controls whether to emit padding.
++
++2009-01-20  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #4289
++
++      fixincludes/
++      * server.c (run_shell): Quote directory name passed to cd.
++
++2009-01-14  Nathan Froyd  <froydnj@codesourcery.com>
++
++      * release-notes-csl.xml: Add note.  Correct TARGET line for
++      previous note.
++
++      gcc/
++      * tree-ssa-remove-local-statics.c (maybe_discover_new_declaration):
++      Avoid variables with aggregate and vector types.
++      (maybe_create_new_variable): Create the var_ann prior to marking
++      the symbol for renaming.
++
++      gcc/testsuite/
++      * gcc.dg/remove-local-statics-15.c: New test.
++      * gcc.dg/remove-local-statics-16.c: New test.
++
++2009-01-14  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/sparc/sol2-bi.h (LINK_ARCH64_SPEC_BASE): Use %R with
++      absolute library paths.
++
++2009-01-12  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/sol2.h (LINK_ARCH32_SPEC_BASE): Use %R with absolute
++      library paths.
++
++2009-01-06  Andrew Stubbs  <ams@codesourcery.com>
++          Nathan Sidwell  <nathan@codesourcery.com>
++
++      Issue #4436
++
++      gcc/
++      * config/rs6000/rs6000.c (rs6000_override_options): Don't override
++      an explicit -mno-isel.
++
++2009-01-02  Nathan Sidwell  <nathan@codesourcery.com>
++
++      Issue 4361
++      gcc/
++      * config/m68k/m68k-devices.def: Add 51jm.
++
++      * release-notes-csl.xml: Document 51jm addition.
++
++2008-12-21  Mark Mitchell  <mark@codesourcery.com>
++
++      * release-notes-csl.xml: Adjust wording of last note.
++
++2008-12-18  Mark Mitchell  <mark@codesourcery.com>
++
++      Issue #4399
++      * release-notes-csl.xml: Document.
++      gcc/
++      * tree-ssa-pre.c (compute_antic): Correct loop bounds.
++
++2008-12-19  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.target/powerpc/20081204-1.c: Require powerpc_spe_ok.
++
++2008-12-19  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport from FSF:
++
++      gcc/testsuite/
++      2008-03-13  Uros Bizjak  <ubizjak@gmail.com>
++      * gcc.dg/vect/vect-align-2.c: Remove dg-do run directive.
++      (main): Call check_vect.
++
++2008-12-18  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport from FSF:
++
++      gcc/
++      2008-12-18  Joseph Myers  <joseph@codesourcery.com>
++      * config/rs6000/rs6000.c (rs6000_generate_compare): Condition
++      choice of e500 comparison instructions on flag_finite_math_only &&
++      !flag_trapping_math, not flag_unsafe_math_optimizations.
++      * config/rs6000/rs6000.md (abstf2): Condition choice of e500
++      instructions on flag_finite_math_only && !flag_trapping_math, not
++      flag_unsafe_math_optimizations.
++      (bltgt, sltgt): Disable for TARGET_HARD_FLOAT && !TARGET_FPRS.
++      * config/rs6000/spe.md (cmpsfeq_gpr, tstsfeq_gpr, cmpsfgt_gpr,
++      tstsfgt_gpr, cmpsflt_gpr, tstsflt_gpr, cmpdfeq_gpr, tstdfeq_gpr,
++      cmpdfgt_gpr, tstdfgt_gpr, cmpdflt_gpr, tstdflt_gpr, cmptfeq_gpr,
++      tsttfeq_gpr, cmptfgt_gpr, tsttfgt_gpr, cmptflt_gpr, tsttflt_gpr):
++      Condition choice of comparison instructions on
++      flag_finite_math_only && !flag_trapping_math, not
++      flag_unsafe_math_optimizations.
++
++2008-12-18  Catherine Moore  <clm@codesourcery.com>
++
++      Issue #4439
++
++      * release-notes-csl.xml: Document -march= bug fix.
++
++2008-12-18  Catherine Moore  <clm@codesourcery.com>
++
++      Issue #4334
++
++      Backport:
++
++      gcc/
++      2008-11-23  Richard Sandiford  <rsandiford@googlemail.com>
++
++      * config/mips/mips.c (mips_legitimize_address): Handle
++      illegitimate CONST_INT addresses.
++
++
++      2008-06-01  Richard Sandiford  <rdsandiford@googlemail.com>
++
++      * config/mips/mips.c (mips_valid_offset_p): New function.
++
++2008-12-18  Catherine Moore  <clm@codesourcery.com>
++
++      Issue #4439
++
++      gcc/
++      * config/mips/mips.h (MIPS_ISA_LEVEL_SPEC): Remove extraneous
++      colon.
++      
++2008-12-16  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/i386/cs-linux.opt (mrh73, mrhel3): New options.
++      * config/i386/cs-linux.h (SYSROOT_SUFFIX_SPEC): Handle new
++      options.
++      * config/i386/t-cs-linux (MULTILIB_OPTIONS, MULTILIB_DIRNAMES,
++      MULTILIB_OSDIRNAMES): Update for new options.
++      (MULTILIB_EXCEPTIONS): Define.
++
++2008-12-05  Catherine Moore  <clm@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc-target/mips/mips-nonpic/mips-nonpic.h: New.
++      * gcc-target/mips/mips-nonpic/nonpic-[0-9]*.c: Rename to
++      main-[0-9]*.c.
++      * gcc-target/mips/mips-nonpic/mips-nonpic.exp: Run
++      main-*.c tests.
++      * gcc-target/mips/mips-nonpic/pic-*.c: Include mips-nonpic.h.
++      * gcc-target/mips/mips-nonpic/nonpic-*.c: Likewise.
++
++2008-12-05  Catherine Moore  <clm@codesourcery.com>
++
++      * gcc/config/mips/MIPS-TOOLCHAIN.pdf: Remove.
++
++2008-12-04  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/rs6000/rs6000.md (move_from_CR_gt_bit): Enable for
++      TARGET_HARD_FLOAT && !TARGET_FPRS, not TARGET_E500.
++      * config/rs6000/spe.md (e500_cr_ior_compare): Likewise.
++
++      gcc/testsuite/
++      * gcc.target/powerpc/20081204-1.c: New test.
++
++2008-12-03  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.dg/vect/vect-shift-2.c, gcc.dg/vect/vect-shift-3.c: New.
++      * lib/target-supports.exp (check_effective_target_vect_shift): New
++      function.
++
++2008-12-02  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      Issue #4343
++      * release-notes-csl.xml: Document right shift fix.
++
++      Backport from trunk:
++
++      gcc/
++      2008-09-25  Dorit Nuzman  <dorit@il.ibm.com>
++
++      * tree-vectorizer.c (vect_is_simple_use): Fix indentation.
++      * tree-vect-transform.c (vect_get_constant_vectors): Use vectype
++      instead of vector_type for constants. Take computation out of loop.
++      (vect_get_vec_def_for_operand): Use only vectype for constant case,
++      and use only vector_type for invariant case.
++      (get_initial_def_for_reduction): Use vectype instead of vector_type.
++
++      gcc/testsuite/
++      2008-09-25  Dorit Nuzman  <dorit@il.ibm.com>
++
++      * gcc.dg/vect/ggc-pr37574.c: New test.
++      * gcc.dg/vect/vect.exp: Compile some tests with ggc flags.
++
++2008-12-02  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.target/m68k/tls-1.c: Rename to tls-ie.c; fix.
++      * gcc.target/m68k/tls-2.c: Rename to tls-le.c; fix.
++      * gcc.target/m68k/tls-1-pic.c: Rename to tls-gd.c; fix.
++      * gcc.target/m68k/tls-2-pic.c: Rename to tls-ld.c; fix.
++      * gcc.target/m68k/xtls-1.c: Rename to tls-ie-xgot.c; fix.
++      * gcc.target/m68k/xtls-2.c: Rename to tls-le-xtls.c; fix.
++      * gcc.target/m68k/xtls-1-pic.c: Rename to tls-gd-xgot.c; fix.
++      * gcc.target/m68k/xtls-2-pic.c: Split into tls-ld-xgot.c,
++      tls-ld-xtls.c and tls-ld-xgot-xtls.c; fix.
++
++      gcc/
++      * config/m68k/m68k.md (UNSPEC_XGOT, UNSPEC_TLS, UNSPEC_XTLS): Replace
++      with ...
++      (UNSPEC_RELOC, UNSPEC_RELOC32): New.
++      * config/m68k/m68k.opt: Fix documentation.
++      * config/m68k/m68k.c (m68k_unwrap_symbol): Update.
++      (m68k_decompose_address): Update comment.
++      (enum m68k_tls_reloc): Rename to m68k_reloc; add RELOC_GOT value.
++      (TLS_RELOC_P): New macro.
++      (m68k_get_tls_unspec): Rewrite, rename to m68k_wrap_symbol.
++      (m68k_move_to_reg, m68k_wrap_symbol_into_got_ref): New static
++      functions.
++      (legitimize_pic_address): Use them, update comment.
++      (m68k_call_tls_get_addr, m68k_call_read_tp): Rewrite.
++      (m68k_legitimize_tls_address): Rewrite, fix code generation for
++      initial exec model.
++      (m68k_tls_referenced_p_1, m68k_tls_mentioned_p): Update.
++      (m68k_legitimize_address): Remove excessive assert.
++      (m68k_get_tls_decoration): Rename to m68k_get_reloc_decoration, update.
++      (m68k_output_addr_const_extra): Update.
++      (sched_attr_op_type): Update comment.
++
++2008-12-01  Catherine Moore  <clm@codesourcery.com>
++
++      * gcc/config/mips/MIPS-TOOLCHAIN.pdf: New.
++
++2008-11-30  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Fix bugs in TLS code generation, add -mxtls option, add tests.
++      
++      gcc/
++      * config/m68k/predicates.md (symbolc_operand): Fix.
++      * config/m68k/m68k.md (UNSPEC_GOTOFF): Rename to UNSPEC_XGOT, update
++      all uses.
++      (UNSPEX_XTLS): New constant.
++      (addsi3_5200): Handle XTLS symbols, indent.
++      * config/m68k/m68k-protos.h (m68k_unwrap_symbol): Declare.
++      * config/m68k/m68k.opt (mxtls): New option.
++      * config/m68k/m68k.c (m68k_unwrap_symbol): New function.
++      (m68k_decompose_address): Handle TLS references.
++      (m68k_get_gp): Move to a better place.
++      (legitimize_pic_address): Update, cleanup, add REG_EQUAL note when
++      appropriate.
++      (m68k_get_tls_unspec): New function to unify generation of TLS
++      references.
++      (m68k_libcall_value_in_a0_p): New static variable.
++      (m68k_call_tls_get_addr, m68k_call_m68k_read_tp): Rewrite.
++      (m68k_legitimize_tls_address): Cleanup, use m68k_get_tls_unspec.
++      (m68k_tls_referenced_p_1, m68k_tls_mentioned_p): Handle UNSPEC_XTLS.
++      (m68k_output_addr_const_extra): Handle UNSPEC_XTLS.
++      (print_operand_address): Update.
++      (m68k_libcall_value): Support calls to TLS helpers.
++      (m68k_sched_attr_op_type): Update.
++      * config/m68k/constraints.md (Cu): New constraint.
++      
++      gcc/testsuite/
++      * gcc.target/m68k/tls-1.c: New test.
++      * gcc.target/m68k/tls-1-pic.c: New test.
++      * gcc.target/m68k/tls-2.c: New test.
++      * gcc.target/m68k/tls-2-pic.c: New test.
++      * gcc.target/m68k/xtls-1.c: New test.
++      * gcc.target/m68k/xtls-1-pic.c: New test.
++      * gcc.target/m68k/xtls-2.c: New test.
++      * gcc.target/m68k/xtls-2-pic.c: New test.
++
++2008-11-29  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport from FSF:
++
++      gcc/testsuite/
++      2008-11-29  Joseph Myers  <joseph@codesourcery.com>
++      * g++.dg/cpp/stringop-1.C: New test.
++
++      libcpp/
++      2008-11-29  Joseph Myers  <joseph@codesourcery.com>
++      * lex.c (cpp_token_len): Use 6 as default length.
++
++2008-11-26  Catherine Moore  <clm@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.target/mips/vr-mult-1.c: Require hard-float.
++      * gcc.target/mips/branch-cost-1.c: Likewise.
++      * gcc.target/mips/movcc-2.c: Likewise.
++      * gcc.target/mips/rsqrt-3.c: Likewise.
++      * gcc.target/mips/vr-mult-2.c: Likewise.
++      * gcc.target/mips/branch-cost-2.c: Likewise.
++      * gcc.target/mips/movcc-3.c: Likewise.
++      * gcc.target/mips/nmadd-1.c: Likewise.
++      * gcc.target/mips/nmadd-2.c: Likewise.
++      * gcc.target/mips/movcc-1.c: Likewise.
++      * gcc.target/mips/nmadd-3.c: Likewise.
++
++2008-11-24  Catherine Moore  <clm@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.target/mips/mips-nonpic/mips-nonpic.exp: Don't run for mips16.
++
++2008-11-24  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config/rs6000/rs6000.c (rs6000_savres_strategy): Always use
++      inline saves and restores when compiling position-independent code.
++
++2008-11-24  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config.gcc (powerpc-*-elf*): Only include e500mc-specific files
++      if --enable-powerpc-e500mc-elf was specified.
++
++2008-11-20  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      PR35018
++      
++      gcc/
++      * config/m68k/m68k.md (addsi_lshrsi_31): Rename to
++      addsi_lshrsi_31_m68k, don't use it for ColdFire.
++      Add (define_expand "addsi_lshrsi_31").
++      (addsi_lshrsi_31_cf): New, almost identical copy of extendsidi2_m68k.
++      
++      gcc/testsuite/
++      * gcc.target/m68k/pr35018.c: New.
++
++2008-11-20  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/arm/thumb2.md (thumb2_casesi_internal,
++      thumb2_casesi_internal_pic): Use earlyclobber for scratch operand
++      4.
++
++2008-11-19  Andrew Stubbs  <ams@codesourcery.com>
++
++      Issue #3283
++
++      gcc/
++      PR target/36133
++      * config/m68k/m68k.h (CC_OVERFLOW_UNUSABLE, CC_NO_CARRY): New defines.
++      * config/m68k/m68k.c (notice_update_cc): Set cc_status properly for
++      shift instructions.
++      * config/m68k/m68k.md: Adjust all conditional branches that use the
++      carry and overflow flags so they understand CC_OVERFLOW_UNUSABLE.
++
++      gcc/testsuite/
++      PR target/36133
++      * gcc.target/m68k/pr36133.c: New test.
++
++2008-11-17  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config/rs6000/rs6000.c (rs6000_emit_epilogue): Adjust
++      computation of restore_lr.  Duplicate restoration of LR and
++      execute the appropriate one depending on whether GPRs are being
++      restored inline.
++
++2008-11-17  Catherine Moore  <clm@codesourcery.com>
++
++      * config/mt-sde: Revert last patch.
++
++2008-11-17  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/t-symbian (MULTILIB_EXCEPTIONS, MULTILIB_MATCHES,
++      MULTILIB_ALIASES): Define.
++
++2008-11-17  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config/rs6000/rs6000.c (rs6000_savres_routine_sym): Fix
++      computation for cache selector.  Mark the generated symbol as a
++      function.
++      (rs6000_emit_prologue): Correct condition.
++      * config/rs6000/rs6000.md (*save_gpregs_<mode>): Use explicit
++      match for register 11.
++      (*save_fpregs_<mode>): Likewise.
++      (*restore_gpregs_<mode>): Likewise.
++      (*return_and_restore_gpregs_<mode>): Likewise.
++      (*return_and_restore_fpregs_<mode>): Likewise.
++      * config/rs6000/spe.md (*save_gpregs_spe): Use explicit match for
++      register 11.
++      (*restore_gpregs_spe): Likewise.
++      (*return_and_restore_gpregs_spe): Likewise.
++
++2008-11-14  Catherine Moore  <clm@codesourcery.com>
++
++      * config/mt-sde (CFLAGS_FOR_TARGET): Add -mexplicit-relocs.
++      (CXXFLAGS_FOR_TARGET): Likewise.
++
++2008-11-14  Maxim Kuvyrkov  <maxim@codesourcery.com>
++          Andrew Stubbs  <ams@codesourcery.com>
++          Gunnar Von Boehn  <gunnar@genesi-usa.com>
++
++      Issue #3284
++
++      gcc/
++      PR target/36134
++      * config/m68k/m68k.md (addsi3_5200): Add a new alternative preferring
++      the shorter LEA insn over ADD.L where possible.
++
++      gcc/testsuite/
++      PR target/36134
++      * gcc.target/m68k/pr36134.c: New test.
++
++2008-11-13  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/mips/sicortex.h, config/mips/t-sicortex: New.
++      * config.gcc (mips64el-sicortex-linux-gnu): Use these config
++      files.
++
++2008-11-13  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config.gcc (powerpc*-elf*): Configure for e500mc.
++      * config/rs6000/t-ppc-e500mc: New.
++      * config/rs6000/e500mc.h: New.
++
++2008-11-12  Nathan Sidwell  <nathan@codesourcery.com>
++
++      Issue 4221/1
++      * release-notes-csl.xml: Document removal of default -mfix-ice9a.
++
++2008-11-11  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * function.c (alignment_for_aligned_arrays): Use floor_log2
++      instead of CLZ_HWI.
++
++2008-11-10  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Issue #4082
++
++      gcc/
++      * config/rs6000/rs6000.c (rs6000_legitimize_address): Check for
++      non-word-aligned REG+CONST addressing.
++
++      gcc/testsuite/
++      * gcc.target/powerpc/20081104-1.c: New test.
++
++2008-11-07  Julian Brown  <julian@codesourcery.com>
++
++      Issue #4085
++
++      gcc/
++      * combine.c (find_split_point): Disable patch from PR27971.
++
++2008-11-06  Kazu Hirata  <kazu@codesourcery.com>
++
++      Issue 4029
++      gcc/
++      Backport:
++      2008-11-06  Kazu Hirata  <kazu@codesourcery.com>
++      PR target/35574
++      * config/sparc/predicates.md (const_double_or_vector_operand):
++      New.
++      * config/sparc/sparc.c (sparc_extra_constraint_check): Handle the
++      'D' constraint.
++      * config/sparc/sparc.h: Document the 'D' constraint.
++      * config/sparc/sparc.md (*movdf_insn_sp32_v9, *movdf_insn_sp64):
++      Use the 'D' constraint in addition to 'F' in some alternatives.
++      (DF splitter): Generalize for V64mode.
++      * doc/md.texi (SPARC): Document the 'D' constraint.
++
++      * release-notes-csl.xml: Add a release note for the fix above.
++
++2008-11-06  Andrew Stubbs  <ams@codesourcery.com>
++
++      Issue #3120
++
++      gcc/
++      * release-notes-csl.xml: -pg support for ARM EABI.
++
++2008-10-29  Andrew Stubbs  <ams@codesourcery.com>
++
++      Issue 3120
++
++      gcc/
++      * config/arm/linux-eabi.h (ARM_FUNCTION_PROFILER): Delete.
++      (SUBTARGET_FRAME_POINTER_REQUIRED): Delete.
++      * config/arm/bpabi.h (PROFILE_HOOK): New undef.
++
++      Back-port from mainline:
++      2008-10-08  Paul Brook  <paul@codesourcery.com>
++      gcc/
++      * config/arm/bpabi.h (ARM_FUNCTION_PROFILER): Define new EABI
++      compatible profiler (__gnu_mcount_nc).
++      (SUBTARGET_FRAME_POINTER_REQUIRED): Define.
++
++2008-10-27  Catherine Moore  <clm@codesourcery.com>
++
++      Issue #4105
++
++      Backport:
++
++      gcc/
++      2008-10-22  Chao-ying Fu  <fu@mips.com>
++
++      * config/mips/mips.opt (msmartmips): Accept -mno-smartmips.
++
++2008-10-24  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      gcc/
++      * config/m68k/m68k.c (m68k_output_dwarf_dtprel): Use .long instead of
++      .word for TLS debug information.
++
++2008-10-24  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config/rs6000/rs6000.c (no_global_regs_above): Fix precedence
++      problem.
++
++2008-10-23  Kazu Hirata  <kazu@codesourcery.com>
++
++      Issue 3852
++      gcc/
++      * config/arm/t-asa (MULTILIB_EXTRA_OPTS): New.
++
++2008-10-22  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/t-uclinux-eabi (MULTILIB_EXCEPTIONS): Exclude bogus ARM
++      multilib.
++
++2008-10-21  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * doc/invoke.texi: Document -mfix-cortex-m3-ldrd.
++      * config/arm/arm.c (arm_override_options): Set fix_cm3_ldrd
++      if Cortex-M3 cpu is selected.
++      (output_move_double): Avoid overlapping base register and first
++      destination register when fix_cm3_ldrd.
++      * config/arm/arm.opt: Add -mfix-cortex-m3-ldrd.
++      * config/arm/t-cs-eabi: Add -mfix-cortex-m3-ldrd to Thumb-2 multilib.
++      * config/arm/t-arm-elf: Ditto.
++      * config/arm/t-uclinux-eabi: Ditto.
++
++2008-10-21  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.md (consttable_4): Handle (high ...).
++
++2008-10-16  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config.gcc (powerpc-*-eabi*): Add rs6000/t-cs-eabi when
++      --enable-extra-sgxx-multilibs is passed to configure.
++      * config/rs6000/t-ppcgas (MULTILIB_OPTIONS): Remove te500mc.
++      (MULTILIB_DIRNAMES): Likewise.
++      (MULTILIB_EXCEPTIONS): Likewise.
++      * config/rs6000/t-cs-eabi: New file.
++
++2008-10-16  Julian Brown  <julian@codesourcery.com>
++
++      Issue #4039
++
++      gcc/
++      * config/arm/neon.md (movmisalign<mode>): Use expander/unnamed insn
++      for both D & Q variants. Don't permit both operands to be mems.
++      * release-notes-csl.xml (Misaligned NEON memory accesses): Add note.
++
++2008-10-15  Catherine Moore  <clm@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc-target/mips/octeon-1.c (dg-mips-options): Use -mno-abicalls.
++      * gcc-target/mips/octeon-5.c (dg-mips-options): Likewise.
++      * gcc-target/mips/octeon-6.c (dg-mips-options): Likewise.
++      * gcc-target/mips/octeon-18.c (dg-mips-options): Likewise.
++      * gcc-target/mips/octeon-19.c (dg-mips-options): Likewise.
++      * gcc-target/mips/octeon-23.c (dg-mips-options): Likewise.
++      * gcc-target/mips/octeon-28.c (dg-mips-options): Likewise.
++      * gcc-target/mips/octeon-34.c (dg-mips-options): Likewise.
++      * gcc-target/mips/octeon-37.c (dg-mips-options): Likewise.
++      * gcc-target/mips/octeon-43.c (dg-mips-options): Likewise.
++      * gcc-target/mips/octeon-44.c (dg-mips-options): Likewise.
++      * gcc-target/mips/octeon-49.c (dg-mips-options): Likewise.
++      * gcc-target/mips/octeon-54.c (dg-mips-options): Likewise.
++
++2008-10-14  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #4017
++
++      * release-notes-csl.xml (Linker script option syntax): New note.
++
++      gcc/
++      * config.gcc (powerpc-*): Make t-ppcgas imply usegas.h.
++      * config/svr4.h (SVR4_ASM_SPEC): New.
++      (ASM_SPEC): Inherit from SVR4_ASM_SPEC.
++      * config/rs6000/sysv4.h (ASM_SPEC): Inherit from SVR4_ASM_SPEC.
++      
++      gcc/doc/
++      * invoke.texi (Option Summary): Add -T to linker options.
++      (Link Options): Document -T.
++      
++2008-10-13  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config/rs6000/rs6000.c (rs6000_file_start): Output gnu
++      attribute for struct return convention.
++
++2008-10-13  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.h (fputype): Remove stray comma.
++
++2008-10-13  Andrew Stubbs  <ams@codesourcery.com>
++
++      Issue #3884
++
++      gcc/
++      * doc/invoke.texi (PowerPC Options): -meabi option no longer places
++      __eabi function in main.
++
++2008-10-12  Mark Mitchell  <mark@codesourcery.com>
++
++      Issue #3224
++      * release-notes-csl.xml: Mention OpenMP add-on.
++
++2008-10-12  Catherine Moore  <clm@codesourcery.com>
++
++      Issue # 3903
++
++      Backport:
++
++      2008-07-28  Ilie Garbacea  <ilie@mips.com>
++                  Chao-ying Fu  <fu@mips.com>
++
++      * configure.tgt: Enable futex for MIPS.
++      * config/linux/mips/futex.h: New file.
++
++2008-10-12  Catherine Moore  <clm@codesourcery.com>
++
++      gcc/
++      * config/mips/mips.opt (muclibc): New option entry.
++      * config/mips/mips.c (mips_override_options): Disable
++      __thread support when the -muclibc option is used.
++
++2008-10-11  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      M68K NPTL support.
++      gcc/
++      * configure.ac (m68k-*-*): Check if binutils support TLS.
++      * configure: Regenerate.
++      * config/m68k/predicates.md (symbolic_operand): Handle UNSPECs.
++      * config/m68k/m68k.md (UNSPEC_TLS): New constant.
++      (movsi): Handle TLS symbols.
++      * config/m68k/m68k-protos.h (m68k_legitimize_tls_address): Declare.
++      (m68k_tls_referenced_p, m68k_tls_mentioned_p): Declare.
++      (m68k_legitimize_address): Declare.
++      * config/m68k/m68k.c (ggc.h): Include.
++      (m68k_output_dwarf_dtprel): Implement hook.
++      (TARGET_HAVE_TLS, TARGET_ASM_OUTPUT_DWARF_DTPREL): Define.
++      (m68k_expand_prologue): Load GOT pointer when function needs it.
++      (m68k_illegitimate_symbolic_constant_p): Handle TLS symbols.
++      (m68k_legitimate_constant_address_p): Same.
++      (legitimize_pic_address): Same.
++      (enum m68k_tls_reloc): New.
++      (m68k_tls_get_addr, m68k_get_tls_get_addr, m68k_get_gp)
++      (m68k_call_tls_get_addr, m68k_read_tp, m68k_get_m68k_read_tp)
++      (m68k_call_m68k_read_tp): Helper variables and functions for ...
++      (m68k_legitimize_tls_address): Handle TLS references.
++      (m68k_tls_symbol_p, m68k_tls_referenced_p_1, m68k_tls_referenced_p)
++      (m68k_tls_mentioned_p): New functions.
++      (m68k_legitimize_address): Rewrite LEGITIMIZE_ADDRESS macro, handle
++      TLS symbols.
++      (m68k_get_tls_decoration): New static function.
++      (m68k_output_addr_const_extra): Handle UNSPEC_TLS.
++      (m68k_output_dwarf_dtprel): Implement hook.
++      (gt-m68k.h): Include.
++      * config/m68k/m68k.h (LEGITIMATE_PIC_OPERAND_P): Support TLS.
++      (LEGITIMATE_ADDRESS): Move logic to m68k.c:m68k_legitimize_address.
++
++2008-10-11  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      gcc/
++      * config/m68k/lb1sf68.asm (PICCALL, PICJUMP): Use GOT instead of
++      PC-relative addressing when compiling for uclinux PIC.
++
++2008-10-09  Catherine Moore  <clm@codesourcery.com>
++
++      Issue #3312
++
++      gcc/
++      * config/mips/mips.h ( DSP_CTRL_REG_FIRST): Define.
++      (DSP_CTRL_REG_LAST): Define.
++      * config/mips/mips.c (mips_conditional_register_usage): Handle
++      DSP registers.
++
++2008-10-08  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      * release-notes-csl.xml: Fix typo.
++
++2008-10-08  Nathan Sidwell  <nathan@codesourcery.com>
++          Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      * release-notes-csl.xml (Shared Libraries bug fix): New.
++
++      gcc/
++      * config/m68k/lb1sf68.asm (__cmpdf_internal, __cmpsf_internal): Hide.
++      (__cmpdf, __cmpsf): Use PIC call sequence.
++
++2008-10-07  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Issue #3988
++
++      * release-notes-csl.xml (Dynamic libraries and -Os bug fix): New.
++
++      gcc/
++      * config/rs6000/ppc-asm.h (HIDDEN_FUNC): New macro.
++      * config/rs6000/crtresfpr.asm, config/rs6000/crtresgpr.asm,
++      config/rs6000/crtresxfpr.asm, config/rs6000/crtresxgpr.asm,
++      config/rs6000/crtsavfpr.asm, config/rs6000/crtsavgpr.asm,
++      config/rs6000/e500crtres32gpr.asm,
++      config/rs6000/e500crtres64gpr.asm,
++      config/rs6000/e500crtres64gprctr.asm,
++      config/rs6000/e500crtrest32gpr.asm,
++      config/rs6000/e500crtrest64gpr.asm,
++      config/rs6000/e500crtresx32gpr.asm,
++      config/rs6000/e500crtresx64gpr.asm,
++      config/rs6000/e500crtsav32gpr.asm,
++      config/rs6000/e500crtsav64gpr.asm,
++      config/rs6000/e500crtsav64gprctr.asm,
++      config/rs6000/e500crtsavg32gpr.asm,
++      config/rs6000/e500crtsavg64gpr.asm,
++      config/rs6000/e500crtsavg64gprctr.asm: Use it.
++
++2008-10-07  Nathan Sidwell  <nathan@codesourcery.com>
++
++      * release-notes-csl.xml: Document it.
++
++      gcc/
++      * doc/invoke.texi (MIPS Options): Add ice9 arch.
++      * config/mips/mips.c (mips_cpu_info_table): Add ice9 arch.
++
++2008-10-03  Catherine Moore  <clm@codesourcery.com>
++
++        gcc/testsuite/
++      * gcc.target/mips/fix-ice9a-1.c: Disable for soft-float
++      multilibs.
++      * gcc.target/mips/fix-ice9a-1.c: Likewise.
++
++2008-10-03  Kazu Hirata  <kazu@codesourcery.com>
++
++      Backport:
++      gcc/testsuite/
++      2008-09-23  Eric Botcazou  <ebotcazou@adacore.com>
++
++      * gcc.dg/pragma-init-fini.c: Use dg-warning in lieu of dg-error.
++      * gcc.dg/pragma-align-2.c: Likewise.
++      * gcc.dg/format/cmn-err-1.c: Likewise.
++
++2008-10-02  Catherine Moore  <clm@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.target/mips/lazy-binding-1.c: Compile with -fpic.
++
++2008-10-02  Maciej W. Rozycki  <macro@codesourcery.com>
++
++      Issue #3673
++      gcc/testsuite/
++      * lib/target-supports.exp
++      (check_effective_target_arm_iwmmxt_ok): New procedure.
++      * gcc.dg/arm-mmx-1.c: Only run if arm_iwmmxt_ok.
++
++2008-09-29  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      2008-09-29  Joseph Myers  <joseph@codesourcery.com>
++      * ifcvt.c (noce_emit_store_flag): If using condition from original
++      jump, reverse it if if_info->cond was reversed.
++
++2008-09-29  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Issue #3922
++      * release-notes-csl.xml (Code generation bug fix): New.
++      gcc/
++      * config/m68k/m68k.md (extendsidi2): Rename to extendsidi2_m68k,
++      don't use it for ColdFire.  Add (define_expand "extendsidi2").
++      (extendsidi2_cf): New, almost identical copy of extendsidi2_m68k.
++      gcc/testsuite/
++      * gcc.c-torture/compile/20080929-1.c: New.
++
++2008-09-29  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      * release-notes-csl.xml (ColdFire M54455 support): Fix target.
++
++2008-09-25  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #3208
++
++      * release-notes-csl.xml (Half-precision floating point): New note.
++
++2008-09-25  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/fp16.c (__gnu_f2h_ieee, __gnu_h2f_ieee): Enable on
++      ARMv6-M.
++      * config/arm/t-bpabi (LIB2FUNCS_EXTRA): Remove fp16.c.
++      (LIB2FUNCS_STATIC_EXTRA): Add fp16.c.
++      * config/arm/t-symbian (LIB2FUNCS_EXTRA): Rename...
++      (LIB2FUNCS_STATIC_EXTRA): ... to this.
++      * config/arm/t-arm-softfp: Remove HFmode conversions.
++      * config/soft-fp/extendhfsf2.c: Revert HFmode suport.
++      * config/soft-fp/truncsfhf2.c: Ditto.
++      * config/soft-fp/README: Ditto.
++      * config/soft-fp/half.h: Ditto.
++
++2008-09-25  Sandra Loosemore  <sandra@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.dg/torture/arm-fp16-ops.h: Fix bogus tests.
++      * g++.dg/ext/arm-fp16/arm-fp16-ops.h: Ditto.
++
++2008-09-25  Julian Brown  <julian@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_hard_regno_mode_ok): Allow 4-word quantities
++      in core registers. Update comment.
++
++2008-09-25  Nathan Sidwell  <nathan@codesourcery.com>
++
++      * release-notes-csl.xml: Document ice9a option.
++
++2008-09-25  Julian Brown  <julian@codesourcery.com>
++
++      Issue #3800
++
++      gcc/testsuite/
++      * gcc.target/arm/eabi1.c (__eabi_uread4, __eabi_uwrite4)
++      (__eabi_uread8, __eabi_uwrite8): Change spellings of declarations
++      to...
++      (__aeabi_uread4, __aeabi_uwrite4, __aeabi_uread8, __aeabi_uwrite8):
++      These.
++
++2008-09-24  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/t-arm-softfp (softfp_extensions): Add hfsf.
++      (softfp_truncations): Add sfhf.
++      * config/arm/sfp-machine.h (_FP_NANFRAC_H, _FP_NANSIGN_H): Define.
++      * config/arm/fp16.c: New file.
++      * config/arm/t-bpabi (LIB2FUNCS_EXTRA): Add fp16.c.
++      * config/arm/t-symbian (LIB2FUNCS_EXTRA):  Add fp16.c.
++      * config/soft-fp/extendhfsf2.c: New file.
++      * config/soft-fp/truncsfhf2.c: New file.
++      * config/soft-fp/half.h: New file.
++      * config/soft-fp/README: HFmode routines do not come from gcc.
++
++2008-09-22  Daniel Gutson  <daniel@codesourcery.com>
++            Nathan Sidwell  <nathan@codesourcery.com>
++            Maciej W. Rozycki  <macro@codesourcery.com>
++
++      Issue #3634
++      gcc/
++      * config.gcc (all_defaults): Add fix-ice9a.
++      * config/mips/mips.c (mips_conditional_register_usage): Add $f30
++      and $f31 as appropriate as fixed registers.
++      * config/mips/mips.h (OPTION_DEFAULT_SPECS): Add -mfix-ice9a
++      handling.
++      (ASM_SPEC): Likewise.
++      * config/mips/mips.md (ice9a_stallnops): New mode attribute.
++      (ice9a_round): Likewise.
++      (ice9a_length_stall): Likewise.
++      (ice9a_length_round): Likewise.
++      (ice9a_length_both): Likewise.
++      (*mul<mode>3): Change condition.
++      (*mul<mode>3_fix_ice9a): New.
++      (*madd<mode>): Change condition.
++      (*madd<mode>_ice9a): New.
++      (*msub<mode>): Change condition.
++      (*msub<mode>_ice9a): New.
++      (*nmadd<mode>): Change condition.
++      (*nmadd<mode>_fastmath): Likewise.
++      (*nmadd<mode>_ice9a): New.
++      (*nmadd<mode>_fastmath_ice9a): New.
++      (*nmsub<mode>): Change condition.
++      (*nmsub<mode>_fastmath): Likewise.
++      (*nmsub<mode>_ice9a): New.
++      (*nmsub<mode>_fastmath_ice9a): Likewise.
++      (*recip<mode>3): Change condition and definition.  Move the SB1
++      fix to...
++      (*recip<mode>3_fix_sb1): ... this new pattern.
++      (*recip<mode>3_fix_ice9a): New.
++      (sqrt<mode>2): Change from define_insn to define_expand.  Move
++      the SB1 fix to...
++      (*sqrt<mode>2): New.
++      (*sqrt<mode>2_fix_sb1): ... this new pattern.
++      (*sqrt<mode>2_fix_ice9a): New.
++      (*rsqrt<mode>a): Change condition and definition.  Move the SB1
++      fix to...
++      (*rsqrt<mode>a_fix_sb1): ... this new pattern.
++      (*rsqrt<mode>a_fix_ice9a): New.
++      (*rsqrt<mode>b): Likewise *rsqrt<mode>a.
++      (*rsqrt<mode>b_fix_sb1): Likewise *rsqrt<mode>a_fix_sb1.
++      (*rsqrt<mode>b_fix_ice9a): New.
++      * config/mips/mips.opt (mfix-ice9a): New option.
++      * doc/invoke.texi (-mno-fix-ice9a): New option.
++      (-mfix-ice9a): Likewise.
++
++      gcc/testsuite/
++      * gcc.target/mips/fix-ice9a.h: New file.
++      * gcc.target/mips/fix-ice9a-1.c: Likewise.
++      * gcc.target/mips/fix-ice9a-2.c: Likewise.
++
++2008-09-23  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #3208
++
++      gcc/
++      * config/arm/arm.c (arm_init_libfuncs): Add NULL entries for
++      HFmode arithmetic functions.
++      (arm_override_options): Call sorry for fp16 and no ldrh.
++      (arm_legitimate_index_p): Treat HFmode like HImode.
++      (coproc_secondary_reload_class): Special-case HFmode.
++      * config/arm/arm.md (floatsihf2): Use emit_move_insn.
++      (floatdihf2): Likewise.
++      (truncdfhf2): Likewise.
++      (*thumb1_movhf): Fix backwards operands to strh.
++
++2008-09-23  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #3208
++
++      gcc/testsuite/
++      * gcc.target/arm/fp16-compile-alt-10.c: Add -std=gnu99 to options.
++      * gcc.target/arm/fp16-compile-alt-11.c: Likewise.
++      * gcc.target/arm/fp16-compile-ieee-10.c: Likewise.
++      * gcc.target/arm/fp16-compile-ieee-11.c: Likewise.
++      * gcc.target/arm/fp16-compile-exprtype.c: New.
++      * gcc.target/arm/fp16-builtins-1.c: New.
++      * gcc.target/arm/fp16-unprototyped-1.c: New.
++      * gcc.target/arm/fp16-unprototyped-2.c: New.
++      * gcc.target/arm/fp16-variadic-1.c: New.
++      * gcc.target/arm/fp16-rounding-alt-1.c: New.
++      * gcc.target/arm/fp16-rounding-ieee-1.c: New.
++      * gcc.dg/torture/arm-fp16-int-convert-alt.c: New.
++      * gcc.dg/torture/arm-fp16-int-convert-ieee.c: New.
++      * gcc.dg/torture/arm-fp16-ops.h: New.
++      * gcc.dg/torture/arm-fp16-ops-1.c: New.
++      * gcc.dg/torture/arm-fp16-ops-2.c: New.
++      * gcc.dg/torture/arm-fp16-ops-3.c: New.
++      * gcc.dg/torture/arm-fp16-ops-4.c: New.
++      * gcc.dg/torture/arm-fp16-ops-5.c: New.
++      * gcc.dg/torture/arm-fp16-ops-6.c: New.
++      * gcc.dg/torture/arm-fp16-ops-7.c: New.
++      * gcc.dg/torture/arm-fp16-ops-8.c: New.
++      * g++.dg/ext/arm-fp16/arm-fp16-ops.h: New.
++      * g++.dg/ext/arm-fp16/arm-fp16-ops-1.C: New.
++      * g++.dg/ext/arm-fp16/arm-fp16-ops-2.C: New.
++      * g++.dg/ext/arm-fp16/arm-fp16-ops-3.C: New.
++      * g++.dg/ext/arm-fp16/arm-fp16-ops-4.C: New.
++      * g++.dg/ext/arm-fp16/arm-fp16-ops-5.C: New.
++      * g++.dg/ext/arm-fp16/arm-fp16-ops-6.C: New.
++      * g++.dg/ext/arm-fp16/arm-fp16-ops-7.C: New.
++      * g++.dg/ext/arm-fp16/arm-fp16-ops-8.C: New.
++
++2008-09-23  Sandra Loosemore  <sandra@codesourcery.com>
++
++      gcc/
++      * optabs.c (prepare_float_lib_cmp):  Test that the comparison,
++      swapped, and reversed optabs exist before trying to use them.
++
++2008-09-23  Julian Brown  <julian@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_override_options): Override alignments if
++      tuning for Cortex-A8.
++      (create_fix_barrier, arm_reorg): If aligning to jumps or loops,
++      make labels have a size.
++      * config/arm/arm.md (VUNSPEC_ALIGN16, VUNSPEC_ALIGN32): New constants.
++      (align_16, align_32): New patterns.
++
++2008-09-23  Julian Brown  <julian@codesourcery.com>
++
++      gcc/
++      * config/arm/vfp.md (*arm_movsi_vfp, *thumb2_movsi_vfp)
++      (*arm_movdi_vfp, *thumb2_movdi_vfp, *movsf_vfp, *thumb2_movsf_vfp)
++      (*movdf_vfp, *thumb2_movdf_vfp, *movsfcc_vfp, *thumb2_movsfcc_vfp)
++      (*movdfcc_vfp, *thumb2_movdfcc_vfp): Add neon_type.
++      * config/arm/arm.md (neon_type): Update comment.
++
++2008-09-23  Julian Brown  <julian@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.md (movsi): Don't split symbol refs here.
++      (define_split): New.
++
++2008-09-22  Maxim Kuvyrkov  <maxim@codesourcery.com>
++          Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/m68k/lb1sf68.asm: Add GNU-stack annotation to avoid
++      executable stack.
++
++2008-09-18  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      2008-09-17  Joseph Myers  <joseph@codesourcery.com>
++      * expr.c (emit_group_store): Do not shift before moving via a
++      stack slot.
++
++      2008-08-13  H.J. Lu  <hongjiu.lu@intel.com>
++      PR middle-end/36701
++      * expr.c (emit_group_store): Allocate stack temp with the
++      largest alignment when copying from register to stack.
++
++      2008-09-02  H.J. Lu  <hongjiu.lu@intel.com>
++      * expr.c (emit_group_store): Don't assert stack temp mode size.
++
++2008-09-15  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/mips-octeon-elf.h (TARGET_OS_CPP_BUILTINS): Remove.
++
++2008-09-11  Mark Mitchell  <mark@codesourcery.com>
++
++      Issue #3606
++      * release-notes-csl.xml: Document dllexport fix.
++      
++      gcc/
++      * tree.c (handle_dll_attribute): Mark dllexport'd inlines as
++      non-external.
++      gcc/cp
++      * decl2.c (decl_needed_p): Consider dllexport'd functions needed.
++      * semantics.c (expand_or_defer_fn): Similarly.
++      gcc/testsuite/
++      * gcc.dg/dll-6.c: New test.
++      * gcc.dg/dll-6a.c: Likewise.
++      * gcc.dg/dll-7.c: Likewise.
++      * gcc.dg/dll-7a.c: Likewise.
++      * g++.dg/ext/dllexport2.C: Likewise.
++      * g++.dg/ext/dllexport2a.cc: Likewise.
++
++2008-09-12  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Backport from mainline:
++
++      gcc/testsuite/
++      2008-08-25  Janis Johnson  <janis187@us.ibm.com>
++      * gcc.dg/Wstrict-aliasing-bogus-ref-all-2.c: Ignore a warning.
++
++2008-09-11  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/testsuite/
++      2008-09-11  Joseph Myers  <joseph@codesourcery.com>
++      * gcc.dg/builtins-8.c: Condition cbrt test on HAVE_C99_RUNTIME.
++
++      2008-09-11  Joseph Myers  <joseph@codesourcery.com>
++      * gcc.target/i386/sse5-haddX.c, gcc.target/i386/sse5-hsubX.c:
++      Avoid intN_t types.
++
++      2008-09-11  Joseph Myers  <joseph@codesourcery.com>
++      * lib/compat.exp, gcc.dg/compat/struct-layout-1.exp,
++      g++.dg/compat/struct-layout-1.exp: Use .exe extension for compat
++      test executables.
++      * gcc.dg/compat/struct-layout-1_generate.c,
++      g++.dg/compat/struct-layout-1_generate.c: Convert backslash to
++      slash in srcdir for dg-options string.
++
++2008-09-11  Nathan Sidwell  <nathan@codesourcery.com>
++
++      gcc/
++      * config.gcc (mips*-sde-elf*): Always apply sdemtk parts.  Apply
++      t-sdelib only when not building newlib.
++      * config/mips/t-sdemtk: Move sdelib specific pieces to ...
++      * config/mips/t-sdelib: ... here.  New file.
++
++2008-09-10  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      Issue #3406
++      * release-notes-csl.xml: Document -fpie fix.
++
++      gcc/
++      * config/mips/linux.h (SUBTARGET_ASM_SPEC): Add -fpie and -fPIE.
++      * config/mips/linux64.h (SUBTARGET_ASM_SPEC): Likewise.
++
++2008-09-09  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #3208
++
++      gcc/testsuite/
++      * gcc.target/arm/fp16-compile-alt-1.c: New.
++      * gcc.target/arm/fp16-compile-alt-2.c: New.
++      * gcc.target/arm/fp16-compile-alt-3.c: New.
++      * gcc.target/arm/fp16-compile-alt-4.c: New.
++      * gcc.target/arm/fp16-compile-alt-5.c: New.
++      * gcc.target/arm/fp16-compile-alt-6.c: New.
++      * gcc.target/arm/fp16-compile-alt-7.c: New.
++      * gcc.target/arm/fp16-compile-alt-8.c: New.
++      * gcc.target/arm/fp16-compile-alt-9.c: New.
++      * gcc.target/arm/fp16-compile-alt-10.c: New.
++      * gcc.target/arm/fp16-compile-alt-11.c: New.
++      * gcc.target/arm/fp16-compile-ieee-1.c: New.
++      * gcc.target/arm/fp16-compile-ieee-2.c: New.
++      * gcc.target/arm/fp16-compile-ieee-3.c: New.
++      * gcc.target/arm/fp16-compile-ieee-4.c: New.
++      * gcc.target/arm/fp16-compile-ieee-5.c: New.
++      * gcc.target/arm/fp16-compile-ieee-6.c: New.
++      * gcc.target/arm/fp16-compile-ieee-7.c: New.
++      * gcc.target/arm/fp16-compile-ieee-8.c: New.
++      * gcc.target/arm/fp16-compile-ieee-9.c: New.
++      * gcc.target/arm/fp16-compile-ieee-10.c: New.
++      * gcc.target/arm/fp16-compile-ieee-11.c: New.
++      * gcc.target/arm/fp16-compile-none-1.c: New.
++      * gcc.target/arm/fp16-param-1.c: New.
++      * gcc.target/arm/fp16-return-1.c: New.
++      * gcc.target/arm/fp16-compile-vcvt.c: New.
++      * gcc.dg/torture/arm-fp16-compile-assign.c: New.
++      * gcc.dg/torture/arm-fp16-compile-convert.c: New.
++      * g++.dg/ext/arm-fp16/fp16-overload-1.C: New.
++      * g++.dg/ext/arm-fp16/fp16-return-1.C: New.
++      * g++.dg/ext/arm-fp16/fp16-param-1.C: New.
++      * g++.dg/ext/arm-fp16/fp16-mangle-1.C: New.
++
++2008-09-09  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #3208
++
++      gcc/
++      * doc/tm.texi (Misc): Document TARGET_INVALID_PARAMETER_TYPE,
++      TARGET_INVALID_RETURN_TYPE, TARGET_PROMOTED_TYPE, and
++      TARGET_CONVERT_TO_TYPE.
++      * doc/invoke.texi (Option Summary): List -mfp16-format.
++      (ARM Options): List neon-fp16 as -mfpu value.  Document -mfp16-format.
++      * hooks.c (hook_tree_const_tree_null): Define.
++      * hooks.h (hook_tree_const_tree_null): Declare.
++      * target.h (struct gcc_target):  Add invalid_parameter_type,
++      invalid_return_type, promoted_type, and convert_to_type fields.
++      * target-def.h: (TARGET_INVALID_PARAMETER_TYPE): Define.
++      (TARGET_INVALID_RETURN_TYPE): Define.
++      (TARGET_PROMOTED_TYPE): Define.
++      (TARGET_CONVERT_TO_TYPE): Define.
++      (TARGET_INITIALIZER): Update for new fields.
++      * fold-const.c (fold_convert_const_real_from_real): Check for
++      overflow.
++      * real.c (encode_ieee_half): Define.
++      (decode_ieee_half): Define.
++      (ieee_half_format): Define.
++      (arm_half_format): Define.
++      * real.h (ieee_half_format): Declare.
++      (arm_half_format): Declare.
++      * c-decl.c (grokdeclarator): Check targetm.invalid_return_type.
++      (grokparms): Check targetm.invalid_parameter_type.
++      * c-typeck.c (default_conversion): Check targetm.promoted_type.
++      * c-convert.c (convert): Check targetm.convert_to_type.
++      * cp/typeck.c (default_conversion): Check targetm.promoted_type.
++      * cp/decl.c (grokdeclarator): Check targetm.invalid_return_type.
++      (grokparms): Check targetm.invalid_parameter_type.
++      * cp/cvt.c (ocp_convert): Check targetm.convert_to_type.
++      (build_expr_type_conversion): Check targetm.promoted_type.
++      * config/arm/arm.c: Include intl.h.
++      (TARGET_INVALID_PARAMETER_TYPE): Redefine.
++      (TARGET_INVALID_RETURN_TYPE): Redefine.
++      (TARGET_PROMOTED_TYPE): Redefine.
++      (TARGET_CONVERT_TO_TYPE): Redefine.
++      (arm_fp16_format): Define.
++      (all_fpus): Add entry for neon-fp16.
++      (fp_model_for_fpu): Likewise.
++      (struct fp16_format): Declare.
++      (all_fp16_formats): Define.
++      (arm_init_libfuncs): Add entries for HFmode conversions.
++      (arm_override_options): Set arm_fp16_format.
++      (thumb1_legitimate_address_p): Make it recognize HFmode constants.
++      (arm_print_operand): Add 'z' specifier for vld1.16/vst1.16.
++      (arm_hard_regno_mode_ok): Allow HFmode values in VFP registers.
++      (arm_init_fp16_builtins): New.
++      (arm_init_builtins): Call it.
++      (arm_invalid_parameter_type): New.
++      (arm_invalid_return_type): New.
++      (arm_promoted_type): New.
++      (arm_convert_to_type).
++      (arm_file_start): Deal with neon-fp16 as fpu_name.  Emit tag for fp16
++      format.
++      (arm_mangle_type): Mangle __fp16 as "Dh".
++      * config/arm/arm.h (TARGET_VFPD32): Make it know about
++      FPUTYPE_NEON_FP16.
++      (TARGET_NEON_FP16): New.
++      (TARGET_NEON): Make it know about FPUTYPE_NEON_FP16.
++      (enum fputype): Add FPUTYPE_NEON_FP16.
++      (enum arm_fp16_format_type): Declare.
++      (arm_fp16_format): Declare.
++      (LARGEST_EXPONENT_IS_NORMAL): Define.
++      * config/arm/arm-modes.def (HFmode): Define.
++      * config/arm/vfp.md: (*movhf_vfp): New.
++      (extendhfsf2): New.
++      (truncsfhf2): New.
++      * config/arm/arm.opt (mfp16-format=): New.
++      * config/arm/arm.md: (fpu): Add neon_fp16.
++      (floatsihf2, floatdihf2): New.
++      (fix_trunchfsi2, fix_trunchfdi2): New.
++      (truncdfhf2): New.
++      (extendhfdf2): New.
++      (movhf): New.
++      (*arm32_movhf): New.
++      (*thumb1_movhf): New.
++      (consttable_2): Handle HFmode constants.
++
++      libiberty/
++      * cp-demangle.c (cplus_demangle_builtin_Dh_type): Declare.
++      (cplus_demangle_type): Make it handle "Dh".
++
++2008-09-09  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Issue #3732
++
++      gcc/
++      * doc/invoke.texi (ARM Options): Correct errors in discussion 
++      of -mfloat-abi, -mhard-float, and -msoft-float.
++
++2008-09-09  Kazu Hirata  <kazu@codesourcery.com>
++
++      gcc/
++      * config.gcc (mips-sgi-irix[56]*, mips*-*-netbsd*,
++      mips*-*-openbsd*, mips*-sde-elf*, mips64octeon*-wrs-elf*,
++      mipsisa64-*-elf*, mipsisa64el-*-elf*, mipsisa64sr71k-*-elf*,
++      mipsisa64sb1-*-elf*, mipsisa64sb1el-*-elf*, mips-*-elf*,
++      mipsel-*-elf*, mips64-*-elf*, mips64el-*-elf*, mips64vr-*-elf*,
++      mips64vrel-*-elf*, mips64orion-*-elf*, mips64orionel-*-elf*,
++      mips*-*-rtems*, mips-wrs-vxworks, mips-wrs-windiss,
++      mipstx39-*-elf*, mipstx39el-*-elf*): Don't add t-crtfm to
++      tmake_file.
++
++      libgcc/
++      * config.host (mips-sgi-irix[56]*, mips*-*-netbsd*,
++      mips*-*-openbsd*, mipsisa32-*-elf*, mipsisa32el-*-elf*,
++      mipsisa32r2-*-elf*, mipsisa32r2el-*-elf*, mipsisa64-*-elf*,
++      mipsisa64el-*-elf*, mipsisa64sr71k-*-elf*, mipsisa64sb1-*-elf*,
++      mipsisa64sb1el-*-elf*, mips-*-elf*, mipsel-*-elf*, mips64-*-elf*,
++      mips64el-*-elf*, mips64vr-*-elf*, mips64vrel-*-elf*,
++      mips64orion-*-elf*, mips64orionel-*-elf*, mips64octeon-wrs-elf*,
++      mips64octeonel-wrs-elf*, mips*-*-rtems*, mips-wrs-vxworks,
++      mips-wrs-windiss, mipstx39-*-elf*, mipstx39el-*-elf*): Remove
++      extra_parts and tmake_file.
++
++2008-09-08  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      * release-notes-csl.xml: Document exception handler fix.
++
++      gcc/
++      * config/arm/unwind-arm.c (__gnu_unwind_pr_common): Correct test
++      for barrier handlers.
++
++2008-09-08  Daniel Jacobowitz  <dan@codesourcery.com>
++          Mark Mitchell  <mark@codesourcery.com>
++
++      gcc/testsuite/
++      * g++.dg/compat/eh/filter2_x.C: Declare abort.
++      * g++.dg/compat/eh/new1_x.C, g++.dg/compat/eh/new1_y.C: Include
++      cstddef and use std::size_t.
++
++      * gcc.dg/compat/compat-common.h: Define SKIP_COMPLEX_INT if
++      SKIP_COMPLEX.  Honor SKIP_COMPLEX.
++      * gcc.dg/compat/scalar-by-value-3_x.c,
++      gcc.dg/compat/scalar-by-value-3_y.c,
++      gcc.dg/compat/scalar-by-value-4_x.c,
++      gcc.dg/compat/scalar-by-value-4_y.c,
++      gcc.dg/compat/scalar-by-value-5.c,
++      gcc.dg/compat/scalar-by-value-5_main.c,
++      gcc.dg/compat/scalar-by-value-6.c,
++      gcc.dg/compat/scalar-by-value-6_main.c,
++      gcc.dg/compat/scalar-by-value-6_x.c,
++      gcc.dg/compat/scalar-by-value-6_y.c,
++      gcc.dg/compat/struct-by-value-16_x.c,
++      gcc.dg/compat/struct-by-value-16_y.c,
++      gcc.dg/compat/struct-by-value-17_x.c,
++      gcc.dg/compat/struct-by-value-17_y.c,
++      gcc.dg/compat/struct-by-value-18_x.c,
++      gcc.dg/compat/struct-by-value-18_y.c,
++      gcc.dg/compat/struct-layout-1.h,
++      gcc.dg/compat/scalar-return-3_x.c,
++      gcc.dg/compat/scalar-return-3_y.c,
++      gcc.dg/compat/scalar-return-4_x.c,
++      gcc.dg/compat/scalar-return-4_y.c: Honor SKIP_COMPLEX.
++
++      * gcc.dg/compat/scalar-by-value-y.h: Use stdarg.h for non-GCC
++      compilers.
++
++      * gcc.dg/compat/struct-by-value-22_y.c,
++      gcc.dg/compat/struct-by-value-22_main.c,
++      gcc.dg/compat/struct-by-value-22_x.c: Honor SKIP_VLA_IN_STRUCT.
++
++      * lib/c-compat.exp (compat_setup_dfp): Check the compiler under test
++      first.
++      * lib/compat.exp: Document COMPLEX and VLA_IN_STRUCT skips.
++
++2008-09-08  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.md (arm_addsi3): Add r/r/k alternative.
++
++2008-09-08  Kazu Hirata  <kazu@codesourcery.com>
++
++      gcc/
++      * config.gcc (mips-sgi-irix[56]*, mips*-*-netbsd*, mips*-*-linux*,
++      mips*-sde-elf*, mips64octeon*-wrs-elf*, mipsisa32r2*,
++      mipsisa64sr71k-*-elf*, mipsisa64sb1*, mips64vr*, mips64orion*,
++      mips*-*-rtems*, mips-wrs-vxworks, mips-wrs-windiss, mipstx39): Add
++      mips/t-crtfm to tmake_file.
++
++      libgcc/
++      * config.host (mips*): Add mips/t-crtfm to tmake_file. Add
++      crtfastmath.o to extra_parts.
++      * config/mips/t-crtfm: New.
++
++2008-09-07  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.gd/struct/wo_prof_global_var.c: Use uninitialized integer
++      values instead of uninitialized FP values to avoid NaNs.
++      * gcc.dg/struct/wo_prof_local_var.c: Same.
++
++2008-09-07  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      gcc/
++      * config/m68k/m68k.c (sched_attr_op_type): Handle all CONSTs.
++      
++      gcc/testsuite/
++      * gcc.target/m68k/xgot-1.c (dg-options): Add -O2.
++
++2008-09-06  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * combine.c (simplify_set): Avoid calling LOAD_EXTEND_OP on
++      non-integer modes.
++
++2008-09-05  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      2008-09-05  Joseph Myers  <joseph@codesourcery.com>
++      * config/mips/mips.h (enum reg_class): Add FRAME_REGS.
++      (REG_CLASS_NAMES): Update.
++      (REG_CLASS_CONTENTS): Update.
++      * config/mips/mips.c (mips_regno_to_class): Use FRAME_REGS instead
++      of ALL_REGS for regs 77 and 78.
++      * function.c (instantiate_virtual_regs_in_insn): Assert that
++      return value of simplify_gen_subreg is not NULL.
++
++      gcc/testsuite/
++      2008-09-05  Joseph Myers  <joseph@codesourcery.com>
++      * gcc.c-torture/compile/20080903-1.c: New test.
++
++2008-09-04  Nathan Sidwell  <nathan@codesourcery.com>
++
++      Issue 3304
++      gcc/
++      * config/arm/arm.c (arm_print_operand): Deal with HIGH.
++      * config/arm/constraints.md (j): New constraint for movw operands.
++      (N): Remove thumb2 meaning.
++      * config/arm/arm.md (*arm_movw): Delete.
++      (*arm_movsi_insn): Use j constraint for movw instead of N constraint.
++      * config/arm/vfp.md (*arm_movsi_vfp, *thumb2_movsi_vfp): Likewise.
++      * config/arm/thumb2.md (*thumb2_movsi_insn): Likewise.
++
++2008-09-04  Julian Brown  <julian@codesourcery.com>
++ 
++      gcc/
++      * Makefile.in (CSL_LICENSELIB): Remove space after -L to appease
++      Darwin ld.
++ 
++2008-09-04  Nathan Sidwell  <nathan@codesourcery.com>
++
++      gcc/
++      * config/arm/bpabi.h (LINK_SPEC): Add --fix-janus-2cc if needed.
++
++      * release-notes-csl.xml: Adjust janus-2cc note.
++
++2008-09-03  Nathan Froyd  <froydnj@codesourcery.com>
++
++      libgomp/
++      * libgomp.texi (Library Index): Renamed from "Index" to prevent
++      conflict with index.html on case-insensitive file systems.
++
++2008-09-03  Julian Brown  <julian@codesourcery.com>
++
++      * release-notes-csl.xml (NEON improvements): Add release note.
++
++2008-09-02  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/testsuite/
++      * g++.dg/abi/arm_va_list.C: Correct order of dg-do and
++      dg-require-effective-target directives.
++
++2008-09-02  Mark Mitchell  <mark@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.target/arm/long-calls-1.c: Tolerate the lack of sibling
++      calls and/or PLT markers.
++      * gcc.target/arm/long-calls-2.c: Tolerate the lack of sibling
++      calls and/or PLT markers.
++      * gcc.target/arm/long-calls-3.c: Tolerate the lack of sibling
++      calls and/or PLT markers.
++      * gcc.target/arm/long-calls-4.c: Tolerate the lack of sibling
++      calls and/or PLT markers.
++
++2008-09-01  Mark Mitchell  <mark@codesourcery.com>
++
++      Backport:
++      2008-09-01  Mark Mitchell  <mark@codesourcery.com>
++      * include/std/type_traits (__make_unsigned_selector<>): Consider
++      enums of size smaller than short.
++      (__make_signed_selector<>): Likewise.
++      * testsuite/20_util/make_signed/requirements/typedefs_neg.cc:
++      Adjust line numbers.
++      * testsuite/20_util/make_usigned/requirements/typedefs_neg.cc:
++      Adjust line numbers.
++      * testsuite/20_util/make_signed/requirements/typedefs-2.cc:
++      Ensure test_enum is the same size as short.
++      * testsuite/20_util/make_unsigned/requirements/typedefs-2.cc:
++      Ensure test_enum is the same size as short.
++
++2008-09-01  Joseph Myers  <joseph@codesourcery.com>
++
++      * release-notes-csl.xml: Avoid line containing only whitespace.
++
++2008-08-27  Daniel Gutson  <daniel@codesourcery.com>
++
++      Janus 2CC ARM shift fix:
++      gcc/
++      * config/arm/arm.md (*addsi3_carryin_shift): Added "length" clause
++      to handle the extra NOP.
++      (andsi_not_shiftsi_si): Likewise.
++      (*thumb1_ashlsi3): Likewise.
++      (*thumb1_ashrsi3): Likewise.
++      (*thumb1_lshrsi3): Likewise.
++      (*thumb1_rotrsi3): Likewise.
++      (*arm_shiftsi3): Likewise.
++      (*shiftsi3_compare0): Likewise.
++      (*shiftsi3_compare0_scratch): Likewise.
++      (*arm_notsi_shiftsi): Likewise.
++      (*arm_notsi_shiftsi_compare0): Likewise.
++      (*arm_not_shiftsi_compare0_scratch): Likewise.
++      (*arm_cmpsi_shiftsi): Likewise.
++      (*arm_cmpsi_shiftsi_swp): Likewise.
++      (*arm_cmpsi_negshiftsi_si): Likewise.
++      (*arith_shiftsi): Likewise.
++      (*arith_shiftsi_compare0): Likewise.
++      (*arith_shiftsi_compare0_scratch): Likewise.
++      (*sub_shiftsi): Likewise.
++      (*sub_shiftsi_compare0): Likewise.
++      (*sub_shiftsi_compare0_scratch): Likewise.
++      (*if_shift_move): Likewise.
++      (*if_move_shift): Likewise.
++      (*if_shift_shift): Likewise.
++      (*thumb1_ashlsi3_janus2): New. Duplicated pattern to handle the
++      extra NOP.
++      (*thumb1_ashrsi3_janus2): Likewise.
++      (*thumb1_lshrsi3_janus2): Likewise.
++      (*thumb1_rotrsi3_janus2): Likewise.
++      * config/arm/arm.c (arm_print_operand): Added the nop after the %S
++      pattern.
++      (arm_override_options): Added handling of the -mfix-janus-2cc flag.
++      * config/arm/arm.h (janus2_code): Declare.
++      * config/arm/arm.opt (-mfix-janus-2cc): New.
++
++      gcc/testsuite/
++      * lib/target-supports.exp (check_effective_target_arm_no_thumb):
++      New function.
++      * gcc.target/arm/janus-2cc-shift-1.c: New.
++      * gcc.target/arm/janus-2cc-shift-2.c: New.
++
++      * release-notes-csl.xml: Document.
++
++2008-08-31  Mark Mitchell  <mark@codesourcery.com>
++
++      gcc/
++      * gcc.target/arm/va_list.c: Return zero on success.
++
++      * release-notes-csl.xml: Update note for va_list change.
++
++2008-08-30  Mark Mitchell  <mark@codesourcery.com>
++
++      libstdc++-v3/
++      * testsuite/25_algorithms/nth_element/2.cc: Constrain iterations
++      when testing on a simultor.
++
++2008-08-29  Mark Mitchell  <mark@codesourcery.com>
++
++      * release-notes-csl.xml: Update note for NEON mangling.
++
++      Issue #3579
++      gcc/
++      * config/arm/arm.c (arm_build_builtin_va_list): New function.
++      (arm_extract_valist_ptr): Likewise.
++      (arm_expand_builtin_va_start): Likewise.
++      (arm_gimplify_va_arg_expr): Likewise.
++      (TARGET_BUILD_BUILTIN_VA_LIST): Define.
++      (TARGET_EXPAND_BUILTIN_VA_START): Likewise.
++      (TARGET_GIMPLIFY_VA_VARG_EXPR): Likewise.
++      (arm_mangle_type): Handle __va_list specially.
++      gcc/testsuite/
++      * lib/target-supports.exp (check_effective_target_arm_eabi): New
++      function.
++      * gcc.target/arm/va_list.c: New test.
++      * g++.dg/abi/arm_va_list.C: Likewise.
++
++2008-08-29  Mark Mitchell  <mark@codesourcery.com>
++
++      gcc/cp/
++      * mangle.c (write_type): Add target-specific manglings for
++      non-fundamental types to the substitution table.
++      gcc/testsuite/
++      * g++.dg/abi/mangle-neon.C: Add substitution test.
++
++      * release-notes-csl.xml: Document change.
++
++2008-08-29  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/testsuite/
++      2008-04-09  Andy Hutchinson  <hutchinsonandy@aim.com>
++      PR testsuite/34894
++      PR testsuite/33782
++      * lib/target-supports.dg: Add check_effective_target_trampolines.
++      Disable profiling for avr-*-*.
++      * gcc.c-torture/compile/pr27889.c: dg-requires trampolines.
++      * gcc.c-torture/compile/nested-1.c: Ditto.
++      * gcc.c-torture/compile/20050122-2.c: Ditto.
++      * gcc.c-torture/compile/20010226-1.c: Ditto.
++      * gcc.c-torture/compile/20010327-1.c:  Skip for avr-*-*.
++      * gcc.c-torture/compile/980506-1.c: Ditto.
++      * gcc.c-torture/compile/20020604-1.c: Ditto.
++      * gcc.c-torture/compile/limits-stringlit.c: Ditto
++      * gcc.c-torture/compile/20001226-1.c: Ditto
++
++      2008-05-12  Andy Hutchinson  <hutchinsonandy@aim.com>
++      * gcc.dg/pr34457-1.c: Skip for target without trampolines.
++      * gcc.dg/20050607-1.c: Ditto.
++      * gcc.dg/trampoline-1.c: Ditto.
++      * gcc.dg/debug/debug-3.c: Ditto.
++      * gcc.dg/debug/debug-5.c: Ditto.
++
++2008-08-29  Mark Mitchell  <mark@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.dg/vect/vect-105.c: Prevent compiler from hoisting abort out
++      of loop.
++
++2008-08-28  Mark Mitchell  <mark@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.dg/struct/wo_prof_single_str_global.c: Mask return value.
++      * gcc.dg/struct/wo_prof_single_str_local.c: Mask return value.
++      * gcc.dg/struct/wo_prof_single_str_pointer.c: Mask return value.
++
++      Backport:
++
++      gcc/testsuite/
++      2008-04-22  Steve Ellcey  <sje@cup.hp.com>
++      * gcc.dg/struct/wo_prof_global_var.c: Initialize array.
++      * gcc.dg/struct/wo_prof_malloc_size_var.c: Ditto.
++      * gcc.dg/struct/w_prof_local_var.c: Ditto.
++      * gcc.dg/struct/w_prof_global_var.c: Ditto.
++      * gcc.dg/struct/wo_prof_local_var.c: Ditto.
++
++2008-08-28  Mark Mitchell  <mark@codesourcery.com>
++
++      gcc/cp
++      * decl.c (maybe_deduce_size_from_array_init): Use relayout_decl.
++      gcc/testsuite/
++      * g++.dg/cpp/_Pragma1.C: Skip on arm*-*-eabi*.
++      * g++.dg/ext/visibility/arm1.C: Require DLL targets.
++      * g++.dg/init/ref15.C: Require unwrapped targets.
++
++2008-08-28  Paul Brook  <paul@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++      gcc/
++      * config/arm/neon.md (neon_type): Move to arm.md.
++      (neon_mov<VSTRUCT>): Add neon_type attribute.
++      (movmisalign<mode>): Ditto.
++      * config/arm/arm.md (neon_type): Move to here.
++      (conds): Add "unconditioal" and use as default for NEON insns.
++
++      gcc/testsuite/
++      * gcc.target/arm/neon-cond-1.c: New test.
++
++2008-08-27  Nathan Froyd  <froydnj@codesourcery.com>
++
++      libgomp/
++      * Makefile.am: Use install-data-local for install-html and
++      install-pdf.
++      * Makefile.in: Regenerate.
++
++2008-08-26  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Port not-reviewed patch from gcc-patches@.
++      
++      gcc/
++      200x-xx-xx  Roman Zippel <zippel@linux-m68k.org>
++      PR middle-end/29474
++      * gcc/recog.c (validate_replace_rtx_1): Prevent swap of 
++      commutative operands during reload
++
++
++2008-08-26  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      gcc/
++      * config/m68k/m68k.md (cmpdi): Use (scratch) instead of pseudo.
++
++2008-08-25  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Issue #3604
++
++      * release-notes-csl.xml (-msim build fix): New.
++
++      gcc/
++      * config/rs6000/sysv4.h (LIB_SIM_SPEC): Use LIB_DEFAULT_SPEC.
++      (STARTFILE_SIM_SPEC): Remove sim-crt0.o%s.
++      (ENDFILE_SIM_SPEC): Add -Tsim-hosted.ld.
++      (LINK_OS_SIM_SPEC): Define to empty.
++
++2008-08-23  Nathan Froyd  <froydnj@codesourcery.com>
++
++      * release-notes-csl.xml (OpenMP support): New.
++
++2008-08-21  Nathan Sidwell  <nathan@codesourcery.com>
++
++      gcc/
++      * config/m68k/m68k-devices.def (52274, 52277): New devices.
++
++      * release-notes-csl.xml: Document addition of DragonFire0.
++
++2008-08-21  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/testsuite/
++      2008-08-21  Joseph Myers  <joseph@codesourcery.com>
++      * g++.dg/opt/anchor1.C (foo): Return the return value of
++      ycf->ascent.
++
++2008-08-21  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Backport from mainline:
++
++      libgomp/
++      2008-08-21  Nathan Froyd  <froydnj@codesourcery.com>
++      * testsuite/libgomp.exp (libgomp_init): Only set things that
++      depend on blddir if blddir exists.
++      (libgomp_target_compile): Likewise.
++      * testsuite/libgomp.c++/c++.exp: Likewise.
++      * testsuite/libgomp.fortran/fortran.exp: Likewise.
++
++2008-08-20  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      2008-08-20  Joseph Myers  <joseph@codesourcery.com>
++      PR target/31070
++      * config/sparc/sparc.c (function_arg_slotno): Handle structure
++      with MODE_VECTOR_INT mode.
++
++2008-08-19  Joseph Myers  <joseph@codesourcery.com>
++
++      * release-notes-csl.xml (Target architecture defaults to i686):
++      Add new release note.
++
++2008-08-19  Joseph Myers  <joseph@codesourcery.com>
++
++      * release-notes-csl.xml: Update release note for upgrade to refer
++      to version 4.3.2.
++
++2008-08-19  Kazu Hirata  <kazu@codesourcery.com>
++
++      Issue 3422
++      gcc/
++      * config.gcc (mips64*-*-linux*, mips-*-elf*, mipsel-*-elf*,
++      mips64-*-elf*, mips64el-*-elf*): Add mips/t-crtfm.
++      * config/mips/crtfastmath.c: New.
++      * config/mips/linux.h (ENDFILE_SPEC): New.
++      * config/mips/linux64.h (ENDFILE_SPEC): New.
++      * config/mips/t-crtfm: New.
++
++      * release-notes-csl.xml: Add a release note for the new FPU
++      defaults on mips64el-sicortex-linux-gnu
++
++2008-08-18  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/testuite/
++      * gcc.dg/pr34856.c: Fix thinko
++
++2008-08-18  Nathan Froyd  <froydnj@codesourcery.com>
++
++      libgomp/
++      * Makefile.am (datarootdir, docdir, htmldir, pdfdir): Define.
++      (HTMLS_INSTALL, HTMLS_BUILD): Define.
++      ($(HTMLS_BUILD)): New rule.
++      (html__strip_dir): Define.
++      (install-data-am): Add install-html and install-pdf prerequsites.
++      (install-html): Add actions.
++      (TEXI2HTML): Define.
++      * Makefile.in: Regenerate.
++      * configure.ac (datarootdir, docdir, htmldir, pdfdir): Add
++      appropriate --with options and AC_SUBSTs.
++      * configure: Regenerate.
++
++2008-08-18  Nathan Froyd  <froydnj@codesourcery.com>
++
++      libgomp/
++      * Makefile.am (LTLDFLAGS): Define.
++      (LINK): Define.
++      * Makefile.in: Regenerate.
++
++2008-08-18  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/testuite/
++      * gcc.dg/pr34856.c: Add powerpc*-eabi* exception.
++
++2008-08-15  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      2008-06-28  Andrew Jenner  <andrew@codesourcery.com>
++      * regrename.c (build_def_use): Don't copy RTX.
++
++2008-08-13  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      2008-08-13  Joseph Myers  <joseph@codesourcery.com>
++      * config/sparc/sparc.c (emit_soft_tfmode_cvt): Explicitly sign or
++      zero extend SImode values being converted to TFmode before passing
++      to libcalls.
++
++2008-08-12  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Backport from mainline:
++
++      gcc/
++      2008-08-12  Nathan Froyd  <froydnj@codesourcery.com>
++
++      PR libgomp/26165
++      * gcc.c (include_spec_function): Tweak call to find_a_file.
++
++2008-08-10  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-02-28  Julian Brown  <julian@codesourcery.com>
++
++      Merge from MIPS:
++
++      gcc/
++      * Makefile.in (stmp-int-hdrs): Don't depend on
++      fixinc_list. Only
++      process fixincludes if fixinc_list is
++      present.
++      (install-mkheaders): Likewise.
++
++      2008-02-11  Julian Brown  <julian@codesourcery.com>
++
++      Merge from MIPS:
++
++      2004-06-29  Nigel Stephens  <nigel@mips.com>
++
++      * Makefile.in (libgcc.mk): Make this depend on
++      $(tmake_file), in
++      case new multilib options have been defined.
++      (s-mlib): Similarly.
++
++2008-08-07  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      * config/arm/neon.md neon_vget_lane<mode>): Adjust element indices
++      for big-endian.
++
++2008-08-07  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      2008-08-07  Joseph Myers  <joseph@codesourcery.com>
++      * config/arm/iwmmxt.md (movv8qi_internal, movv4hi_internal,
++      movv2si_internal): Combine into mov<mode>_internal.
++      (movv2si_internal_2): Remove.
++
++2008-08-06  Catherine Moore  <clm@codesourcery.com>
++
++      gcc/
++      * config/mips/mips.h (MIPS_ARCH_DSP_SPEC): Add missing *.
++
++      * release-notes-csl.xml: Fix target.
++
++2008-08-06  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      2008-08-06  Joseph Myers  <joseph@codesourcery.com>
++      * jump.c (rtx_renumbered_equal_p): Do not call subreg_regno_offset
++      for unrepresentable subregs or treat them as equal to other regs
++      or subregs with the same register number.
++
++2008-08-05  Catherine Moore  <clm@codesourcery.com>
++
++      Issue #3088
++      gcc/
++      * config/mips/sde.h (SUBTARGET_SELF_SPECS): Add
++      MIPS_ARCH_DSP_SPEC.
++      * config/mips/mips.h (MIPS_ARCH_DSP_SPEC): New.
++
++      * release-notes-csl.xml: Document.
++
++2008-08-04  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.target/mips/mips-nonpic/nonpic-9.c (main): Call exit.
++
++2008-07-30  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Issue #2576
++
++      Backport:
++
++      gcc/
++      2008-07-30  Nathan Froyd  <froydnj@codesourcery.com>
++
++      * config/arm/arm.c (arm_expand_prologue): Use 0-length rtvec
++      instead of NULL_RTVEC.
++
++2008-07-28  Mark Mitchell  <mark@codesourcery.com>
++
++      Issue #466
++      gcc/
++      * config/arm/thumb2.md: Add 16-bit multiply instructions.
++      gcc/testsuite/
++      * lib/target-supports.exp (check_effective_target_arm_thumb2_ok):
++      New function.
++      * gcc.target/arm/thumb2-mul-space.c: New file.
++      * gcc.target/arm/thumb2-mul-space-2.c: New file.
++      * gcc.target/arm/thumb2-mul-space-3.c: New file.
++      * gcc.target/arm/thumb2-mul-speed.c: New file.
++
++      * release-notes-csl.xml: Document.
++
++2008-07-29  Catherine Moore  <clm@codesourcery.com>
++          Daniel Jacobowitz <dan@codesourcery.com>
++
++      gcc/
++      * config/mips/mips.h (ISA_HAS_BBIT):  Enable for TARGET_OCTEON.
++      * config/mips/mips.md (branch_with_likely): New attribute.
++      (branch_without_likely): New attribute.
++      (define_delay): Check for new branch_likely attributes.
++      (branch_bit<mode>): Set branch_without_likely to "yes".
++      (branch_bit_truncdi<mode>): Likewise.
++      (branch_bit<mode>_inverted): Likewise.
++      (branch_bit_truncdi<mode>_inverted): Likewise.
++
++2008-07-25  Mark Mitchell  <mark@codesourcery.com>
++
++      Issue #3433
++      gcc/
++      * gcc.c (SWITCHES_NEED_SPACES): Define to "o".
++
++      * release-notes-csl.xml: Document.
++
++2008-07-25  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/arm/iwmmxt.md (movv8qi_internal, movv4hi_internal,
++      movv2si_internal): Use "*" for pool_range and neg_pool_range for
++      mem = reg alternative.
++
++2008-07-25  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-06-03  Maxim Kuvyrkov  <maxim@codesourcery.com>
++      * release-notes-csl.xml: Add note.
++      gcc/
++      * config/mips/mips.c (mips_expand_prologue): Fix thinko.
++
++      2008-05-27  Maxim Kuvyrkov  <maxim@codesourcery.com>
++      -mwarn-framesize=<size> option for MIPS.
++      * release-notes-csl.xml: Add note.
++      gcc/
++      * doc/invoke.texi (mwarn-framesize): Document option.
++      * config/mips/mips.opt (mwarn-framesize): Add option.
++      * config/mips/mips.c (mips_warn_framesize): New static variable.
++      (mips_handle_option): Handle mwarn-framesize.
++      (mips_expand_prologue): Emit warning if frame size exceeds specified
++      value.
++
++2008-07-24  Joseph Myers  <joseph@codesourcery.com>
++
++      * config.sub: Allow mips64octeon* targets.
++
++      NOT ASSIGNED TO FSF
++      COPYRIGHT CAVIUM
++      gcc/
++      * config/mips/octeon-elf-unwind.h, config/mips/octeon-elf.h,
++      config/mips/octeon.h, config/mips/t-octeon-elf: New.
++      * config.gcc: Handle mips64octeon*-wrs-elf*.
++      (mips-wrs-linux-gnu): Use mips/octeon.h.
++      * config/mips/mips-protos.h (octeon_output_shared_variable): New.
++      * config/mips/mips.c (octeon_handle_cvmx_shared_attribute,
++      octeon_select_section, octeon_unique_section,
++      octeon_output_shared_variable): New.
++      (mips_attribute_table): Add cvmx_shared.
++      (mips_in_small_data_p): Check for cvmx_shared attribute.
++      * config/mips/mips.opt (mocteon-useun): Use Mask.
++
++      libgcc/
++      * config.host: Handle mips64octeon*-wrs-elf*.
++
++2008-07-24  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/mips/mips.c (mips_expand_ins_as_unaligned_store): Restore
++      Octeon unaligned store support.
++
++2008-07-21  Mark Mitchell  <mark@codesourcery.com>
++
++      Issue #3245
++
++      Backport:
++
++      libstdc++-v3/
++      2008-07-21  Mark Mitchell  <mark@codesourcery.com>
++      * config/os/gnu-linux/arm-eabi-extra.ver: New file.
++      * configure.host: Use it for arm*-*-linux-*eabi.
++
++      * release-notes-csl.xml: Document.
++
++2008-07-21  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/mips/mips.md (extzv): Avoid using dext instructions for
++      certain DImode subreg extractions.  From Cavium toolchain.
++
++2008-07-21  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * tree-ssa-remove-local-statics.c
++      (find_static_nonvolatile_declarations): Don't check for potential
++      definitions if we're looking at a statement with a CALL_EXPR.
++      (compute_definedness_for_block): Reorganize logic.
++
++      gcc/testsuite/
++      * gcc.dg/remove-local-statics-13.c: New test.
++      * gcc.dg/remove-local-statics-14.c: New test.
++
++2008-07-18  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/testsuite/
++      2008-07-18  Joseph Myers  <joseph@codesourcery.com>
++      * gcc.dg/fshort-wchar.c: Use -Wl,--no-wchar-size-warning on
++      arm*-*-*eabi.
++
++2008-07-17  Catherine Moore  <clm@codesourcery.com>
++
++      gcc/
++      * config/mips/sde.h (TARET_MIPS_SDE): Define to 1.
++      (SUBTARGET_SELF_SPECS): Undefine before defining.
++
++2008-07-10  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/testsuite/
++      2008-07-10  Joseph Myers  <joseph@codesourcery.com>
++      PR middle-end/29056
++      * gcc.target/powerpc/ppc-negeq0-1.c: Use long instead of int.
++      Adjust shift and scan-assembler-not pattern to allow for 64-bit
++      case.
++
++2008-07-10  Joseph Myers  <joseph@codesourcery.com>
++
++      config/
++      * mh-mingw (LDFLAGS): Append to rather than replacing previous
++      value.
++
++2008-07-09  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/mips/linux64.h (SUBTARGET_ASM_SPEC): Update for non-PIC.
++
++2008-07-09  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/mips/wrs-linux.h (SUBTARGET_SELF_SPECS): Add missing
++      comma.
++
++2008-07-09  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      libstdc++-v3/
++      2008-07-09  Joseph Myers  <joseph@codesourcery.com>
++      * libsupc++/unwind-cxx.h (__is_gxx_forced_unwind_class,
++      __GXX_INIT_FORCED_UNWIND_CLASS): Define for ARM EABI unwinder.
++      * libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Call
++      __GXX_INIT_FORCED_UNWIND_CLASS for forced unwind with ARM EABI
++      unwinder.
++      * libsupc++/eh_arm.cc (__cxa_type_match): Use
++      __is_gxx_forced_unwind_class to check for forced unwind.
++
++2008-07-09  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/mips/wrs-linux.h (SUBTARGET_SELF_SPECS): Add
++      NO_SHARED_SPECS.
++
++2008-07-09  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      libstdc++-v3/
++      2008-07-09  Joseph Myers  <joseph@codesourcery.com>
++      * testsuite/20_util/make_signed/requirements/typedefs-2.cc,
++      testsuite/20_util/make_unsigned/requirements/typedefs-2.cc: Use
++      -Wl,--no-enum-size-warning for arm*-*-linux*eabi.
++
++2008-07-09  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/mips/mips.h (ISA_HAS_BBIT): Temporarily disable.
++
++2008-07-09  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/mips/linux64.h (SUBTARGET_SELF_SPECS): Undefine before
++      redefining.
++
++2008-07-08  Catherine Moore  <clm@codesourcery.com>
++
++      gcc/config/mips
++      xlr.md (ir_xlr_alu): Add logical, signext attributes.
++
++2008-07-08  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * passes.c (init_optimization_passes): Move pass_remove_local_statics
++      later in the pass order.
++      * tree-ssa-remove-local-statics.c (rls_done): Conditionally free the
++      bitmaps and NULL out bb->aux.
++      (unstaticize_variable): Deal with GIMPLE_MODIFY_STMTs instead of
++      MODIFY_EXPRs.
++      (compute_definedness_for_block): Check for defines only if we haven't
++      found a CALL_EXPR.
++
++2008-07-07  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      2008-07-07  Joseph Myers  <joseph@codesourcery.com>
++      * config/arm/aout.h (DOLLARS_IN_IDENTIFIERS): Remove.
++
++2008-07-07  Vladimir Prus  <vladimir@codesourcery.com>
++
++      gcc/
++      * gcc.c (print_sysroot): New.
++      (option_map, display_help, process_command): Handle the
++      -print-sysroot option.
++      (main): Print the sysroot if requested.
++
++      gcc/doc/
++      * invoke.texi (Debugging Options): Document -print-sysroot.
++
++2008-07-03  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_init_neon_builtins): Register built-in
++      types immediately after creating them.
++
++2008-07-03  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (add_minipool_backward_ref): Check for
++      8-byte-aligned entries in second case of forcing insertion after a
++      particular entry.  Change third case to avoid inserting
++      non-8-byte-aligned entries before 8-byte-aligned ones.
++
++2008-07-03  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/arm/iwmmxt.md (movv8qi_internal, movv4hi_internal,
++      movv2si_internal): Add mem = reg alternative.
++
++2008-07-03  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-07-02  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config/rs6000/t-ppcgas (MULTILIB_OPTIONS): Add te500mc.
++      (MULTILIB_DIRNAMES): Likewise.
++      (MULTILIB_EXCEPTIONS): Add exception for te500mc.
++      * config/rs6000/eabi.h (NAME__MAIN, INVOKE__main): Remove.
++      (CC1_EXTRA_SPEC): Add te500mc clause.
++      (ASM_DEFAULT_SPEC): Likewise.
++      * config/rs6000/t-ppccomm (LIB2FUNS_STATIC_EXTRA): Remove eabi.S.
++      (eabi.S): Remove rule.
++
++2008-07-03  Nathan Sidwell  <nathan@codesourcery.com>
++
++      gcc/
++      * config/m68k/t-uclinux (M68K_MLIB_CPU): Check for FL_UCLINUX.
++      * config/m68k/m68k-devices.def: Add FL_UCLINUX to 68020 and 54455
++      multilibs.
++      * config/m68k/m68k.h (FL_UCLINUX): Define.
++
++      * release-notes-csl.xml: Document.
++
++2008-07-02  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * c-incpath.c: Include toplev.h.
++      (merge_include_chains): Use warning instead of cpp_error for
++      system directory poisoning diagnostic.
++      * Makefile.in (c-incpath.o): Depend on toplev.h.
++      * gcc.c (LINK_COMMAND_SPEC): Pass
++      --error-poison-system-directories if
++      -Werror=poison-system-directories.
++
++2008-07-02  Julian Brown  <julian@codesourcery.com>
++
++      Backport from mainline:
++
++      2008-06-27  Mark Mitchell  <mark@codesourcery.com>
++
++      libstdc++-v3/
++      * libsupc++/vec.cc (__aeabi_vec_dtor_cookie): Handle NULL array
++      address.
++      (__aeabi_vec_delete): Likewise.
++      (__aeabi_vec_delete3): Likewise.
++      (__aeabi_vec_delete3_nodtor): Likewise.
++
++      gcc/testsuite/
++      * g++.dg/abi/arm_cxa_vec2.C: New test.
++
++2008-07-01  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/testsuite/
++      * lib/target-supports.exp (check_effective_target_arm_neon): New.
++      (check_effective_target_vect_cmdline_needed): Use it.
++
++2008-07-01  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/arm/neon.md (neon_vget_lane<mode>_sext_internal,
++      neon_vget_lane<mode>_zext_internal): Adjust element indices for
++      big-endian.
++
++2008-07-01  Nathan Sidwell  <nathan@codesourcery.com>
++
++      gcc/
++      * config/mips/linux.h (SUBTARGET_SELF_SPECS): Override this,
++      rather than ...
++      (DRIVER_SELF_SPECS): ... this.
++      * config/mips/mips.md (extzv, extzv<mode>, insv, insv<mode>,
++      *insv<mode>di): Use mips_use_ins_ext_p rather than mips_use_ext_p
++      and mips_use_ins_p.
++      * config/mips/mips-protos.h (mips_lower_sign_bit_p,
++      mips_use_ext_p): Delete.
++      (mips_expand_vector_init): Declare.
++      * config/mips/mips.c (mips_gnu_local_gp): Declare.
++      (mips_got_base): Use can_create_pseudo_p.
++      (mips16_build_function_stub): Remove unused variable.
++      (mips_lower_sign_bit_p, mips_use_ins_p, mips_use_ext_p): Delete.
++
++      gcc/
++      * config/mips/mips.md (type): Correct typo for accext.
++
++2008-06-30  Joseph Myers  <joseph@codesourcery.com>
++
++      config/
++      * mh-mingw (BOOT_CFLAGS): Do not use -D__USE_MINGW_ACCESS.
++
++2008-06-28  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Backport 2 patches from mainline:
++
++      2008-06-28  Sandra Loosemore  <sandra@codesourcery.com>
++
++      gcc/
++      * doc/extend.texi (Variable Attributes): Use @ref instead of @xref.
++      (Type Attributes): Fix nesting of @table and @subsection.  Adjust
++      punctuation.  Use @ref instead of @xref.
++      (Function Names): Remove stray @display/@end display.
++      (C++ Attributes): Use @ref instead of @xref.
++      (Deprecated Features): Fix punctuation around @xref.
++      (Backwards Compatibility): Likewise.
++      * doc/rtl.texi (Incdec): Remove stray @table/@end table.
++
++      2008-06-15  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
++
++      gcc/
++      * doc/sourcebuild.texi (Config Fragments): Remove obsolete
++      FIXME note about gcc/config.guess.
++      * doc/options.texi (Option file format): Remove non-ASCII bytes.
++      * doc/cpp.texi: Expand TABs, drop indentation outside examples.
++      * doc/cppopts.texi: Likewise.
++      * doc/extend.texi: Likewise.
++      * doc/gcc.texi: Likewise.
++      * doc/gccint.texi: Likewise.
++      * doc/gcov.texi: Likewise.
++      * doc/gty.texi: Likewise.
++      * doc/hostconfig.texi: Likewise.
++      * doc/install.texi: Likewise.
++      * doc/invoke.texi: Likewise.
++      * doc/loop.texi: Likewise.
++      * doc/makefile.texi: Likewise.
++      * doc/md.texi: Likewise.
++      * doc/passes.texi: Likewise.
++      * doc/tm.texi: Likewise.
++      * doc/tree-ssa.texi: Likewise.
++      * doc/trouble.texi: Likewise.
++
++2008-06-27  Julian Brown  <julian@codesourcery.com>
++
++      gcc/cp/
++      * decl2.c (determine_visibility): Allow target to override
++      visibility of class data.
++
++      gcc/
++      * config/arm/arm.c (arm_cxx_determine_class_data_visibility): Make
++      no-op for targets which don't use DLLs.
++
++      gcc/testsuite/
++      * g++.dg/ext/visibility/arm3.C: Add explanatory text. Skip on
++      non-DLL targets.
++
++2008-06-26  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-02-13  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * optabs.c (expand_binop): Force operands to registers before
++      generating libcalls.
++
++2008-06-26  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/
++      * config/mips/mips.c (mips_call_tls_get_addr)
++      (mips_emit_loadgp): Correct merge.
++
++2008-06-26  Joseph Myers  <joseph@codesourcery.com>
++
++      * release-notes-csl.xml: Resync release note text with Sourcery
++      G++ 4.2.
++
++2008-06-25  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from SourceryG++ 4.2:
++
++      2008-04-01  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/mips/mips.h (TARGET_CPU_CPP_BUILTINS): Define
++      __mips_isa_rev=2 for Octeon.
++
++2008-06-25  Julian Brown  <julian@codesourcery.com>
++
++      gcc/
++      * config.gcc (arm*-*-uclinux*): Remove duplicate uclinux-elf.h.
++
++2008-06-25  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from SourceryG++ 4.2:
++
++      2008-02-15  Julian Brown  <julian@codesourcery.com>
++
++      Merge from MIPS:
++
++      2007-11-06  David Ung  <davidu@mips.com>
++
++      gcc/
++      * config/mips/mips.h (AC1HI_REGNUM, AC1LO_REGNUM, AC2HI_REGNUM)
++      (AC2LO_REGNUM, AC3HI_REGNUM, AC3LO_REGNUM): Define constants.
++
++2008-06-25  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from SourceryG++ 4.2:
++
++      2007-07-02  Richard Sandiford  <richard@codesourcery.com>
++
++      gcc/
++      * config/mips/mips.h (MIPS_ISA_LEVEL_SPEC): Handle -march=octeon.
++
++2008-06-25  Catherine Moore  <clm@codesourcery.com>
++
++      Revert:
++
++      2008-06-25  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from SourceryG++ 4.2:
++
++      2007-10-18  Joseph Myers  <joseph@codesourcery.com>
++
++      NOT ASSIGNED TO FSF
++      COPYRIGHT RAZA
++      * config.sub (mipsisa64xlr, ipsisa64xlrel): Add new machine names.
++
++      gcc/
++      * config.gcc (mipsisa64xlr-*-elf*, mipsisa64xlrel-*-elf*): New
++      targets.
++
++2008-06-25  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from SourceryG++ 4.2:
++
++      2007-10-18  Joseph Myers  <joseph@codesourcery.com>
++
++      NOT ASSIGNED TO FSF
++      COPYRIGHT RAZA
++      * config.sub (mipsisa64xlr, ipsisa64xlrel): Add new machine names.
++
++      gcc/
++      * config.gcc (mipsisa64xlr-*-elf*, mipsisa64xlrel-*-elf*): New
++      targets.
++      * config/mips/mips.h (PROCESSOR_XLR, TARGET_XLR): Define.
++      (MIPS_ISA_LEVEL_SPEC): Handle -march=xlr.
++
++2008-06-24  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from SourceryG++ 4.2:
++
++      2008-02-12  Julian Brown  <julian@codesourcery.com>
++
++      Merge from MIPS:
++
++      2008-01-16  David Ung  <davidu@mips.com>
++
++      * config/mips/sdemtk.h: Define macro TARGET_MIPS_SDEMTK.
++      * config/mips/mips.c (mips_file_start): Check against
++      TARGET_MIPS_SDEMTK which supports the TARGET_NO_FLOAT option.
++
++      2007-11-02  Thiemo Seufer  <ths@mips.com>
++
++      * config/mips/mips.c (mips_file_start): Add support for flagging
++      32-bit code with -mfp64 floating point.
++
++2008-06-24  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from SourceryG++ 4.2:
++
++      2008-03-12  Julian Brown  <julian@codesourcery.com>
++
++      Merge from MIPS:
++
++      2007-11-29  Thiemo Seufer  <ths@mips.com>
++
++      gcc/
++      * config/mips/mips.c (override_options): Let -fpic imply
++      -mabicalls, forward port from SDE6.
++
++2008-06-23  Julian Brown  <julian@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.h (ASM_OUTPUT_REG_PUSH): Handle STATIC_CHAIN_REGNUM
++      specially for Thumb-1.
++      (ASM_OUTPUT_REG_POP): Likewise.
++
++2008-06-23  Julian Brown  <julian@codesourcery.com>
++
++      gcc/
++      * config/arm/thumb2.md (*thumb2_negscc): Remove bad negated-GT
++      code sequence.
++
++2008-06-20  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from SourceryG++ 4.2:
++
++      2007-10-21  Sandra Loosemore  <sandra@codesourcery.com>
++
++      gcc/
++      * config/mips/mips.c (mips_cpu_info_table): Fix damaged merge
++      of XLR entry from r185319.
++      (mips_rtx_cost_data): Likewise.
++      (mips_sched_reorder): Add ATTRIBUTE_UNUSED to cycle parameter.
++
++2008-06-18  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from SourceryG++ 4.2:
++
++      2007-09-06  Sandra Loosemore  <sandra@codesourcery.com>
++
++      gcc/
++      * config/mips/mips.opt (mips16e): Add as deprecated alias
++      for -mips16.
++      * doc/invoke.texi (Option Summary, MIPS Options): Document it.
++
++2008-06-18  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from SourceryG++ 4.2:
++
++      2008-02-12  Julian Brown  <julian@codesourcery.com>
++
++      Merge from MIPS:
++
++      2007-12-21  David Ung  <davidu@mips.com>
++
++      gcc/
++      * config/mips/mips.h (TARGET_MIPS_SDE): Define macro as 0.
++      * config/mips/sde.h (TARGET_MIPS_SDE): Override macro definition to 1.
++      * config/mips/mips.md (abs<mode>2): Enable abs.[sd] patterns if
++      TARGET_MIPS_SDE && TARGET_HARD_FLOAT.
++
++2008-06-18  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from SourceryG++ 4.2:
++
++      2007-10-14  Sandra Loosemore  <sandra@codesourcery.com>
++
++      * config/mt-sde: Update to make it agree with the mainline
++      version committed with the below patch.
++
++      Backport from mainline:
++      gcc/
++
++      2007-08-17  Richard Sandiford  <richard@codesourcery.com>
++          Nigel Stephens  <nigel@mips.com>
++
++      * config/mips/sde.h (DRIVER_SELF_SPECS): Add commas.
++      Treat -mno-data-in-code and -mcode-xonly as aliases for
++      -mcode-readable=no and -mcode-readable=pcrel respectively.
++      * config/mips/t-sde (TARGET_LIBGCC2_CFLAGS): Add -mcode-xonly.
++      (MULTILIB_OPTIONS): Add -mcode-readable=no multilibs.
++      (MULTILIB_DIRNAMES): Update accordingly.
++
++2008-06-18  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from SourceryG++ 4.2:
++
++      2007-09-08  Sandra Loosemore  <sandra@codesourcery.com>
++
++      gcc/
++      * config/mips/t-sde (MULTILIB_MATCHES):  Add mips16e as alias
++      for mips16.
++
++2008-06-18  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_assemble_integer): Do not handle
++      big-endian NEON vectors specially.
++      * config/arm/neon.md (vec_set<mode>_internal, vec_extract<mode>):
++      Adjust element indices for big-endian.
++
++2008-06-18  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from SourceryG++ 4.2:
++
++      2008-02-11  Julian Brown  <julian@codesourcery.com>
++
++      Merge from MIPS:
++
++      gcc/
++      * config/mips/t-sde (MULTILIB_OPTIONS): Substitute mno-data-in-code for
++      mcode-readable=no option.
++
++2008-06-17  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from SourceryG++ 4.2:
++
++      2008-03-28  Nathan Sidwell  <nathan@codesourcery.com>
++
++      * config/mips/t-sdemtk (MULTILIB_OPTIONS, MULTILIB_DIRNAMES,
++      MULTILIB_EXCLUSIONS): Likewise.
++
++2008-06-17  Catherine Moore  <clm@codesourcery.com>
++
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-03-17  Julian Brown  <julian@codesourcery.com>
++
++      gcc/
++      * config.gcc (mips*-sde-elf*): Add SourceryG++ multilib support.
++      * config/mips/t-sgxx-sde: New.
++      * config/mips/sdemtk.h (MIPS_ARCH_FLOAT_SPEC): Override, adding
++      -mno-float option.
++
++2008-06-17  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      2008-03-09  Ira Rosen  <irar@il.ibm.com>
++      * config/rs6000/rs6000.c (builtin_description): Rename vector
++      left shift operations.
++      * config/rs6000/altivec.md (UNSPEC_VSL): Remove.
++      (altivec_vsl<VI_char>): Rename to ...
++      (ashl<mode>3): ... new name.
++      (mulv4sf3, mulv4si3, negv4sf2): Replace gen_altivec_vslw with
++      gen_ashlv4si3.
++      (absv4sf2): Convert to use ashift:V4SI instead of UNSPEC_VSL.
++
++2008-06-16  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-30  Mark Mitchell  <mark@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.dg/sibcall-3.c: XFAIL for Thumb.
++      * gcc.dg/sibcall-4.c: Likewise.
++
++2008-06-16  Paul Brook  <paul@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2
++      2007-03-30  Paul Brook  <paul@codesourcery.com>
++      gcc/
++      * calls.c (store_one_arg): Check alignment of mode used for save.
++
++2008-06-13  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config.gcc (powerpc-*-linux*): Add rs6000/e500.h to tm_file
++      and rs6000/t-linux to tmake_file.
++
++2008-06-13  Paul Brook  <paul@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2
++      Issue #1510
++      2007-04-27  Paul Brook  <paul@codesourcery.com>
++      gcc/
++      * cse.c (cse_process_notes): Make sure PLUS are canonical.
++
++2008-06-13  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      libgcc/
++      * config.host (arm*-*-linux*, arm*-*-uclinux*, arm*-*-eabi*)
++      (arm*-*-symbianelf): Add arm/t-divmod-ef to tmake_file.
++      * Makefile.in (LIB2_DIVMOD_EXCEPTION_FLAGS): Set to previous
++      default if not set by a target-specific Makefile fragment.
++      (lib2-divmod-o, lib2-divmod-s-o): Use above.
++      * config/arm/t-divmod-ef: New.
++
++2008-06-13  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      libgcc/
++      * shared-object.mk (c_flags-$(base)$(objext)): New.
++      ($(base)$(objext)): Use above.
++      ($(base)_s$(objext)): Likewise.
++      * static-object.mk (c_flags-$(base)$(objext)): New.
++      ($(base)$(objext)): Use above.
++
++2008-06-13  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/testsuite/
++      * lib/target-supports.exp (check_effective_target_vect_int)
++      (check_effective_target_vect_shift)
++      (check_effective_target_vect_long)
++      (check_effective_target_vect_float)
++      (check_effective_target_vect_int_mult): Check for ARM.
++
++2008-06-12  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/
++      * config/mips/linux64.h: USE_SUBTARGET_SELF_SPECS.
++      * config/mips/sde.h: Likewise.
++      * config/mips/iris6.h: Likewise.
++
++2008-06-12  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-02-15  Julian Brown  <julian@codesourcery.com>
++
++      gcc/
++      * config/mips/t-sgxx-linux: New target fragment.
++      * config/mips/t-sgxxlite-linux: New target fragment.
++      * config/mips/cs-sgxx-linux.h: New header file.
++      * config/mips/cs-sgxxlite-linux.h: New header file.
++      * config/mips/t-none-linux: Remove.
++      * config/mips/cs-linux.h: Remove.
++      * config.gcc (mips*-*-linux*): Handle --enable-extra-sgxx-multilibs
++      and --enable-extra-sgxxlite-multilibs configure options. Use
++      sgxx-specific header files and target fragments. Remove use of
++      t-none-linux and cs-linux.h.
++
++2008-06-12  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-03-25  Maxim Kuvyrkov  <maxim@codesourcery.com>
++          Julian Brown  <julian@codesourcery.com>
++
++      * 74k.md: (r74k_dsp_alu, r74k_dsp_alu_sat, r74k_dsp_mac, r74k_dsp_mac_sat)
++      (r74k_dsp_acc_ext, r74k_dsp_acc_mod): New insn reservations.
++      (r74k_dsp_mac, r74k_dsp_mac_sat, r74k_int_mult, r74k_int_mul3)
++      (r74k_dsp_mac, r74k_dsp_mac_sat): New bypasses.
++
++
++2008-06-12  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-03-25  Maxim Kuvyrkov  <maxim@codesourcery.com>
++          Julian Brown  <julian@codesourcery.com>
++
++      Merge from MIPS:
++
++      gcc/
++      * config/mips/mips-protos.h (dspalu_bypass_p): Add prototype.
++      * config/mips/mips.c (dspalu_bypass_table): New.
++      (dspalu_bypass_p): New.
++      * 24k.md (r24k_dsp_alu, r24k_dsp_mac, r24k_dsp_mac_sat)
++      (r24k_dsp_acc_ext, r24k_dsp_acc_mod): New insn reservations.
++      (r24k_int_mult, r24k_int_mthilo, r24k_dsp_mac, r24k_dsp_mac_sat)
++      (r24k_dsp_acc_ext, r24k_dsp_acc_mod, r24k_dsp_alu): New bypasses.
++      * config/mips/mips.md (dspmac, dspmacsat, accext, accmod, dspalu)
++      (dspalusat): Add insn types.
++      * config/mips/mips-dsp.md (add<DSPV:mode>3)
++      (mips_add<DSP:dspfmt1>_s_<DSP:dspfmt2>)
++      (sub<DSPV:mode>3, mips_sub<DSP:dspfmt1>_s_<DSP:dspfmt2>, mips_addsc)
++      (mips_addwc, mips_modsub, mips_raddu_w_qb, mips_absq_s_<DSPQ:dspfmt2>)
++      (mips_precrq_qb_ph, mips_precrq_ph_w, mips_precrq_rs_ph_w)
++      (mips_precrqu_s_qb_ph, mips_preceq_w_phl, mips_preceq_w_phr)
++      (mips_precequ_ph_qbl, mips_precequ_ph_qbr, mips_precequ_ph_qbla)
++      (mips_precequ_ph_qbra, mips_preceu_ph_qbl, mips_preceu_ph_qbr)
++      (mips_preceu_ph_qbla, mips_preceu_ph_qbra, mips_shll_<DSPV:dspfmt2>)
++      (mips_shll_s_<DSPQ:dspfmt2>, mips_shll_s_<DSPQ:dspfmt2>, mips_shrl_qb)
++      (mips_shra_ph, mips_shra_r_<DSPQ:dspfmt2>, mips_bitrev, mips_insv)
++      (mips_repl_qb, mips_repl_ph, mips_cmp<DSPV:dspfmt1_1>_eq_<DSPV:dspfmt2>)
++      (mips_cmp<DSPV:dspfmt1_1>_lt_<DSPV:dspfmt2>)
++      (mips_cmp<DSPV:dspfmt1_1>_le_<DSPV:dspfmt2>, mips_cmpgu_eq_qb)
++      (mips_cmpgu_lt_qb, mips_cmpgu_le_qb, mips_pick_<DSPV:dspfmt2>)
++      (mips_packrl_ph, mips_wrdsp, mips_rddsp): Change type to dspalu.
++      (mips_dpau_h_qbl, mips_dpau_h_qbr, mips_dpsu_h_qbl, mips_dpsu_h_qbr)
++      (mips_dpaq_s_w_ph, mips_dpsq_s_w_ph, mips_mulsaq_s_w_ph)
++      (mips_maq_s_w_phl, mips_maq_s_w_phr, mips_maq_sa_w_phr: Set type to
++      dspmac.
++      (mips_dpaq_sa_l_w, mips_dpsq_sa_l_w, mips_maq_sa_w_phl): Set type to
++      dspmacsat.
++      (mips_extr_w, mips_extr_r_w, mips_extr_rs_w, mips_extp, mips_extpdp):
++      Set type to accext.
++      (mips_shilo, mips_mthlip): Set type to accmod.
++      * config/mips/mips-dspr2.md (mips_absq_s_qb, mips_addu_s_ph)
++      (mips_adduh_r_qb): Set type to dspalusat.
++      (mips_addu_ph, mips_adduh_qb, mips_append, mips_balign)
++      (mips_cmpgdu_eq_qb, mips_cmpgdu_lt_qb, mips_cmpgdu_le_qb)
++      (mips_precr_qb_ph, mips_precr_sra_ph_w, mips_precr_sra_r_ph_w)
++      (mips_prepend, mips_shra_qb, mips_shra_r_qb, mips_shrl_ph)
++      (mips_subu_ph, mips_subuh_qb, mips_subuh_r_qb, mips_addqh_ph)
++      (mips_addqh_r_ph, mips_addqh_w, mips_addqh_r_w, mips_subqh_ph)
++      (mips_subqh_r_ph, mips_subqh_w, mips_subqh_r_w): Set type to dspalu.
++      (mips_dpa_w_ph, mips_dps_w_ph, mips_mulsa_w_ph, mips_dpax_w_ph)
++      (mips_dpsx_w_ph, mips_dpaqx_s_w_ph, mips_dpsqx_s_w_ph): Set type to
++      dspmac.
++      (mips_subu_s_ph): Set type to dspalusat.
++      (mips_dpaqx_sa_w_ph, mips_dpsqx_sa_w_ph): Set type to dspmacsat.
++
++2008-06-12  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/testsuite/
++      * lib/target-supports.exp
++      (check_effective_target_powerpc_hard_double): New.
++      * gcc.dg/tree-ssa/loop-19.c: Use powerpc_hard_double instead of
++      powerpc*-*-*.
++
++2008-06-12  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.dg/dfp/convert-bfp-6.c, gcc.dg/dfp/convert-bfp-9.c: XFAIL
++      for lax_strtofp.
++
++2008-06-12  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      2008-05-21  Janis Johnson  <janis187@us.ibm.com>
++      * doc/sourcebuild.texi (Test Directives): Add dg-xfail-run-if.
++
++      gcc/testsuite/
++      2008-05-21  Janis Johnson  <janis187@us.ibm.com>
++      * lib/target-supports-dg.exp (dg-xfail-run-if): New.
++
++2008-06-12  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-03-25  Maxim Kuvyrkov  <maxim@codesourcery.com>
++          Julian Brown  <julian@codesourcery.com>
++
++      Merge from MIPS:
++
++      gcc/
++      * config/mips/mips.c (mips_mult_madd_chain_bypass_p): New.
++      * config/mips/mips-protos.h (mips_mult_madd_chain_bypass_p): Add
++      prototype.
++      * config/mips/74k.md: Add bypasses for r74k_int_mult, r74_int_madd,
++      r74k_int_mul3.
++
++
++2008-06-11  Catherine Moore  <clm@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      2008-06-06  Sandip Matte  <sandip@rmicorp.com>
++
++      * doc/invoke.texi: Document -march=xlr.
++      * config/mips/xlr.md: New file.
++      * config/mips/mips.md: Include it.
++      (cpu): Add "xlr".
++      * config/mips/mips.h (PROCESSOR_XLR): New processor_type.
++      * config/mips/mips.c (mips_cpu_info_table): Add an XLR entry.
++      (mips_rtx_cost_data): Likewise.
++
++2008-06-10  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++
++      2008-03-27  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/
++      * config/mips/mips.md (loadgp_nonpic): New pattern.
++      (builtin_longjmp): Use for all TARGET_ABICALLS.
++      (exception_receiver): Revert local changes.
++      * config/mips/mips.c (mips_gnu_local_gp, mips_got_base): New functions.
++      (struct machine_function): Update the comment for
++      mips16_gp_pseudo_rtx.
++      (mips_call_tls_get_addr, mips_legitimize_tls_address): Use
++      mips_got_base.
++      (mips_restore_gp): Revert local changes.  Assert PIC.
++      (mips_load_call_address, mips_expand_call): Revert local changes.
++      (mips_conditional_register_usage): Make $gp ordinary for
++      non-PIC.
++      (mips_tls_got_ref_1, mips_tls_got_ref_p): Delete.
++      (mips_function_has_gp_insn, mips_global_pointer): Revert local changes.
++      (mips_save_reg_p): Check for fixed $gp.
++      (mips_gnu_local_gp_rtx): Renamed from mips_gnu_local_gp.
++      (mips_emit_loadgp): Use mips_gnu_local_gp.
++      (mips_dangerous_for_la25_p): Revert local change.
++      (mips16_gp_pseudo_reg): Use gen_loadgp_nonpic.
++      (mips_extra_live_on_entry): Revert local change.
++      * config/mips/mips.h (TARGET_USE_GOT): Require flag_pic.
++      (TARGET_CALL_CLOBBERED_GP): Likewise.
++      (TARGET_NONPIC_ABICALLS): Define.
++      2008-03-19  Mark Shinwell  <shinwell@codesourcery.com>
++                  Catherine Moore  <clm@codesourcery.com>
++                  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/
++      * configure.ac: Add --enable-mips-nonpic.
++      * configure: Regenerated.
++      * config.gcc: Set TARGET_ABICALLS_DEFAULT instead of MASK_ABICALLS
++      for MIPS targets.  Handle --enable-mips-nonpic.
++      * config/mips/linux.h (TARGET_DEFAULT): Delete.
++      (SUBTARGET_ASM_SPEC): Use -mnon-pic-abicalls.
++      * config/mips/elfoabi.h, config/mips/linux64.h,
++      config/mips/sde.h, config/mips/iris6.h, config/mips/wrs-linux.h,
++      config/mips/vr.h: Use SUBTARGET_SELF_SPECS.
++      * config/mips/mips.md (exception_receiver): Disable for
++      non-PIC.
++      * config/mips/mips.c (mips_classify_symbol): Do not use the GOT
++      for non-PIC.
++      (mips_tls_symbol_ref_1, mips_cannot_force_const_mem): Correct comments.
++      (mips_restore_gp): Skip for non-PIC.
++      (mips_load_call_address): Skip lazy binding for non-PIC.
++      (mips_expand_call): Skip GP usage for non-PIC.
++      (override_options): Remove flag_pic override.  Use sorry for
++      other ABIs.
++      (mips_file_start): Emit pic0 for non-PIC.
++      (mips_tls_got_ref_1, mips_tls_got_ref_p): New.
++      (mips_function_has_gp_insn): Use mips_tls_got_ref_p.  Skip jump
++      tables.
++      (mips_global_pointer, mips_current_loadgp_style): Adjust for non-PIC.
++      (mips_expand_prologue): Do not cprestore for non-PIC.
++      (mips_function_rodata_section): Skip for non-PIC.
++      (mips_dangerous_for_la25_p): Likewise.
++      (mips_extra_live_on_entry): Skip for non-PIC.
++      * config/mips/mips.h (TARGET_GPWORD): Require flag_pic.
++      (ABICALLS_SPEC, ABICALLS_SELF_SPECS, SUBTARGET_SELF_SPECS)
++      (DRIVER_SELF_SPECS): New.
++      (MIPS_CALL): Correct for non-PIC.
++
++2008-06-09  Kazu Hirata  <kazu@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-05-28  Kazu Hirata  <kazu@codesourcery.com>
++
++      Issue 2895
++      gcc/
++      * config.gcc (arm*-*-linux*): Handle enable_extra_asa_multilibs.
++      enable_extra_asa_multilibs.
++      * config/arm/t-asa: New.
++
++      2008-05-28  Kazu Hirata  <kazu@codesourcery.com>
++
++      * config/arm/t-asa (MULTILIB_EXCEPTIONS): Remove
++      march=armv4t/mfpu=neon* and march=armv4t/*mfloat-abi=softfp.  Add
++      *march=armv4t*/*mfpu=neon* and *march=armv4t*/*mfloat-abi=softfp*.
++      (MULTILIB_ALIASES): Remove march?armv4t=mthumb/march?armv4t* and
++      march?armv6=mthumb/march?armv6*. Add
++      march?armv4t=mthumb/march?armv4t, march?armv6=mthumb/march?armv6,
++      and
++      march?armv6/mfloat-abi?softfp=mthumb/march?armv6/mfloat-abi?softfp.
++
++2008-06-09  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.target/powerpc/20030218-1.c: Separate dg-message and
++      dg-error for two diagnostics on the same line.
++
++2008-06-09  Catherine Moore  <clm@codesourcery.com>
++
++      From 4.2 branch:
++
++      gcc/testsuite/
++      * gcc.target/mips/branch-1.c: Support OCTEON.
++
++2008-06-09  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/testsuite/
++      2008-05-20  Janis Johnson  <janis187@us.ibm.com>
++      * g++.dg/ext/vector14.C: Ignore a possible warning.
++
++2008-06-09  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/testsuite/
++      2008-06-09  Joseph Myers  <joseph@codesourcery.com>
++      * gcc.dg/pr34856.c: Condition use of -maltivec on
++      powerpc_altivec_ok.  Use -w on other powerpc*-*-linux*.
++
++2008-06-09  Catherine Moore  <clm@codesourcery.com>
++
++      From 4.2 branch:
++
++      gcc/testsuite/
++      * gcc.target/mips/mips-nonpic: New testsuite.
++
++2008-06-09  Catherine Moore  <clm@codesourery.com>
++
++      gcc/testsuite/
++      * gcc.target/mips/mips32-dsp-run.c (mipsisa32-sde-elf): Add as
++      target.
++      * gcc.target/mips/mips32-dsp.c: Likewise.
++
++2008-06-07  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/testsuite/
++      2008-04-04  Janis Johnson  <janis187@us.ibm.com>
++      * g++.dg/other/anon5.C: Don't depend on line number for error message.
++      * gcc.dg/torture/builtin-modf-1.c: Use special options for
++      powerpc*-*-linux*.
++      * gcc.dg/var-expand3.c: Skip for powerpc-linux if not on AltiVec HW.
++      * gcc.dg/pr34856.c: Use -maltivec on powerpc linux.
++
++2008-06-07  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.target/powerpc/altivec-24.c, gcc.target/powerpc/pr35907.c:
++      Correct target selector syntax.
++
++2008-06-06  Sandra Loosemore  <sandra@codesourcery.com>
++
++      From 4.2 branch:
++
++      * release-notes-csl.xml (GCC stack size limit increased):
++      Conditionalize release note for host.
++      (UNC pathname bug fix): Likewise.
++
++2008-06-06  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/arm/wrs-linux.h (SUBTARGET_EXTRA_LINK_SPEC): Don't pass
++      --be8 for -r links.
++
++2008-06-06  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      libstdc++-v3/
++      2008-06-06  Joseph Myers  <joseph@codesourcery.com>
++      * configure.ac: Do not check for gconv.h.
++      * crossconfig.m4 (GLIBCXX_CROSSCONFIG): Do not test for gconv.h or
++      gconf.h.  For glibc and uClibc systems, define
++      _GLIBCXX_USE_RANDOM_TR1 and HAVE_MMAP and use AC_LC_MESSAGES and
++      AM_ICONV.
++      * configure, config.h.in: Regenerate.
++
++2008-06-06  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      libstdc++-v3/
++      2008-06-06  Joseph Myers  <joseph@codesourcery.com>
++      * testsuite/17_intro/headers/all.cc,
++      testsuite/17_intro/headers/all_c++200x_compatibility.cc,
++      testsuite/17_intro/headers/all_pedantic_errors.cc,
++      testsuite/ext/headers.cc: Only include
++      <ext/codecvt_specializations.h> and <ext/enc_filebuf.h> if
++      _GLIBCXX_HAVE_ICONV.
++
++2008-06-05  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2006-12-15  Richard Sandiford  <richard@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.target/mips/mips.exp (setup_mips_tests): Record whether
++      endianness is forced.  Trest -mabicalls and -mno-abicalls as
++      ABI options.
++      (is_gp32_flag): Treat -mabi=32 as a 32-bit option.
++      (is_gp64_flag): New function.
++      (dg-mips-options): Generalize -mgp64 handling to is_gp64_flag.
++      Do not set the ABI if the arguments already specify one.
++      Skip tests if the arguments specify an incompatible ABI.
++      Use -mno-abicalls for -mabi=eabi.
++      * gcc.target/mips/octeon-1.c, gcc.target/mips/octeon-2.c: New tests.
++      * gcc.target/mips/octeon-3.c, gcc.target/mips/octeon-4.c: Likewise
++      * gcc.target/mips/octeon-5.c, gcc.target/mips/octeon-6.c: Likewise
++      * gcc.target/mips/octeon-7.c, gcc.target/mips/octeon-8.c: Likewise
++      * gcc.target/mips/octeon-9.c, gcc.target/mips/octeon-10.c: Likewise
++      * gcc.target/mips/octeon-11.c, gcc.target/mips/octeon-12.c: Likewise
++      * gcc.target/mips/octeon-13.c, gcc.target/mips/octeon-14.c: Likewise
++      * gcc.target/mips/octeon-15.c, gcc.target/mips/octeon-16.c: Likewise
++      * gcc.target/mips/octeon-17.c, gcc.target/mips/octeon-18.c: Likewise
++      * gcc.target/mips/octeon-19.c, gcc.target/mips/octeon-20.c: Likewise
++      * gcc.target/mips/octeon-21.c, gcc.target/mips/octeon-22.c: Likewise
++      * gcc.target/mips/octeon-23.c, gcc.target/mips/octeon-24.c: Likewise
++      * gcc.target/mips/octeon-25.c, gcc.target/mips/octeon-26.c: Likewise
++      * gcc.target/mips/octeon-27.c, gcc.target/mips/octeon-28.c: Likewise
++      * gcc.target/mips/octeon-29.c, gcc.target/mips/octeon-30.c: Likewise
++      * gcc.target/mips/octeon-31.c, gcc.target/mips/octeon-32.c: Likewise
++      * gcc.target/mips/octeon-33.c, gcc.target/mips/octeon-34.c: Likewise
++      * gcc.target/mips/octeon-35.c, gcc.target/mips/octeon-36.c: Likewise
++      * gcc.target/mips/octeon-37.c, gcc.target/mips/octeon-38.c: Likewise
++      * gcc.target/mips/octeon-39.c, gcc.target/mips/octeon-40.c: Likewise
++      * gcc.target/mips/octeon-41.c, gcc.target/mips/octeon-42.c: Likewise
++      * gcc.target/mips/octeon-43.c, gcc.target/mips/octeon-44.c: Likewise
++      * gcc.target/mips/octeon-45.c, gcc.target/mips/octeon-46.c: Likewise
++      * gcc.target/mips/octeon-47.c, gcc.target/mips/octeon-48.c: Likewise
++      * gcc.target/mips/octeon-49.c, gcc.target/mips/octeon-50.c: Likewise
++      * gcc.target/mips/octeon-51.c, gcc.target/mips/octeon-52.c: Likewise
++      * gcc.target/mips/octeon-53.c, gcc.target/mips/octeon-54.c: Likewise
++      * gcc.target/mips/octeon-55.c, gcc.target/mips/octeon-56.c: Likewise
++      * gcc.target/mips/scc-1.c, gcc.target/mips/scc-2.c: Likewise.
++      * gcc.target/mips/branch-1.c: Likewise.
++2008-06-05  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2006-12-15  Richard Sandiford  <richard@codesourcery.com>
++
++      Adapted from a patch by Cavium Networks.
++
++      gcc/
++      * config/mips/mips.opt (mocteon-useun): New option.
++      * config/mips/mips-protos.h (mask_low_and_shift_len): Declare.
++      (mips_lower_sign_bit_p, mips_use_ins_p, mips_use_ext_p): Declare.
++      (mips_adjust_register_ext_operands): Likewise.
++      * config/mips/mips.h (PROCESSOR_OCTEON): New processor_type.
++      (TARGET_OCTEON): New macro.
++      (ISA_HAS_DCLZ_DCLO): Delete.
++      (ISA_HAS_POPCOUNT): New macro.
++      (ISA_HAS_ROTR_SI, ISA_HAS_ROTR_DI): Include TARGET_OCTEON.
++      (ISA_HAS_SEB_SEH, ISA_HAS_INS_EXT): Likewise.
++      (ISA_HAS_EXTS, ISA_HAS_BBIT, ISA_HAS_SEQ_SNE, ISA_HAS_BADDU)
++      (ISA_HAS_UL_US, ISA_HAS_CINS): New macros.
++      (ASM_SPEC): Pass down -mocteon-useun and -mno-octeon-useun.
++      * config/mips/mips.c (mips_cpu_info_table): Add an octeon entry.
++      (mips_rtx_cost_data): Likewise.
++      (mask_low_and_shift_len, mips_get_seq_sne_operand): New functions.
++      (mips_emit_scc): Use mips_get_seq_sne_operand to choose between
++      seq/sne and xor/addu.
++      (mips_expand_unaligned_load): Use mov_ulw and mov_uld if
++      ISA_HAS_UL_US.
++      (mips_expand_unaligned_store): Likewise mov_usw and mov_usd.
++      (mips_lower_sign_bit_p, mips_use_ins_p, mips_use_ext_p): New functions.
++      (mips_adjust_register_ext_operands): Likewise.
++      (print_operand): Add %E, %G and %H formats.
++      (mips_issue_rate): Return 2 when scheduling for PROCESSOR_OCTEON.
++      (mips_multipass_dfa_lookahead): Likewise.
++      * config/mips/octeon.md: New file.
++      * config/mips/mips.md: Include it.
++      (UNSPEC_UNALIGNED_LOAD, UNSPEC_UNALIGNED_STORE): New constants.
++      (type): Add pop.
++      (cpu): Add octeon.
++      (SUBDI): New mode macro.
++      (topbit): New mode attribute.
++      (any_extract, any_shiftrt, equailty_op): New code macros.
++      (*baddu_si, *baddu_disi, *baddu_didi, *baddu_didi2, popcount<mode>2)
++      (*<code>_trunc_exts<mode>, *trunc_zero_ext_<SHORT:mode><GPR:mode>):
++      New patterns.
++      (zero_extendsidi2): Turn into a define_expand.  Rename old
++      define_insn_and_split to...
++      (*zero_extendsidi2): ...this and require !ISA_HAS_EXT_INS.
++      (*clear_upper32): Require !ISA_HAS_EXT_INS.
++      (*zero_extendsidi2_dext, *clear_upper32_dext): New patterns.
++      (extv): Change operand 1 from a QImode memory_operand to any
++      nonimmediate_operand.  Try using extvsi and extvdi for register
++      extractions if ISA_HAS_EXTS.
++      (extv<mode>, *extv_truncdi<mode>): New patterns.
++      (extzv): Use mips_use_ext_p instead of mips_use_ins_ext_p.
++      Call mips_adjust_register_ext_operands.
++      (extzv<mode>): Use mips_use_ext_p instead of mips_use_ins_ext_p.
++      (*extzv_truncdi<mode>, *extz_truncdi<mode>_exts): New patterns.
++      (insv):  Use mips_use_ins_p instead of mips_use_ins_ext_p.
++      Fix formatting.
++      (insv<mode>): Use mips_use_ins_p instead of mips_use_ins_ext_p.
++      (*insv<mode>di, *insv_<code>_<mode>di, *insvdi_clear_upper32)
++      (*cins): New patterns.
++      (mov_<load>l, mov_<load>r, mov_<store>l, mov_<store>r): Require
++      ISA_HAS_UL_US.
++      (mov_u<load>, mov_u<store>): New patterns.
++      (*truncsi_storeqi, *truncsi_storehi): Likewise.
++      (*branch_bit<mode>, *branch_bit<mode>_testdi): New patterns.
++      (*branch_bit<mode>_inverted): New pattern.
++      (*branch_bit_truncdi<mode>_inverted): Likewise.
++      (*seq_<mode>, *seq_<mode>_mips16, *sne_<mode>): Require
++      !ISA_HAS_SEQ_SNE.
++      (*seq_si_to_di, *seq_si_to_di_mips16, *sne_si_to_di): New patterns.
++      (*s<code>_<mode>_s<code>, *s<code>_si_to_di_s<code>): Likewise.
++      * config/mips/predicates.md (mask_low_and_shift_operator): New
++      predicate.
++
++2008-06-05  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config.gcc (powerpc-*-linux*spe*): Use t-dfprules.
++      * config/rs6000/dfp.md (negdd2, absdd2, negtd2, abstd2): Do not
++      enable for TARGET_E500_DOUBLE.
++      (*movdd_softfloat32): Also enable for !TARGET_FPRS.
++      * config/rs6000/rs6000.c (invalid_e500_subreg): Treat decimal
++      floating-point modes like integer modes for E500 double.
++      (rs6000_legitimate_offset_address_p): Likewise.
++      (rs6000_legitimize_address): Likewise.  Do not allow REG+REG
++      addressing for DDmode for E500 double.
++      (rs6000_hard_regno_nregs): Do not treat decimal floating-point
++      modes as using 64-bits of registers for E500 double.
++      (spe_build_register_parallel): Do not handle DDmode or TDmode.
++      (rs6000_spe_function_arg): Do not handle DDmode or TDmode
++      specially for E500 double.
++      (function_arg): Do not call rs6000_spe_function_arg for DDmode or
++      TDmode for E500 double.
++      (rs6000_gimplify_va_arg): Only handle SDmode in registers
++      specially if TARGET_HARD_FLOAT && TARGET_FPRS.
++      (rs6000_split_multireg_move): Do not handle TDmode specially for
++      E500 double.
++      (spe_func_has_64bit_regs_p): Do not treat DDmode or TDmode as
++      using 64-bit registers for E500 double.
++      (emit_frame_save): Do not handle DDmode specially for E500 double.
++      (gen_frame_mem_offset): Likewise.
++      (rs6000_function_value): Do not call spe_build_register_parallel
++      for DDmode or TDmode.
++      (rs6000_libcall_value): Likewise.
++      * config/rs6000/rs6000.h (LOCAL_ALIGNMENT, MEMBER_TYPE_FORCES_BLK,
++      DATA_ALIGNMENT, CLASS_MAX_NREGS): Do not handle DDmode specially
++      for E500 double.
++
++2008-06-05  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * dfp.c (WORDS_BIGENDIAN): Define to 0 if not defined.
++      (encode_decimal64, decode_decimal64, encode_decimal128,
++      decode_decimal128): Reverse order of 32-bit parts of value if host
++      and target endianness differ.
++
++      libdecnumber/
++      * dconfig.h: New.
++      * decContext.c, decExcept.c, decExcept.h, decLibrary.c,
++      decNumber.c, decNumberLocal.h, decRound.c, dpd/decimal128.c,
++      dpd/decimal32.c, dpd/decimal64.c: Include dconfig.h not config.h.
++      * dpd/decimal128Local.h (decimal128SetSign, decimal128ClearSign,
++      decimal128FlipSign): Use WORDS_BIGENDIAN not
++      FLOAT_WORDS_BIG_ENDIAN.
++      * bid/host-ieee128.c: Include dconfig.h.
++      (__host_to_ieee_128, __ieee_to_host_128): Swap 64-bit halves of
++      value if WORDS_BIGENDIAN.
++
++      libgcc/
++      * Makefile.in (DECNUMINC): Remove
++      -I$(MULTIBUILDTOP)../../libdecnumber.
++      * gstdint.h: New.
++
++2008-06-05  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_init_neon_builtins): Move initialization
++      with function calls after declarations.  Lay out
++      neon_float_type_node before further use.
++
++2008-06-04  Catherine Moore  <clm@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-03-27  Robin Randhawa <robin@mips.com>
++
++      * libstdc++-v3/config/cpu/mips/atomicity.h : Added memory barriers
++      to enforce strict ordering on weakly ordered systems.
++
++2008-06-04  Paul Brook  <paul@codesourcery.com>
++
++      Fix Issue #2917
++      gcc/
++      * config/arm/arm.c (neon_vector_mem_operand): Handle element/structure
++      loads.  Allow PRE_DEC.
++      (output_move_neon): Handle PRE_DEC.
++      (arm_print_operand): Add 'A' for neon structure loads.
++      * config/arm/arm-protos.h (neon_vector_mem_operand): Update prototype.
++      * config/arm/neon.md (movmisalign): Use Um constraint and %A.
++      * config/arm/constraints.md (Un, Us): Update neon_vector_mem_operand
++      calls.
++      (Um): New constraint.
++
++2008-06-04  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/testsuite/
++      2008-06-04  Joseph Myers  <joseph@codesourcery.com>
++      * lib/target-supports.exp (check_effective_target_powerpc_spu):
++      Call check_effective_target_powerpc_altivec_ok.
++      * gcc.target/powerpc/dfp-dd.c, gcc.target/powerpc/dfp-td.c,
++      gcc.target/powerpc/ppc32-abi-dfp-1.c,
++      gcc.target/powerpc/ppu-intrinsics.c: Require powerpc_fprs.
++
++2008-06-04  Kazu Hirata  <kazu@codesourcery.com>
++
++      Issue 1073
++      gcc/
++      * config/m68k/m68k.c (m68k_tune_flags): New.
++      (override_options): Compute m68k_tune_flags.
++      (MULL_COST, MULW_COST): Update for various variants of CFV2.
++      * config/m68k/m68k.h (TUNE_MAC, TUNE_EMAC): New.
++
++2008-06-03  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-06-02  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config/rs6000/t-linux (MULTILIB_OPTIONS): Add te500mc.
++      (MULTILIB_DIRNAMES): Likewise.
++      (MULTILIB_EXCEPTIONS): Handle te500mc.
++      * config/rs6000/linux.h (CC1_EXTRA_SPEC): Handle te500mc.
++      (ASM_DEFAULT_SPEC): Likewise.
++      * config/rs6000/rs6000.h (OPTION_DEFAULT_SPECS): Handle te500mc.
++
++2008-06-03  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-06-02  Nathan Froyd  <froydnj@codesourcery.com>
++
++      NOT ASSIGNED TO FSF
++      COPYRIGHT FREESCALE
++
++      gcc/doc:
++      * invoke.texi: Mention e500mc as a legitimate Power cpu.
++
++      gcc/
++      * config.gcc: Mention e500mc as a legitimate --with-cpu option.
++      * config/rs6000/rs6000.c (ppce500mc_cost): New.
++      (rs6000_override_options): Add e500mc to processor_target_table.
++      Enable isel for e500mc.  Disable string instructions for e500mc.
++      Set rs6000_cost for e500mc.
++      (rs6000_issue_rate): Handle CPU_PPCE500MC.
++      * config/rs6000/rs6000.h (ASM_CPU_SPEC): Handle mcpu=e500mc.
++      (enum processor_type): Add PROCESSOR_PPCE500MC.
++      (TARGET_ISEL): Use rs6000_isel.
++      * config/rs6000/e500mc.md: New file.
++      * config/rs6000/rs6000.md: Include it.
++      (define_attr "cpu"): Add e500mc.
++      (define_attr "type"): Add insert_dword.
++      * config/rs6000/e500.h (TARGET_ISEL): Remove.
++      (CHECK_E500_OPTIONS): Remove TARGET_ISEL condition.
++
++      2008-06-02  Nathan Froyd  <froydnj@codesourcery.com>
++
++      * release-notes-csl.xml (E500mc support): New.
++
++      gcc/
++      * config/rs6000/e500mc.md: Eliminate duplication.
++
++2008-06-03  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      2008-02-22  Nathan Froyd  <froydnj@codesourcery.com>
++      * config/rs6000/rs6000.c (rs6000_legitimize_address): Check to
++      ensure that we can address an entire entity > 8 bytes.  Don't
++      generate reg+reg addressing for such data.
++
++      2008-03-07  Peter Bergner  <bergner@vnet.ibm.com>
++      PR target/35373
++      * config/rs6000/rs6000.c (rs6000_legitimize_address): Don't generate
++      reg+const addressing for Altivec modes.  Don't generate reg+reg
++      addressing for TFmode or TDmode quantities.
++
++2008-06-03  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-28  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/testsuite/
++      * lib/target-supports.exp (check_effective_target_powerpc_spe_ok): New.
++
++2008-06-03  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config/rs6000/predicates.md (save_world_operation): Adjust checks.
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-05-22  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Issue #3062
++
++      * release-notes-csl.xml (E500 size optimization compiler crash): New.
++
++      gcc/
++      * config/rs6000/rs6000.c (rs6000_emit_prologue): Mark the
++      adjustment to r11 as frame related when generating out-of-line
++      prologues.
++
++      2008-03-07  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config/rs6000/rs6000.c (rs6000_savres_strategy): Be slightly
++      smarter about restoring with an out-of-line function.
++      (rs6000_emit_prologue): Make sure we only set r11 once.  Be
++      smarter about restoring LR.
++
++      2008-02-29  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config/rs6000/rs6000.c (emit_allocate_stack): Add copy_r11
++      parameter.  Copy stack_reg to r11 where appropriate.
++      (rs6000_stack_info): Only add padding for SPE save area if we
++      are saving SPE GPRs and CR.
++      (saveres_routine_syms): New variable.
++      (FIRST_SAVRES_REGISTER, LAST_SAVRES_REGISTER, N_SAVRES_REGISTERS):
++      Define.
++      (rs6000_savres_routine_sym): New function.
++      (rs6000_emit_stack_reset, rs6000_restore_saved_cr): New functions,
++      split out of...
++      (rs6000_emit_epilogue): ...here.  Use rs6000_use_multiple_p and
++      rs6000_savres_strategy.  Restore GPRs out-of-line if appropriate.
++      Tweak FPR out-of-line saving.
++      (rs6000_make_savres_rtx): New function.
++      (rs6000_use_multiple_p): New function.
++      (rs6000_savres_strategy): New function.
++      (rs6000_emit_prologue): Use rs6000_savres_strategy.  Save GPRs
++      out-of-line if appropriate.
++      * config/rs6000/sysv4.h (FP_SAVE_INLINE): Save FPRs out-of-line
++      if we are optimizing for size.
++      (GP_SAVE_INLINE): Define.
++      (SAVE_FP_SUFFIX, RESTORE_FP_SUFFIX): Only use _l on 64-bit targets.
++      * config/rs6000/darwin.h (GP_SAVE_INLINE): Define.
++      * config/rs6000/aix.h (GP_SAVE_INLINE): Define.
++      * config/rs6000/rs6000.md (*save_gpregs_<mode>): New insn.
++      (*save_fpregs_<mode>): Add use of r11.
++      (*restore_gpregs_<mode>): New insn.
++      (*return_and_restore_gpregs_<mode>): New insn.
++      (*return_and_restore_fpregs_<mode>): Adjust to clobber LR and
++      use r11.
++      * config/rs6000/spe.md (*save_gpregs_spe): New insn.
++      (*restore_gpregs_spe): New insn.
++      (*return_and_restore_gpregs_spe): New insn.
++
++2008-06-02  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config/rs6000/rs6000.md (absv2sf2, negv2sf2, addv2sf3, subv2sf3,
++      mulv2sf3, divv2sf3): New expanders.
++      * config/rs6000/spe.md (spe_evabs, spe_evand, spe_evaddw,
++      spe_evdivws): Rename to use standard GCC names.
++      * config/rs6000/paired.md (negv2sf, absv2sf2, addv2sf3, subv2sf3,
++      mulv2sf3, divv2sf3): Rename to avoid conflict with the new expanders.
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-09-19  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config/rs6000/rs6000.c (bdesc_2arg, bdesc_1arg): Use new CODE_FOR_
++      names for renamed patterns.
++
++2008-05-30  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/arm/wrs-linux.h (CC1_SPEC): Allow -tcortex-a8-be8
++      -mfloat-abi=softfp.
++      (SUBTARGET_EXTRA_ASM_SPEC): Use -meabi=5.
++      * config/arm/t-wrs-linux (MULTILIB_EXCEPTIONS): Remove
++      *cortex-a8-be8*/*mfloat-abi=softfp*.
++      (MULTILIB_ALIASES): Add
++      tcortex-a8-be8=tcortex-a8-be8/mfloat-abi?softfp.
++
++2008-05-30  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2006-12-12  Richard Sandiford  <richard@codesourcery.com>
++      gcc/testsuite/
++      * gcc.dg/torture/m68k-interrupt-1.c: New file.
++      2006-06-23  Richard Sandiford  <richard@codesourcery.com>
++      gcc/testsuite/
++      * gcc.dg/tree-ssa/20040204-1.c: Don't XFAIL for m68k*-*-*.
++
++2008-05-30  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config/rs6000/rs6000.c (ppc8540_cost): Fix typo.
++      (spe_synthesize_frame_save): Remove declaration.
++
++2008-05-30  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * tree-ssa-remove-local-statics.c
++      (find_static_nonvolatile_declarations): Use SSA_OP_VDEF.
++      (unstaticize_variable): Likewise.
++      (dump_final_bitmaps): Remove.
++
++2008-05-30  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Tree->const_tree fix.
++
++      gcc/
++      * config/m68k/m68k.c (m68k_return_in_memory): Fix arguments types.
++
++2008-05-30  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-02-16  Richard Sandiford  <richard@codesourcery.com>
++      gcc/
++      * config/m68k/m68k.h (INDEX_REG_CLASS): Delete in favor of...
++      (MODE_INDEX_REG_CLASS): ...this new macro.  Return NO_REGS unless
++      MODE_OK_FOR_INDEX_P.
++      (MODE_OK_FOR_INDEX_P): New macro.
++      (REGNO_OK_FOR_INDEX_P): Delete in favor of...
++      (REGNO_MODE_OK_FOR_INDEX_P): ...this new macro.  Return false
++      unless MODE_OK_FOR_INDEX_P.
++      (REG_OK_FOR_INDEX_P): Delete in favor of...
++      (REG_MODE_OK_FOR_INDEX_P): ...this new macro.  Return false
++      unless MODE_OK_FOR_INDEX_P.
++      * m68k-protos.h (m68k_legitimate_index_reg_p): Add mode argument.
++      * m68k.c (m68k_legitimate_index_reg_p, m68k_decompose_index):
++      Add mode argument.  Use it.
++      * config/m68k/m68k.md (tst<mode>_cf, cmp<mode>_cf, movsf_cf_hard)
++      (movdf_cf_hard, extendsfdf2_cf, truncdfsf2_cf, ftrunc<mode>2_cf)
++      (add<mode>3_cf, sub<mode>3_cf, fmul<mode>3_cf, div<mode>3_cf)
++      (neg<mode>2_cf, sqrt<mode>2_cf, abs<mode>2_cf): Replace "Q<U>"
++      constraints for FP addresses with "m" constraints.
++      2007-02-16  Nathan Sidwell  <nathan@codesourcery.com>
++      gcc/testsuite/
++      * gcc.dg/m68k-fp-1.c: New.
++
++2008-05-30  Julian Brown  <julian@codesourcery.com>
++
++      gcc/
++      * config/arm/cortex-r4.md: Update GPLv3 notice.
++      * hwdiv.md: Likewise.
++      * marvell-f-vfp.md: Likewise.
++      * marvell-f.md: Likewise.
++      * nocrt0.h: Likewise.
++      * vfp11.md: Likewise.
++
++2008-05-30  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2 (Add missing testcase from
++      earlier merge):
++
++      2008-02-01  Joseph Myers  <joseph@codesourcery.com>
++      gcc/testsuite/
++      * gcc.target/m68k/xgot-1.c: New test.
++
++2008-05-30  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-01-11  Kazu Hirata  <kazu@codesourcery.com>
++      Issue 2396
++      gcc/
++      * configure.ac: Teach that fido supports .debug_line.
++      * configure: Regenerate.
++
++2008-05-30  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2 (config.gcc part was merged earlier):
++
++      2007-03-26  Nathan Sidwell  <nathan@codesourcery.com>
++      gcc/
++      * config.gcc (m68k-*-linux*): Add sysroot-suffix.h to tm_file. Add
++      m68k/t-floatlib, m68k/t-linux & m68k/t-mlibs to tmake_file.
++      * config/m68k/t-linux: New.
++      * doc/install.texi: Document m68k-*-linux is now multilibbed by
++      default.
++
++2008-05-30  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Revert:
++
++      2008-05-29  Maxim Kuvyrkov  <maxim@codesourcery.com>
++      Merge from Sourcery G++ 4.2:
++      2007-02-16  Paul Brook  <paul@codesourcery.com>
++          Richard Sandiford  <richard@codesourcery.com>
++      gcc/
++      * config/m68k/m68k.md (UNSPEC_MOVEQ_MEM): New constant.
++      (*movsi_smallconst): New pattern.
++
++2008-05-29  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      * config/m68k/m68k.md: Fix previous commit.
++
++2008-05-29  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-02-16  Richard Sandiford  <richard@codesourcery.com>
++      gcc/
++      * config/m68k/m68k.md (tst<mode>_cf, cmp<mode>_cf, movsf_cf_hard)
++      (movdf_cf_hard, extendsfdf2_cf, truncdfsf2_cf, floatsi<mode>2_cf)
++      (floathi<mode>2_cf, floatqi<mode>2_cf, ftrunc<mode>2_cf)
++      (fix<mode>qi2_cf, fix<mode>hi2_cf, fix<mode>si2_cf)
++      (add<mode>3_cf, sub<mode>3_cf, fmul<mode>3_cf, div<mode>3_cf)
++      (divmodsi4_cf, udivmodsi4_cf)
++      (neg<mode>2_cf, sqrt<mode>2_cf, abs<mode>2_cf): Replace "Q<U>"
++      constraints for FP addresses with "m" constraints.
++
++2008-05-29  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-02-16  Paul Brook  <paul@codesourcery.com>
++          Richard Sandiford  <richard@codesourcery.com>
++      gcc/
++      * config/m68k/m68k.md (UNSPEC_MOVEQ_MEM): New constant.
++      (*movsi_smallconst): New pattern.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-05-19  Kazu Hirata  <kazu@codesourcery.com>
++
++      gcc/
++      * config.gcc (arm-timesys-linux-gnueabi): Add ./sysroot-suffix.h
++      ./sysroot-suffix.h to tm_file while removing arm/timesys-linux.h
++      from tm_file.  Add tmake_file.
++      * config/arm/t-timesys (MULTILIB_OSDIRNAMES): Populate.
++      * config/arm/timesys-liunx.h: Remove.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-05-07  Paul Brook  <paul@codesourcery.com>
++
++      * config/arm/arm.c (arm_no_early_mul_dep): Correct the logic to
++      look into a MAC instruction.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-04-04  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/linux-eabi.h (ARM_FUNCTION_PROFILER): Define.
++      (SUBTARGET_FRAME_POINTER_REQUIRED): Define.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-03-08  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/t-linux-eabi (MULTILIB_OSDIRNAMES): Override old value.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-02-29  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/lib1funcs.asm (THUMB_LDIV0): Fix bogus ARCH_7 ifdefs.
++      Use cbz.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-02-25  Sandra Loosemore  <sandra@codesourcery.com>
++
++      gcc/
++      * testsuite/gcc.dg/arm-mmx-1.c: Skip if conflicting -mcpu or -mabi
++      argument specified.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-02-18  Julian Brown  <julian@codesourcery.com>
++
++      gcc/
++      * config/arm/bpabi.S (test_div_by_zero): New macro.
++      (aeabi_ldivmod): Use above macro to tailcall long long div-by-zero
++      handler.
++      (aeabi_uldivmod): Likewise.
++      * config/arm/bpabi-v6m.S (test_div_by_zero): New macro.
++      (aeabi_ldivmod, aeabi_uldivmod): Use above macro.
++      * config/arm/lib1funcs.asm (ARM_LDIV0): Tailcall int div-by-zero
++      handler. Add signed/unsigned argument, pass correct value to that
++      handler.
++      (THUMB_LDIV0): Same, for Thumb.
++      (DIV_FUNC_END): Add signed argument.
++      (WEAK): New macro.
++      (__udivsi3, __umodsi3): Add unsigned argument to DIV_FUNC_END.
++      (__divsi3, modsi3): Add signed argument to DIV_FUNC_END.
++      (__aeabi_uidivmod, __aeabi_idivmod): Check division by zero.
++      (__div0): Rename to __aeabi_idiv0, __aeabi_ldiv0 for EABI, and declare
++      those names weak.
++      * config/arm/t-bpabi (LIB1ASMFUNCS): Add _aeabi_idiv0, _aeabi_ldiv0.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-02-17  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * doc/invoke.texi: Document -mword-relocations.
++      * config/arm/uclinux-elf.h: Define TARGET_DEFAULT_WORD_RELOCATIONS.
++      * config/arm/symbian.h: Define TARGET_DEFAULT_WORD_RELOCATIONS.
++      * config/arm/vxworks.h: Define TARGET_DEFAULT_WORD_RELOCATIONS.
++      * config/arm/arm.h: Define TARGET_DEFAULT_WORD_RELOCATIONS.
++      * config/arm/arm.md (movsi): Don't use movt if only word relocations
++      are permitted.
++      * config/arm/arm.opt: Add -mword-relocations.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-02-16  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config.gcc (arm*): Handle --enable-extra-sgxx-multilibs.
++      Use arm/t-sysroot-suffix and ./sysroot-suffix.h.
++      * config/arm/uclinux-eabi.h (SYSROOT_SUFFIX_SPEC): Remove.
++      * config/arm/linux-eabi.h (SYSROOT_SUFFIX_SPEC): Remove.
++      * config/arm/t-linux-eabi: Remove marvell-f multilib.
++      Match Cortex-A9 and Cortex-R4F.
++      * config/arm/t-arm-elf: Remove marvell-f multilib.
++      Match Cortex-A9 and Cortex-R4F.
++      * config/arm/t-uclinux-eabi: Match Cortex-A9 and Cortex-R4F.
++      * config/arm/print-sysroot-suffix.sh: New file.
++      * config/arm/t-sysroot-suffix: New file.
++      * config/arm/t-cs-eabi: New file.
++      * config/arm/t-cs-linux: New file.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-02-05  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * genmultilib: Fix sed patterns.
++      Verify that aliases are valid.
++      * config/arm/t-timesys (MULTILIB_ALIASES): Set.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-02-05  Paul Brook  <paul@codesourcery.com>
++
++      gcc/doc/
++      * fragments.texi: Document MULTILIB_ALIASES.
++
++      gcc/
++      * genmultilib: Add aliases.
++      * Makefile.in (s-mlib): Pass MULTILIB_ALIASES.
++      * config/arm/t-linux-eabi: Use MULTILIB_ALIASES.
++      * config/arm/t-arm-elf: Ditto.
++      * config/arm/t-uclinux-eabi: Ditto.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-01-28  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_override_options): Set arm_abi earlier.
++      Allow Interworking on ARMv4 EABI based targets.
++      * config/arm/bpabi.h (TARGET_FIX_V4BX_SPEC): Define.
++      (SUBTARGET_EXTRA_ASM_SPEC, LINK_SPEC): Add TARGET_FIX_V4BX_SPEC.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-01-25  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/ieee754-df.S (muldf3): Use RET macros.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-01-23  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_tune_cortex_a9): New variable.
++      (arm_override_options): Set arm_tune_cortex_a9.
++      (arm_split_constant): Use arm_emit_movpair.
++      (arm_rtx_costs_1): Increase cost of register shifts on cortex-A9.
++      Add costs for HIGH and LO_SUM.
++      (arm_size_rtx_costs): Add costs for HIGH and LO_SUM.
++      (arm_emit_movpair): New function.
++      (arm_print_operand): Handle symbols with %c.
++      (arm_final_prescan_insn): Use TARGET_NO_SINGLE_COND_EXEC.
++      (arm_issue_rate): Add cortexa9.
++      * config/arm/arm.h (TARGET_NO_SINGLE_COND_EXEC): Define.
++      (TARGET_USE_MOVT): Define.
++      (arm_tune_cortex_a9): Add prototype.
++      * config/arm/arm-cores.def: Add cortex-a9.
++      * config/arm/arm-tune.md: Regenerate.
++      * config/arm/arm-protos.h (arm_emit_movpair): Add prototype.
++      * config/arm/arm.md: Include cortex-a9.md.
++      Add TARGET_NO_SINGLE_COND_EXEC conditions.
++      (generic_sched, generic_vfp): Add cortex-a9.
++      (movsi): Use arm_emit_movpair.
++      (arm_movt, arm_movw): New patterns.
++      * config/arm/cortex-a9.md: New file.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-01-09  Julian Brown  <julian@codesourcery.com>
++
++      gcc/
++      * config/arm/neon.md (UNSPEC_MISALIGNED_ACCESS): New constant.
++      (movmisalign<mode>): Define for D and Q width registers.
++
++      gcc/testsuite/
++      * lib/target-supports.exp
++      (check_effective_target_arm_vect_no_misalign): New function.
++      (check_effective_target_vect_no_align): Use above to determine
++      whether misaligned accesses are expected for ARM.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-01-04  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_output_epilogue): Avoid clobbering tail call
++      arguments.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-01-03  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_rtx_costs_1): Add costs for ARMv6 value
++      extension instructions.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-12-20  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/cortex-r4f.md: New file.
++      * config/arm/arm.c (arm_no_early_mul_dep): Also match
++      multiply-subtract.
++      (arm_issue_rate): Return 2 for cortex-a8 and cortex-r4.
++      * config/arm/cortex-r4.md: Replace (eq_attr "tune" "cortexr4")
++      with (eq_attr "tune_cortexr4" "yes").
++      * config/arm/vfp.md: Split ffarith and ffarith into fcpys, ffariths,
++      ffarithd, fadds, faddd, fconsts, fconstd, fcmps and fcmpd.
++      * config/arm/arm.md: Inlcude cortex-r4f.md.
++      (define_attr fpu): Add new VFP variants.
++      (define_attr type): Add new types.
++      (tune_cortexr4): New attr.
++      (generic_sched, generic_vfp): Use tune_cortexr4 and new FPU types.
++      * config/arm/cortex-a8-neon.md: Split farith and ffarith insn types.
++      * config/arm/marvell-f-vfp.md: Ditto.
++      * config/arm/arm1020e.md: Ditto.
++      * config/arm/vfp11.md: Ditto.
++      * config/arm/arm-tune.md: Regenerate.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-12-14  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * doc/invoke.texi: Document new ARM -mfpu= and -mcpu= options.
++      * config/arm/arm.c (all_fpus): Add vfpv3 and vfpv3-d16.
++      (fp_model_for_fpu): Add entry for FPUTYPE_VFP3D16.
++      (arm_file_start): Add FPUTYPE_VFP3D16.  Rename vfp3 to vfpv3.
++      * config/arm/arm.h (TARGET_VFPD32): Define.
++      (TARGET_VFP3): Use TARGET_VFPD32.
++      (fputype): Add FPUTYPE_VFP3D16.
++      (LAST_VFP_REGNUM): Use TARGET_VFPD32.
++      * config/arm/constraints.md ("w"): Use TARGET_VFPD32.
++      * config/arm/arm-cores.def: Add cortex-r4f.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-12-11  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/thumb2.md: Extend peephole to cover 3-arg subs.
++      (thumb2_alusi3_short): Exclude MINUS.
++      (thumb2_subsi_short): New pattern.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-09-27  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_optimization_options): Revert flag_see
++      change.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-09-19  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (FL_COMPAT): Define.
++      (arm_override_options): Mask out FL_COMPAT when checking cpu vs. arch.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-09-19  Vladimir Prus  <vladimir@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_optimization_options):
++      Enable -fsee and disable -fmove-loop-invariants.
++      Use very restrictive inlining heuristics.
++
++      gcc/testsuite/
++      * gcc.c-torture/execute/bcp-1.x: New.  Don't
++      run bcp-1.c test on arm, with -Os.
++      * gcc.c-torture/execute/990208-1.x: New.  Likewise.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-08-20  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.md (insv): Use gen_insv_t2 and gen_insv_zero.
++      (extzv): Use gen_extzv_t2.
++      (insv_t2, insv_zero, extv, extzv_t2): New patterns.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-08-20  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/thumb2.md (thumb2_one_cmplsi2_short,
++      thumb2_negsi2_short): New patterns and peepholes.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-08-20  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_size_rtx_costs): Use ARM costs for Thumb-2.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-08-13  Paul Brook  <paul@codesourcery.com>
++
++      * config/arm/arm.c (arm_output_epilogue): Adjust stack pointer by
++      popping call-clobbered registers.
++      (arm_expand_prologue): Adjust stack pointer by pushing extra
++      registers.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-08-12  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (TARGET_ADJUST_REG_ALLOC_ORDER): Define.
++      (thumb_core_reg_alloc_order): New.
++      (arm_adjust_reg_alloc_order): New.
++      * config/arm/arm.h (REG_ALLOC_ORDER): Adjust comment.
++      * config/arm/arm-protos.h (arm_adjust_reg_alloc_order): New
++      prototype.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-08-12  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.h (CLASS_LIKELY_SPILLED_P): Update comment.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-08-12  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.h (CLASS_LIKELY_SPILLED_P): Check against
++      LO_REGS only for Thumb-1.
++      (MODE_BASE_REG_CLASS): Restrict base registers to low
++      registers for Thumb-2.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-08-10  Paul Brook  <paul@codesourcery.com>
++
++      * config/arm/arm.md (arm_addsi3): Add r/k/n alternative.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-08-07  Kazu Hirata  <kazu@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.dg/arm-g2.c, gcc.dg/arm-mmx-1.c, gcc.dg/arm-scd42-2.c:
++      Skip if the multilib testing specifies -march that does not
++      agree with the one specified in the testcase.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-07-25  Nathan Sidwell  <nathan@codesourcery.com>
++
++      gcc/
++      * config.gcc (arm*-*-linux*): Add timesys specific files.
++      * config/arm/timesys-linux.h: New.
++      * config/arm/t-timesys: New.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-07-16  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (use_return_insn): Use offsets->saved_regs_mask
++      instead of {arm,thumb}_compute_save_reg_mask.
++      (output_return_instruction): Ditto.
++      (arm_output_epilogue): Ditto.
++      (arm_expand_prologue): Ditto.
++      (thumb_unexpanded_epilogue): Ditto.
++      (thumb1_expand_prologue): Ditto.
++      (thumb1_output_function_prologue): Ditto.
++      (arm_set_return_address): Ditto.
++      (thumb_set_return_address): Ditto.
++      (arm_get_frame_offsets): Set offsets->saved_regs_mask.  Push extra
++      regs to achieve stack alignment.
++      (thumb1_compute_save_reg_mask): Fix compiler warning.
++      * gcc/config/arm.h (arm_stack_offsets): Add saved_regs_mask.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-07-05  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.h (BRANCH_COST): Set to 1 when optimizing
++      for size on Thumb-2.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-07-05  Richard Sandiford  <richard@codesourcery.com>
++
++      gcc/
++      * config/arm/neon-gen.ml: Include vxWorks.h rather than stdint.h
++      for VxWorks kernels.
++      * config/arm/arm_neon.h: Regenerate.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-07-05  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * config/arm/thumb2.md (thumb2_movsi_insn): Split ldr and
++      str alternatives according to use of high and low regs.
++      * config/arm/vfp.md (thumb2_movsi_vfp): Likewise.
++      * config/arm/arm.h (CONDITIONAL_REGISTER_USAGE): Use high
++      regs when optimizing for size on Thumb-2.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-07-02  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/thumb2.md (thumb2_alusi3_short): Exclude PLUS.
++      (thumb2_addsi_shortim): Rename ...
++      (thumb2_addsi_short): ... to this.  Allow register operands.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Backport from mainline:
++
++      2008-02-26  Paul Brook  <paul@codesourcery.com>
++
++      * config/arm/arm.c (thumb_set_frame_pointer): Ensure SP is first
++      operand for Thumb-2.
++      * config/arm/arm.h (reg_class): Add CORE_REGS.
++      (REG_CLASS_NAMES, REG_CLASS_CONTENTS): Ditto.
++      (BASE_REG_CLASS): Use CORE_REGS.
++      (PREFERRED_RELOAD_CLASS): Add STACK_REG.
++      (REGNO_MODE_OK_FOR_REG_BASE_P): Use REGNO_MODE_OK_FOR_BASE_P.
++      (REGNO_OK_FOR_INDEX_P): Exclude SP.
++      (ARM_REG_OK_FOR_INDEX_P): Always define.  Use
++      ARM_REGNO_OK_FOR_INDEX_P.
++      (ARM_PRINT_OPERAND_ADDRESS): Swap operands for [reg, sp].
++      * config/arm/arm.md (arm_addsi3, thumb1_addsi3, arm_subsi3_insn,
++      arm_movsi_insn, thumb1_movsi_insni, stack_tie): Add "k" alternatives.
++      (ldm/stm peepholes): Ditto.
++      * config/arm/thumb2.md (thumb2_movdi): Add "k" alternatives.
++      * config/arm/vfp.md (arm_movsi_vfp, thumb2_movsi_vfp): Ditto.
++      * config/arm/iwmmxt.md (iwmmxt_movsi_insn): Ditto.
++      * config/arm/constraints.md: Enable "k" constraint on ARM.
++
++2008-05-29  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-02-01  Joseph Myers  <joseph@codesourcery.com>
++      * release-notes-csl.xml: Add -mxgot release note.
++      gcc/
++      * config/m68k/m68k.opt (mxgot): New option.
++      * config/m68k/m68k.c (legitimize_pic_address): Handle -mxgot.
++      (m68k_output_addr_const_extra): New.
++      * config/m68k/m68k.h (OUTPUT_ADDR_CONST_EXTRA): New.
++      * config/m68k/m68k-protos.h (m68k_output_addr_const_extra): Declare.
++      * config/m68k/m68k.md (UNSPEC_GOTOFF): Define.
++      * doc/invoke.texi (M680x0 Options): Document -mxgot.
++      gcc/testsuite/
++      * gcc.target/m68k/xgot-1.c: New test.
++
++2008-05-29  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-03-12  Nathan Sidwell  <nathan@codesourcery.com>
++      gcc/
++      * config/m68k/t-cf (MULTILIB_EXTRA_OPTS): Add no-mac.
++      * config/m68k/m68k-devices.def: Remove multilibs that only differ
++      by MAC/EMAC.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-06-13  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/arm/crti.asm, config/arm/crtn.asm: Remove .file
++      directives.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-06-06  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.h (VALID_IWMMXT_REG_MODE): Allow SImode.
++      (ARM_LEGITIMIZE_RELOAD_ADDRESS): Reduce range allowed for SImode
++      offsets with iWMMXt.
++      * config/arm/arm.c (arm_hard_regno_mode_ok): Update for change to
++      VALID_IWMMXT_REG_MODE.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-05-17  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (output_move_double): Prefer LDRD to LDM.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-05-15  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/nocrt0.h (LIB_SPEC): Remove default -T.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-05-04  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * config/arm/bpabi.h (SUBTARGET_EXTRA_ASM_SPEC): Bump EABI
++      version number to five.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-05-02  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_unwind_emit): Suppress unused unwinding
++      annotations.
++      (arm_output_fn_unwind): Mark functions that can not be unwound.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-04-26  Vladimir Prus  <vladimir@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (vfp_output_fldmd): When low_irq_latency
++      is non zero, pop each register separately.
++      (vfp_emit_fstmd): When low_irq_latency is non zero,
++      save each register separately.
++      (arm_get_vfp_saved_size): Adjust saved register
++      size calculation for the above changes.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-04-25  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/bpabi-v6m.S (aeabi_lcmp): Use unsigned comparison for
++      low word.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-04-22  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * config/arm/lib1funcs.asm (div0): Use correct punctuation.
++      * config/arm/ieee754-sf.S (mulsf3): Likewise.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-04-18  Vladimir Prus  <vladimir@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Set
++      __low_irq_latency__.
++      * config/arm/lib1funcs.asm: Define do_pop and
++      do_push as variadic macros. When __low_irq_latency__
++      is defined, push and pop registers individually.
++      * config/arm/ieee754-df.S: Adjust syntax of using
++      do_push.
++      * config/arm/ieee754-sf.S: Likewise.
++      * config/arm/bpapi.S: Likewise.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-04-17  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (TARGET_DWARF_REGISTER_SPAN): Define.
++      (arm_dwarf_register_span): New function.
++      (arm_dbx_register_number): Add VFPv3 dwarf numbering.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-04-16  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (print_pop_reg_by_ldr): Fix warning about ambiguous
++      else.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Backport from mainline:
++
++      2008-05-06  Mark Shinwell  <shinwell@codesourcery.com>
++                  Daniel Jacobowitz  <dan@codesourcery.com>
++                  Andrew Jenner  <andrew@codesourcery.com>
++
++      * g++.old-deja/g++.jason/enum6.C, g++.old-deja/g++.law/enum9.C,
++      g++.old-deja/g++.other/enum4.C, gfortran/enum_9.f90,
++      gfortran.dg/enum_10.f90: Broaden dg-options pattern.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-04-01  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/uclinux-eabi.h (SUBTARGET_EXTRA_LINK_SPEC): Add
++      --target2=abs.
++      * config/arm/unwind-arm.h (_Unwind_decode_target2): Handle uClinux.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-31  Paul Brook  <paul@codesourcery.com>
++
++      * config/arm/arm.c (output_move_double): Only apply limited range
++      check in ARM mode.
++
++2008-05-29  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-30  Sandra Loosemore  <sandra@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (use_return_insn): Test for TARGET_APCS_FRAME
++      if we need to adjust the stack.
++
++2008-05-29  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-09-07  Mark Shinwell  <shinwell@codesourcery.com>
++      gcc/
++      * config/m68k/lb1sf68.asm: Add PIC macros for Linux targets.
++
++2008-05-29  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/
++      * config.gcc (m68k-*-linux*): Add with_arch, adjust tm_file,
++      add tmake_file.
++
++2008-05-28  Paul Brook  <paul@codesourcery.com>
++
++      Avoid Issue #2945
++      gcc/
++      * config/arm/arm.md (abssi2): Add TARGET_NO_SINGLE_COND_EXEC expander.
++      (arm_abssi2, arm_neg_abssi2): Enable for Thumb-2. Always split.
++      (arm_nocond_abssi2, arm_nocond_neg_abssi2): New patterns.
++      Add splitters for abssi patterns.
++      * config/arm/thumb2.md (thumb2_abssi2, thumb2_neg_abssi2): Remove.
++
++2008-05-26  Carlos O'Donell  <carlos@codesourcery.com>
++
++      Backport from mainline:
++
++      gcc/
++      2008-05-23  Paul Brook  <paul@codesourcery.com>
++                  Carlos O'Donell  <carlos@codesourcery.com>
++
++      * doc/extend.texi: Clarify use of __attribute__((naked)).
++      * doc/tm.texi: Document TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS.
++      * target.h (gcc_target): Add allocate_stack_slots_for_args.
++      * function.c (use_register_for_decl): Use
++      targetm.calls.allocate_stack_slots_for_args.
++      * target-def.h (TARGET_CALLS): Add
++      TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS.
++      * config/arm/arm.c (arm_allocate_stack_slots_for_args):
++      New function.
++      (TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS): Define.
++
++      gcc/testsuite/
++      2008-05-23  Paul Brook  <paul@codesourcery.com>
++                  Carlos O'Donell  <carlos@codesourcery.com>
++
++      * gcc.target/arm/naked-1.c: New test.
++      * gcc.target/arm/naked-2.c: New test.
++
++2008-05-26  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Backport from mainline:
++
++      gcc/
++      2008-04-30  Nathan Froyd  <froydnj@codesourcery.com>
++
++      * config/rs6000/crtresgpr.asm, config/rs6000/crtresxgpr.asm,
++      config/rs6000/crtsavgpr.asm, config/rs6000/crtresfpr.asm,
++      config/rs6000/crtresxfpr.asm, config/rs6000/crtsavfpr.asm: Break out
++      from...
++      * config/rs6000/crtsavres.asm: ...here.  Remove unneeded file.
++      * config/rs6000/e500crtres32gpr.asm, config/rs6000/e500crtres64gpr.asm,
++      config/rs6000/e500crtres64gprctr.asm,
++      config/rs6000/e500crtrest32gpr.asm, config/rs6000/e500crtrest64gpr.asm,
++      config/rs6000/e500crtresx32gpr.asm, config/rs6000/e500crtresx64gpr.asm,
++      config/rs6000/e500crtsav32gpr.asm, config/rs6000/e500crtsav64gpr.asm,
++      config/rs6000/e500crtsav64gprctr.asm,
++      config/rs6000/e500crtsavg32gpr.asm, config/rs6000/e500crtsavg64gpr.asm,
++      config/rs6000/e500crtsavg64gprctr.asm: New files.
++      * config/rs6000/t-ppccomm: Add build rules for new files.
++      (LIB2FUNCS_STATIC_EXTRA): Add new files.
++      * config/rs6000/t-netbsd: Add build rules for new files.
++      (LIB2FUNCS_STATIC_EXTRA): New variable.
++      * config/rs6000/sysv4.h (ENDFILE_SPEC): Don't include crtsavres.o
++      (CRTSAVRES_DEFAULT_SPEC): Likewise.
++      * config/rs6000/netbsd.h (ENDFILE_SPEC): Likewise.
++
++      libgcc/
++      2008-04-30  Nathan Froyd  <froydnj@codesourcery.com>
++
++      * config/rs6000/t-ppccomm: Add build rules for new files.
++      (LIB2ADD_ST): New variable.
++
++2008-05-26  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-02-25  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * tree-ssa-remove-local-statics. (initialize_statement_dataflow):
++      Continue hash table traversal.
++      (compute_definedness_for_block): Delete useless return statement.
++      Adjust comment accordingly.
++
++      2007-03-05  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * tree-pass.h (pass_remove_local_statics): Declare.
++      * passes.c (init_optimization_passes): Add
++      pass_remove_local_statics to the optimization passes.
++      * Makefile.in (OBJS-common): Add tree-ssa-remove-local-statics.c.
++      (tree-ssa-remove-local-statics.o): New rule.
++      * tree-ssa-remove-local-statics.c: New file.
++      * c.opt (fremove-local-statics): New option.
++      * timevar.def (TV_RLS): New timevar.
++      * toplev.h (flag_remove_local_statics): Declare.
++      * cgraph.h (struct cgraph_node): Add 'ever_was_nested'.
++      * cgraph.c (cgraph_node): Set ever_was_nested in the node and
++      its parent when creating a new node.
++      gcc/doc/
++      * invoke.texi: Document -fremove-local-statics.
++      gcc/testsuite/
++      * gcc.dg/remove-local-statics-1.c: New file.
++      * gcc.dg/remove-local-statics-2.c: New file.
++      * gcc.dg/remove-local-statics-3.c: New file.
++      * gcc.dg/remove-local-statics-4.c: New file.
++      * gcc.dg/remove-local-statics-5.c: New file.
++      * gcc.dg/remove-local-statics-6.c: New file.
++      * gcc.dg/remove-local-statics-7.c: New file.
++      * gcc.dg/remove-local-statics-8.c: New file.
++      * gcc.dg/remove-local-statics-9.c: New file.
++      * gcc.dg/remove-local-statics-10.c: New file.
++      * gcc.dg/remove-local-statics-11.c: New file.
++      * gcc.dg/remove-local-statics-12.c: New file.
++
++
++2008-05-26  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Backport from mainline:
++
++      2008-04-24  Nathan Froyd  <froydnj@codesourcery.com>
++                  Nathan Sidwell  <nathan@codesourcery.com>
++
++      * config/rs6000/rs6000.opt (mspe): Remove Var property.
++      (misel): Likewise.
++      * config/rs6000/rs6000.h (rs6000_spe): Declare.
++      (rs6000_isel): Likewise.
++      * config/rs6000/rs6000.c (rs6000_spe): New variable.
++      (rs6000_isel): New variable.
++      (rs6000_handle_option): Handle OPT_mspe and OPT_misel.
++
++2008-05-26  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.target/powerpc/altivec-24.c, gcc.target/powerpc/pr35907.c:
++      Run if vmx_hw, compile otherwise.  Do not check for AltiVec at
++      runtime.
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-22  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/testsuite/
++      * gcc.target/powerpc/altivec-vec-merge.c,
++      gcc.target/powerpc/altivec-10.c, gcc.target/powerpc/altivec-12.c,
++      gcc.target/powerpc/altivec-1.c, gcc.target/powerpc/altivec-3.c,
++      g++.dg/ext/altivec-2.C, g++.dg/ext/altivec-3.C: Run if vmx_hw, compile
++      otherwise.  Do not check for AltiVec at runtime.
++      * gcc.target/powerpc/altivec_check.h: Delete.
++      * g++.dg/eh/simd-2.C: Only use -maltivec if vmx_hw.
++      * g++.dg/ext/altivec_check.h: Delete.
++      * g++.dg/eh/check-vect.h (sig_ill_handler): Remove AltiVec runtime
++      check.
++
++      * gcc.target/powerpc/20030505.c: Compile for all EABI targets.
++      Explicitly enable SPE.
++      * gcc.target/powerpc/ppc-spe.c: Likewise.
++
++      * gcc.target/powerpc/darwin-longlong.c: Explicitly require 64-bit
++      instruction support.  Do not check for it at runtime.
++
++      * gcc.target/powerpc/20030218-1.c: Pass -mfloat-gprs=single.  Expect
++      -flax-vector-conversions message.
++      * gcc.target/powerpc/spe1.c: Pass -mfloat-gprs=single.  Make Foo
++      extern.
++      * g++.dg/other/opaque-2.C: Pass -mfloat-gprs=single.
++      * g++.dg/other/opaque-3.C, g++.dg/ext/spe1.C: Likewise.
++
++      * gcc.dg/cpp/assert4.c: Recognize __PPC__.
++
++      * g++.dg/other/opaque-1.C: Run on targets with SPE.
++      * g++.dg/other/profile1.C: Use dg-require-profiling.
++
++      * g++.dg/conversion/simd1.C: Expect warning on all PowerPC
++      non-AltiVec targets.
++      * g++.dg/ext/attribute-test-1.C, g++.dg/ext/attribute-test-2.C,
++      g++.dg/ext/attribute-test-3.C, g++.dg/ext/attribute-test-4.C: Likewise.
++
++      * lib/target-supports.exp (check_effective_target_ppc64): New.
++
++2008-05-26  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      * release-notes-csl.xml: Add missing release note.
++
++2008-05-23  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/arm/t-wrs-linux (MULTILIB_OPTIONS, MULTILIB_DIRNAMES,
++      MULTILIB_EXCEPTIONS): Add -tcortex-a8-be8 multilib.
++      * config/arm/wrs-linux.h (CC1_SPEC, SUBTARGET_EXTRA_ASM_SPEC,
++      SUBTARGET_EXTRA_LINK_SPEC, SYSROOT_SUFFIX_SPEC): Update for new
++      multilib.
++
++2008-05-23  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Backport from mainline:
++
++      gcc/
++      2008-02-23  David Edelsohn  <edelsohn@gnu.org>
++
++      * config/rs6000/rs6000.h (CONSTANT_ALIGNMENT): Use STRICT_ALIGNMENT
++      instead of TARGET_STRICT_ALIGN.
++
++      gcc/
++      2008-02-22  Nathan Froyd  <froydnj@codesourcery.com>
++
++      * config/rs6000/rs6000.h (CONSTANT_ALIGNMENT): Don't overalign
++      strings when optimizing for size, unless the target cares about
++      alignment.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-28  Paul Brook  <paul@codesourcery.com>
++
++      Merge ARMv6-M support.
++      gcc/
++      * config/arm/t-linux-eabi: Remove explicit marm (default) multilib.
++      Add entries for all multilibs to MULTILIB_OSDIRNAMES.
++      * config/arm/t-arm-elf: Ditto. Add armv6-m multilib.
++      (LIB1ASMFUNCS): Prefix sf/df routines with arm_.
++      * config/arm/t-uclinux-eabi: New file.
++      * config/arm/t-linux-eabi: Add Thumb-2 multilib.
++      * config/arm/uclinux-eabi.h (SYSROOT_SUFFIX_SPEC): Define.
++      * config/arm/linux-eabi.h (SYSROOT_SUFFIX_SPEC): Add thumb-2 sysroot.
++      * config.gcc: Add t-softfp and t-arm-softfp to ARM ELF based targets.
++      Add armv6-m.
++      * config/arm/t-arm-softfp: New file.
++      * config/arm/elf.h: Prevent libgcc float conversion routines being
++      built when we have assembly implementations.
++      * config/arm/ieee754-sf.S: Rename L_* L_arm_*
++      * config/arm/ieee754-df.S: Ditto.
++      * config/arm/arm.c (FL_FOR_ARCH6M): Define.
++      (all_architectures): Add armv6-m.
++      (arm_output_mi_thunk): Add TARGET_THUNMB1_ONLY code.
++      * config/arm/arm.h (TARGET_THUMB1_ONLY): Define.
++      (ARM_DECLARE_FUNCTION_NAME): Handle v6m thunks.
++      * config/arm/lib1funcs.asm: Add __ARM_ARCH_6M__. Omit ARM mode
++      code and macros when it is defined.  Include bpabi-v6m.S.
++      (gnu_Unwind_Restore_VFP_D, gnu_Unwind_Save_VFP_D,
++      gnu_Unwind_Restore_VFP_D_16_to_31, gnu_Unwind_Save_VFP_D_16_to_31,
++      gnu_Unwind_Restore_WMMXD, gnu_Unwind_Save_WMMXD,
++      gnu_Unwind_Restore_WMMXC, gnu_Unwind_Save_WMMXC): Stubs for ARMv6-M.
++      * config/arm/sfp-machine.h: New file.
++      * config/arm/arm-cores.def: Add cortex-m1.
++      * config/arm/arm-tune.md: Regenerate.
++      * config/arm/libunwind.S: Add ARMv6-M implementation.
++      * config/arm/bpabi.h: Add renames for unsigned conversion routines.
++      * config/arm/bpabi-v6m.S: New file.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-26  Joseph Myers  <joseph@codesourcery.com>
++
++      Merge from Sourcery G++ 4.1 branch:
++
++      2006-03-01  Paul Brook  <paul@codesourcery.com>
++      gcc/testsuite/
++      * g++.dg/other/armv7m-1.C: New test.
++
++      2006-10-27  Joseph Myers  <joseph@codesourcery.com>
++                  Richard Sandiford  <richard@codesourcery.com>
++      gcc/testsuite/
++      * gcc.dg/arm-vfp1.c, gcc.target/arm/vfp-ldmdbd.c,
++      gcc.target/arm/vfp-ldmdbs.c, gcc.target/arm/vfp-ldmiad.c,
++      gcc.target/arm/vfp-ldmias.c, gcc.target/arm/vfp-stmdbd.c,
++      gcc.target/arm/vfp-stmdbs.c, gcc.target/arm/vfp-stmiad.c,
++      gcc.target/arm/vfp-stmias.c: Use arm_vfp_ok.
++
++      2006-08-19  Joseph Myers  <joseph@codesourcery.com>
++      gcc/testsuite/
++      * gcc.target/arm/vfp-ldmdbd.c, gcc.target/arm/vfp-ldmdbs.c,
++      gcc.target/arm/vfp-ldmiad.c, gcc.target/arm/vfp-ldmias.c,
++      gcc.target/arm/vfp-stmdbd.c, gcc.target/arm/vfp-stmdbs.c,
++      gcc.target/arm/vfp-stmiad.c, gcc.target/arm/vfp-stmias.c: Skip for
++      iWMMXt.
++
++      2006-04-21  Kazu Hirata  <kazu@codesourcery.com>
++      gcc/testsuite/
++      * gcc.target/arm/vfp-ldmdbd.c, gcc.target/arm/vfp-ldmdbs.c,
++      gcc.target/arm/vfp-ldmiad.c, gcc.target/arm/vfp-ldmias.c,
++      gcc.target/arm/vfp-stmdbd.c, gcc.target/arm/vfp-stmdbs.c,
++      gcc.target/arm/vfp-stmiad.c, gcc.target/arm/vfp-stmias.c: New.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-25  Vladimir Prus  <vladimir@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (load_multiple_sequence): Return
++      0 if low irq latency is requested.
++      (store_multiple_sequence): Likewise.
++      (arm_gen_load_multiple): Load registers one-by-one
++      if low irq latency is requested.
++      (arm_gen_store_multiple): Likewise.
++      * config/arm/predicates.md (load_multiple_operation):
++      Return false is low irq latency is requested.
++      (store_multiple_operation): Likewise.
++      * config/arm/arm.h (low_irq_latency): Define.
++      * config/arm/arm.md (movmemqi): Don't use
++      it if low irq latency is requsted.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-24  Vladimir Prus  <vladimir@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_override_options): Warn if
++      mlow-irq-latency is specified in thumb mode.
++      (print_pop_reg_by_ldr): New.
++      (arm_output_epilogue): Use print_pop_reg_by_ldr
++      when low irq latency is requested.
++      (emit_multi_reg_push): Push registers separately
++      if low irq latency is requested.
++      * config/arm/arm.opt (mlow-irq-latency): New option.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-23  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config/arm/uclinux-eabi.h (SUBTARGET_EXTRA_LINK_SPEC): Add -elf2flt
++      and --pic-veneer.
++      * config/arm/bpabi.h (SUBTARGET_EXTRA_LINK_SPEC): Provide empty
++      default definition.
++      (LINK_SPEC): Include SUBTARGET_EXTRA_LINK_SPEC.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-22  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config.gcc: Loosen checks for arm uclinux eabi targets.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-22  Sandra Loosemore  <sandra@codesourcery.com>
++
++      gcc/
++      * config/arm/lib1funcs.asm (ARM_DIV_BODY):  Conditionalize for
++      __ARM_TUNE_MARVELL_F__.
++      * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Add code to define
++      __ARM_TUNE_MARVELL_F__.
++      * config/arm/linux-eabi.h (SYSROOT_SUFFIX_SPEC): Add support for
++      marvell-f multilibs.
++      * config/arm/t-linux-eabi (MULTILIB_OPTIONS, MULTILIB_DIRNAMES,
++      MULTILIB_EXCEPTIONS, MULTILIB_MATCHES): Likewise.
++      * config/arm/t-arm-elf (MULTILIB_OPTIONS, MULTILIB_DIRNAMES,
++      MULTILIB_EXCEPTIONS, MULTILIB_MATCHES): Likewise.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-22  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * config/arm/cortex-r4.md: New.
++      * config/arm/hwdiv.md (divsi3, udivsi3): Annotate with
++      insn attributes.
++      * config/arm/arm.md: Include cortex-r4.md.
++      (insn): Add sdiv and udiv values.
++      (generic_sched): Don't use generic scheduling for Cortex-R4.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-22  Vladimir Prus  <vladimir@codesourcery>
++
++      * config/arm/arm.c
++      (arm_compute_save_reg0_reg12_mask): Always
++      check if register 11 must be saved.  Additionally
++      force save of it if frame_pointer_needeed.
++      (arm_compute_save_reg_mask): Save IP and PC
++      only with apcs frames.
++      (arm_output_epilogue): Adjust Thumb2 codepath to
++      be also invoked and work for ARM non-apcs frames.
++      (arm_expand_prologue): Don't bother saving IP
++      for non-apcs frame, since it's not clobbered by
++      prologue code.  Implement non-apcs frame
++      layout.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-20  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_arch_marvell_f): Delete.
++      (all_architectures): Delete marvell-f entry.
++      (arm_override_options): Improve diagnostic.  Ignore
++      FL_MARVELL_F when checking CPU feature flags against
++      architecture feature flags.  Don't set arm_arch_marvell_f.
++      Check insn_flags instead of TARGET_MARVELL_F.
++      * config/arm/arm.h (arm_arch_marvell_f): Delete.
++      (TARGET_MARVELL_F): Delete.
++      * doc/invoke.texi: Remove marvell-f entry from -march=
++      documentation.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-20  Carlos O'Donell  <carlos@codesourcery.com>
++
++      Issue #1314
++      gcc/
++      * target.h (calls): Add use_reg_for_func.
++      * function.c (use_register_for_decl): Return true if
++      target hook use_ref_for_func returns true.
++      * target-def.h (TARGET_USE_REG_FOR_FUNC): Define.
++      (TARGET_CALLS): Add TARGET_USE_REG_FOR_FUNC.
++      * config/arm/arm.c (arm_use_reg_for_func): New function.
++      (TARGET_USE_REG_FOR_FUNC): Define as arm_use_reg_for_func.
++      * doc/extend.texi (naked): Naked functions must only have
++      asms without operands.
++      * release-notes-csl.xml: Document #1314 fix.
++
++2008-05-23  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Backport from mainline:
++
++      gcc/
++      2008-05-23  Steven Munroe  <sjmunroe@us.ibm.com>
++
++      * config/rs6000/darwin-ldouble.c (fmsub): Eliminate the full
++      PACK/UNPACK between FP_SUB_Q and FD_TRUNC so that the result
++      is only rounded once.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-18  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * doc/invoke.texi: Document -mmarvell-div.
++      * config/arm/arm.c (arm_override_options): Take setting of
++      -mmarvell-div and TARGET_THUMB2 into account when setting
++      arm_arch_hwdiv.  Cause error if -mmarvell-div is used when
++      not targeting a Marvell core.
++      * config/arm/arm.opt: Add entry for -mmarvell-div option.
++      * config/arm/hwdiv.md: Use only arm_arch_hwdiv to check
++      applicability of instruction patterns.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-18  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * config/arm/vfp.md: When targeting a Marvell core, only
++      enable patterns involving multiply-accumulate type
++      instructions when optimizing for size.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-12  Sandra Loosemore  <sandra@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.c (arm_final_prescan_insn):  Skip this processing
++      if TARGET_NO_COND_EXEC is true.
++      * config/arm/arm.h (TARGET_NO_COND_EXEC):  Define.
++      * config/arm/arm.md (smaxsi3, *arm_smax_insn):  Disable if
++      TARGET_NO_COND_EXEC is set.
++      (sminsi3, *arm_smin_insn): Likewise.
++      (umaxsi3, *arm_umaxsi3): Likewise.
++      (uminsi3, *arm_uminsi3): Likewise.
++      (*store_minmaxsi): Likewise.
++      (seq, sne, sgt, sle, sge, slt): Likewise.
++      (sgtu, sleu, sgeu, sltu): Likewise.
++      (sunordered, sordered): Likewise.
++      (sungt, sunge, sunlt, sunle): Likewise.
++      (movsicc, movsfcc, movdfcc): Likewise.
++      (*cond_return, *cond_return_inverted): Likewise.
++      (*compare_scc): Likewise.
++      (*cond_arith): Likewise.
++      (movcond): Likewise.
++      (anonymous define_split patterns): Likewise.
++      (define_cond_exec): Likewise.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-02-02  Mark Shinwell  <shinwell@codesourcery.com>
++                  Richard Earnshaw  <richard.earnshaw@arm.com>
++
++      gcc/
++      * config/arm/arm.c (TARGET_MAX_ANCHOR_OFFSET): New.
++      (TARGET_MIN_ANCHOR_OFFSET): New.
++      (arm_override_options): Set correct anchor ranges for Thumb-1
++      and Thumb-2 if required.
++      (legitimize_pic_address): Handle case involving a TLS symbol
++      reference with an addend.
++      (arm_optimization_options): Enable section anchors at -O1 and
++      above.
++      * config/arm/arm.h (OPTIMIZATION_OPTIONS): New.
++      * config/arm/arm-protos.h (arm_optimization_options): New.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-02-02  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * config/arm/arm.md (UNSPEC_STACK_ALIGN): Use a number that
++      does not clash with other unspecs.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-02-02  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * config/arm/thumb2.md: Update copyright notice and FSF address.
++      Include hwdiv.md and move instruction patterns for sdiv and udiv
++      to that file.
++      * config/arm/arm.c (arm_arch_marvell_f): New.
++      (all_architectures): Add marvell-f entry.
++      (ARM_ARCH_NAME_SIZE): Define.
++      (arm_arch_name): Allocate ARM_ARCH_NAME_SIZE bytes of space.
++      (arm_override_options): Be more careful writing to arm_arch_name.
++      Set arm_arch_hwdiv if arm_tune_marvell_f is set.
++      * config/arm/arm.h (arm_arch_marvell_f): New.
++      * config/arm/arm_cores.def: Add FL_MARVELL_F for the marvell-f
++      entry.
++      * config/arm/hwdiv.md: New.
++      * config/arm/t-arm (MD_INCLUDES): Add hwdiv.md.
++      * config.gcc: Recognize marvell-f as a supported ARM architecture.
++      * doc/invoke.texi (ARM Options): Document -mcpu=marvell-f and
++      -march=marvell-f.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-01-10  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * config/arm/marvell-f.md: Fix FSF address and comment
++      capitalization.
++      * config/arm/marvell-f-vfp.md: New.
++      * config/arm/arm-cores.def: Add FL_VFPV2 for marvell-f.
++      * config/arm/arm.md: Include marvell-f-vfp.md.
++      (generic_vfp): Don't set attribute to "yes" for marvell_f tuning.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-01-07  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * config/arm/vfp.md: Document fmul{s,d} and fmac{s,d} types.
++      Remove documentation entry for fmul type.
++      Use fmuls to annotate single-precision multiplication patterns,
++      fmuld to annotate double-precision multiplication patterns,
++      fmacs to annotate single-precision multiply-accumulate patterns
++      and fmacd to annotate double-precision multiply-accumulate patterns.
++      * config/arm/vfp11.md: Update reservations accordingly.
++      * config/arm/arm.md: Note that certain values of the "type"
++      attribute are documented in vfp.md.  Add fmul{s,d} and fmac{s,d}
++      values for that attribute.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-01-04  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * config/arm/vfp.md: Move pipeline description for VFP11 to...
++      * config/arm/vfp11.md: ...here.  New.
++      * config/arm/arm.md: Include vfp11.md.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-01-03  Mark Shinwell  <shinwell@codesourcery.com>
++
++      NOT ASSIGNED TO FSF
++      Port from Marvell compiler:
++      gcc/
++      * config/arm/arm.c (arm_issue_rate): New.
++      (arm_multipass_dfa_lookahead): New.
++      (TARGET_SCHED_ISSUE_RATE): Define.
++      (TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD): Define.
++      (FL_MARVELL_F): New.
++      (arm_tune_marvell_f): New.
++      (arm_override_options): Set arm_tune_marvell_f as appropriate.
++      * config/arm/arm.h (arm_tune_marvell_f): Declare.
++      * config/arm/arm-cores.def: Add marvell-f entry.
++      * config/arm/arm-tune.md: Regenerate.
++      * config/arm/t-arm (MD_INCLUDES): Add marvell-f.md.
++      * config/arm/arm.md: Don't use generic scheduler for marvell-f.
++      Include marvell-f.md.  Extend "insn" attribute with mov/mvn/
++      and/orr/eor cases and annotate instruction patterns accordingly.
++      * config/arm/vfp.md: Annotate likewise.
++      * config/arm/marvell-f.md: New.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2006-11-09  Paul Brook  <paul@codesourcery.com>
++
++      Merge from branches/csl/sourcerygxx-4_1.
++      gcc/
++      * config/arm/arm.c (all_architectures): Add iWMMXt2 entry.
++      * config/arm/arm-cores.def: New ARM_CORE entry for iWMMXt2.
++      * config/arm/arm-tune.md: Regenerate.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2006-11-09  Paul Brook  <paul@codesourcery.com>
++
++      Merge from branches/csl/sourcerygxx-4_1.
++      2006-09-10  Paul Brook  <paul@codesourcery.com>
++      gcc/
++      * config/arm/linux-eabi.h (SYSROOT_SUFFIX_SPEC): Define.
++      * config/arm/t-linux-eabi (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
++      Add armv4t multilib.
++
++2008-05-23  Julian Brown  <julian@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2006-11-02  Paul Brook  <paul@codesourcery.com>
++
++      gcc/
++      * config.gcc (arm*-*-eabi*): Add arm/nocrt0.h to tm_file.
++      * config/arm/nocrt0.h: New file.
++
++2008-05-23  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config/rs6000/e300c2c3.md: Correctly use FSF upstream version,
++      not Sourcery G++ 4.2 version.
++
++2008-05-23  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Backport from mainline:
++
++      gcc/
++      2008-02-26  Edmar Wienskoski  <edmar@freescale.com>
++
++      * config/rs6000/rs6000.c (processor_costs): Update e300 cache
++      line sizes.
++      * doc/invoke.texi: Add e300c2 and e300c3 to list of cpus.
++
++      gcc/
++      2008-02-24  Edmar Wienskoski  <edmar@freescale.com>
++
++      * config.gcc (powerpc*-*-*): Add new cores e300c2 and e300c3.
++      * config/rs6000/e300c2c3.md: New file.
++      * config/rs6000/rs6000.c (processor_costs): Add new costs for
++      e300c2 and e300c3.
++      (rs6000_override_options): Add e300c2 and e300c3 cases to
++      processor_target_table. Do not allow usage of Altivec or Spe
++      with e300 cores. Initialize rs6000_cost for e300c2 and e300c3.
++      (rs6000_issue_rate): Set issue rate for e300c2 and e300c3.
++      * config/rs6000/rs6000.h (processor_type): Add
++      PROCESSOR_PPCE300C2 and PROCESSOR_PPCE300C3.
++      (ASM_CPU_SPEC): Add e300c2 and e300c3.
++      * config/rs6000/rs6000.md (define_attr "cpu"): Add ppce300c2
++      and ppce300c3. Include e300c2c3.md.
++
++2008-05-23  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-12-31  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config/rs6000/eabi-cn.asm, config/rs6000/sol-ci.asm,
++      config/rs6000/sol-cn.asm: Remove .file directives.
++
++2008-05-23  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Backport from mainline:
++
++      2008-03-06  Nathan Froyd  <froydnj@codesourcery.com>
++
++      * dwarf2out.c (dwarf2out_frame_debug_expr): Consult the
++      dwarf_register_span hook when emitting unwind information for
++      register-to-memory saves.
++      * config/rs6000/rs6000.c (spe_synthesize_frame): Delete.
++      (rs6000_frame_related): Remove call to spe_synthesize_frame.
++
++2008-05-23  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-03-04  Nathan Froyd  <froydnj@codesourcery.com>
++
++      gcc/
++      * config/rs6000/eabi.asm (__eabi): Don't run __init.
++      (__eabi_convert, __eabi_uconvert): Define only if _RELOCATABLE.
++
++2008-05-23  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-22  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/
++      * config/rs6000/eabi.asm (.Lfini): New.
++
++2008-05-23  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-02-12  Nathan Sidwell  <nathan@codesourcery.com>
++                  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/
++      * config/rs6000/eabi-ci.asm (__init): Add _init func start.
++      (__fini): Also declare _fini for newlib.
++
++2008-05-22  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/
++      * function.c (assign_parm_remove_parallels): New.
++      (assign_parm_setup_block_p): Do not return true for non-BLKmode
++      PARALLELs.
++      (assign_parm_setup_block): Do not handle them.
++      (assign_parm_setup_reg, assign_parm_setup_stack): Call
++      assign_parm_remove_parallels.
++
++2008-05-22  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/
++      * c-typeck.c (convert_for_assignment): Use
++      vector_targets_convertible_p.
++      * c-common.c (vector_targets_convertible_p): New.
++      * c-common.h (vector_targets_convertible_p): New prototype.
++      * config/rs6000/rs6000.c (rs6000_is_opaque_type): Do not check
++      opaque_p_V2SI_type_node.
++
++      gcc/cp/
++      * typeck.c (comp_ptr_ttypes_real): Use vector_targets_convertible_p.
++      (comp_ptr_ttypes_const): Likewise.
++
++      gcc/testsuite/
++      * g++.dg/other/opaque-1.C, g++.dg/other/opaque-2.C,
++      g++.dg/other/opaque-3.C: Also run on powerpc*-*-linux*spe*.
++
++2008-05-22  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Revert (as already fixed in a different way):
++
++      2008-05-21  Sandra Loosemore  <sandra@codesourcery.com>
++
++      libgcc/
++      * config/t-vxworks:  New file.
++      * config.host (Common parts for widely ported systems): Use it.
++
++2008-05-22  Nathan Sidwell  <nathan@codesourcery.com>
++
++      gcc/testsuite/
++      Backport 2008-05-22  Nathan Sidwell  <nathan@codesourcery.com>
++      * lib/dg-pch.exp (dg-pch): Fix if bracing.
++
++2008-05-21  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-04-13  Joseph Myers  <joseph@codesourcery.com>
++
++      Merge from Sourcery G++ 4.1 branch:
++
++      2007-03-27  Mark Mitchell  <mark@codesourcery.com>
++      gcc/testsuite/
++      * gcc.target/i386/sse-10.c: Pass -mno-omit-leaf-frame-pointer.
++
++2008-05-21  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-08-26  Mark Mitchell  <mark@codesourcery.com>
++
++      gcc/testsuite/
++      * lib/prune.exp (prune_warnings): Extend the default
++      implementation to prune linker warnings about libm on Solaris.
++      libstdc++-v3/
++      * testsuite/lib/prune.exp (prune_g++_output): Prune linker
++      warnings about libm on Solaris.
++
++2008-05-21  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-08-26  Mark Mitchell  <mark@codesourcery.com>
++
++      fixincludes/
++      * inclhack.def (solaris_mutex_init_2): Remove precise machine
++      checks; look at <sys/types.h> to determine whether fix is
++      required.
++      (solaris_rwlock_init_1): Likewise.
++      (solaris_once_init_2): Likewise.
++      * tests/base/sys/types.h: Add output generated by
++      solaris_mutex_init_2.
++      * fixincl.x: Regenerated.
++
++2008-05-21  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-05  Mark Mitchell  <mark@codesourcery.com>
++
++      * configure.in (*-*-vxworks*): Remove target-libstdc++-v3 from
++      noconfigdirs.
++      * configure: Regenerated.
++
++2008-05-21  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-12  Richard Sandiford  <richard@codesourcery.com>
++
++      gcc/
++      * config/vx-common.h (TARGET_FLEXLM): Define.
++
++2008-05-21  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-22  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      gcc/testsuite/
++      * g++.dg/other/profile1.C: Use dg-require-profiling.
++
++2008-05-21  Sandra Loosemore  <sandra@codesourcery.com>
++
++      libgcc/
++      * config/t-vxworks:  New file.
++      * config.host (Common parts for widely ported systems): Use it.
++
++2008-05-21  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-04-25  Paul Brook  <paul@codesourcery.com>
++
++      Merge from sourcerygxx-4_1
++      2005-03-10  Julian Brown  <julian@codesourcery.com>
++      libstdc++-v3/
++      * configure.ac (LIBSUPCXX_PRONLY): New AM_CONDITIONAL: yes
++      if we are compiling for SymbianOS on ARM.
++      * include/Makefile.am: Don't install C++ headers if
++      LIBSUPCXX_PRONLY is true.
++      * libsupc++/Makefile.am: Include only eh_personality.cc
++      in libsupc++ if LIBSUPCXX_PRONLY is true.
++      * Makefile.in: Regenerate.
++      * configure: Regenerate.
++      * include/Makefile.in: Regenerate.
++      * libmath/Makefile.in: Regenerate.
++      * libsupc++/Makefile.in: Regenerate.
++      * po/Makefile.in: Regenerate.
++      * src/Makefile.in: Regenerate.
++      * testsuite/Makefile.in: Regenerate.
++
++2008-05-21  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-05-02  Maxim Kuvyrkov  <maxim@codesourcery.com>
++      gcc/
++      Backport from mainline.
++      2008-02-19  Christian Bruel  <christian.bruel@st.com>
++          Zdenek Dvorak  <ook@ucw.cz>
++      * tree-ssa-loop-ivopts.c (may_be_unaligned_p): Check step alignment.
++
++2008-05-21  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-12-05  Maxim Kuvyrkov  <maxim@codesourcery.com>
++      Make scheduler better process end of the blocks.
++
++      gcc/
++      * haifa-sched.c (insn_finishes_cycle_p): New static function.
++      (max_issue): Use it.  Fix handling of number of instruction to try.
++      * sched-int.h (struct sched_info: insn_finished_block_p): New
++      scheduler hook.
++      * sched-rgn.c (rgn_insn_finishes_block_p): Implement it.
++      (region_sched_info): Update.
++      * sched-ebb.c (ebb_sched_info): Update.
++      * modulo-sched.c (sms_sched_info): Update.
++
++2008-05-20  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-03-22  Daniel Jacobowitz  <dan@codesourcery.com>
++
++      libstdc++-v3/
++      * testsuite/27_io/basic_filebuf/sputbackc/char/9425.cc: Use
++      dg-require-fileio.
++      * testsuite/27_io/basic_filebuf/sputbackc/char/1-out.cc: Likewise.
++      * testsuite/27_io/basic_filebuf/sputbackc/char/2-out.cc: Likewise.
++
++2008-05-20  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2008-02-12  Julian Brown  <julian@codesourcery.com>
++
++      Merge from MIPS:
++
++      2007-12-05  Thiemo Seufer  <ths@mips.com>
++
++      libcpp/
++      * Makefile.in ($(srcdir)/config.in): Fix dependency.
++
++2008-05-20  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2006-03-29  Richard Sandiford  <richard@codesourcery.com>
++      gcc/
++      * config.gcc (tm_file): Update commentary.
++
++2008-05-20  Nathan Sidwell  <nathan@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      * gcc.c-torture/execute/builtins/memops-asm.c: Set inside_main.
++
++      * lib/gcc-dg.exp (cleanup-saved-temps): Add optional list of
++      suffixes not to delete.
++      * gcc.dg/pch/save-temps-1.c: Don't delete ".s" temp.
++      * g++.dg/pch/pch.C: Likewise.
++
++      * g++.old-deja/g++.pt/static11.C: Replace xfail by target requirement.
++
++      * lib/dg-pch.exp (dg-pch): Don't expect .s files if there are
++      dg-errors expected.
++
++2008-05-20  Nathan Sidwell  <nathan@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      * c-incpath.c (INO_T_EQ): Do not define on non-inode systems.
++      (DIRS_EQ): New.
++      (remove_duplicates): Do not set inode on non-inode systems.  Use
++      DIRS_EQ.
++
++2008-05-19  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-08-12  Mark Shinwell  <shinwell@codesourcery.com>
++
++      gcc/
++      * target.h (gcc_target): Add adjust_reg_alloc_order member.
++      * target-def.h (TARGET_ADJUST_REG_ALLOC_ORDER): New.
++      (TARGET_INITIALIZER): Add TARGET_ADJUST_REG_ALLOC_ORDER.
++      * regclass.c (init_reg_sets): Don't initialize
++      inv_reg_alloc_order.
++      (init_reg_sets_1): Call adjust_reg_alloc_order hook and
++      then initialize inv_reg_alloc_order.
++      * hooks.c (hook_intp_void): New.
++      * hooks.h (hook_intp_void): New.
++      * doc/tm.texi: Document TARGET_ADJUST_REG_ALLOC_ORDER.
++
++2008-05-19  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-02-02  Mark Shinwell  <shinwell@codesourcery.com>
++          Richard Earnshaw  <richard.earnshaw@arm.com>
++
++      gcc/
++      * varasm.c (use_object_blocks_p): Prevent use of object blocks
++      if -fno-toplevel-reorder is specified.
++
++2008-05-19  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-02-16  Richard Sandiford  <richard@codesourcery.com>
++
++      gcc/
++      * Makefile.in (postreload.o): Depend on addresses.h.
++      * addresses.h (index_reg_class, ok_for_index_p_1): New functions.
++      (regno_ok_for_index_p): New function.
++      * postreload.c: Include addresses.h.
++      (reload_combine): Use index_reg_class instead of INDEX_REG_CLASS.
++      * regclass.c (ok_for_index_p_nonstrict): Add a mode argument.
++      Use ok_for_index_p_1 instead of REGNO_OK_FOR_INDEX_P.
++      (record_address_regs): Use index_reg_class instead of INDEX_REG_CLASS.
++      Update calls to ok_for_index_p_nonstrict.
++      * regrename.c (scan_rtx_address): Use regno_ok_for_index_p instead of
++      REGNO_OK_FOR_INDEX_P and index_reg_class instead of INDEX_REG_CLASS.
++      (replace_oldest_value_addr): Likewise.
++      * reload.c (find_reloads_address): Use index_reg_class instead
++      of INDEX_REG_CLASS.  Do not push an index register reload if
++      index_reg_class returns NO_REGS.
++      (find_reloads_address_1): Use index_reg_class instead
++      of INDEX_REG_CLASS and regno_ok_for_index_p instead of
++      REGNO_OK_FOR_INDEX_P.
++      * doc/tm.texi (MODE_INDEX_REG_CLASS): Document new macro.
++      (REGNO_MODE_OK_FOR_INDEX_P): Likewise.
++
++2008-05-19  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-06-05  Mark Shinwell  <shinwell@codesourcery.com>
++
++      * release-notes-csl.xml (Register allocation bug fix): New.
++
++      gcc/
++      * reload1.c (emit_reload_insns): Upon discovery of an input
++      reload whose reload register is not a spill register,
++      invalidate any existing reloads involving that register.
++
++2008-05-19  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2006-10-24  Mark Shinwell  <shinwell@codesourcery.com>
++      gcc/
++      * final.c (asm_insn_count): Return zero for an empty asm body.
++
++2008-05-19  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2006-12-15  Richard Sandiford  <richard@codesourcery.com>
++      gcc/testsuite/
++      * gcc.c-torture/compile/20061214-1.c: New test.
++
++2008-05-19  Sandra Loosemore  <sandra@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-05-02  Mark Shinwell  <shinwell@codesourcery.com>
++
++      * release-notes-csl.xml (Forced alignment of array variables):
++      New.
++
++      gcc/
++      * doc/tm.texi: Document that LOCAL_ALIGNMENT and
++      DATA_ALIGNMENT should not be used directly.
++      * doc/invoke.texi (-falign-arrays): Document.
++      * function.c (DATA_ALIGNMENT): Define to a default if
++      undefined.
++      (alignment_for_aligned_arrays): New.
++      (calculate_local_alignment): New.
++      (calculate_global_alignment): New.
++      * function.h (calculate_local_alignment): New.
++      (calculate_global_alignment): New.
++      * cfgexpand.c (LOCAL_ALIGNMENT): Don't define to a default.
++      (get_decl_align_unit): Use calculate_local_alignment.
++      * common.opt (-falign-arrays): New.
++      * varasm.c (assemble_variable): Use calculate_data_alignment,
++      and use it irrespective of whether DATA_ALIGNMENT is defined.
++
++2008-05-16  Nathan Froyd  <froydnj@codesourcery.com>
++          Kazu Hirata <kazu@codesourcery.com>
++          Daniel Jacobowitz  <dan@codesourcery.com>
++          Nathan Sidwell  <nathan@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/
++      * config/rs6000/linux.h (CC1_EXTRA_SPEC, ASM_DEFAULT_SPEC,
++      SYSROOT_SUFFIX_SPEC): Define.
++      * config/rs6000/eabi.h (CC1_EXTRA_SPEC, ASM_DEFAULT_SPEC): Define.
++      * config/rs6000/t-linux: New file.
++      * config/rs6000/t-ppcgas (MULTILIB_OPTIONS): Add te500v1/te500v2/te600.
++      (MULTILIB_DIRNAMES): Add te500v1 te500v2 te600.
++      (MULTILIB_EXCEPTIONS): New.
++      (MULTILIB_EXTRA_OPTS): Remove mrelocatable-lib.
++
++2008-05-16  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-09-07  Daniel Jacobowitz  <dan@codesourcery.com>
++      gcc/
++      * config/rs6000/rs6000.c (rs6000_dwarf_register_span): Fix
++      debug output for other floating point modes.
++
++2008-05-16  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      2007-08-16  Daniel Jacobowitz  <dan@codesourcery.com>
++      gcc/
++      * config/rs6000/rs6000.c (rs6000_conditional_register_usage): Mark
++      call-saved AltiVec registers call-used if ! TARGET_ALTIVEC_ABI.
++      * config/rs6000/rs6000.h (CALL_USED_REGISTERS): Mark the first 20
++      AltiVec registers call-used.
++      (CALL_REALLY_USED_REGISTERS): Likewise.
++
++      gcc/testsuite/
++      * gcc.target/powerpc/altivec-consts.c: Remove -mabi=altivec.
++      * gcc.target/powerpc/altivec-varargs-1.c: Likewise.
++      * gcc.dg/vmx/vmx.exp: Likewise.
++
++2008-05-16  Nathan Froyd  <froydnj@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/
++      * config.gcc (powerpc-timesys-linux-gnu): Handle new target.
++      * config/rs6000/timesys-linux.h: New file.
++      * config/rs6000/t-timesys: New file.
++
++2008-05-14  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      fixincludes/
++      2008-05-14  Joseph Myers  <joseph@codesourcery.com>
++      * inclhack.def (AAB_fd_zero_asm_posix_types_h): Bypass on
++      posix_types_64.
++      * fixincl.x: Regenerate.
++
++2008-05-09  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Backport from mainline.
++
++      gcc/
++      2008-05-09  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      * rtl-factoring.c (collect_pattern_seqs): Fix typo.
++
++2008-05-09  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Backport from mainline.
++
++      gcc/
++      2008-05-07  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Cleanup ColdFire scheduling support and add V4 pipeline model.
++
++      * config/m68k/m68k.md (UNSPEC_TIE): New constant.
++      (define_attr cpu): Add cfv4 value.
++      (define_attr type, define_attr type1): Merge into a single 'type'
++      attribute.  Update all uses.
++      (define_attr opx_type, define_attr opy_type, define_attr opx_access):
++      Rearrange and update.  Rename value 'reg' to 'Rn', add value 'FPn'.
++      Update all uses.
++      (define_attr opx_mem, define_attr opy_mem): Remove.
++      (define_attr op_mem): Clean up, update comment.
++      (define_attr size): Use specific values instead of general int.
++      (define_attr guess, define_attr split): Remove.  Update all uses.
++      (movdf_internal, tstsi_internal, tsthi_internal, tstqi_internal,
++      tst<mode>_68881, pushexthisi_const, movsi_const0_68000_10,
++      movsi_const0_68040_60, movsi_const0, movsi_cf, movstrictqi_cf,
++      zero_extendhisi2_cf, zero_extendqisi2_cfv4, cfv4_extendhisi2,
++      68k_extendhisi2, extendqihi2, cfv4_extendqisi2, 68k_extendqisi2,
++      floatsi<mode>2_68881, ftrunc<mode>2_68881, ftrunc<mode>2_cf,
++      fix<mode>qi2_68881, fix<mode>hi2_68881, fix<mode>si2_68881,
++      adddi_dishl32, addsi3_5200, add<mode>3_floatsi_68881,
++      add<mode>3_floathi_68881, add<mode>3_floatqi_68881,
++      add<mode>3_68881, add<mode>3_cf, subdi_dishl32, subsi3,
++      sub<mode>3_floatsi_68881, sub<mode>3_floathi_68881,
++      sub<mode>3_floatqi_68881, sub<mode>3_68881, sub<mode>3_cf,
++      mulhi3, mulhisi3, mulhisisi3_s, mulsi3_68020, mulsi3_cf,
++      umulhisi3, mulhisisi3_z, mul<mode>3_floatsi_68881,
++      mul<mode>3_floathi_68881, mul<mode>3_floatqi_68881, fmul<mode>3_cf,
++      div<mode>3_cf, sqrt<mode>2_cf, abs<mode>2_cf, clzsi2,
++      one_cmplsi2_5200, subreghi1ashrdi_const32, ashrsi3, lshrsi3,
++      bsetmemqi, bsetmemqi_ext, bclrmemqi, bclrmemqi_ext,
++      beq, bne, bgt, blt, bordered, bunordered, buneq, bunge, bungt, bunle,
++      bunlt, bltgt, tablejump_internal, call, non_symbolic_call_value,
++      symbolic_call_value_jsr, symbolic_call_value_bsr, link):
++      Update or set attributes.
++      (stack_tie): New fake instruction.
++
++      * config/m68k/m68k.h (TUNE_CFV4): New macro.
++      (m68k_sched_attr_size): Update declaration.
++      (m68k_sched_attr_type2): Remove.
++      (m68k_sched_address_bypass_p, m68k_sched_indexed_address_bypass_p):
++      Declare new bypass predicates.
++
++      * config/m68k/m68k.c (m68k_sched_issue_rate,
++      m68k_sched_first_cycle_multipass_dfa_lookahead): Declare hook
++      implementations.
++      (TARGET_SCHED_ISSUE_RATE,
++      TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD): Override hooks.
++      (override_options): Handle scheduling for ColdFire V4 core.
++      (m68k_expand_prologue): Emit stack_tie.
++      (enum attr_op_type): Split value 'OP_TYPE_REG' to 'OP_TYPE_RN' and
++      'OP_TYPE_FPN'.  Update all uses.
++      (sched_guess_p): Remove.
++      (sched_address_type): Handle symbolic addresses.
++      (sched_get_operand): New static function.
++      (sched_operand_type): Merge into sched_attr_op_type.
++      (sched_attr_op_type): Handle FP registers, handle quick constants,
++      update.
++      (m68k_sched_attr_opx_type, m68k_sched_attr_opy_type): Update.
++      (m68k_sched_attr_size): Update.  Move logic to ...
++      (sched_get_attr_size_int): New static function.
++      (sched_get_opxy_mem_type): New static function.
++      (m68k_sched_attr_op_mem): Update.
++      (m68k_sched_attr_type2): Remove.
++      (sched_cfv4_bypass_data): New static variable.
++      (m68k_sched_adjust_cost): Handle ColdFire V4 bypass.
++      (m68k_sched_issue_rate): Implement scheduler hook.
++      (struct _sched_ib: enabled_p): New field.
++      (m68k_sched_variable_issue): Update.  Handle V4.
++      (SCHED_DUMP_TODO, SCHED_DUMP_DONE, SCHED_DUMP_NOTHING,
++      sched_dump_class_func_t, sched_dump_split_class,
++      sched_dump_dfa_guess_unit_code, sched_dump_dfa_state,
++      sched_dump_dfa_class, m68k_sched_dump): Remove.
++      (m68k_sched_first_cycle_multipass_dfa_lookahead): Implement scheduler
++      hook.
++      (m68k_sched_init_global): Remove statisctics dumping, introduce
++      sanity check that all instructions have pipeline reservations.  Handle
++      ColdFire V4 core.
++      (m68k_sched_dfa_pre_advance_cycle, m68k_sched_dfa_post_advance_cycle):
++      Handle ColdFire V4 core.
++      (sched_mem_operand_p, sched_get_reg_operand, sched_get_mem_operand):
++      New static functions.
++      (m68k_sched_address_bypass_p): New bypass predicate.
++      (sched_get_indexed_address_scale): New static function.
++      (m68k_sched_indexed_address_bypass_p): New bypass predicate.
++
++      * cf.md: Update comments.
++      (define_attr type2): Remove.  Use 'type' attribute instead.
++      Update all uses.
++      (cf_ib): Rename to cfv123_ib.  Update all uses.
++      (cf_oep): Rename to cfv123_oep.  Update all uses.
++      (cf_chr): Rename to cfv123_chr.  Update all uses.
++      (cf_mem): Rename to cfv123_mem.  Update all uses.
++      (cf_mac): Move to more appropriate place.
++      (cfv123_guess): New automaton and cpu_unit.
++      (cfv123_*, cfv12_*, cfv1_*, cfv2_*, cfv3_*): Use type attribute.
++      Update uses of 'size' attribute.  Handle before reload scheduling.
++      (cfv123_guess): New dummy reservation for unhandled instructions.
++      (cfv4_*): Pipeline description of ColdFire V4 core.
++      (ignore): New reservation to handle 'ignore' type.
++
++2008-05-09  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Backport from mainline.
++
++      gcc/
++
++      2008-04-22  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Support scheduling for ColdFire V1 and V3 microarchitecture.
++      Improve scheduling of multiplication instructions.
++
++      * config/m68k/m68k.md (cpu): Add cfv1 and cfv3.  Rename cf_v2 to cfv1.
++      (mac): New instruction attribute.
++      * config/m68k/m68k.c (override_options): Handle cfv1, cfv3 and mac.
++      (m68k_sched_mac): New variable.
++      (m68k_sched_attr_type2, m68k_sched_md_init_global): Update.
++      Handle cfv1 and cfv3.
++      (max_insn_size): New static variable.
++      (struct _sched_ib): New type.
++      (sched_ib): New static variable.
++      (sched_ib_size, sched_ib_filled, sched_ib_insn): Convert variables
++      to fields of 'struct _sched_ib sched_ib'.  Update all uses.
++      (m68k_sched_variable_issue): Add modeling of cfv3 instruction buffer.
++      Update.
++      (m68k_sched_md_init_global, m68k_sched_md_finish_global,
++      m68k_sched_md_init, m68k_sched_md_finish): Handle cfv1 and cfv3.  Init
++      new variables.  Update.
++      (m68k_sched_dfa_pre_advance_cycle, m68k_sched_dfa_post_advance_cycle):
++      Add modeling of cfv3 instruction buffer.  Update.
++      * config/m68k/m68k-protos.h (m68k_sched_mac): Declare.
++      * config/m68k/m68k.h (TUNE_CFV3): New macro.
++      * config/m68k/cf.md: Change substrings 'cf_v2' to 'cfv12' or 'cfv123'.
++      (cf_* reservations): Rename to cfv12 or cfv123 to indicate cores
++      a particular reservation applies to.
++      (type2): Reorganize attribute values.  Rename alu to alu_reg,
++      alu_l to alu, move_l to omove.  Join move to alu.  Split mul
++      to mul_l and mul_w.
++      (cf_ib_*): Simplify description of instruction buffer.
++      (cf_ib_w0, cf_ib_w4, cf_ib_w5, cf_ib_w6): Remove.
++      (cf_mem): Split into cf_mem1 and cf_mem2.
++      (cf_v2_move_??): Rename to cfv12_alu_??.
++      (cf_v2_move_l_??): Rename to cfv12_omove_??.
++      (cf_v2_mul_??): Remove reservations.
++      (cfv12_mul_l_??, cfv12_mul_w_??, cfv12_mac_w_??, cfv12_mac_l_??,
++      cfv12_emac_??, cfv12_emac_w_i0): New reservations.
++      (cfv12_rts, cfv12_call, cfv12_bcc, cfv12_bra, cfv12_jmp): Move to
++      appropriate place.
++      (cfv3_alu_10, cfv3_omove_10, cfv3_alu_i0, cfv3_omove_i0, cfv3_alu_01,
++      cfv3_alu_0i, cfv3_alu_11, cfv3_omove_11, cfv3_alu_i1, cfv3_omove_i1,
++      cfv3_alu_1i, cfv3_omove_1i, cfv3_pea_11, cfv3_pea_i1, cfv3_mul_w_10,
++      cfv3_mul_l_10, cfv3_mul_w_i0, cfv3_mac_w_10, cfv3_mac_l_10,
++      cfv3_mac_w_i0, cfv3_emac_10, cfv3_emac_w_i0, cfv3_rts, cfv3_call,
++      cfv3_bcc, cfv3_bra, cfv3_jmp): New reservations.
++      (cfv3_*_1, cfv3_*_2, cfv3_*_3): New instruction reservations that are
++      expansions of the above reservations for instructions of sizes
++      1, 2 and 3 words.
++
++2008-05-09  Maxim Kuvyrkov  <maxim@codesourcery.com>
++
++      Backport from mainline.
++
++      gcc/
++      2008-04-22  Maxim Kuvyrkov  <maxim@codesourcery.com>
++      * rtl-factoring.c (collect_patterns_seqs): Handle CC0 targets.
++
++2008-05-05  Mark Mitchell  <mark@codesourcery.com>
++          Joseph Myers  <joseph@codesourcery.com>
++          Mark Shinwell  <shinwell@codesourcery.com>
++          Vladimir Prus  <vladimir@codesourcery.com>
++          Paul Brook  <paul@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/
++      * config.gcc (arm-wrs-linux-gnueabi, i586-wrs-linux-gnu,
++      mips-wrs-linux-gnu, powerpc-wrs-linux-gnu, sparc-wrs-linux-gnu):
++      Handle new targets.
++      * config/arm/t-wrs-linux, config/arm/wrs-linux.h,
++      config/mips/t-wrs-linux, config/mips/wrs-linux.h,
++      config/rs6000/t-wrs-linux, config/rs6000/wrs-linux.h: New.
++      * config/sparc/linux64.h (TARGET_DEFAULT): Define differently for
++      BIARCH_32BIT_DEFAULT.
++
++      libcpp/
++      * configure.ac (sparc-wrs-linux-gnu): Add to need_64bit_hwint=yes
++      targets.
++      * configure: Regenerate.
++
++2008-05-05  Joseph Myers  <joseph@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/
++      * config/sparc/linux64.h (LINK_ARCH32_SPEC, LINK_ARCH64_SPEC,
++      LINK_SPEC): Use %R in -Y P argument.
++
++2008-05-05  Joseph Myers  <joseph@codesourcery.com>
++          Daniel Jacobowitz  <dan@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/
++      * config/rs6000/rs6000.h (OPTION_DEFAULT_SPECS): Handle -te500v1,
++      -te500v2 and -te600.
++
++2008-05-05  Joseph Myers  <joseph@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/
++      * config/rs6000/sysv4.h (CC1_EXTRA_SPEC): Define and use.
++
++2008-05-05  Joseph Myers  <joseph@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/testsuite/
++      * g++.dg/compat/struct-layout-1.exp: Compile generator on build
++      system.
++      * gcc.dg/compat/struct-layout-1.exp: Likewise.
++
++2008-05-05  Joseph Myers  <joseph@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/testsuite/
++      * lib/gcc-dg.exp (remove-build-file): Remove files on remote host
++      as well as on build.
++
++2008-05-05  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      2008-03-04  Joseph Myers  <joseph@codesourcery.com>
++      * config/i386/i386.c (override_options): Force
++      -maccumulate-outgoing-args on if TARGET_STACK_PROBE.
++
++      gcc/testsuite/
++      2008-03-04  Joseph Myers  <joseph@codesourcery.com>
++      * gcc.target/i386/sse-10.c: Don't use
++      -mno-accumulate-outgoing-args on *-*-mingw* *-*-cygwin*.
++
++2008-05-05  Joseph Myers  <joseph@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      config/
++      * config/mh-mingw (LDFLAGS): Define.
++
++      gcc/
++      * configure.ac: Use empty LDFLAGS when running configure for the
++      build system.
++      * configure: Regenerate.
++      * Makefile.in (BUILD_LDFLAGS): Do not define to $(LDFLAGS) unless
++      host == build.
++
++2008-05-05  Joseph Myers  <joseph@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/
++      * libgcc2.c (__do_global_dtors): Do not call
++      __deregister_frame_info on MinGW.
++      (__do_global_ctors): Call atexit before calling constructors.  Do
++      not call __register_frame_info on MinGW.
++      * config/i386/mingw32.h (LIBGCC_SPEC): Start with -lgcc.
++
++2008-05-05  Joseph Myers  <joseph@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/
++      2007-06-13  Joseph Myers  <joseph@codesourcery.com>
++      * common.opt (--Wno-poison-system-directories): New.
++      * doc/invoke.texi (-Wno-poison-system-directories): Document.
++      * c-incpath.c: Include flags.h.
++      (merge_include_chains): Check flag_poison_system_directories.
++      * gcc.c (LINK_COMMAND_SPEC): Pass --no-poison-system-directories
++      to linker if -Wno-poison-system-directories.
++      * Makefile.in (c-incpath.o): Depend on $(FLAGS_H).
++
++      2007-03-20  Daniel Jacobowitz  <dan@codesourcery.com>
++                  Joseph Myers  <joseph@codesourcery.com>
++      * configure.ac (--enable-poison-system-directories): New option.
++      * configure, config.in: Regenerate.
++      * c-incpath.c (merge_include_chains): If
++      ENABLE_POISON_SYSTEM_DIRECTORIES defined, warn for use of
++      /usr/include, /usr/local/include or /usr/X11R6/include.
++
++2008-05-02  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      gcc/
++      2008-02-23  Joseph Myers  <joseph@codesourcery.com>
++      * explow.c (memory_address): Assert that the generated address is
++      valid.
++
++2008-05-02  Joseph Myers  <joseph@codesourcery.com>
++
++      Backport:
++
++      libstdc++-v3/
++      2008-03-04  Joseph Myers  <joseph@codesourcery.com>
++      * crossconfig.m4 (*-mingw32*): Define HAVE_STRTOF and
++      HAVE_STRTOLD.
++      * configure: Regenerate.
++
++2008-05-02  Joseph Myers  <joseph@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/
++      * collect2.c (find_a_file): Use IS_ABSOLUTE_PATH.
++
++2008-05-02  Joseph Myers  <joseph@codesourcery.com>
++
++      gcc/
++      * config.gcc (i[34567]86-*-* | x86_64-*-*): Support arch32 arch64.
++      * config/i386/i386.h (OPT_ARCH32, OPT_ARCH64): Define.
++      (OPTION_DEFAULT_SPECS): Add arch32 and arch64.
++
++2008-05-02  Joseph Myers  <joseph@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/
++      * config.gcc (mips*-*-*): Support arch32 arch64 tune32 tune64.
++      (powerpc*-*-* | rs6000-*-*): Support cpu32 cpu64.
++      (all_defaults): Add arch32 arch64 cpu32 cpu64 tune32 tune64.
++      * config/mips/mips.h (OPTION_DEFAULT_SPECS): Add support for
++      arch32 arch64 tune32 tune64.
++      * gcc/config/rs6000/rs6000.h (OPTION_DEFAULT_SPECS): Add cpu32 and
++      cpu64.
++
++2008-05-02  Joseph Myers  <joseph@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/
++      * config.gcc (i[34567]86-*-linux*): Use extra config files if
++      --enable-extra-sgxx-multilibs.
++      * config/i386/cs-linux.h, config/i386/cs-linux.opt,
++      config/i386/t-cs-linux: New.
++
++2008-05-01  Mark Mitchell  <mark@codesourcery.com>
++          Vladimir Prus  <vladimir@codesourcery.com>
++          Joseph Myers  <joseph@codesourcery.com>
++          Carlos O'Donell  <carlos@codesourcery.com>
++          Daniel Jacobowitz  <dan@codesourcery.com>
++          Kazu Hirata  <kazu@codesourcery.com>
++
++      libiberty/
++      * configure.ac: Add cygpath for mingw hosts.
++      * configure: Regenerate.
++      * Makefile.in: Add cygpath.
++      * cygpath.c: New.
++      * pex-win32.c (pex_win32_open_read, pex_win32_open_write): Use
++      open not _open.
++
++      include/
++      * libiberty.h (cygpath): Declare.
++
++2008-05-01  Carlos O'Donell  <carlos@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      * Makefile.tpl (install): Call install-html and install-pdf.
++      * Makefile.in: Regenerate.
++
++      gcc/
++      * Makefile.in (install): Depend on install-html and install-pdf.
++
++2008-05-01  Joseph Myers  <joseph@codesourcery.com>
++
++      Merge from Sourcery G++ 4.2:
++
++      gcc/
++      2007-10-16  Joseph Myers  <joseph@codesourcery.com>
++      * gcc.c (license_me_flag): Define to 1 if not TARGET_FLEXLM.
++
++      2007-08-10  Nathan Froyd  <froydnj@codesourcery.com>
++      * gcc.c (main): Consult license_me_flag to see if failure to
++      acquire a license implies bailing out entirely.
++
++      2007-08-24  Nathan Froyd  <froydnj@codesourcery.com>
++      Issue #1892
++      * gcc.c (main): Check license_me_flag before declaring failure.
++
++      2007-08-30  Nathan Sidwell  <nathan@codesourcery.com>
++      Issue #1892
++      * gcc.c (main): Don't complain if license fails without -flicense-me
++
++      2007-04-12  Richard Sandiford  <richard@codesourcery.com>
++      * gcc.c (main): If find_a_file fails, pass the original subproc
++      to csl_subproc_license_new.
++
++      2006-12-27  Mark Mitchell  <mark@codesourcery.com>
++      NOT ASSIGNED TO FSF
++      COPYRIGHT CODESOURCERY
++      * gcc.c (main): If the license check fails, remove the generated
++      file.
++
++      2006-12-22  Mark Mitchell  <mark@codesourcery.com>
++      NOT ASSIGNED TO FSF
++      COPYRIGHT CODESOURCERY
++      * aclocal.m4: Move licensing options ...
++      * acinclude.m4: ... here.
++
++      2006-12-13  Mark Mitchell  <mark@codesourcery.com>
++      NOT ASSIGNED TO FSF
++      COPYRIGHT CODESOURCERY
++      * gcc.c (csl/license.h): Include, if required.
++      (license_checked): New variable.
++      (no_license): Remove.
++      (process_command): Set license_checked, not no_license.
++      (main): Use CodeSourcery license library.  Remove most
++      TARGET_FLEXLM code.
++      * aclocal.m4 (--with-license): New option.
++      (--with-csl-license-feature): Likewise.
++      (--with-csl-license-version): Likewise.
++      * Makefile.in (CSL_LICENSEINC): Define it.
++      (CSL_LICENSELIB): Likewise.
++      (CSL_LICENSE_PROG): Likewise.
++      (LIBS): Depend on CSL_LICENSELIB.
++      (GCC_PASSES): Depend on CSL_LICENSE_PROG.
++      (INCLUDES): Add CSL_LICENSEINC.
++      * configure.ac (CSL_AC_LICENSE_VERSION): Use it.
++      (CSL_AC_LICENSE): Likewise.
++      (CSL_AC_LICENSE_FEATURE): Likewise.
++      * config.in: Regenerated.
++      * configure: Regenerated.
++
++      2006-10-29  Richard Sandiford  <richard@codesourcery.com>
++                  Joseph Myers  <joseph@codesourcery.com>
++      * gcc.c (license_me_flag): New variable.
++      (feature_proxy_flag): New variable.
++      (no_license): New variable.
++      (process_command): Handle -flicense-me, -ffeature-proxy and
++      -fno-feature-proxy.  Initialize no_license.
++      (main): Check licenses.
++
++2008-05-01  Joseph Myers  <joseph@codesourcery.com>
++
++      * release-notes-csl.xml: New.
++
++\f
++Local Variables:
++mode: change-log
++change-log-default-name: "ChangeLog.csl"
++End:
+--- a/boehm-gc/Makefile.am
++++ b/boehm-gc/Makefile.am
+@@ -66,7 +66,8 @@ TESTS = gctest
+ ## CFLAGS, not those passed in from the top level make.
+ LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(MY_CFLAGS) $(GC_CFLAGS) 
+-LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LDFLAGS) -o $@
++LTLDFLAGS = $(shell $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
++LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LTLDFLAGS) -o $@
+ # Work around what appears to be a GNU make bug handling MAKEFLAGS
+ # values defined in terms of make variables, as is the case for CC and
+--- a/boehm-gc/Makefile.in
++++ b/boehm-gc/Makefile.in
+@@ -303,7 +303,8 @@ TESTS = gctest
+ LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(MY_CFLAGS) $(GC_CFLAGS) 
+-LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LDFLAGS) -o $@
++LTLDFLAGS = $(shell $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
++LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LTLDFLAGS) -o $@
+ # Work around what appears to be a GNU make bug handling MAKEFLAGS
+ # values defined in terms of make variables, as is the case for CC and
+--- a/config.sub
++++ b/config.sub
+@@ -254,6 +254,7 @@ case $basic_machine in
+       | mips | mipsbe | mipseb | mipsel | mipsle \
+       | mips16 \
+       | mips64 | mips64el \
++      | mips64octeon | mips64octeonel \
+       | mips64vr | mips64vrel \
+       | mips64orion | mips64orionel \
+       | mips64vr4100 | mips64vr4100el \
+@@ -335,6 +336,7 @@ case $basic_machine in
+       | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+       | mips16-* \
+       | mips64-* | mips64el-* \
++      | mips64octeon-* | mips64octeonel-* \
+       | mips64vr-* | mips64vrel-* \
+       | mips64orion-* | mips64orionel-* \
+       | mips64vr4100-* | mips64vr4100el-* \
+--- a/config/mh-mingw
++++ b/config/mh-mingw
+@@ -1,3 +1,7 @@
+ # Add -D__USE_MINGW_ACCESS to enable the built compiler to work on Windows
+ # Vista (see PR33281 for details).
+-BOOT_CFLAGS += -D__USE_MINGW_ACCESS
++# Because we wrap access in libiberty/cygpath.c, we do not want to use
++# the MinGW wrappers for access.
++# BOOT_CFLAGS += -D__USE_MINGW_ACCESS
++# Increase stack limit to same as Linux default.
++LDFLAGS += -Wl,--stack,8388608
+--- a/config/mt-sde
++++ b/config/mt-sde
+@@ -6,5 +6,5 @@
+ # has two purposes: it allows libraries to be used in situations where
+ # $gp != our _gp, and it allows them to be built with -G8 while
+ # retaining link compability with -G0 and -G4.
+-CFLAGS_FOR_TARGET += -Os -minterlink-mips16 -mcode-xonly -mno-gpopt
++CFLAGS_FOR_TARGET += -Os -minterlink-mips16 -mcode-xonly -mno-gpopt 
+ CXXFLAGS_FOR_TARGET += -Os -minterlink-mips16 -mcode-xonly -mno-gpopt
+--- a/configure
++++ b/configure
+@@ -2195,7 +2195,7 @@ case "${target}" in
+     noconfigdirs="$noconfigdirs target-newlib target-libgloss target-rda ${libgcj}"
+     ;;
+   *-*-vxworks*)
+-    noconfigdirs="$noconfigdirs target-newlib target-libgloss target-libiberty target-libstdc++-v3 ${libgcj}"
++    noconfigdirs="$noconfigdirs target-newlib target-libgloss target-libiberty ${libgcj}"
+     ;;
+   alpha*-dec-osf*)
+     # ld works, but does not support shared libraries.
+--- a/configure.ac
++++ b/configure.ac
+@@ -472,7 +472,7 @@ case "${target}" in
+     noconfigdirs="$noconfigdirs target-newlib target-libgloss target-rda ${libgcj}"
+     ;;
+   *-*-vxworks*)
+-    noconfigdirs="$noconfigdirs target-newlib target-libgloss target-libiberty target-libstdc++-v3 ${libgcj}"
++    noconfigdirs="$noconfigdirs target-newlib target-libgloss target-libiberty ${libgcj}"
+     ;;
+   alpha*-dec-osf*)
+     # ld works, but does not support shared libraries.
+--- a/fixincludes/fixincl.x
++++ b/fixincludes/fixincl.x
+@@ -2,11 +2,11 @@
+  * 
+  * DO NOT EDIT THIS FILE   (fixincl.x)
+  * 
+- * It has been AutoGen-ed  Monday January  5, 2009 at 04:00:24 PM PST
++ * It has been AutoGen-ed  Tuesday February 17, 2009 at 01:49:33 PM PST
+  * From the definitions    inclhack.def
+  * and the template file   fixincl
+  */
+-/* DO NOT SVN-MERGE THIS FILE, EITHER Mon Jan  5 16:00:24 PST 2009
++/* DO NOT SVN-MERGE THIS FILE, EITHER Tue Feb 17 13:49:33 PST 2009
+  *
+  * You must regenerate it.  Use the ./genfixes script.
+  *
+@@ -214,11 +214,14 @@ tSCC zAab_Fd_Zero_Asm_Posix_Types_HBypas
+        "} while";
+ tSCC zAab_Fd_Zero_Asm_Posix_Types_HBypass1[] =
+        "x86_64";
++tSCC zAab_Fd_Zero_Asm_Posix_Types_HBypass2[] =
++       "posix_types_64";
+-#define    AAB_FD_ZERO_ASM_POSIX_TYPES_H_TEST_CT  2
++#define    AAB_FD_ZERO_ASM_POSIX_TYPES_H_TEST_CT  3
+ static tTestDesc aAab_Fd_Zero_Asm_Posix_Types_HTests[] = {
+   { TT_NEGREP,   zAab_Fd_Zero_Asm_Posix_Types_HBypass0, (regex_t*)NULL },
+-  { TT_NEGREP,   zAab_Fd_Zero_Asm_Posix_Types_HBypass1, (regex_t*)NULL }, };
++  { TT_NEGREP,   zAab_Fd_Zero_Asm_Posix_Types_HBypass1, (regex_t*)NULL },
++  { TT_NEGREP,   zAab_Fd_Zero_Asm_Posix_Types_HBypass2, (regex_t*)NULL }, };
+ /*
+  *  Fix Command Arguments for Aab_Fd_Zero_Asm_Posix_Types_H
+@@ -5974,8 +5977,7 @@ tSCC zSolaris_Mutex_Init_2List[] =
+  *  Machine/OS name selection pattern
+  */
+ tSCC* apzSolaris_Mutex_Init_2Machs[] = {
+-        "*-*-solaris2.[0-9]",
+-        "*-*-solaris2.[0-9][!0-9]*",
++        "*-*-solaris*",
+         (const char*)NULL };
+ /*
+@@ -5984,8 +5986,15 @@ tSCC* apzSolaris_Mutex_Init_2Machs[] = {
+ tSCC zSolaris_Mutex_Init_2Select0[] =
+        "@\\(#\\)pthread.h[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
+-#define    SOLARIS_MUTEX_INIT_2_TEST_CT  1
++/*
++ *  perform the 'test' shell command - do fix on success
++ */
++tSCC zSolaris_Mutex_Init_2Test0[] =
++       " -n \"`grep '#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)' \\`dirname $file\\`/sys/types.h`\"";
++
++#define    SOLARIS_MUTEX_INIT_2_TEST_CT  2
+ static tTestDesc aSolaris_Mutex_Init_2Tests[] = {
++  { TT_TEST,     zSolaris_Mutex_Init_2Test0,   0 /* unused */ },
+   { TT_EGREP,    zSolaris_Mutex_Init_2Select0, (regex_t*)NULL }, };
+ /*
+@@ -6027,8 +6036,15 @@ tSCC* apzSolaris_Rwlock_Init_1Machs[] = 
+ tSCC zSolaris_Rwlock_Init_1Select0[] =
+        "@\\(#\\)pthread.h[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
+-#define    SOLARIS_RWLOCK_INIT_1_TEST_CT  1
++/*
++ *  perform the 'test' shell command - do fix on success
++ */
++tSCC zSolaris_Rwlock_Init_1Test0[] =
++       " -n \"`grep '#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)' \\`dirname $file\\`/sys/types.h`\"";
++
++#define    SOLARIS_RWLOCK_INIT_1_TEST_CT  2
+ static tTestDesc aSolaris_Rwlock_Init_1Tests[] = {
++  { TT_TEST,     zSolaris_Rwlock_Init_1Test0,   0 /* unused */ },
+   { TT_EGREP,    zSolaris_Rwlock_Init_1Select0, (regex_t*)NULL }, };
+ /*
+@@ -6098,8 +6114,7 @@ tSCC zSolaris_Once_Init_2List[] =
+  *  Machine/OS name selection pattern
+  */
+ tSCC* apzSolaris_Once_Init_2Machs[] = {
+-        "*-*-solaris2.[0-9]",
+-        "*-*-solaris2.[0-9][!0-9]*",
++        "*-*-solaris*",
+         (const char*)NULL };
+ /*
+@@ -6108,8 +6123,15 @@ tSCC* apzSolaris_Once_Init_2Machs[] = {
+ tSCC zSolaris_Once_Init_2Select0[] =
+        "@\\(#\\)pthread.h[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
+-#define    SOLARIS_ONCE_INIT_2_TEST_CT  1
++/*
++ *  perform the 'test' shell command - do fix on success
++ */
++tSCC zSolaris_Once_Init_2Test0[] =
++       " -n \"`grep '#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)' \\`dirname $file\\`/sys/types.h`\"";
++
++#define    SOLARIS_ONCE_INIT_2_TEST_CT  2
+ static tTestDesc aSolaris_Once_Init_2Tests[] = {
++  { TT_TEST,     zSolaris_Once_Init_2Test0,   0 /* unused */ },
+   { TT_EGREP,    zSolaris_Once_Init_2Select0, (regex_t*)NULL }, };
+ /*
+@@ -8606,7 +8628,7 @@ static const char* apzX11_SprintfPatch[]
+  *
+  *  List of all fixes
+  */
+-#define REGEX_COUNT          255
++#define REGEX_COUNT          256
+ #define MACH_LIST_SIZE_LIMIT 261
+ #define FIX_COUNT            212
+--- a/fixincludes/inclhack.def
++++ b/fixincludes/inclhack.def
+@@ -141,6 +141,7 @@ fix = {
+     mach     = 'i[34567]86-*-linux*';
+     bypass   = '} while';
+     bypass   = 'x86_64';
++    bypass   = 'posix_types_64';
+     /*
+      * Define _POSIX_TYPES_H_WRAPPER at the end of the wrapper, not
+@@ -3274,24 +3275,32 @@ fix = {
+ /*
+- * Sun Solaris defines PTHREAD_MUTEX_INITIALIZER with a trailing
+- * "0" for the last field of the pthread_mutex_t structure, which is
+- * of type upad64_t, which itself is typedef'd to int64_t, but with
+- * __STDC__ defined (e.g. by -ansi) it is a union. So change the
+- * initializer to "{0}" instead
++ * Sun Solaris defines the last field of the pthread_mutex_t structure
++ * to have type upad64_t.  Whether upad64_t is an integer type or a
++ * union depends on whether or not the headers believe that a 64-bit
++ * integer type is available.  But, PTHREAD_MUTEX_INITIALIZER is not
++ * appropriately conditionalized; it always uses "0", and never "{0}".
++ * In order to avoid warnings/errors from the compiler, we must make
++ * the initializer use braces where appropriate.
++ *
++ * Prior to Solaris 10, if __STDC__ is 1 (as when compiling with
++ * -ansi), the definition would be a union.  Beginning with Solaris
++ * 10, the headers check for __GNUC__, and will never use a union with
++ * GCC.  We check /usr/include/sys/types.h to see if it checks for
++ * __STDC__.
++ *
++ * A "mach" test for Solaris 10 is undesirable because we want to
++ * allow a compiler built for Solaris <10 to be used on Solaris >=10,
++ * but the installed version of fixincludes hard-wires the target
++ * machine to the configure-time $target, rather than automatically
++ * determining it at installation time.
+  */
+ fix = {
+     hackname = solaris_mutex_init_2;
+     select = '@\(#\)pthread.h' "[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
+     files = pthread.h;
+-    /*
+-     * On Solaris 10, this fix is unnecessary because upad64_t is
+-     * always defined correctly regardless of the definition of the
+-     * __STDC__ macro.  The first "mach" pattern matches up to
+-     * solaris9.  The second "mach" pattern will not match any two (or
+-     * more) digit solaris version, but it will match e.g. 2.5.1.
+-     */
+-    mach = '*-*-solaris2.[0-9]', '*-*-solaris2.[0-9][!0-9]*';
++    mach = '*-*-solaris*';
++    test = " -n \"`grep '#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)' \\`dirname $file\\`/sys/types.h`\"";
+     c_fix = format;
+     c_fix_arg = "#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)\n"
+                 "%0\n"
+@@ -3302,6 +3311,7 @@ fix = {
+                 "(|/\*.*\*/[ \t]*\\\\\n[ \t]*)\\{.*)"
+                 ",[ \t]*0\\}" "(|[ \t].*)$";
+     test_text =
++    "`mkdir -p sys; echo '#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)' >> sys/types.h`"
+     '#ident "@(#)pthread.h  1.26  98/04/12 SMI"'"\n"
+     "#define PTHREAD_MUTEX_INITIALIZER\t{{{0},0}, {{{0}}}, 0}\n"
+     "#define PTHREAD_COND_INITIALIZER\t{{{0}, 0}, 0}\t/* DEFAULTCV */\n"
+@@ -3313,17 +3323,14 @@ fix = {
+ /*
+- * Sun Solaris defines PTHREAD_RWLOCK_INITIALIZER with a "0" for some
+- *  fields of the pthread_rwlock_t structure, which are of type
+- *  upad64_t, which itself is typedef'd to int64_t, but with __STDC__
+- *  defined (e.g. by -ansi) it is a union. So change the initializer
+- *  to "{0}" instead.
++ * See comments for solaris_mutex_init_2 re. upad64_t.
+  */
+ fix = {
+     hackname = solaris_rwlock_init_1;
+     select = '@\(#\)pthread.h' "[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
+     files = pthread.h;
+     mach = '*-*-solaris*';
++    test = " -n \"`grep '#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)' \\`dirname $file\\`/sys/types.h`\"";
+     c_fix = format;
+     c_fix_arg = "#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)\n"
+                 "%0\n"
+@@ -3359,24 +3366,14 @@ fix = {
+ /*
+- * Sun Solaris defines PTHREAD_ONCE_INIT with a "0" for some
+- *  fields of the pthread_once_t structure, which are of type
+- *  upad64_t, which itself is typedef'd to int64_t, but with __STDC__
+- *  defined (e.g. by -ansi) it is a union. So change the initializer
+- *  to "{0}" instead.  This test relies on solaris_once_init_1.
++ * See comments for solaris_mutex_init_2 re. upad64_t.
+  */
+ fix = {
+     hackname = solaris_once_init_2;
+     select = '@\(#\)pthread.h' "[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
+     files = pthread.h;
+-    /*
+-     * On Solaris 10, this fix is unnecessary because upad64_t is
+-     * always defined correctly regardless of the definition of the
+-     * __STDC__ macro.  The first "mach" pattern matches up to
+-     * solaris9.  The second "mach" pattern will not match any two (or
+-     * more) digit solaris version, but it will match e.g. 2.5.1.
+-     */
+-    mach = '*-*-solaris2.[0-9]', '*-*-solaris2.[0-9][!0-9]*';
++    mach = '*-*-solaris*';
++    test = " -n \"`grep '#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)' \\`dirname $file\\`/sys/types.h`\"";
+     c_fix = format;
+     c_fix_arg = "#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)\n"
+                 "%0\n"
+--- a/fixincludes/server.c
++++ b/fixincludes/server.c
+@@ -266,7 +266,7 @@ run_shell (const char* pz_cmd)
+   /*  Make sure the process will pay attention to us, send the
+      supplied command, and then have it output a special marker that
+      we can find.  */
+-  fprintf (server_pair.pf_write, "cd %s\n%s\n\necho\necho %s\n",
++  fprintf (server_pair.pf_write, "cd '%s'\n%s\n\necho\necho %s\n",
+            p_cur_dir, pz_cmd, z_done);
+   fflush (server_pair.pf_write);
+--- a/fixincludes/tests/base/sys/types.h
++++ b/fixincludes/tests/base/sys/types.h
+@@ -28,3 +28,4 @@ typedef __WCHAR_TYPE__ wchar_t;
+ #endif /* ushort_t */
+ #endif  /* GNU_TYPES_CHECK */
++#if  !defined(__STRICT_ANSI__) && !defined(_NO_LONGLONG)
+--- a/gcc/Makefile.in
++++ b/gcc/Makefile.in
+@@ -321,6 +321,8 @@ GCC_FOR_TARGET = $(STAGE_CC_WRAPPER) ./x
+ # It also specifies -isystem ./include to find, e.g., stddef.h.
+ GCC_CFLAGS=$(CFLAGS_FOR_TARGET) $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(LOOSE_WARN) -Wold-style-definition $($@-warn) -isystem ./include $(TCFLAGS)
++EGLIBC_CONFIGS = @EGLIBC_CONFIGS@
++
+ # ---------------------------------------------------
+ # Programs which produce files for the target machine
+ # ---------------------------------------------------
+@@ -402,6 +404,9 @@ TARGET_SYSTEM_ROOT = @TARGET_SYSTEM_ROOT
+ xmake_file=@xmake_file@
+ tmake_file=@tmake_file@
++TM_ENDIAN_CONFIG=@TM_ENDIAN_CONFIG@
++TM_MULTILIB_CONFIG=@TM_MULTILIB_CONFIG@
++TM_MULTILIB_EXCEPTIONS_CONFIG=@TM_MULTILIB_EXCEPTIONS_CONFIG@
+ out_file=$(srcdir)/config/@out_file@
+ out_object_file=@out_object_file@
+ md_file=$(srcdir)/config/@md_file@
+@@ -688,7 +693,11 @@ CC_FOR_BUILD = @CC_FOR_BUILD@
+ BUILD_CFLAGS= @BUILD_CFLAGS@ -DGENERATOR_FILE
+ # Native linker and preprocessor flags.  For x-fragment overrides.
++ifeq ($(host),$(build))
+ BUILD_LDFLAGS=$(LDFLAGS)
++else
++BUILD_LDFLAGS=
++endif
+ BUILD_CPPFLAGS=$(ALL_CPPFLAGS)
+ # Actual name to use when installing a native compiler.
+@@ -1205,6 +1214,7 @@ OBJS-common = \
+       tree-ssa-loop-manip.o \
+       tree-ssa-loop-niter.o \
+       tree-ssa-loop-prefetch.o \
++      tree-ssa-loop-promote.o \
+       tree-ssa-loop-unswitch.o \
+       tree-ssa-loop.o \
+       tree-ssa-math-opts.o \
+@@ -1213,6 +1223,7 @@ OBJS-common = \
+       tree-ssa-pre.o \
+       tree-ssa-propagate.o \
+       tree-ssa-reassoc.o \
++      tree-ssa-remove-local-statics.o \
+       tree-ssa-sccvn.o \
+       tree-ssa-sink.o \
+       tree-ssa-structalias.o \
+@@ -1605,7 +1616,7 @@ libgcc-support: libgcc.mvars stmp-int-hd
+       $(MACHMODE_H) $(FPBIT) $(DPBIT) $(TPBIT) $(LIB2ADD) \
+       $(LIB2ADD_ST) $(LIB2ADDEH) $(srcdir)/emutls.c gcov-iov.h $(SFP_MACHINE)
+-libgcc.mvars: config.status Makefile $(LIB2ADD) $(LIB2ADD_ST) specs \
++libgcc.mvars: config.status Makefile $(LIB2ADD) $(LIB2ADD_ST) specs $(tmake_file) \
+               xgcc$(exeext)
+       : > tmp-libgcc.mvars
+       echo LIB1ASMFUNCS = '$(LIB1ASMFUNCS)' >> tmp-libgcc.mvars
+@@ -1656,7 +1667,7 @@ libgcc.mvars: config.status Makefile $(L
+ # driver program needs to select the library directory based on the
+ # switches.
+ multilib.h: s-mlib; @true
+-s-mlib: $(srcdir)/genmultilib Makefile
++s-mlib: $(srcdir)/genmultilib Makefile $(tmakefile)
+       if test @enable_multilib@ = yes \
+          || test -n "$(MULTILIB_OSDIRNAMES)"; then \
+         $(SHELL) $(srcdir)/genmultilib \
+@@ -1667,10 +1678,11 @@ s-mlib: $(srcdir)/genmultilib Makefile
+           "$(MULTILIB_EXTRA_OPTS)" \
+           "$(MULTILIB_EXCLUSIONS)" \
+           "$(MULTILIB_OSDIRNAMES)" \
++          "$(MULTILIB_ALIASES)" \
+           "@enable_multilib@" \
+           > tmp-mlib.h; \
+       else \
+-        $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' no \
++        $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' '' no \
+           > tmp-mlib.h; \
+       fi
+       $(SHELL) $(srcdir)/../move-if-change tmp-mlib.h multilib.h
+@@ -1744,7 +1756,7 @@ gcc.srcextra: gengtype-lex.c
+ c-incpath.o: c-incpath.c c-incpath.h $(CONFIG_H) $(SYSTEM_H) $(CPPLIB_H) \
+               intl.h prefix.h coretypes.h $(TM_H) cppdefault.h $(TARGET_H) \
+-              $(MACHMODE_H)
++              $(MACHMODE_H) $(FLAGS_H) toplev.h
+ c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+     $(RTL_H) $(C_TREE_H) $(GGC_H) $(TARGET_H) $(FLAGS_H) $(FUNCTION_H) output.h \
+@@ -1874,7 +1886,8 @@ DRIVER_DEFINES = \
+   -DTOOLDIR_BASE_PREFIX=\"$(libsubdir_to_prefix)$(prefix_to_exec_prefix)\" \
+   @TARGET_SYSTEM_ROOT_DEFINE@ \
+   $(VALGRIND_DRIVER_DEFINES) \
+-  `test "X$${SHLIB_LINK}" = "X" || test "@enable_shared@" != "yes" || echo "-DENABLE_SHARED_LIBGCC"`
++  `test "X$${SHLIB_LINK}" = "X" || test "@enable_shared@" != "yes" || echo "-DENABLE_SHARED_LIBGCC"` \
++  -DCONFIGURE_SPECS="\"@CONFIGURE_SPECS@\""
+ gcc.o: gcc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h multilib.h \
+     Makefile $(lang_specs_files) specs.h prefix.h $(GCC_H) $(FLAGS_H) \
+@@ -2091,6 +2104,9 @@ tree-ssa-pre.o : tree-ssa-pre.c $(TREE_F
+    $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(CFGLOOP_H) \
+    alloc-pool.h $(BASIC_BLOCK_H) bitmap.h $(HASHTAB_H) $(TREE_GIMPLE_H) \
+    $(TREE_INLINE_H) tree-iterator.h tree-ssa-sccvn.h $(PARAMS_H)
++tree-ssa-remove-local-statics.o: tree-ssa-remove-local-statics.c \
++   coretypes.h $(CONFIG_H) $(SYSTEM_H) $(BASIC_BLOCK_H) tree.h tree-pass.h \
++   $(TM_H)
+ tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \
+    $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
+    $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(CFGLOOP_H) \
+@@ -2190,6 +2206,9 @@ tree-ssa-loop-prefetch.o: tree-ssa-loop-
+    $(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) hard-reg-set.h \
+    tree-chrec.h toplev.h langhooks.h $(TREE_INLINE_H) $(TREE_DATA_REF_H) \
+    $(OPTABS_H)
++tree-ssa-loop-promote.o: tree-ssa-loop-promote.c \
++   coretypes.h $(CONFIG_H) $(SYSTEM_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) $(TIMEVAR_H) \
++   $(TREE_DUMP_H) tree.h tree-pass.h $(TM_H)
+ tree-predcom.o: tree-predcom.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_P_H) \
+    $(CFGLOOP_H) $(TREE_FLOW_H) $(GGC_H) $(TREE_DATA_REF_H) $(SCEV_H) \
+    $(PARAMS_H) $(DIAGNOSTIC_H) tree-pass.h $(TM_H) coretypes.h tree-affine.h \
+@@ -2759,7 +2778,7 @@ postreload.o : postreload.c $(CONFIG_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) $(MACHMODE_H) \
+-   $(OBSTACK_H) $(TIMEVAR_H) tree-pass.h $(DF_H)
++   $(OBSTACK_H) $(TIMEVAR_H) tree-pass.h addresses.h $(DF_H)
+ postreload-gcse.o : postreload-gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+    $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
+    $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h \
+@@ -3406,7 +3425,7 @@ gcov-dump$(exeext): $(GCOV_DUMP_OBJS) $(
+ # be rebuilt.
+ # Build the include directories.
+-stmp-int-hdrs: $(STMP_FIXINC) $(USER_H) $(UNWIND_H) fixinc_list
++stmp-int-hdrs: $(STMP_FIXINC) $(USER_H) $(UNWIND_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.
+@@ -3425,21 +3444,23 @@ stmp-int-hdrs: $(STMP_FIXINC) $(USER_H) 
+       done
+       rm -f include/unwind.h
+       cp $(UNWIND_H) include/unwind.h
+-      set -e; for ml in `cat fixinc_list`; do \
+-        sysroot_headers_suffix=`echo $${ml} | sed -e 's/;.*$$//'`; \
+-        multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \
+-        fix_dir=include-fixed$${multi_dir}; \
+-        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; \
+-        $(mkinstalldirs) $${fix_dir}; \
+-        chmod a+rx $${fix_dir} || true; \
+-        rm -f $${fix_dir}/limits.h; \
+-        mv tmp-xlimits.h $${fix_dir}/limits.h; \
+-        chmod a+r $${fix_dir}/limits.h; \
+-      done
++      set -e; if [ -f fixinc_list ] ; then \
++        for ml in `cat fixinc_list`; do \
++          sysroot_headers_suffix=`echo $${ml} | sed -e 's/;.*$$//'`; \
++          multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \
++          fix_dir=include-fixed$${multi_dir}; \
++          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; \
++          $(mkinstalldirs) $${fix_dir}; \
++          chmod a+rx $${fix_dir} || true; \
++          rm -f $${fix_dir}/limits.h; \
++          mv tmp-xlimits.h $${fix_dir}/limits.h; \
++          chmod a+r $${fix_dir}/limits.h; \
++        done; \
++      fi
+ # Install the README
+       rm -f include-fixed/README
+       cp $(srcdir)/../fixincludes/README-fixinc include-fixed/README
+@@ -4164,16 +4185,18 @@ real-install-headers-cp:
+ # Install supporting files for fixincludes to be run later.
+ install-mkheaders: stmp-int-hdrs $(STMP_FIXPROTO) install-itoolsdirs \
+-  macro_list fixinc_list
++  macro_list
+       $(INSTALL_DATA) $(srcdir)/gsyslimits.h \
+         $(DESTDIR)$(itoolsdatadir)/gsyslimits.h
+       $(INSTALL_DATA) macro_list $(DESTDIR)$(itoolsdatadir)/macro_list
+-      $(INSTALL_DATA) fixinc_list $(DESTDIR)$(itoolsdatadir)/fixinc_list
+-      set -e; for ml in `cat fixinc_list`; do \
+-        multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \
+-        $(mkinstalldirs) $(DESTDIR)$(itoolsdatadir)/include$${multi_dir}; \
+-        $(INSTALL_DATA) include-fixed$${multidir}/limits.h $(DESTDIR)$(itoolsdatadir)/include$${multi_dir}/limits.h; \
+-      done
++      set -e; if [ -f fixinc_list ] ; then \
++        $(INSTALL_DATA) fixinc_list $(DESTDIR)$(itoolsdatadir)/fixinc_list; \
++        for ml in `cat fixinc_list`; do \
++          multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \
++          $(mkinstalldirs) $(DESTDIR)$(itoolsdatadir)/include$${multi_dir}; \
++          $(INSTALL_DATA) include-fixed$${multidir}/limits.h $(DESTDIR)$(itoolsdatadir)/include$${multi_dir}/limits.h; \
++        done; \
++      fi
+       $(INSTALL_SCRIPT) $(srcdir)/../mkinstalldirs \
+               $(DESTDIR)$(itoolsdir)/mkinstalldirs ; \
+       if [ x$(STMP_FIXPROTO) != x ] ; then \
+--- a/gcc/addresses.h
++++ b/gcc/addresses.h
+@@ -78,3 +78,42 @@ regno_ok_for_base_p (unsigned regno, enu
+   return ok_for_base_p_1 (regno, mode, outer_code, index_code);
+ }
++
++/* Wrapper function to unify target macros MODE_INDEX_REG_CLASS and
++   INDEX_REG_CLASS.  Arguments as for the MODE_INDEX_REG_CLASS macro.  */
++
++static inline enum reg_class
++index_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED)
++{
++#ifdef MODE_INDEX_REG_CLASS
++  return MODE_INDEX_REG_CLASS (mode);
++#else
++  return INDEX_REG_CLASS;
++#endif
++}
++
++/* Wrapper function to unify target macros REGNO_MODE_OK_FOR_INDEX_P
++   and REGNO_OK_FOR_INDEX_P.  Arguments as for the
++   REGNO_MODE_OK_FOR_INDEX_P macro.  */
++
++static inline bool
++ok_for_index_p_1 (unsigned regno, enum machine_mode mode ATTRIBUTE_UNUSED)
++{
++#ifdef REGNO_MODE_OK_FOR_INDEX_P
++  return REGNO_MODE_OK_FOR_INDEX_P (regno, mode);
++#else
++  return REGNO_OK_FOR_INDEX_P (regno);
++#endif
++}
++
++/* Wrapper around ok_for_index_p_1, for use after register allocation is
++   complete.  Arguments as for the called function.  */
++
++static inline bool
++regno_ok_for_index_p (unsigned regno, enum machine_mode mode)
++{
++  if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0)
++    regno = reg_renumber[regno];
++
++  return ok_for_index_p_1 (regno, mode);
++}
+--- a/gcc/c-common.c
++++ b/gcc/c-common.c
+@@ -1173,6 +1173,20 @@ check_main_parameter_types (tree decl)
+    pedwarn ("%q+D takes only zero or two arguments", decl);
+ }
++/* True if pointers to distinct types T1 and T2 can be converted to
++   each other without an explicit cast.  Only returns true for opaque
++   vector types.  */
++bool
++vector_targets_convertible_p (const_tree t1, const_tree t2)
++{
++  if (TREE_CODE (t1) == VECTOR_TYPE && TREE_CODE (t2) == VECTOR_TYPE
++      && (targetm.vector_opaque_p (t1) || targetm.vector_opaque_p (t2))
++      && tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2)))
++    return true;
++
++  return false;
++}
++
+ /* True if vector types T1 and T2 can be converted to each other
+    without an explicit cast.  If EMIT_LAX_NOTE is true, and T1 and T2
+    can only be converted with -flax-vector-conversions yet that is not
+--- a/gcc/c-common.h
++++ b/gcc/c-common.h
+@@ -829,6 +829,7 @@ extern tree finish_label_address_expr (t
+ extern tree lookup_label (tree);
+ extern tree lookup_name (tree);
++extern bool vector_targets_convertible_p (const_tree t1, const_tree t2);
+ extern bool vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note);
+ extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
+--- a/gcc/c-convert.c
++++ b/gcc/c-convert.c
+@@ -70,6 +70,7 @@ convert (tree type, tree expr)
+   tree e = expr;
+   enum tree_code code = TREE_CODE (type);
+   const char *invalid_conv_diag;
++  tree e1;
+   if (type == error_mark_node
+       || expr == error_mark_node
+@@ -85,7 +86,8 @@ convert (tree type, tree expr)
+   if (type == TREE_TYPE (expr))
+     return expr;
+-
++  if (e1 = targetm.convert_to_type (type, expr))
++    return e1;
+   if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
+     return fold_convert (type, expr);
+   if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
+--- a/gcc/c-decl.c
++++ b/gcc/c-decl.c
+@@ -3995,6 +3995,7 @@ grokdeclarator (const struct c_declarato
+   bool bitfield = width != NULL;
+   tree element_type;
+   struct c_arg_info *arg_info = 0;
++  const char *errmsg;
+   if (decl_context == FUNCDEF)
+     funcdef_flag = true, decl_context = NORMAL;
+@@ -4513,6 +4514,12 @@ grokdeclarator (const struct c_declarato
+               error ("%qs declared as function returning an array", name);
+               type = integer_type_node;
+             }
++          errmsg = targetm.invalid_return_type (type);
++          if (errmsg)
++            {
++              error (errmsg);
++              type = integer_type_node;
++            }
+           /* Construct the function type and go to the next
+              inner layer of declarator.  */
+@@ -5039,6 +5046,7 @@ grokparms (struct c_arg_info *arg_info, 
+     {
+       tree parm, type, typelt;
+       unsigned int parmno;
++      const char *errmsg;
+       /* If there is a parameter of incomplete type in a definition,
+        this is an error.  In a declaration this is valid, and a
+@@ -5082,6 +5090,14 @@ grokparms (struct c_arg_info *arg_info, 
+               }
+           }
++        errmsg = targetm.invalid_parameter_type (type);
++        if (errmsg)
++          {
++            error (errmsg);
++            TREE_VALUE (typelt) = error_mark_node;
++            TREE_TYPE (parm) = error_mark_node;
++          }
++
+         if (DECL_NAME (parm) && TREE_USED (parm))
+           warn_if_shadowing (parm);
+       }
+--- a/gcc/c-incpath.c
++++ b/gcc/c-incpath.c
+@@ -30,6 +30,8 @@
+ #include "intl.h"
+ #include "c-incpath.h"
+ #include "cppdefault.h"
++#include "flags.h"
++#include "toplev.h"
+ /* Windows does not natively support inodes, and neither does MSDOS.
+    Cygwin's emulation can generate non-unique inodes, so don't use it.
+@@ -37,15 +39,18 @@
+ #ifdef VMS
+ # define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
+ # define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC))
+-#else
+-# if (defined _WIN32 && !defined (_UWIN)) || defined __MSDOS__
+-#  define INO_T_EQ(A, B) 0
+-# else
+-#  define INO_T_EQ(A, B) ((A) == (B))
+-# endif
++#elif !((defined _WIN32 && !defined (_UWIN)) || defined __MSDOS__)
++# define INO_T_EQ(A, B) ((A) == (B))
+ # define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
+ #endif
++#if defined INO_T_EQ
++#define DIRS_EQ(A, B) ((A)->dev == (B)->dev \
++      && INO_T_EQ((A)->ino, (B)->ino))
++#else
++#define DIRS_EQ(A, B) (!strcasecmp ((A)->name, (B)->name))
++#endif
++
+ static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
+ static void add_env_var_paths (const char *, int);
+@@ -241,14 +246,15 @@ remove_duplicates (cpp_reader *pfile, st
+                            "%s: not a directory", cur->name);
+       else
+       {
++#if defined (INO_T_COPY)
+         INO_T_COPY (cur->ino, st.st_ino);
+         cur->dev  = st.st_dev;
++#endif
+         /* Remove this one if it is in the system chain.  */
+         reason = REASON_DUP_SYS;
+         for (tmp = system; tmp; tmp = tmp->next)
+-         if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev
+-             && cur->construct == tmp->construct)
++         if (DIRS_EQ (tmp, cur) && cur->construct == tmp->construct)
+             break;
+         if (!tmp)
+@@ -256,16 +262,14 @@ remove_duplicates (cpp_reader *pfile, st
+             /* Duplicate of something earlier in the same chain?  */
+             reason = REASON_DUP;
+             for (tmp = head; tmp != cur; tmp = tmp->next)
+-             if (INO_T_EQ (cur->ino, tmp->ino) && cur->dev == tmp->dev
+-                 && cur->construct == tmp->construct)
++             if (DIRS_EQ (cur, tmp) && cur->construct == tmp->construct)
+                 break;
+             if (tmp == cur
+                 /* Last in the chain and duplicate of JOIN?  */
+                 && !(cur->next == NULL && join
+-                     && INO_T_EQ (cur->ino, join->ino)
+-                    && cur->dev == join->dev
+-                    && cur->construct == join->construct))
++                     && DIRS_EQ (cur, join)
++                     && cur->construct == join->construct))
+               {
+                 /* Unique, so keep this directory.  */
+                 pcur = &cur->next;
+@@ -297,8 +301,8 @@ add_sysroot_to_chain (const char *sysroo
+ }
+ /* Merge the four include chains together in the order quote, bracket,
+-   system, after.  Remove duplicate dirs (as determined by
+-   INO_T_EQ()).
++   system, after.  Remove duplicate dirs (determined in
++   system-specific manner).
+    We can't just merge the lists and then uniquify them because then
+    we may lose directories from the <> search path that should be
+@@ -352,6 +356,24 @@ merge_include_chains (const char *sysroo
+       }
+       fprintf (stderr, _("End of search list.\n"));
+     }
++
++#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES
++  if (flag_poison_system_directories)
++    {
++      struct cpp_dir *p;
++
++      for (p = heads[QUOTE]; p; p = p->next)
++        {
++         if ((!strncmp (p->name, "/usr/include", 12))
++             || (!strncmp (p->name, "/usr/local/include", 18))
++             || (!strncmp (p->name, "/usr/X11R6/include", 18)))
++           warning (OPT_Wpoison_system_directories,
++                    "include location \"%s\" is unsafe for "
++                    "cross-compilation",
++                    p->name);
++        }
++    }
++#endif
+ }
+ /* Use given -I paths for #include "..." but not #include <...>, and
+--- a/gcc/c-typeck.c
++++ b/gcc/c-typeck.c
+@@ -1754,6 +1754,7 @@ default_conversion (tree exp)
+   tree orig_exp;
+   tree type = TREE_TYPE (exp);
+   enum tree_code code = TREE_CODE (type);
++  tree promoted_type;
+   /* Functions and arrays have been converted during parsing.  */
+   gcc_assert (code != FUNCTION_TYPE);
+@@ -1790,6 +1791,10 @@ default_conversion (tree exp)
+   if (exp == error_mark_node)
+     return error_mark_node;
++  promoted_type = targetm.promoted_type (type);
++  if (promoted_type)
++    return convert (promoted_type, exp);
++
+   if (INTEGRAL_TYPE_P (type))
+     return perform_integral_promotions (exp);
+@@ -4196,10 +4201,7 @@ convert_for_assignment (tree type, tree 
+       if (TREE_CODE (mvr) != ARRAY_TYPE)
+       mvr = TYPE_MAIN_VARIANT (mvr);
+       /* Opaque pointers are treated like void pointers.  */
+-      is_opaque_pointer = (targetm.vector_opaque_p (type)
+-                         || targetm.vector_opaque_p (rhstype))
+-      && TREE_CODE (ttl) == VECTOR_TYPE
+-      && TREE_CODE (ttr) == VECTOR_TYPE;
++      is_opaque_pointer = vector_targets_convertible_p (ttl, ttr);
+       /* C++ does not allow the implicit conversion void* -> T*.  However,
+        for the purpose of reducing the number of false positives, we
+--- a/gcc/c.opt
++++ b/gcc/c.opt
+@@ -697,6 +697,10 @@ fpreprocessed
+ C ObjC C++ ObjC++
+ Treat the input file as already preprocessed
++fremove-local-statics
++C Var(flag_remove_local_statics)
++Convert function-local static variables to automatic variables when it is safe to do so
++
+ freplace-objc-classes
+ ObjC ObjC++
+ Used in Fix-and-Continue mode to indicate that object files may be swapped in at runtime
+--- a/gcc/calls.c
++++ b/gcc/calls.c
+@@ -3834,7 +3834,7 @@ emit_library_call_value_1 (int retval, r
+      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);
++          ? hard_libcall_value (outmode, orgfun) : NULL_RTX);
+   /* Stack must be properly aligned now.  */
+   gcc_assert (!(stack_pointer_delta
+@@ -4133,8 +4133,17 @@ store_one_arg (struct arg_data *arg, rtx
+             /* We need to make a save area.  */
+             unsigned int size = arg->locate.size.constant * BITS_PER_UNIT;
+             enum machine_mode save_mode = mode_for_size (size, MODE_INT, 1);
+-            rtx adr = memory_address (save_mode, XEXP (arg->stack_slot, 0));
+-            rtx stack_area = gen_rtx_MEM (save_mode, adr);
++            rtx adr;
++            rtx stack_area;
++
++            /* We can only use save_mode if the arg is sufficiently
++               aligned.  */
++            if (STRICT_ALIGNMENT
++                && GET_MODE_ALIGNMENT (save_mode) > arg->locate.boundary)
++              save_mode = BLKmode;
++
++            adr = memory_address (save_mode, XEXP (arg->stack_slot, 0));
++            stack_area = gen_rtx_MEM (save_mode, adr);
+             if (save_mode == BLKmode)
+               {
+--- a/gcc/cfgexpand.c
++++ b/gcc/cfgexpand.c
+@@ -86,10 +86,6 @@ failed:
+ }
+-#ifndef LOCAL_ALIGNMENT
+-#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
+-#endif
+-
+ #ifndef STACK_ALIGNMENT_NEEDED
+ #define STACK_ALIGNMENT_NEEDED 1
+ #endif
+@@ -160,7 +156,7 @@ get_decl_align_unit (tree decl)
+   unsigned int align;
+   align = DECL_ALIGN (decl);
+-  align = LOCAL_ALIGNMENT (TREE_TYPE (decl), align);
++  align = calculate_local_alignment (TREE_TYPE (decl), align);
+   if (align > PREFERRED_STACK_BOUNDARY)
+     align = PREFERRED_STACK_BOUNDARY;
+   if (cfun->stack_alignment_needed < align)
+--- a/gcc/cgraph.c
++++ b/gcc/cgraph.c
+@@ -205,9 +205,11 @@ cgraph_node (tree decl)
+   if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
+     {
+       node->origin = cgraph_node (DECL_CONTEXT (decl));
++      node->origin->ever_was_nested = 1;
+       node->next_nested = node->origin->nested;
+       node->origin->nested = node;
+       node->master_clone = node;
++      node->ever_was_nested = 1;
+     }
+   return node;
+ }
+--- a/gcc/cgraph.h
++++ b/gcc/cgraph.h
+@@ -178,6 +178,8 @@ struct cgraph_node GTY((chain_next ("%h.
+   unsigned output : 1;
+   /* Set for aliases once they got through assemble_alias.  */
+   unsigned alias : 1;
++  /* Set if the function is a nested function or has nested functions.  */
++  unsigned ever_was_nested : 1;
+   /* In non-unit-at-a-time mode the function body of inline candidates is saved
+      into clone before compiling so the function in original form can be
+--- a/gcc/collect2.c
++++ b/gcc/collect2.c
+@@ -605,11 +605,7 @@ find_a_file (struct path_prefix *pprefix
+   /* Determine the filename to execute (special case for absolute paths).  */
+-  if (*name == '/'
+-#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+-      || (*name && name[1] == ':')
+-#endif
+-      )
++  if (IS_ABSOLUTE_PATH (name))
+     {
+       if (access (name, X_OK) == 0)
+       {
+--- a/gcc/combine.c
++++ b/gcc/combine.c
+@@ -3989,14 +3989,18 @@ find_split_point (rtx *loc, rtx insn)
+           return &XEXP (XEXP (x, 0), 0);
+       }
++#if 0
+       /* If we have a PLUS whose first operand is complex, try computing it
+-         separately by making a split there.  */
++       separately by making a split there.
++       This causes non-canonical RTL to be created, at least on ARM.
++       See CSL issue #4085.  */
+       if (GET_CODE (XEXP (x, 0)) == PLUS
+           && ! memory_address_p (GET_MODE (x), XEXP (x, 0))
+           && ! OBJECT_P (XEXP (XEXP (x, 0), 0))
+           && ! (GET_CODE (XEXP (XEXP (x, 0), 0)) == SUBREG
+                 && OBJECT_P (SUBREG_REG (XEXP (XEXP (x, 0), 0)))))
+         return &XEXP (XEXP (x, 0), 0);
++#endif
+       break;
+     case SET:
+@@ -5876,6 +5880,7 @@ simplify_set (rtx x)
+      zero_extend to avoid the reload that would otherwise be required.  */
+   if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)
++      && GET_MODE_CLASS (GET_MODE (SUBREG_REG (src))) == MODE_INT
+       && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (src))) != UNKNOWN
+       && SUBREG_BYTE (src) == 0
+       && (GET_MODE_SIZE (GET_MODE (src))
+--- a/gcc/common.opt
++++ b/gcc/common.opt
+@@ -142,6 +142,10 @@ Wpadded
+ Common Var(warn_padded) Warning
+ Warn when padding is required to align structure members
++Wpoison-system-directories
++Common Var(flag_poison_system_directories) Init(1)
++Warn for -I and -L options using system directories if cross compiling
++
+ Wshadow
+ Common Var(warn_shadow) Warning
+ Warn when one local variable shadows another
+@@ -259,6 +263,12 @@ Common Separate
+ fabi-version=
+ Common Joined UInteger Var(flag_abi_version) Init(2)
++falign-arrays
++Target Report Var(flag_align_arrays)
++Set the minimum alignment for array variables to be the largest power
++of two less than or equal to their total storage size, or the biggest
++alignment used on the machine, whichever is smaller.
++
+ falign-functions
+ Common Report Var(align_functions,0)
+ Align the start of functions
+@@ -444,6 +454,10 @@ fearly-inlining
+ Common Report Var(flag_early_inlining) Init(1) Optimization
+ Perform early inlining
++feglibc=
++Common Report Joined Undocumented
++EGLIBC configuration specifier, serves multilib purposes.
++
+ feliminate-dwarf2-dups
+ Common Report Var(flag_eliminate_dwarf2_dups)
+ Perform DWARF2 duplicate elimination
+@@ -805,6 +819,10 @@ fprofile-values
+ Common Report Var(flag_profile_values)
+ Insert code to profile values of expressions
++fpromote-loop-indices
++Common Report Var(flag_promote_loop_indices) Optimization
++Promote loop indices to word-sized indices when safe
++
+ frandom-seed
+ Common
+--- a/gcc/config.gcc
++++ b/gcc/config.gcc
+@@ -70,6 +70,10 @@
+ #                     This helps to keep OS specific stuff out of the CPU
+ #                     defining header ${cpu_type}/${cpu_type.h}.
+ #
++#                     It is possible to include automatically-generated
++#                     build-directory files by prefixing them with "./".
++#                     All other files should relative to $srcdir/config.
++#
+ #  tm_p_file          Location of file with declarations for functions
+ #                     in $out_file.
+ #
+@@ -751,32 +755,62 @@ arm*-*-linux*)                   # ARM GNU/Linux with EL
+           need_64bit_hwint=yes
+           # The EABI requires the use of __cxa_atexit.
+           default_use_cxa_atexit=yes
++          case  ${target} in
++          arm-timesys-linux-gnueabi)
++              tmake_file="${tmake_file} arm/t-timesys"
++              tm_file="$tm_file ./sysroot-suffix.h"
++              tmake_file="$tmake_file t-sysroot-suffix"
++              ;;      
++          arm-wrs-linux-gnueabi) 
++              tm_file="$tm_file arm/wrs-linux.h"
++              tmake_file="$tmake_file arm/t-wrs-linux"
++              tm_defines="$tm_defines TARGET_FLEXLM"
++              ;;
++          arm-montavista*-linux-gnueabi)
++              tm_file="$tm_file arm/montavista-linux.h"
++              tmake_file="$tmake_file arm/t-montavista-linux"
++              ;;
++          *)
++              if test x$enable_extra_asa_multilibs = xyes; then
++                      tmake_file="${tmake_file} arm/t-asa"
++              elif test x$enable_extra_sgxx_multilibs = xyes; then
++                      tmake_file="${tmake_file} arm/t-cs-linux"
++              fi
++              tm_file="$tm_file ./sysroot-suffix.h"
++              tmake_file="$tmake_file t-sysroot-suffix"
++              ;;
++          esac
+           ;;
+       *)
+           tmake_file="$tmake_file arm/t-linux"
+           ;;
+       esac
+       tm_file="$tm_file arm/aout.h arm/arm.h"
++      tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp"
+       ;;
+ arm*-*-uclinux*)              # ARM ucLinux
+-      tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/linux-gas.h arm/uclinux-elf.h arm/uclinux-elf.h"
++      tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/linux-gas.h arm/uclinux-elf.h"
+       tmake_file="arm/t-arm arm/t-arm-elf"
+       case ${target} in
+-      arm*-*-uclinux-*eabi)
++      arm*-*-uclinux*eabi)
+           tm_file="$tm_file arm/bpabi.h arm/uclinux-eabi.h"
+-          tmake_file="$tmake_file arm/t-bpabi"
++          tmake_file="$tmake_file arm/t-bpabi arm/t-uclinux-eabi"
+           # The BPABI long long divmod functions return a 128-bit value in
+           # registers r0-r3.  Correctly modeling that requires the use of
+           # TImode.
+           need_64bit_hwint=yes
+           # The EABI requires the use of __cxa_atexit.
+           default_use_cxa_atexit=yes
++          tm_file="$tm_file ./sysroot-suffix.h"
++          tmake_file="$tmake_file t-sysroot-suffix"
+       esac
++      tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp"
+       tm_file="$tm_file arm/aout.h arm/arm.h"
+       ;;
+ arm*-*-ecos-elf)
+       tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/ecos-elf.h"
+       tmake_file="arm/t-arm arm/t-arm-elf"
++      tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp"
+       ;;
+ arm*-*-eabi* | arm*-*-symbianelf* )
+       # The BPABI long long divmod functions return a 128-bit value in
+@@ -788,7 +822,11 @@ arm*-*-eabi* | arm*-*-symbianelf* )
+       tmake_file="arm/t-arm arm/t-arm-elf"
+       case ${target} in
+       arm*-*-eabi*)
++        tm_file="${tm_file} arm/nocrt0.h"
+         tmake_file="${tmake_file} arm/t-bpabi"
++        if test x$enable_extra_sgxx_multilibs = xyes; then
++                tmake_file="${tmake_file} arm/t-cs-eabi"
++        fi
+         ;;
+       arm*-*-symbianelf*)
+         tm_file="${tm_file} arm/symbian.h"
+@@ -798,14 +836,17 @@ arm*-*-eabi* | arm*-*-symbianelf* )
+         ;;
+       esac
+       tm_file="${tm_file} arm/aout.h arm/arm.h"
++      tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp"
+       ;;
+ arm*-*-rtems*)
+       tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/rtems-elf.h rtems.h"
+       tmake_file="arm/t-arm arm/t-arm-elf t-rtems arm/t-rtems"
++      tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp"
+       ;;
+ arm*-*-elf | ep9312-*-elf)
+       tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h"
+       tmake_file="arm/t-arm arm/t-arm-elf"
++      tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp"
+       ;;
+ arm*-wince-pe*)
+       tm_file="arm/semi.h arm/aout.h arm/arm.h arm/coff.h dbxcoff.h arm/pe.h arm/wince-pe.h"
+@@ -822,6 +863,7 @@ arm-*-pe*)
+ arm*-*-kaos*)
+       tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h kaos.h arm/kaos-arm.h"
+       tmake_file="arm/t-arm arm/t-arm-elf"
++      tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp"
+       ;;
+ avr-*-rtems*)
+       tm_file="avr/avr.h dbxelf.h avr/rtems.h rtems.h"
+@@ -1179,6 +1221,16 @@ i[34567]86-*-linux* | i[34567]86-*-kfree
+               else
+                       tm_file="${tm_file} i386/linux.h"
+               fi
++              case ${target} in
++              *-wrs-linux*)
++                      tm_defines="${tm_defines} TARGET_FLEXLM"
++                      ;;
++              esac
++              if test x$enable_extra_sgxx_multilibs = xyes; then
++                      tm_file="${tm_file} i386/cs-linux.h"
++                      tmake_file="${tmake_file} i386/t-cs-linux"
++                      extra_options="${extra_options} i386/cs-linux.opt"
++              fi
+               ;;
+       i[34567]86-*-knetbsd*-gnu) tm_file="${tm_file} i386/linux.h knetbsd-gnu.h i386/knetbsd-gnu.h" ;;
+       i[34567]86-*-kfreebsd*-gnu) tm_file="${tm_file} i386/linux.h kfreebsd-gnu.h i386/kfreebsd-gnu.h" ;;
+@@ -1616,9 +1668,11 @@ m68k-*-linux*)          # Motorola m68k's runnin
+                               # aka the GNU/Linux C library 6.
+       default_m68k_cpu=68020
+       default_cf_cpu=5475
+-      tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h m68k/linux.h"
++      with_arch=${with_arch:-m68k}
++      tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h m68k/linux.h ./sysroot-suffix.h"
+       extra_options="${extra_options} m68k/ieee.opt"
+       tm_defines="${tm_defines} MOTOROLA=1"
++      tmake_file="${tmake_file} m68k/t-floatlib m68k/t-linux m68k/t-mlibs"
+       # if not configured with --enable-sjlj-exceptions, bump the
+       # libgcc version number
+       if test x$sjlj != x1; then
+@@ -1646,7 +1700,7 @@ mcore-*-pe*)
+ mips-sgi-irix[56]*)
+       tm_file="elfos.h ${tm_file} mips/iris.h"
+       tmake_file="mips/t-iris mips/t-slibgcc-irix"
+-      target_cpu_default="MASK_ABICALLS"
++      tm_defines="${tm_defines} TARGET_ABICALLS_DEFAULT=1"
+       case ${target} in
+       *-*-irix5*)
+               tm_file="${tm_file} mips/iris5.h"
+@@ -1672,31 +1726,77 @@ mips-sgi-irix[56]*)
+       use_fixproto=yes
+       ;;
+ mips*-*-netbsd*)                      # NetBSD/mips, either endian.
+-      target_cpu_default="MASK_ABICALLS"
++      tm_defines="${tm_defines} TARGET_ABICALLS_DEFAULT=1"
+       tm_file="elfos.h ${tm_file} mips/elf.h netbsd.h netbsd-elf.h mips/netbsd.h"
+       ;;
+ mips64*-*-linux*)
+       tm_file="dbxelf.h elfos.h svr4.h linux.h ${tm_file} mips/linux.h mips/linux64.h"
++      tm_defines="${tm_defines} TARGET_ABICALLS_DEFAULT=1"
+       tmake_file="${tmake_file} mips/t-linux64"
+-      tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_N32"
++      if test x${enable_mips_nonpic}; then
++              tm_defines="${tm_defines} TARGET_ABICALLS_NONPIC=1"
++      fi
++      case "$with_abi" in
++              "" | "n32" )
++                      tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_N32"
++                      ;;
++              64 )
++                      tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_64"
++                      ;;
++              *)
++                      echo "Unknown ABI used in --with-abi=$with_abi"
++                      exit 1
++                      ;;
++      esac
++      case ${target} in
++              mips64el-sicortex-linux-gnu)
++                      tm_file="${tm_file} mips/sicortex.h"
++                      tmake_file="${tmake_file} mips/t-sicortex"
++                      ;;
++      esac
++      tmake_file="$tmake_file mips/t-crtfm"
+       gnu_ld=yes
+       gas=yes
+       test x$with_llsc != x || with_llsc=yes
+       ;;
+ mips*-*-linux*)                               # Linux MIPS, either endian.
+         tm_file="dbxelf.h elfos.h svr4.h linux.h ${tm_file} mips/linux.h"
++      tm_defines="${tm_defines} TARGET_ABICALLS_DEFAULT=1"
++      if test x${enable_mips_nonpic}; then
++              tm_defines="${tm_defines} TARGET_ABICALLS_NONPIC=1"
++      fi
+       case ${target} in
+         mipsisa32r2*)
+               tm_defines="${tm_defines} MIPS_ISA_DEFAULT=33"
+                 ;;
+         mipsisa32*)
+               tm_defines="${tm_defines} MIPS_ISA_DEFAULT=32"
++              ;;
++      mips-wrs-linux-gnu) 
++              tmake_file="$tmake_file mips/t-linux64 mips/t-wrs-linux"
++              tm_file="$tm_file mips/linux64.h mips/octeon.h mips/wrs-linux.h"
++              tm_defines="$tm_defines TARGET_FLEXLM"
++              ;;
++      mips-montavista*-linux-gnu)
++              tmake_file="$tmake_file mips/t-linux64 mips/t-montavista-linux"
++              tm_file="$tm_file mips/linux64.h mips/octeon.h mips/montavista-linux.h"
++              ;;
++      *)
++              if test x$enable_extra_sgxx_multilibs = xyes; then
++                  tmake_file="$tmake_file mips/t-sgxx-linux"
++                  tm_file="$tm_file mips/cs-sgxx-linux.h"
++              elif test x$enable_extra_sgxxlite_multilibs = xyes; then
++                  tmake_file="$tmake_file mips/t-sgxxlite-linux"
++                  tm_file="$tm_file mips/cs-sgxxlite-linux.h"
++              fi
++              ;;
+         esac
+       test x$with_llsc != x || with_llsc=yes
++      tmake_file="$tmake_file mips/t-crtfm"
+       ;;
+ mips*-*-openbsd*)
+       tm_defines="${tm_defines} OBSD_HAS_DECLARE_FUNCTION_NAME OBSD_HAS_DECLARE_OBJECT OBSD_HAS_CORRECT_SPECS"
+-      target_cpu_default="MASK_ABICALLS"
++      tm_defines="${tm_defines} TARGET_ABICALLS_DEFAULT=1"
+       tm_file="mips/mips.h openbsd.h mips/openbsd.h mips/sdb.h"
+       case ${target} in
+       mips*el-*-openbsd*)
+@@ -1707,15 +1807,15 @@ mips*-*-openbsd*)
+ mips*-sde-elf*)
+       tm_file="elfos.h ${tm_file} mips/elf.h mips/sde.h"
+       tmake_file="mips/t-sde mips/t-libgcc-mips16"
++      tm_file="$tm_file mips/sdemtk.h"
++      extra_options="$extra_options mips/sdemtk.opt"
+       case "${with_newlib}" in
+         yes)
+-          # newlib / libgloss.
++          # newlib
++          # FIXME: threading?
+           ;;
+         *)
+-          # MIPS toolkit libraries.
+-          tm_file="$tm_file mips/sdemtk.h"
+-          tmake_file="$tmake_file mips/t-sdemtk"
+-          extra_options="$extra_options mips/sdemtk.opt"
++          tmake_file="$tmake_file mips/t-sdelib"
+           case ${enable_threads} in
+             "" | yes | mipssde)
+               thread_file='mipssde'
+@@ -1734,6 +1834,23 @@ mips*-sde-elf*)
+           tm_defines="MIPS_ISA_DEFAULT=64 MIPS_ABI_DEFAULT=ABI_N32"
+           ;;
+       esac
++      if [ "$enable_sgxx_sde_multilibs" = "yes" ]; then
++        tmake_file="$tmake_file mips/t-sgxx-sde"
++          # SourceryG++ is configured --with-arch=mips32r2.
++        tm_defines="MIPS_ISA_DEFAULT=33 MIPS_ABI_DEFAULT=ABI_32"
++      fi
++      ;;
++mips64octeon*-wrs-elf*)
++      tm_file="elfos.h ${tm_file} mips/elf.h mips/octeon.h mips/octeon-elf.h"
++      tmake_file=mips/t-octeon-elf
++      tm_defines="MIPS_ABI_DEFAULT=ABI_EABI MIPS_CPU_STRING_DEFAULT=\\\"octeon\\\" TARGET_FLEXLM"
++      default_use_cxa_atexit=no
++      ;;
++mips64octeon*-montavista-elf*)
++      tm_file="elfos.h ${tm_file} mips/elf.h mips/octeon.h mips/octeon-elf.h"
++      tmake_file="mips/t-octeon-elf mips/t-montavista-elf"
++      tm_defines="MIPS_ABI_DEFAULT=ABI_EABI MIPS_CPU_STRING_DEFAULT=\\\"octeon\\\""
++      default_use_cxa_atexit=no
+       ;;
+ mipsisa32-*-elf* | mipsisa32el-*-elf* | \
+ mipsisa32r2-*-elf* | mipsisa32r2el-*-elf* | \
+@@ -1767,10 +1884,11 @@ mipsisa64-*-elf* | mipsisa64el-*-elf*)
+       ;;
+ mipsisa64sr71k-*-elf*)
+         tm_file="elfos.h ${tm_file} mips/elf.h"
+-        tmake_file=mips/t-sr71k
++        tmake_file="mips/t-sr71k"
+       target_cpu_default="MASK_64BIT|MASK_FLOAT64"
+       tm_defines="${tm_defines} MIPS_ISA_DEFAULT=64 MIPS_CPU_STRING_DEFAULT=\\\"sr71000\\\" MIPS_ABI_DEFAULT=ABI_EABI"
+       use_fixproto=yes
++      tmake_file="$tmake_file"
+         ;;
+ mipsisa64sb1-*-elf* | mipsisa64sb1el-*-elf*)
+       tm_file="elfos.h ${tm_file} mips/elf.h"
+@@ -1793,7 +1911,7 @@ mips64-*-elf* | mips64el-*-elf*)
+       ;;
+ mips64vr-*-elf* | mips64vrel-*-elf*)
+         tm_file="mips/vr.h elfos.h ${tm_file} mips/elf.h"
+-        tmake_file=mips/t-vr
++        tmake_file="mips/t-vr"
+       use_fixproto=yes
+         ;;
+ mips64orion-*-elf* | mips64orionel-*-elf*)
+@@ -1926,15 +2044,18 @@ powerpc-*-eabisimaltivec*)
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcendian rs6000/t-ppccomm"
+       ;;
+ powerpc-*-eabisim*)
+-      tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/eabisim.h"
++      tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/eabisim.h"
+       extra_options="${extra_options} rs6000/sysv4.opt"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
+       ;;
+ powerpc-*-elf*)
+-      tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h"
++      tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h"
+       extra_options="${extra_options} rs6000/sysv4.opt"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
+-      use_fixproto=yes
++        if test x$enable_powerpc_e500mc_elf = xyes; then
++        tm_file="${tm_file} rs6000/e500mc.h"
++        tmake_file="${tmake_file} rs6000/t-ppc-e500mc"
++      fi
+       ;;
+ powerpc-*-eabialtivec*)
+       tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/eabialtivec.h"
+@@ -1942,9 +2063,12 @@ powerpc-*-eabialtivec*)
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcendian rs6000/t-ppccomm"
+       ;;
+ powerpc-*-eabi*)
+-      tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h"
++      tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h"
+       extra_options="${extra_options} rs6000/sysv4.opt"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
++      if test x$enable_extra_sgxx_multilibs = xyes; then
++        tmake_file="${tmake_file} rs6000/t-cs-eabi"
++      fi
+       ;;
+ powerpc-*-rtems*)
+       tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/rtems.h rtems.h"
+@@ -1959,7 +2083,7 @@ powerpc-*-linux*altivec*)
+ powerpc-*-linux*spe*)
+       tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxspe.h rs6000/e500.h"
+       extra_options="${extra_options} rs6000/sysv4.opt"
+-      tmake_file="rs6000/t-fprules rs6000/t-fprules-softfp soft-fp/t-softfp rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
++      tmake_file="t-dfprules rs6000/t-fprules rs6000/t-fprules-softfp soft-fp/t-softfp rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
+       ;;
+ powerpc-*-linux*paired*)
+         tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h rs6000/750cl.h"
+@@ -1980,12 +2104,28 @@ powerpc-*-linux*)
+               extra_options="${extra_options} rs6000/linux64.opt"
+               ;;
+           *)
+-              tm_file="${tm_file} rs6000/linux.h"
++              tm_file="${tm_file} rs6000/linux.h rs6000/e500.h"
++              tmake_file="$tmake_file rs6000/t-linux"
+               ;;
+       esac
+       if test x${enable_secureplt} = xyes; then
+               tm_file="rs6000/secureplt.h ${tm_file}"
+       fi
++      case ${target} in
++      powerpc-wrs-linux-gnu)
++              tm_file="$tm_file rs6000/wrs-linux.h rs6000/e500.h"
++              tmake_file="$tmake_file rs6000/t-wrs-linux"
++              tm_defines="$tm_defines TARGET_FLEXLM"
++              ;;
++      powerpc-montavista*-linux-gnu)
++              tm_file="$tm_file rs6000/montavista-linux.h"
++              tmake_file="$tmake_file rs6000/t-montavista-linux"
++              ;;
++      powerpc-timesys-linux-gnu*)
++              tmake_file="${tmake_file} rs6000/t-timesys"
++              tm_file="${tm_file} rs6000/timesys-linux.h"
++              ;;      
++      esac
+       ;;
+ powerpc-*-gnu-gnualtivec*)
+       tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxaltivec.h rs6000/gnu.h"
+@@ -2019,7 +2159,7 @@ powerpc-wrs-vxworks|powerpc-wrs-vxworksa
+       esac
+       ;;
+ powerpc-wrs-windiss*)  # Instruction-level simulator for VxWorks.
+-      tm_file="${tm_file} elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/windiss.h"
++      tm_file="${tm_file} elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/windiss.h"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
+       extra_options="${extra_options} rs6000/sysv4.opt"
+       thread_file=""
+@@ -2043,28 +2183,28 @@ powerpcle-*-sysv*)
+       use_fixproto=yes
+       ;;
+ powerpcle-*-elf*)
+-      tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h"
++      tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
+       extra_options="${extra_options} rs6000/sysv4.opt"
+       use_fixproto=yes
+       ;;
+ powerpcle-*-eabisim*)
+-      tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/e500.h rs6000/eabisim.h"
++      tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/e500.h rs6000/eabisim.h"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
+       extra_options="${extra_options} rs6000/sysv4.opt"
+       ;;
+ powerpcle-*-eabi*)
+-      tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/e500.h"
++      tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/e500.h"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
+       extra_options="${extra_options} rs6000/sysv4.opt"
+       ;;
+ powerpc-*-kaos*)
+-      tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h kaos.h rs6000/kaos-ppc.h"
++      tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h kaos.h rs6000/kaos-ppc.h"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
+       extra_options="${extra_options} rs6000/sysv4.opt"
+       ;;
+ powerpcle-*-kaos*)
+-      tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h kaos.h rs6000/kaos-ppc.h"
++      tm_file="${tm_file} dbxelf.h elfos.h usegas.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h kaos.h rs6000/kaos-ppc.h"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
+       extra_options="${extra_options} rs6000/sysv4.opt"
+       ;;
+@@ -2162,8 +2302,10 @@ sh-*-symbianelf* | sh[12346l]*-*-symbian
+               esac
+       fi
+       case ${with_endian} in
+-      big|little)     tmake_file="${tmake_file} sh/t-1e" ;;
+-      big,little|little,big) ;;
++      big)            TM_ENDIAN_CONFIG=mb ;;
++      little)         TM_ENDIAN_CONFIG=ml ;;
++      big,little)     TM_ENDIAN_CONFIG="mb ml" ;;
++      little,big)     TM_ENDIAN_CONFIG="ml mb" ;;
+       *)      echo "with_endian=${with_endian} not supported."; exit 1 ;;
+       esac
+       case ${with_endian} in
+@@ -2288,29 +2430,40 @@ sh-*-symbianelf* | sh[12346l]*-*-symbian
+       fi
+       target_cpu_default=SELECT_`echo ${sh_cpu_default}|tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`
+       tm_defines=${tm_defines}' SH_MULTILIB_CPU_DEFAULT=\"'`echo $sh_cpu_default|sed s/sh/m/`'\"'
+-      sh_multilibs=`echo $sh_multilibs,$sh_cpu_default | sed -e 's/[  ,/][    ,]*/ /g' -e 's/ $//' -e 's/^m/sh/' -e 's/ m/ sh/g' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ_ abcdefghijklmnopqrstuvwxyz-`
++      tm_defines="$tm_defines SUPPORT_`echo $sh_cpu_default | sed 's/^m/sh/' | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`=1"
++      sh_multilibs=`echo $sh_multilibs | sed -e 's/,/ /g' -e 's/^sh/m/i' -e 's/ sh/ m/gi' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ_ abcdefghijklmnopqrstuvwxyz-`
+       for sh_multilib in ${sh_multilibs}; do
+               case ${sh_multilib} in
+-              sh1 | sh2 | sh2e | sh3 | sh3e | \
+-              sh4 | sh4-single | sh4-single-only | sh4-nofpu | sh4-300 |\
+-              sh4a | sh4a-single | sh4a-single-only | sh4a-nofpu | sh4al | \
+-              sh2a | sh2a-single | sh2a-single-only | sh2a-nofpu | \
+-              sh5-64media | sh5-64media-nofpu | \
+-              sh5-32media | sh5-32media-nofpu | \
+-              sh5-compact | sh5-compact-nofpu)
+-                      tmake_file="${tmake_file} sh/t-mlib-${sh_multilib}"
+-                      tm_defines="$tm_defines SUPPORT_`echo $sh_multilib|tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`=1"
++              m1 | m2 | m2e | m3 | m3e | \
++              m4 | m4-single | m4-single-only | m4-nofpu | m4-300 |\
++              m4a | m4a-single | m4a-single-only | m4a-nofpu | m4al | \
++              m2a | m2a-single | m2a-single-only | m2a-nofpu | \
++              m5-64media | m5-64media-nofpu | \
++              m5-32media | m5-32media-nofpu | \
++              m5-compact | m5-compact-nofpu)
++                      TM_MULTILIB_CONFIG="${TM_MULTILIB_CONFIG}/${sh_multilib}"
++                      tm_defines="$tm_defines SUPPORT_`echo $sh_multilib | sed 's/^m/sh/' | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`=1"
+                       ;;
++              !*)     TM_MULTILIB_EXCEPTIONS_CONFIG="${TM_MULTILIB_EXCEPTIONS_CONFIG} ${sh_multilib#!}" ;;
++              none)   ;;
+               *)
+                       echo "with_multilib_list=${sh_multilib} not supported."
+                       exit 1
+                       ;;
+               esac
+       done
++      TM_MULTILIB_CONFIG=${TM_MULTILIB_CONFIG#/}
+       if test x${enable_incomplete_targets} = xyes ; then
+               tm_defines="$tm_defines SUPPORT_SH1=1 SUPPORT_SH2E=1 SUPPORT_SH4=1 SUPPORT_SH4_SINGLE=1 SUPPORT_SH2A=1 SUPPORT_SH2A_SINGLE=1 SUPPORT_SH5_32MEDIA=1 SUPPORT_SH5_32MEDIA_NOFPU=1 SUPPORT_SH5_64MEDIA=1 SUPPORT_SH5_64MEDIA_NOFPU=1"
+       fi
+-      use_fixproto=yes
++      if test x$enable_extra_sgxxlite_multilibs = xyes \
++         || test x$enable_extra_sgxx_multilibs = xyes; then
++              # SG++ and Lite do not differ, as yet, so use the Lite files for both
++              tm_file="$tm_file sh/cs-sgxxlite-linux.h"
++              tmake_file="$tmake_file sh/t-sgxxlite-linux"
++      fi
++      tm_file="$tm_file ./sysroot-suffix.h"
++      tmake_file="$tmake_file t-sysroot-suffix"
+       ;;
+ sh-*-rtems*)
+       tmake_file="sh/t-sh sh/t-elf t-rtems sh/t-rtems"
+@@ -2340,6 +2493,13 @@ sparc-*-elf*)
+       extra_parts="crti.o crtn.o crtbegin.o crtend.o"
+       use_fixproto=yes
+       ;;
++sparc-wrs-linux*)
++      tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux64.h"
++      extra_options="${extra_options} sparc/long-double-switch.opt"
++      tmake_file="${tmake_file} sparc/t-linux sparc/t-linux64 sparc/t-crtfm"
++      tm_defines="${tm_defines} BIARCH_32BIT_DEFAULT TARGET_FLEXLM"
++      need_64bit_hwint=yes
++      ;;
+ sparc-*-linux*)               # SPARC's running GNU/Linux, libc6
+       tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux.h"
+       extra_options="${extra_options} sparc/long-double-switch.opt"
+@@ -2882,7 +3042,8 @@ case "${target}" in
+               "" \
+               | armv[23456] | armv2a | armv3m | armv4t | armv5t \
+               | armv5te | armv6j |armv6k | armv6z | armv6zk \
+-              | iwmmxt | ep9312)
++              | armv6-m | armv7-a | armv7-r | armv7-m \
++              | iwmmxt | ep9312 | marvell-f )
+                       # OK
+                       ;;
+               *)
+@@ -3017,8 +3178,8 @@ case "${target}" in
+               ;;
+       i[34567]86-*-* | x86_64-*-*)
+-              supported_defaults="arch cpu tune"
+-              for which in arch cpu tune; do
++              supported_defaults="arch arch32 arch64 cpu tune"
++              for which in arch arch32 arch64 cpu tune; do
+                       eval "val=\$with_$which"
+                       case ${val} in
+                       i386 | i486 \
+@@ -3029,8 +3190,10 @@ case "${target}" in
+                       | prescott | pentium-m | pentium4m | pentium3m)
+                               case "${target}" in
+                                 x86_64-*-*)
+-                                    echo "CPU given in --with-$which=$val doesn't support 64bit mode." 1>&2
+-                                    exit 1
++                                    if [ "x$which" != "xarch32" ]; then
++                                            echo "CPU given in --with-$which=$val doesn't support 64bit mode." 1>&2
++                                            exit 1
++                                    fi
+                                     ;;
+                               esac
+                               # OK
+@@ -3047,7 +3210,7 @@ case "${target}" in
+               ;;
+       mips*-*-*)
+-              supported_defaults="abi arch float tune divide llsc"
++              supported_defaults="abi arch arch32 arch64 float tune tune32 tune64 divide llsc"
+               case ${with_float} in
+               "" | soft | hard)
+@@ -3079,6 +3242,21 @@ case "${target}" in
+                       ;;
+               esac
++              for fix in ice9a; do
++                      supported_defaults="$supported_defaults fix-$fix"
++                      eval "val=\$with_fix_$fix"
++                      case $val in
++                      "" | off)
++                              eval "\$with_fix_$fix="
++                              ;;
++                      on)
++                              ;;
++                      *)
++                              echo "Unknown argument to --with-fix-$fix: $val"
++                              ;;
++                      esac
++              done
++
+               case ${with_llsc} in
+               yes)
+                       with_llsc=llsc
+@@ -3116,9 +3294,9 @@ case "${target}" in
+               ;;
+       powerpc*-*-* | rs6000-*-*)
+-              supported_defaults="cpu float tune"
++              supported_defaults="cpu cpu32 cpu64 float tune"
+-              for which in cpu tune; do
++              for which in cpu cpu32 cpu64 tune; do
+                       eval "val=\$with_$which"
+                       case ${val} in
+                       default32 | default64)
+@@ -3134,8 +3312,8 @@ case "${target}" in
+                       | rios | rios1 | rios2 | rsc | rsc1 | rs64a \
+                       | 401 | 403 | 405 | 405fp | 440 | 440fp | 505 \
+                       | 601 | 602 | 603 | 603e | ec603e | 604 \
+-                      | 604e | 620 | 630 | 740 | 750 | 7400 | 7450 \
+-                      | 854[08] | 801 | 821 | 823 | 860 | 970 | G3 | G4 | G5 | cell)
++                      | 604e | 620 | 630 | 740 | 750 | 7400 | 7450 |e300c[23] \
++                      | 854[08] | e500mc | 801 | 821 | 823 | 860 | 970 | G3 | G4 | G5 | cell)
+                               # OK
+                               ;;
+                       *)
+@@ -3356,11 +3534,28 @@ case ${target} in
+               ;;
+ esac
++case ${target} in
++    *-eglibc-*-*)
++      tmake_file="${tmake_file} t-eglibc"
++
++      case ${target} in
++          arm-*)
++           # ARM already includes below.
++              ;;
++          *)
++              tmake_file="${tmake_file} t-sysroot-suffix"
++              tm_file="${tm_file} ./sysroot-suffix.h"
++              ;;
++      esac
++      ;;
++esac
++
+ t=
+-all_defaults="abi cpu arch tune schedule float mode fpu divide llsc"
++all_defaults="abi cpu cpu32 cpu64 arch arch32 arch64 tune tune32 tune64 schedule float mode fpu divide fix-ice9a llsc"
+ for option in $all_defaults
+ do
+-      eval "val=\$with_$option"
++      underscoreoption=`echo $option | sed -e s/-/_/g`
++      eval "val=\$with_$underscoreoption"
+       if test -n "$val"; then
+               case " $supported_defaults " in
+               *" $option "*)
+--- a/gcc/config.in
++++ b/gcc/config.in
+@@ -100,6 +100,12 @@
+ #endif
++/* Define to warn for use of native system header directories */
++#ifndef USED_FOR_TARGET
++#undef ENABLE_POISON_SYSTEM_DIRECTORIES
++#endif
++
++
+ /* Define if you want all operations on RTL (the basic data structure of the
+    optimizer and back end) to be checked for dynamic type safety at runtime.
+    This is quite expensive. */
+@@ -1369,37 +1375,37 @@
+ #endif
+-/* The size of `int', as computed by sizeof. */
++/* The size of a `int', as computed by sizeof. */
+ #ifndef USED_FOR_TARGET
+ #undef SIZEOF_INT
+ #endif
+-/* The size of `long', as computed by sizeof. */
++/* The size of a `long', as computed by sizeof. */
+ #ifndef USED_FOR_TARGET
+ #undef SIZEOF_LONG
+ #endif
+-/* The size of `long long', as computed by sizeof. */
++/* The size of a `long long', as computed by sizeof. */
+ #ifndef USED_FOR_TARGET
+ #undef SIZEOF_LONG_LONG
+ #endif
+-/* The size of `short', as computed by sizeof. */
++/* The size of a `short', as computed by sizeof. */
+ #ifndef USED_FOR_TARGET
+ #undef SIZEOF_SHORT
+ #endif
+-/* The size of `void *', as computed by sizeof. */
++/* The size of a `void *', as computed by sizeof. */
+ #ifndef USED_FOR_TARGET
+ #undef SIZEOF_VOID_P
+ #endif
+-/* The size of `__int64', as computed by sizeof. */
++/* The size of a `__int64', as computed by sizeof. */
+ #ifndef USED_FOR_TARGET
+ #undef SIZEOF___INT64
+ #endif
+--- a/gcc/config/arm/aout.h
++++ b/gcc/config/arm/aout.h
+@@ -191,9 +191,6 @@
+ }
+ #endif
+-/* Arm Assembler barfs on dollars.  */
+-#define DOLLARS_IN_IDENTIFIERS 0
+-
+ #ifndef NO_DOLLAR_IN_LABEL
+ #define NO_DOLLAR_IN_LABEL 1
+ #endif
+--- a/gcc/config/arm/arm-cores.def
++++ b/gcc/config/arm/arm-cores.def
+@@ -102,6 +102,8 @@ ARM_CORE("arm1020e",      arm1020e,        5TE,
+ ARM_CORE("arm1022e",      arm1022e,   5TE,                             FL_LDSCHED, fastmul)
+ ARM_CORE("xscale",        xscale,     5TE,                             FL_LDSCHED | FL_STRONG | FL_XSCALE, xscale)
+ ARM_CORE("iwmmxt",        iwmmxt,     5TE,                             FL_LDSCHED | FL_STRONG | FL_XSCALE | FL_IWMMXT, xscale)
++ARM_CORE("iwmmxt2",       iwmmxt2,    5TE,                             FL_LDSCHED | FL_STRONG | FL_XSCALE | FL_IWMMXT, xscale)
++ARM_CORE("marvell-f",   marvell_f,    5TE,                             FL_LDSCHED | FL_MARVELL_F | FL_VFPV2, 9e)
+ /* V5TEJ Architecture Processors */
+ ARM_CORE("arm926ej-s",    arm926ejs,  5TEJ,                            FL_LDSCHED, 9e)
+@@ -115,6 +117,12 @@ ARM_CORE("arm1176jzf-s",  arm1176jzfs,    6
+ ARM_CORE("mpcorenovfp",         mpcorenovfp,  6K,                              FL_LDSCHED, 9e)
+ ARM_CORE("mpcore",      mpcore,       6K,                              FL_LDSCHED | FL_VFPV2, 9e)
+ ARM_CORE("arm1156t2-s",         arm1156t2s,   6T2,                             FL_LDSCHED, 9e)
++
++/* V7 Architecture Processors */
+ ARM_CORE("cortex-a8",   cortexa8,     7A,                              FL_LDSCHED, 9e)
++ARM_CORE("cortex-a9",   cortexa9,     7A,                              FL_LDSCHED, 9e)
+ ARM_CORE("cortex-r4",   cortexr4,     7R,                              FL_LDSCHED, 9e)
++ARM_CORE("cortex-r4f",          cortexr4f,    7R,                              FL_LDSCHED, 9e)
+ ARM_CORE("cortex-m3",   cortexm3,     7M,                              FL_LDSCHED, 9e)
++ARM_CORE("cortex-m1",   cortexm1,     6M,                              FL_LDSCHED, 9e)
++ARM_CORE("cortex-m0",   cortexm0,     6M,                              FL_LDSCHED, 9e)
+--- a/gcc/config/arm/arm-modes.def
++++ b/gcc/config/arm/arm-modes.def
+@@ -25,6 +25,11 @@
+    FIXME What format is this?  */
+ FLOAT_MODE (XF, 12, 0);
++/* Half-precision floating point */
++FLOAT_MODE (HF, 2, 0);
++ADJUST_FLOAT_FORMAT (HF, ((arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
++                        ? &arm_half_format : &ieee_half_format));
++
+ /* CCFPEmode should be used with floating inequalities,
+    CCFPmode should be used with floating equalities.
+    CC_NOOVmode should be used with SImode integer equalities.
+@@ -62,6 +67,4 @@ VECTOR_MODES (FLOAT, 16);     /*       V
+ INT_MODE (EI, 24);
+ INT_MODE (OI, 32);
+ INT_MODE (CI, 48);
+-/* ??? This should actually have 512 bits but the precision only has 9
+-   bits.  */
+-FRACTIONAL_INT_MODE (XI, 511, 64);
++INT_MODE (XI, 64);
+--- a/gcc/config/arm/arm-protos.h
++++ b/gcc/config/arm/arm-protos.h
+@@ -24,6 +24,7 @@
+ #define GCC_ARM_PROTOS_H
+ extern void arm_override_options (void);
++extern void arm_optimization_options (int, int);
+ extern int use_return_insn (int, rtx);
+ extern int arm_regno_class (int);
+ extern void arm_load_pic_register (unsigned long);
+@@ -42,9 +43,6 @@ extern unsigned int arm_dbx_register_num
+ extern void arm_output_fn_unwind (FILE *, bool);
+   
+-#ifdef TREE_CODE
+-extern int arm_return_in_memory (const_tree);
+-#endif
+ #ifdef RTX_CODE
+ extern bool arm_vector_mode_supported_p (enum machine_mode);
+ extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
+@@ -90,7 +88,7 @@ extern bool arm_cannot_force_const_mem (
+ extern int cirrus_memory_offset (rtx);
+ extern int arm_coproc_mem_operand (rtx, bool);
+-extern int neon_vector_mem_operand (rtx, bool);
++extern int neon_vector_mem_operand (rtx, int);
+ extern int neon_struct_mem_operand (rtx);
+ extern int arm_no_early_store_addr_dep (rtx, rtx);
+ extern int arm_no_early_alu_shift_dep (rtx, rtx);
+@@ -125,6 +123,7 @@ extern const char *fp_immediate_constant
+ extern void arm_emit_call_insn (rtx, rtx);
+ extern const char *output_call (rtx *);
+ extern const char *output_call_mem (rtx *);
++void arm_emit_movpair (rtx, rtx);
+ extern const char *output_mov_long_double_fpa_from_arm (rtx *);
+ extern const char *output_mov_long_double_arm_from_fpa (rtx *);
+ extern const char *output_mov_long_double_arm_from_arm (rtx *);
+@@ -145,6 +144,7 @@ extern void arm_final_prescan_insn (rtx)
+ extern int arm_debugger_arg_offset (int, rtx);
+ extern bool arm_is_long_call_p (tree);
+ extern int    arm_emit_vector_const (FILE *, rtx);
++extern void arm_emit_fp16_const (rtx c);
+ extern const char * arm_output_load_gr (rtx *);
+ extern const char *vfp_output_fstmd (rtx *);
+ extern void arm_set_return_address (rtx, rtx);
+@@ -155,13 +155,15 @@ extern bool arm_output_addr_const_extra 
+ #if defined TREE_CODE
+ extern rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
++extern void arm_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
++                                    tree, bool);
+ extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
+ extern bool arm_pad_arg_upward (enum machine_mode, const_tree);
+ extern bool arm_pad_reg_upward (enum machine_mode, tree, int);
+ extern bool arm_needs_doubleword_align (enum machine_mode, tree);
+-extern rtx arm_function_value(const_tree, const_tree);
+ #endif
+ extern int arm_apply_result_size (void);
++extern rtx aapcs_libcall_value (enum machine_mode);
+ #endif /* RTX_CODE */
+@@ -208,6 +210,7 @@ extern void arm_pr_no_long_calls (struct
+ extern void arm_pr_long_calls_off (struct cpp_reader *);
+ extern void arm_lang_object_attributes_init(void);
++extern void arm_adjust_reg_alloc_order (int *);
+ extern const char *arm_mangle_type (const_tree);
+--- a/gcc/config/arm/arm-tune.md
++++ b/gcc/config/arm/arm-tune.md
+@@ -1,5 +1,5 @@
+ ;; -*- buffer-read-only: t -*-
+ ;; Generated automatically by gentune.sh from arm-cores.def
+ (define_attr "tune"
+-      "arm2,arm250,arm3,arm6,arm60,arm600,arm610,arm620,arm7,arm7d,arm7di,arm70,arm700,arm700i,arm710,arm720,arm710c,arm7100,arm7500,arm7500fe,arm7m,arm7dm,arm7dmi,arm8,arm810,strongarm,strongarm110,strongarm1100,strongarm1110,arm7tdmi,arm7tdmis,arm710t,arm720t,arm740t,arm9,arm9tdmi,arm920,arm920t,arm922t,arm940t,ep9312,arm10tdmi,arm1020t,arm9e,arm946es,arm966es,arm968es,arm10e,arm1020e,arm1022e,xscale,iwmmxt,arm926ejs,arm1026ejs,arm1136js,arm1136jfs,arm1176jzs,arm1176jzfs,mpcorenovfp,mpcore,arm1156t2s,cortexa8,cortexr4,cortexm3"
++      "arm2,arm250,arm3,arm6,arm60,arm600,arm610,arm620,arm7,arm7d,arm7di,arm70,arm700,arm700i,arm710,arm720,arm710c,arm7100,arm7500,arm7500fe,arm7m,arm7dm,arm7dmi,arm8,arm810,strongarm,strongarm110,strongarm1100,strongarm1110,arm7tdmi,arm7tdmis,arm710t,arm720t,arm740t,arm9,arm9tdmi,arm920,arm920t,arm922t,arm940t,ep9312,arm10tdmi,arm1020t,arm9e,arm946es,arm966es,arm968es,arm10e,arm1020e,arm1022e,xscale,iwmmxt,iwmmxt2,marvell_f,arm926ejs,arm1026ejs,arm1136js,arm1136jfs,arm1176jzs,arm1176jzfs,mpcorenovfp,mpcore,arm1156t2s,cortexa8,cortexa9,cortexr4,cortexr4f,cortexm3,cortexm1,cortexm0"
+       (const (symbol_ref "arm_tune")))
+--- a/gcc/config/arm/arm.c
++++ b/gcc/config/arm/arm.c
+@@ -1,6 +1,6 @@
+ /* Output routines for GCC for ARM.
+    Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+-   2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
++   2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+    Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
+    and Martin Simmons (@harleqn.co.uk).
+    More major hacks by Richard Earnshaw (rearnsha@arm.com).
+@@ -42,6 +42,7 @@
+ #include "optabs.h"
+ #include "toplev.h"
+ #include "recog.h"
++#include "cgraph.h"
+ #include "ggc.h"
+ #include "except.h"
+ #include "c-pragma.h"
+@@ -52,6 +53,7 @@
+ #include "debug.h"
+ #include "langhooks.h"
+ #include "df.h"
++#include "intl.h"
+ /* Forward definitions of types.  */
+ typedef struct minipool_node    Mnode;
+@@ -62,6 +64,7 @@ const struct attribute_spec arm_attribut
+ void (*arm_lang_output_object_attributes_hook)(void);
+ /* Forward function declarations.  */
++static int arm_compute_static_chain_stack_bytes (void);
+ static arm_stack_offsets *arm_get_frame_offsets (void);
+ static void arm_add_gc_roots (void);
+ static int arm_gen_constant (enum rtx_code, enum machine_mode, rtx,
+@@ -74,7 +77,6 @@ static int thumb1_base_register_rtx_p (r
+ inline static int thumb1_index_register_rtx_p (rtx, int);
+ static int thumb_far_jump_used_p (void);
+ static bool thumb_force_lr_save (void);
+-static unsigned long thumb1_compute_save_reg_mask (void);
+ static int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
+ static rtx emit_sfm (int, int);
+ static unsigned arm_size_return_regs (void);
+@@ -109,6 +111,7 @@ static unsigned long arm_compute_save_re
+ static unsigned long arm_isr_value (tree);
+ static unsigned long arm_compute_func_type (void);
+ static tree arm_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
++static tree arm_handle_pcs_attribute (tree *, tree, tree, int, bool *);
+ static tree arm_handle_isr_attribute (tree *, tree, tree, int, bool *);
+ #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
+ static tree arm_handle_notshared_attribute (tree *, tree, tree, int, bool *);
+@@ -122,15 +125,20 @@ static int arm_adjust_cost (rtx, rtx, rt
+ static int count_insns_for_constant (HOST_WIDE_INT, int);
+ static int arm_get_strip_length (int);
+ static bool arm_function_ok_for_sibcall (tree, tree);
++static bool arm_return_in_memory (const_tree, const_tree);
++static rtx arm_function_value (const_tree, const_tree, bool);
++static rtx arm_libcall_value (enum machine_mode, rtx);
++
+ static void arm_internal_label (FILE *, const char *, unsigned long);
+ static void arm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
+                                tree);
+-static int arm_rtx_costs_1 (rtx, enum rtx_code, enum rtx_code);
++static bool arm_rtx_costs_1 (rtx, enum rtx_code, int*);
+ static bool arm_size_rtx_costs (rtx, int, int, int *);
+-static bool arm_slowmul_rtx_costs (rtx, int, int, int *);
+-static bool arm_fastmul_rtx_costs (rtx, int, int, int *);
+-static bool arm_xscale_rtx_costs (rtx, int, int, int *);
+-static bool arm_9e_rtx_costs (rtx, int, int, int *);
++static bool arm_slowmul_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *);
++static bool arm_fastmul_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *);
++static bool arm_xscale_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *);
++static bool arm_9e_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *);
++static bool arm_rtx_costs (rtx, int, int, int *);
+ static int arm_address_cost (rtx);
+ static bool arm_memory_load_p (rtx);
+ static bool arm_cirrus_insn_p (rtx);
+@@ -146,6 +154,9 @@ static void emit_constant_insn (rtx cond
+ static rtx emit_set_insn (rtx, rtx);
+ static int arm_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
+                                 tree, bool);
++static rtx aapcs_allocate_return_reg (enum machine_mode, const_tree,
++                                    const_tree);
++static int aapcs_select_return_coproc (const_tree, const_tree);
+ #ifdef OBJECT_FORMAT_ELF
+ static void arm_elf_asm_constructor (rtx, int) ATTRIBUTE_UNUSED;
+@@ -167,11 +178,13 @@ static bool arm_default_short_enums (voi
+ static bool arm_align_anon_bitfield (void);
+ static bool arm_return_in_msb (const_tree);
+ static bool arm_must_pass_in_stack (enum machine_mode, const_tree);
++static bool arm_return_in_memory (const_tree, const_tree);
+ #ifdef TARGET_UNWIND_INFO
+ static void arm_unwind_emit (FILE *, rtx);
+ static bool arm_output_ttype (rtx);
+ #endif
+ static void arm_dwarf_handle_frame_unspec (const char *, rtx, int);
++static rtx arm_dwarf_register_span(rtx);
+ static tree arm_cxx_guard_type (void);
+ static bool arm_cxx_guard_mask_bit (void);
+@@ -183,12 +196,22 @@ static void arm_cxx_determine_class_data
+ static bool arm_cxx_class_data_always_comdat (void);
+ static bool arm_cxx_use_aeabi_atexit (void);
+ static void arm_init_libfuncs (void);
++static tree arm_build_builtin_va_list (void);
++static void arm_expand_builtin_va_start (tree, rtx);
++static tree arm_gimplify_va_arg_expr (tree, tree, tree *, tree *);
+ static bool arm_handle_option (size_t, const char *, int);
+ static void arm_target_help (void);
+ static unsigned HOST_WIDE_INT arm_shift_truncation_mask (enum machine_mode);
+ static bool arm_cannot_copy_insn_p (rtx);
+ static bool arm_tls_symbol_p (rtx x);
+ static void arm_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
++static bool arm_allocate_stack_slots_for_args (void);
++static int arm_issue_rate (void);
++static int arm_multipass_dfa_lookahead (void);
++static const char *arm_invalid_parameter_type (const_tree t);
++static const char *arm_invalid_return_type (const_tree t);
++static tree arm_promoted_type (const_tree t);
++static tree arm_convert_to_type (tree type, tree expr);
\f
+ /* Initialize the GCC target structure.  */
+@@ -248,14 +271,19 @@ static void arm_output_dwarf_dtprel (FIL
+ #undef  TARGET_FUNCTION_OK_FOR_SIBCALL
+ #define TARGET_FUNCTION_OK_FOR_SIBCALL arm_function_ok_for_sibcall
++#undef  TARGET_FUNCTION_VALUE
++#define TARGET_FUNCTION_VALUE arm_function_value
++
++#undef  TARGET_LIBCALL_VALUE
++#define TARGET_LIBCALL_VALUE arm_libcall_value
++
+ #undef  TARGET_ASM_OUTPUT_MI_THUNK
+ #define TARGET_ASM_OUTPUT_MI_THUNK arm_output_mi_thunk
+ #undef  TARGET_ASM_CAN_OUTPUT_MI_THUNK
+ #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+-/* This will be overridden in arm_override_options.  */
+ #undef  TARGET_RTX_COSTS
+-#define TARGET_RTX_COSTS arm_slowmul_rtx_costs
++#define TARGET_RTX_COSTS arm_rtx_costs
+ #undef  TARGET_ADDRESS_COST
+ #define TARGET_ADDRESS_COST arm_address_cost
+@@ -289,6 +317,9 @@ static void arm_output_dwarf_dtprel (FIL
+ #undef  TARGET_SETUP_INCOMING_VARARGS
+ #define TARGET_SETUP_INCOMING_VARARGS arm_setup_incoming_varargs
++#undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
++#define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arm_allocate_stack_slots_for_args
++
+ #undef TARGET_DEFAULT_SHORT_ENUMS
+ #define TARGET_DEFAULT_SHORT_ENUMS arm_default_short_enums
+@@ -329,6 +360,9 @@ static void arm_output_dwarf_dtprel (FIL
+ #undef TARGET_RETURN_IN_MSB
+ #define TARGET_RETURN_IN_MSB arm_return_in_msb
++#undef TARGET_RETURN_IN_MEMORY
++#define TARGET_RETURN_IN_MEMORY arm_return_in_memory
++
+ #undef TARGET_MUST_PASS_IN_STACK
+ #define TARGET_MUST_PASS_IN_STACK arm_must_pass_in_stack
+@@ -347,6 +381,9 @@ static void arm_output_dwarf_dtprel (FIL
+ #undef TARGET_DWARF_HANDLE_FRAME_UNSPEC
+ #define TARGET_DWARF_HANDLE_FRAME_UNSPEC arm_dwarf_handle_frame_unspec
++#undef TARGET_DWARF_REGISTER_SPAN
++#define TARGET_DWARF_REGISTER_SPAN arm_dwarf_register_span
++
+ #undef  TARGET_CANNOT_COPY_INSN_P
+ #define TARGET_CANNOT_COPY_INSN_P arm_cannot_copy_insn_p
+@@ -355,17 +392,54 @@ static void arm_output_dwarf_dtprel (FIL
+ #define TARGET_HAVE_TLS true
+ #endif
++#undef TARGET_ADJUST_REG_ALLOC_ORDER
++#define TARGET_ADJUST_REG_ALLOC_ORDER arm_adjust_reg_alloc_order
++
+ #undef TARGET_CANNOT_FORCE_CONST_MEM
+ #define TARGET_CANNOT_FORCE_CONST_MEM arm_cannot_force_const_mem
+ #undef TARGET_MANGLE_TYPE
+ #define TARGET_MANGLE_TYPE arm_mangle_type
++#undef TARGET_BUILD_BUILTIN_VA_LIST
++#define TARGET_BUILD_BUILTIN_VA_LIST arm_build_builtin_va_list
++#undef TARGET_EXPAND_BUILTIN_VA_START
++#define TARGET_EXPAND_BUILTIN_VA_START arm_expand_builtin_va_start
++#undef TARGET_GIMPLIFY_VA_ARG_EXPR
++#define TARGET_GIMPLIFY_VA_ARG_EXPR arm_gimplify_va_arg_expr
++
+ #ifdef HAVE_AS_TLS
+ #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
+ #define TARGET_ASM_OUTPUT_DWARF_DTPREL arm_output_dwarf_dtprel
+ #endif
++#undef TARGET_MAX_ANCHOR_OFFSET
++#define TARGET_MAX_ANCHOR_OFFSET 4095
++
++/* The minimum is set such that the total size of the block
++   for a particular anchor is -4088 + 1 + 4095 bytes, which is
++   divisible by eight, ensuring natural spacing of anchors.  */
++#undef TARGET_MIN_ANCHOR_OFFSET
++#define TARGET_MIN_ANCHOR_OFFSET -4088
++
++#undef TARGET_SCHED_ISSUE_RATE
++#define TARGET_SCHED_ISSUE_RATE arm_issue_rate
++
++#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
++#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD arm_multipass_dfa_lookahead
++
++#undef TARGET_INVALID_PARAMETER_TYPE
++#define TARGET_INVALID_PARAMETER_TYPE arm_invalid_parameter_type
++
++#undef TARGET_INVALID_RETURN_TYPE
++#define TARGET_INVALID_RETURN_TYPE arm_invalid_return_type
++
++#undef TARGET_PROMOTED_TYPE
++#define TARGET_PROMOTED_TYPE arm_promoted_type
++
++#undef TARGET_CONVERT_TO_TYPE
++#define TARGET_CONVERT_TO_TYPE arm_convert_to_type
++
+ struct gcc_target targetm = TARGET_INITIALIZER;
\f
+ /* Obstack for minipool constant handling.  */
+@@ -403,6 +477,9 @@ enum fputype arm_fpu_tune;
+ /* Whether to use floating point hardware.  */
+ enum float_abi_type arm_float_abi;
++/* Which __fp16 format to use.  */
++enum arm_fp16_format_type arm_fp16_format;
++
+ /* Which ABI to use.  */
+ enum arm_abi_type arm_abi;
+@@ -441,9 +518,18 @@ static int thumb_call_reg_needed;
+ #define FL_DIV              (1 << 18)       /* Hardware divide.  */
+ #define FL_VFPV3      (1 << 19)       /* Vector Floating Point V3.  */
+ #define FL_NEON       (1 << 20)       /* Neon instructions.  */
++#define FL_MARVELL_F  (1 << 21)       /* Marvell Feroceon.  */
+ #define FL_IWMMXT     (1 << 29)             /* XScale v2 or "Intel Wireless MMX technology".  */
++/* Some flags are ignored when comparing -mcpu and -march:
++    FL_MARVELL_F so that -mcpu=marvell-f -march=v5te works.
++    FL_LDSCHED and FL_WBUF only effect tuning,
++    FL_CO_PROC, FL_VFPV2, FL_VFPV3 and FL_NEON because FP
++      coprocessors are handled separately.  */
++#define FL_COMPAT (FL_MARVELL_F | FL_LDSCHED | FL_WBUF | FL_CO_PROC | \
++                 FL_VFPV2 | FL_VFPV3 | FL_NEON)
++
+ #define FL_FOR_ARCH2  FL_NOTM
+ #define FL_FOR_ARCH3  (FL_FOR_ARCH2 | FL_MODE32)
+ #define FL_FOR_ARCH3M (FL_FOR_ARCH3 | FL_ARCH3M)
+@@ -460,6 +546,7 @@ static int thumb_call_reg_needed;
+ #define FL_FOR_ARCH6Z FL_FOR_ARCH6
+ #define FL_FOR_ARCH6ZK        FL_FOR_ARCH6K
+ #define FL_FOR_ARCH6T2        (FL_FOR_ARCH6 | FL_THUMB2)
++#define FL_FOR_ARCH6M (FL_FOR_ARCH6 & ~FL_NOTM)
+ #define FL_FOR_ARCH7  (FL_FOR_ARCH6T2 &~ FL_NOTM)
+ #define FL_FOR_ARCH7A (FL_FOR_ARCH7 | FL_NOTM)
+ #define FL_FOR_ARCH7R (FL_FOR_ARCH7A | FL_DIV)
+@@ -518,13 +605,22 @@ int arm_arch_xscale = 0;
+ /* Nonzero if tuning for XScale  */
+ int arm_tune_xscale = 0;
++/* Nonzero if tuning for Marvell Feroceon.  */
++int arm_tune_marvell_f = 0;
++
+ /* Nonzero if we want to tune for stores that access the write-buffer.
+    This typically means an ARM6 or ARM7 with MMU or MPU.  */
+ int arm_tune_wbuf = 0;
++/* Nonzero if tuning for Cortex-A9.  */
++int arm_tune_cortex_a9 = 0;
++
+ /* Nonzero if generating Thumb instructions.  */
+ int thumb_code = 0;
++/* Nonzero if generating code for Janus2. */
++int janus2_code = 0;
++
+ /* Nonzero if we should define __THUMB_INTERWORK__ in the
+    preprocessor.
+    XXX This is a bit of a hack, it's intended to help work around
+@@ -557,6 +653,8 @@ static int after_arm_reorg = 0;
+ /* The maximum number of insns to be used when loading a constant.  */
+ static int arm_constant_limit = 3;
++static enum arm_pcs arm_pcs_default;
++
+ /* For an explanation of these variables, see final_prescan_insn below.  */
+ int arm_ccfsm_state;
+ /* arm_current_cc is also used for Thumb-2 cond_exec blocks.  */
+@@ -593,7 +691,7 @@ struct processors
+   enum processor_type core;
+   const char *arch;
+   const unsigned long flags;
+-  bool (* rtx_costs) (rtx, int, int, int *);
++  bool (* rtx_costs) (rtx, enum rtx_code, enum rtx_code, int *);
+ };
+ /* Not all of these give usefully different compilation alternatives,
+@@ -632,12 +730,14 @@ static const struct processors all_archi
+   {"armv6z",  arm1176jzs, "6Z",  FL_CO_PROC |             FL_FOR_ARCH6Z, NULL},
+   {"armv6zk", arm1176jzs, "6ZK", FL_CO_PROC |             FL_FOR_ARCH6ZK, NULL},
+   {"armv6t2", arm1156t2s, "6T2", FL_CO_PROC |             FL_FOR_ARCH6T2, NULL},
++  {"armv6-m", cortexm1,         "6M",                           FL_FOR_ARCH6M, NULL},
+   {"armv7",   cortexa8,         "7",   FL_CO_PROC |             FL_FOR_ARCH7, NULL},
+   {"armv7-a", cortexa8,         "7A",  FL_CO_PROC |             FL_FOR_ARCH7A, NULL},
+   {"armv7-r", cortexr4,         "7R",  FL_CO_PROC |             FL_FOR_ARCH7R, NULL},
+   {"armv7-m", cortexm3,         "7M",  FL_CO_PROC |             FL_FOR_ARCH7M, NULL},
+   {"ep9312",  ep9312,     "4T",  FL_LDSCHED | FL_CIRRUS | FL_FOR_ARCH4, NULL},
+   {"iwmmxt",  iwmmxt,     "5TE", FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT , NULL},
++  {"iwmmxt2", iwmmxt2,     "5TE", FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT , NULL},
+   {NULL, arm_none, NULL, 0 , NULL}
+ };
+@@ -667,7 +767,8 @@ static struct arm_cpu_select arm_select[
+ /* The name of the preprocessor macro to define for this architecture.  */
+-char arm_arch_name[] = "__ARM_ARCH_0UNK__";
++#define ARM_ARCH_NAME_SIZE 25
++char arm_arch_name[ARM_ARCH_NAME_SIZE] = "__ARM_ARCH_0UNK__";
+ struct fpu_desc
+ {
+@@ -680,13 +781,16 @@ struct fpu_desc
+ static const struct fpu_desc all_fpus[] =
+ {
+-  {"fpa",     FPUTYPE_FPA},
+-  {"fpe2",    FPUTYPE_FPA_EMU2},
+-  {"fpe3",    FPUTYPE_FPA_EMU2},
+-  {"maverick",        FPUTYPE_MAVERICK},
+-  {"vfp",     FPUTYPE_VFP},
+-  {"vfp3",    FPUTYPE_VFP3},
+-  {"neon",    FPUTYPE_NEON}
++  {"fpa",             FPUTYPE_FPA},
++  {"fpe2",            FPUTYPE_FPA_EMU2},
++  {"fpe3",            FPUTYPE_FPA_EMU2},
++  {"maverick",                FPUTYPE_MAVERICK},
++  {"vfp",             FPUTYPE_VFP},
++  {"vfp3",            FPUTYPE_VFP3},
++  {"vfpv3",           FPUTYPE_VFP3},
++  {"vfpv3-d16",               FPUTYPE_VFP3D16},
++  {"neon",            FPUTYPE_NEON},
++  {"neon-fp16",               FPUTYPE_NEON_FP16}
+ };
+@@ -702,8 +806,10 @@ static const enum fputype fp_model_for_f
+   ARM_FP_MODEL_FPA,           /* FPUTYPE_FPA_EMU3  */
+   ARM_FP_MODEL_MAVERICK,      /* FPUTYPE_MAVERICK  */
+   ARM_FP_MODEL_VFP,           /* FPUTYPE_VFP  */
++  ARM_FP_MODEL_VFP,           /* FPUTYPE_VFP3D16  */
+   ARM_FP_MODEL_VFP,           /* FPUTYPE_VFP3  */
+-  ARM_FP_MODEL_VFP            /* FPUTYPE_NEON  */
++  ARM_FP_MODEL_VFP,           /* FPUTYPE_NEON  */
++  ARM_FP_MODEL_VFP            /* FPUTYPE_NEON_FP16  */
+ };
+@@ -724,6 +830,23 @@ static const struct float_abi all_float_
+ };
++struct fp16_format
++{
++  const char *name;
++  enum arm_fp16_format_type fp16_format_type;
++};
++
++
++/* Available values for -mfp16-format=.  */
++
++static const struct fp16_format all_fp16_formats[] =
++{
++  {"none",            ARM_FP16_FORMAT_NONE},
++  {"ieee",            ARM_FP16_FORMAT_IEEE},
++  {"alternative",     ARM_FP16_FORMAT_ALTERNATIVE}
++};
++
++
+ struct abi_name
+ {
+   const char *name;
+@@ -881,6 +1004,131 @@ arm_init_libfuncs (void)
+   set_optab_libfunc (umod_optab, DImode, NULL);
+   set_optab_libfunc (smod_optab, SImode, NULL);
+   set_optab_libfunc (umod_optab, SImode, NULL);
++
++  /* Half-precision float operations.  The compiler handles all operations
++     with NULL libfuncs by converting the SFmode.  */
++  switch (arm_fp16_format)
++    {
++    case ARM_FP16_FORMAT_IEEE:
++    case ARM_FP16_FORMAT_ALTERNATIVE:
++
++      /* Conversions.  */
++      set_conv_libfunc (trunc_optab, HFmode, SFmode,
++                      (arm_fp16_format == ARM_FP16_FORMAT_IEEE
++                       ? "__gnu_f2h_ieee"
++                       : "__gnu_f2h_alternative"));
++      set_conv_libfunc (sext_optab, SFmode, HFmode, 
++                      (arm_fp16_format == ARM_FP16_FORMAT_IEEE
++                       ? "__gnu_h2f_ieee"
++                       : "__gnu_h2f_alternative"));
++      
++      /* Arithmetic.  */
++      set_optab_libfunc (add_optab, HFmode, NULL);
++      set_optab_libfunc (sdiv_optab, HFmode, NULL);
++      set_optab_libfunc (smul_optab, HFmode, NULL);
++      set_optab_libfunc (neg_optab, HFmode, NULL);
++      set_optab_libfunc (sub_optab, HFmode, NULL);
++
++      /* Comparisons.  */
++      set_optab_libfunc (eq_optab, HFmode, NULL);
++      set_optab_libfunc (ne_optab, HFmode, NULL);
++      set_optab_libfunc (lt_optab, HFmode, NULL);
++      set_optab_libfunc (le_optab, HFmode, NULL);
++      set_optab_libfunc (ge_optab, HFmode, NULL);
++      set_optab_libfunc (gt_optab, HFmode, NULL);
++      set_optab_libfunc (unord_optab, HFmode, NULL);
++      break;
++
++    default:
++      break;
++    }
++}
++
++/* On AAPCS systems, this is the "struct __va_list".  */
++static GTY(()) tree va_list_type;
++
++/* Return the type to use as __builtin_va_list.  */
++static tree
++arm_build_builtin_va_list (void)
++{
++  tree va_list_name;
++  tree ap_field;
++  
++  if (!TARGET_AAPCS_BASED)
++    return std_build_builtin_va_list ();
++
++  /* AAPCS \S 7.1.4 requires that va_list be a typedef for a type
++     defined as:
++
++       struct __va_list 
++       {
++       void *__ap;
++       };
++
++     The C Library ABI further reinforces this definition in \S
++     4.1.
++
++     We must follow this definition exactly.  The structure tag
++     name is visible in C++ mangled names, and thus forms a part
++     of the ABI.  The field name may be used by people who
++     #include <stdarg.h>.  */
++  /* Create the type.  */
++  va_list_type = lang_hooks.types.make_type (RECORD_TYPE);
++  /* Give it the required name.  */
++  va_list_name = build_decl (TYPE_DECL,
++                           get_identifier ("__va_list"),
++                           va_list_type);
++  DECL_ARTIFICIAL (va_list_name) = 1;
++  TYPE_NAME (va_list_type) = va_list_name;
++  /* Create the __ap field.  */
++  ap_field = build_decl (FIELD_DECL, 
++                       get_identifier ("__ap"),
++                       ptr_type_node);
++  DECL_ARTIFICIAL (ap_field) = 1;
++  DECL_FIELD_CONTEXT (ap_field) = va_list_type;
++  TYPE_FIELDS (va_list_type) = ap_field;
++  /* Compute its layout.  */
++  layout_type (va_list_type);
++
++  return va_list_type;
++}
++
++/* Return an expression of type "void *" pointing to the next
++   available argument in a variable-argument list.  VALIST is the
++   user-level va_list object, of type __builtin_va_list.  */
++static tree
++arm_extract_valist_ptr (tree valist)
++{
++  if (TREE_TYPE (valist) == error_mark_node)
++    return error_mark_node;
++
++  /* On an AAPCS target, the pointer is stored within "struct
++     va_list".  */
++  if (TARGET_AAPCS_BASED)
++    {
++      tree ap_field = TYPE_FIELDS (TREE_TYPE (valist));
++      valist = build3 (COMPONENT_REF, TREE_TYPE (ap_field), 
++                     valist, ap_field, NULL_TREE);
++    }
++
++  return valist;
++}
++
++/* Implement TARGET_EXPAND_BUILTIN_VA_START.  */
++static void
++arm_expand_builtin_va_start (tree valist, rtx nextarg)
++{
++  valist = arm_extract_valist_ptr (valist);
++  std_expand_builtin_va_start (valist, nextarg);
++}
++
++/* Implement TARGET_GIMPLIFY_VA_ARG_EXPR.  */
++static tree
++arm_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, 
++                        tree *post_p)
++{
++  valist = arm_extract_valist_ptr (valist);
++  return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
+ }
+ /* Implement TARGET_HANDLE_OPTION.  */
+@@ -1007,7 +1255,9 @@ void
+ arm_override_options (void)
+ {
+   unsigned i;
++  int len;
+   enum processor_type target_arch_cpu = arm_none;
++  enum processor_type selected_cpu = arm_none;
+   /* Set up the flags based on the cpu/architecture selected by the user.  */
+   for (i = ARRAY_SIZE (arm_select); i--;)
+@@ -1023,7 +1273,11 @@ arm_override_options (void)
+               {
+               /* Set the architecture define.  */
+               if (i != ARM_OPT_SET_TUNE)
+-                sprintf (arm_arch_name, "__ARM_ARCH_%s__", sel->arch);
++                {
++                  len = snprintf (arm_arch_name, ARM_ARCH_NAME_SIZE,
++                                  "__ARM_ARCH_%s__", sel->arch);
++                  gcc_assert (len < ARM_ARCH_NAME_SIZE);
++                }
+               /* Determine the processor core for which we should
+                  tune code-generation.  */
+@@ -1040,14 +1294,17 @@ arm_override_options (void)
+               if (i == ARM_OPT_SET_ARCH)
+                 target_arch_cpu = sel->core;
++              if (i == ARM_OPT_SET_CPU)
++                selected_cpu = (enum processor_type) (sel - ptr->processors);
++                
+               if (i != ARM_OPT_SET_TUNE)
+                 {
+                   /* If we have been given an architecture and a processor
+                      make sure that they are compatible.  We only generate
+                      a warning though, and we prefer the CPU over the
+                      architecture.  */
+-                  if (insn_flags != 0 && (insn_flags ^ sel->flags))
+-                    warning (0, "switch -mcpu=%s conflicts with -march= switch",
++                  if (insn_flags != 0 && ((insn_flags ^ sel->flags) & ~FL_COMPAT))
++                    warning (0, "switch -mcpu=%s conflicts with -march= switch, assuming CPU feature set", 
+                              ptr->string);
+                   insn_flags = sel->flags;
+@@ -1070,21 +1327,20 @@ arm_override_options (void)
+     {
+       const struct processors * sel;
+       unsigned int        sought;
+-      enum processor_type cpu;
+-      cpu = TARGET_CPU_DEFAULT;
+-      if (cpu == arm_none)
++      selected_cpu = TARGET_CPU_DEFAULT;
++      if (selected_cpu == arm_none)
+       {
+ #ifdef SUBTARGET_CPU_DEFAULT
+         /* Use the subtarget default CPU if none was specified by
+            configure.  */
+-        cpu = SUBTARGET_CPU_DEFAULT;
++        selected_cpu = SUBTARGET_CPU_DEFAULT;
+ #endif
+         /* Default to ARM6.  */
+-        if (cpu == arm_none)
+-          cpu = arm6;
++        if (selected_cpu == arm_none)
++          selected_cpu = arm6;
+       }
+-      sel = &all_cores[cpu];
++      sel = &all_cores[selected_cpu];
+       insn_flags = sel->flags;
+@@ -1148,7 +1404,11 @@ arm_override_options (void)
+         insn_flags = sel->flags;
+       }
+-      sprintf (arm_arch_name, "__ARM_ARCH_%s__", sel->arch);
++
++      len = snprintf (arm_arch_name, ARM_ARCH_NAME_SIZE,
++                    "__ARM_ARCH_%s__", sel->arch);
++      gcc_assert (len < ARM_ARCH_NAME_SIZE);
++
+       arm_default_cpu = (enum processor_type) (sel - all_cores);
+       if (arm_tune == arm_none)
+       arm_tune = arm_default_cpu;
+@@ -1158,18 +1418,59 @@ arm_override_options (void)
+      chosen.  */
+   gcc_assert (arm_tune != arm_none);
++  if (arm_tune == cortexa8 && optimize >= 3)
++    {
++      /* These alignments were experimentally determined to improve SPECint
++       performance on SPECCPU 2000.  */
++      if (align_functions <= 0)
++      align_functions = 16;
++      if (align_jumps <= 0)
++      align_jumps = 16;
++    }
++
+   tune_flags = all_cores[(int)arm_tune].flags;
+-  if (optimize_size)
+-    targetm.rtx_costs = arm_size_rtx_costs;
++
++  if (target_fp16_format_name)
++    {
++      for (i = 0; i < ARRAY_SIZE (all_fp16_formats); i++)
++      {
++        if (streq (all_fp16_formats[i].name, target_fp16_format_name))
++          {
++            arm_fp16_format = all_fp16_formats[i].fp16_format_type;
++            break;
++          }
++      }
++      if (i == ARRAY_SIZE (all_fp16_formats))
++      error ("invalid __fp16 format option: -mfp16-format=%s",
++             target_fp16_format_name);
++    }
++  else
++    arm_fp16_format = ARM_FP16_FORMAT_NONE;
++
++  if (target_abi_name)
++    {
++      for (i = 0; i < ARRAY_SIZE (arm_all_abis); i++)
++      {
++        if (streq (arm_all_abis[i].name, target_abi_name))
++          {
++            arm_abi = arm_all_abis[i].abi_type;
++            break;
++          }
++      }
++      if (i == ARRAY_SIZE (arm_all_abis))
++      error ("invalid ABI option: -mabi=%s", target_abi_name);
++    }
+   else
+-    targetm.rtx_costs = all_cores[(int)arm_tune].rtx_costs;
++    arm_abi = ARM_DEFAULT_ABI;
+   /* Make sure that the processor choice does not conflict with any of the
+      other command line choices.  */
+   if (TARGET_ARM && !(insn_flags & FL_NOTM))
+     error ("target CPU does not support ARM mode");
+-  if (TARGET_INTERWORK && !(insn_flags & FL_THUMB))
++  /* BPABI targets use linker tricks to allow interworking on cores
++     without thumb support.  */
++  if (TARGET_INTERWORK && !((insn_flags & FL_THUMB) || TARGET_BPABI))
+     {
+       warning (0, "target CPU does not support interworking" );
+       target_flags &= ~MASK_INTERWORK;
+@@ -1245,10 +1546,45 @@ arm_override_options (void)
+   arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
+   arm_tune_strongarm = (tune_flags & FL_STRONG) != 0;
+   thumb_code = (TARGET_ARM == 0);
++  janus2_code = (TARGET_FIX_JANUS != 0);
++  if (janus2_code && TARGET_THUMB2)
++    error ("janus2 fix is not applicable when targeting a thumb2 core");
+   arm_tune_wbuf = (tune_flags & FL_WBUF) != 0;
+   arm_tune_xscale = (tune_flags & FL_XSCALE) != 0;
++  arm_tune_marvell_f = (tune_flags & FL_MARVELL_F) != 0;
++  arm_tune_cortex_a9 = (arm_tune == cortexa9) != 0;
+   arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0;
+-  arm_arch_hwdiv = (insn_flags & FL_DIV) != 0;
++
++ /* Hardware integer division is supported by some variants of the ARM
++    architecture in Thumb-2 mode.  In addition some (but not all) Marvell
++    CPUs support their own hardware integer division instructions.
++    The assembler will pick the correct encoding.  */
++  if (TARGET_MARVELL_DIV && (insn_flags & FL_MARVELL_F) == 0)
++    error ("-mmarvell-div is only supported when targeting a Marvell core");
++
++  arm_arch_hwdiv = (TARGET_ARM && TARGET_MARVELL_DIV)
++                 || (TARGET_THUMB2 && (insn_flags & FL_DIV) != 0);
++
++  /* If we are not using the default (ARM mode) section anchor offset
++     ranges, then set the correct ranges now.  */
++  if (TARGET_THUMB1)
++    {
++      /* Thumb-1 LDR instructions cannot have negative offsets.
++         Permissible positive offset ranges are 5-bit (for byte loads),
++         6-bit (for halfword loads), or 7-bit (for word loads).
++         Empirical results suggest a 7-bit anchor range gives the best
++         overall code size.  */
++      targetm.min_anchor_offset = 0;
++      targetm.max_anchor_offset = 127;
++    }
++  else if (TARGET_THUMB2)
++    {
++      /* The minimum is set such that the total size of the block
++         for a particular anchor is 248 + 1 + 4095 bytes, which is
++         divisible by eight, ensuring natural spacing of anchors.  */
++      targetm.min_anchor_offset = -248;
++      targetm.max_anchor_offset = 4095;
++    }
+   /* V5 code we generate is completely interworking capable, so we turn off
+      TARGET_INTERWORK here to avoid many tests later on.  */
+@@ -1261,22 +1597,6 @@ arm_override_options (void)
+   if (arm_arch5)
+     target_flags &= ~MASK_INTERWORK;
+-  if (target_abi_name)
+-    {
+-      for (i = 0; i < ARRAY_SIZE (arm_all_abis); i++)
+-      {
+-        if (streq (arm_all_abis[i].name, target_abi_name))
+-          {
+-            arm_abi = arm_all_abis[i].abi_type;
+-            break;
+-          }
+-      }
+-      if (i == ARRAY_SIZE (arm_all_abis))
+-      error ("invalid ABI option: -mabi=%s", target_abi_name);
+-    }
+-  else
+-    arm_abi = ARM_DEFAULT_ABI;
+-
+   if (TARGET_IWMMXT && !ARM_DOUBLEWORD_ALIGN)
+     error ("iwmmxt requires an AAPCS compatible ABI for proper operation");
+@@ -1354,9 +1674,6 @@ arm_override_options (void)
+   else
+     arm_float_abi = TARGET_DEFAULT_FLOAT_ABI;
+-  if (arm_float_abi == ARM_FLOAT_ABI_HARD && TARGET_VFP)
+-    sorry ("-mfloat-abi=hard and VFP");
+-
+   /* FPA and iWMMXt are incompatible because the insn encodings overlap.
+      VFP and iWMMXt can theoretically coexist, but it's unlikely such silicon
+      will ever exist.  GCC makes no attempt to support this combination.  */
+@@ -1367,10 +1684,36 @@ arm_override_options (void)
+   if (TARGET_THUMB2 && TARGET_IWMMXT)
+     sorry ("Thumb-2 iWMMXt");
++  /* __fp16 support currently assumes the core has ldrh.  */
++  if (!arm_arch4 && arm_fp16_format != ARM_FP16_FORMAT_NONE)
++    sorry ("__fp16 and no ldrh");
++
+   /* If soft-float is specified then don't use FPU.  */
+   if (TARGET_SOFT_FLOAT)
+     arm_fpu_arch = FPUTYPE_NONE;
++  if (TARGET_AAPCS_BASED)
++    {
++      if (arm_abi == ARM_ABI_IWMMXT)
++      arm_pcs_default = ARM_PCS_AAPCS_IWMMXT;
++      else if (arm_float_abi == ARM_FLOAT_ABI_HARD
++             && TARGET_HARD_FLOAT
++             && TARGET_VFP)
++      arm_pcs_default = ARM_PCS_AAPCS_VFP;
++      else
++      arm_pcs_default = ARM_PCS_AAPCS;
++    }
++  else
++    {
++      if (arm_float_abi == ARM_FLOAT_ABI_HARD && TARGET_VFP)
++      sorry ("-mfloat-abi=hard and VFP");
++
++      if (arm_abi == ARM_ABI_APCS)
++      arm_pcs_default = ARM_PCS_APCS;
++      else
++      arm_pcs_default = ARM_PCS_ATPCS;
++    }
++
+   /* For arm2/3 there is no need to do any scheduling if there is only
+      a floating point emulator, or we are doing software floating-point.  */
+   if ((TARGET_SOFT_FLOAT
+@@ -1456,6 +1799,15 @@ arm_override_options (void)
+       arm_pic_register = pic_register;
+     }
++  /* Enable -mfix-cortex-m3-ldrd by default for Cortex-M3 cores.  */
++  if (fix_cm3_ldrd == 2)
++    {
++      if (selected_cpu == cortexm3)
++      fix_cm3_ldrd = 1;
++      else
++      fix_cm3_ldrd = 0;
++    }
++
+   /* ??? We might want scheduling for thumb2.  */
+   if (TARGET_THUMB && flag_schedule_insns)
+     {
+@@ -1493,6 +1845,13 @@ arm_override_options (void)
+   /* Register global variables with the garbage collector.  */
+   arm_add_gc_roots ();
++
++  if (low_irq_latency && TARGET_THUMB)
++    {
++      warning (0, 
++             "-low-irq-latency has no effect when compiling for the Thumb");
++      low_irq_latency = 0;
++    }
+ }
+ static void
+@@ -1614,6 +1973,14 @@ arm_current_func_type (void)
+   return cfun->machine->func_type;
+ }
++
++bool
++arm_allocate_stack_slots_for_args (void)
++{
++  /* Naked functions should not allocate stack slots for arguments.  */
++  return !IS_NAKED (arm_current_func_type ());
++}
++
\f
+ /* Return 1 if it is possible to return using a single instruction.
+    If SIBLING is non-null, this is a test for a return before a sibling
+@@ -1656,10 +2023,11 @@ use_return_insn (int iscond, rtx sibling
+       || current_function_calls_alloca
+       /* Or if there is a stack adjustment.  However, if the stack pointer
+        is saved on the stack, we can use a pre-incrementing stack load.  */
+-      || !(stack_adjust == 0 || (frame_pointer_needed && stack_adjust == 4)))
++      || !(stack_adjust == 0 || (TARGET_APCS_FRAME && frame_pointer_needed
++                               && stack_adjust == 4)))
+     return 0;
+-  saved_int_regs = arm_compute_save_reg_mask ();
++  saved_int_regs = offsets->saved_regs_mask;
+   /* Unfortunately, the insn
+@@ -1812,6 +2180,24 @@ const_ok_for_op (HOST_WIDE_INT i, enum r
+   switch (code)
+     {
+     case PLUS:
++    case COMPARE:
++    case EQ:
++    case NE:
++    case GT:
++    case LE:
++    case LT:
++    case GE:
++    case GEU:
++    case LTU:
++    case GTU:
++    case LEU:
++    case UNORDERED:
++    case ORDERED:
++    case UNEQ:
++    case UNGE:
++    case UNLT:
++    case UNGT:
++    case UNLE:
+       return const_ok_for_arm (ARM_SIGN_EXTEND (-i));
+     case MINUS:               /* Should only occur with (MINUS I reg) => rsb */
+@@ -1872,14 +2258,22 @@ arm_split_constant (enum rtx_code code, 
+           {
+             /* Currently SET is the only monadic value for CODE, all
+                the rest are diadic.  */
+-            emit_set_insn (target, GEN_INT (val));
++            if (TARGET_USE_MOVT)
++              arm_emit_movpair (target, GEN_INT (val));
++            else
++              emit_set_insn (target, GEN_INT (val));
++
+             return 1;
+           }
+         else
+           {
+             rtx temp = subtargets ? gen_reg_rtx (mode) : target;
+-            emit_set_insn (temp, GEN_INT (val));
++            if (TARGET_USE_MOVT)
++              arm_emit_movpair (temp, GEN_INT (val));
++            else
++              emit_set_insn (temp, GEN_INT (val));
++
+             /* For MINUS, the value is subtracted from, since we never
+                have subtraction of a constant.  */
+             if (code == MINUS)
+@@ -2678,14 +3072,19 @@ arm_canonicalize_comparison (enum rtx_co
+ /* Define how to find the value returned by a function.  */
+-rtx
+-arm_function_value(const_tree type, const_tree func ATTRIBUTE_UNUSED)
++static rtx
++arm_function_value(const_tree type, const_tree func,
++                 bool outgoing ATTRIBUTE_UNUSED)
+ {
+   enum machine_mode mode;
+   int unsignedp ATTRIBUTE_UNUSED;
+   rtx r ATTRIBUTE_UNUSED;
+   mode = TYPE_MODE (type);
++
++  if (TARGET_AAPCS_BASED)
++    return aapcs_allocate_return_reg (mode, type, func);
++
+   /* Promote integer types.  */
+   if (INTEGRAL_TYPE_P (type))
+     PROMOTE_FUNCTION_MODE (mode, unsignedp, type);
+@@ -2702,7 +3101,36 @@ arm_function_value(const_tree type, cons
+       }
+     }
+-  return LIBCALL_VALUE(mode);
++  return LIBCALL_VALUE (mode);
++}
++
++rtx
++arm_libcall_value (enum machine_mode mode, rtx libcall)
++{
++  if (TARGET_AAPCS_BASED && arm_pcs_default != ARM_PCS_AAPCS
++      && GET_MODE_CLASS (mode) == MODE_FLOAT)
++    {
++      /* The following libcalls return their result in integer registers,
++       even though they return a floating point value.  */
++      if (rtx_equal_p (libcall,
++                     convert_optab_libfunc (sfloat_optab, mode, SImode))
++        || rtx_equal_p (libcall,
++                        convert_optab_libfunc (ufloat_optab, mode, SImode))
++        || rtx_equal_p (libcall,
++                        convert_optab_libfunc (sfloat_optab, mode, DImode))
++        || rtx_equal_p (libcall,
++                        convert_optab_libfunc (ufloat_optab, mode, DImode))
++        || rtx_equal_p (libcall,
++                        convert_optab_libfunc (trunc_optab, HFmode, SFmode))
++        || rtx_equal_p (libcall,
++                        convert_optab_libfunc (sext_optab, SFmode, HFmode)))
++      return gen_rtx_REG (mode, ARG_REGISTER(1));
++
++      /* XXX There are other libcalls that return in integer registers,
++       but I think they are all handled by hard insns.  */
++    }
++
++  return LIBCALL_VALUE (mode);
+ }
+ /* Determine the amount of memory needed to store the possible return
+@@ -2712,10 +3140,12 @@ arm_apply_result_size (void)
+ {
+   int size = 16;
+-  if (TARGET_ARM)
++  if (TARGET_32BIT)
+     {
+       if (TARGET_HARD_FLOAT_ABI)
+       {
++        if (TARGET_VFP)
++          size += 32;
+         if (TARGET_FPA)
+           size += 12;
+         if (TARGET_MAVERICK)
+@@ -2728,27 +3158,56 @@ arm_apply_result_size (void)
+   return size;
+ }
+-/* Decide whether a type should be returned in memory (true)
+-   or in a register (false).  This is called by the macro
+-   RETURN_IN_MEMORY.  */
+-int
+-arm_return_in_memory (const_tree type)
++/* Decide whether TYPE should be returned in memory (true)
++   or in a register (false).  FNTYPE is the type of the function making
++   the call.  */
++static bool
++arm_return_in_memory (const_tree type, const_tree fntype)
+ {
+   HOST_WIDE_INT size;
+-  size = int_size_in_bytes (type);
++  size = int_size_in_bytes (type);  /* Negative if not fixed size.  */
++
++  if (TARGET_AAPCS_BASED)
++    {
++      /* Simple, non-aggregate types (ie not including vectors and
++       complex) are always returned in a register (or registers).
++       We don't care about which register here, so we can short-cut
++       some of the detail.  */
++      if (!AGGREGATE_TYPE_P (type)
++        && TREE_CODE (type) != VECTOR_TYPE
++        && TREE_CODE (type) != COMPLEX_TYPE)
++      return false;
++
++      /* Any return value that is no larger than one word can be
++       returned in r0.  */
++      if (((unsigned HOST_WIDE_INT) size) <= UNITS_PER_WORD)
++      return false;
++
++      /* Check any available co-processors to see if they accept the
++       type as a register candidate (VFP, for example, can return
++       some aggregates in consecutive registers).  These aren't
++       available if the call is variadic.  */
++      if (aapcs_select_return_coproc (type, fntype) >= 0)
++      return false;
++
++      /* Vector values should be returned using ARM registers, not
++       memory (unless they're over 16 bytes, which will break since
++       we only have four call-clobbered registers to play with).  */
++      if (TREE_CODE (type) == VECTOR_TYPE)
++      return (size < 0 || size > (4 * UNITS_PER_WORD));
++
++      /* The rest go in memory.  */
++      return true;
++    }
+-  /* Vector values should be returned using ARM registers, not memory (unless
+-     they're over 16 bytes, which will break since we only have four
+-     call-clobbered registers to play with).  */
+   if (TREE_CODE (type) == VECTOR_TYPE)
+     return (size < 0 || size > (4 * UNITS_PER_WORD));
+   if (!AGGREGATE_TYPE_P (type) &&
+-      !(TARGET_AAPCS_BASED && TREE_CODE (type) == COMPLEX_TYPE))
+-    /* All simple types are returned in registers.
+-       For AAPCS, complex types are treated the same as aggregates.  */
+-    return 0;
++      (TREE_CODE (type) != VECTOR_TYPE))
++    /* All simple types are returned in registers.  */
++    return false;
+   if (arm_abi != ARM_ABI_APCS)
+     {
+@@ -2765,7 +3224,7 @@ arm_return_in_memory (const_tree type)
+      the aggregate is either huge or of variable size, and in either case
+      we will want to return it via memory and not in a register.  */
+   if (size < 0 || size > UNITS_PER_WORD)
+-    return 1;
++    return true;
+   if (TREE_CODE (type) == RECORD_TYPE)
+     {
+@@ -2785,18 +3244,18 @@ arm_return_in_memory (const_tree type)
+       continue;
+       if (field == NULL)
+-      return 0; /* An empty structure.  Allowed by an extension to ANSI C.  */
++      return false; /* An empty structure.  Allowed by an extension to ANSI C.  */
+       /* Check that the first field is valid for returning in a register.  */
+       /* ... Floats are not allowed */
+       if (FLOAT_TYPE_P (TREE_TYPE (field)))
+-      return 1;
++      return true;
+       /* ... Aggregates that are not themselves valid for returning in
+        a register are not allowed.  */
+-      if (RETURN_IN_MEMORY (TREE_TYPE (field)))
+-      return 1;
++      if (arm_return_in_memory (TREE_TYPE (field), NULL_TREE))
++      return true;
+       /* Now check the remaining fields, if any.  Only bitfields are allowed,
+        since they are not addressable.  */
+@@ -2808,10 +3267,10 @@ arm_return_in_memory (const_tree type)
+           continue;
+         if (!DECL_BIT_FIELD_TYPE (field))
+-          return 1;
++          return true;
+       }
+-      return 0;
++      return false;
+     }
+   if (TREE_CODE (type) == UNION_TYPE)
+@@ -2828,18 +3287,18 @@ arm_return_in_memory (const_tree type)
+           continue;
+         if (FLOAT_TYPE_P (TREE_TYPE (field)))
+-          return 1;
++          return true;
+-        if (RETURN_IN_MEMORY (TREE_TYPE (field)))
+-          return 1;
++        if (arm_return_in_memory (TREE_TYPE (field), NULL_TREE))
++          return true;
+       }
+-      return 0;
++      return false;
+     }
+ #endif /* not ARM_WINCE */
+   /* Return all other types in memory.  */
+-  return 1;
++  return true;
+ }
+ /* Indicate whether or not words of a double are in big-endian order.  */
+@@ -2864,60 +3323,811 @@ arm_float_words_big_endian (void)
+   return 1;
+ }
+-/* Initialize a variable CUM of type CUMULATIVE_ARGS
+-   for a call to a function whose data type is FNTYPE.
+-   For a library call, FNTYPE is NULL.  */
+-void
+-arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
+-                        rtx libname  ATTRIBUTE_UNUSED,
+-                        tree fndecl ATTRIBUTE_UNUSED)
++const struct pcs_attribute_arg
+ {
+-  /* On the ARM, the offset starts at 0.  */
+-  pcum->nregs = 0;
+-  pcum->iwmmxt_nregs = 0;
+-  pcum->can_split = true;
+-
+-  /* Varargs vectors are treated the same as long long.
+-     named_count avoids having to change the way arm handles 'named' */
+-  pcum->named_count = 0;
+-  pcum->nargs = 0;
++  const char *arg;
++  enum arm_pcs value;
++} pcs_attribute_args[] =
++  {
++    {"aapcs", ARM_PCS_AAPCS},
++    {"aapcs-vfp", ARM_PCS_AAPCS_VFP},
++    {"aapcs-iwmmxt", ARM_PCS_AAPCS_IWMMXT},
++    {"atpcs", ARM_PCS_ATPCS},
++    {"apcs", ARM_PCS_APCS},
++    {NULL, ARM_PCS_UNKNOWN}
++  };
+-  if (TARGET_REALLY_IWMMXT && fntype)
+-    {
+-      tree fn_arg;
++static enum arm_pcs
++arm_pcs_from_attribute (tree attr)
++{
++  const struct pcs_attribute_arg *ptr;
++  const char *arg;
+-      for (fn_arg = TYPE_ARG_TYPES (fntype);
+-         fn_arg;
+-         fn_arg = TREE_CHAIN (fn_arg))
+-      pcum->named_count += 1;
++  /* Get the value of the argument.  */
++  if (TREE_VALUE (attr) == NULL_TREE
++      || TREE_CODE (TREE_VALUE (attr)) != STRING_CST)
++    return ARM_PCS_UNKNOWN;
+-      if (! pcum->named_count)
+-      pcum->named_count = INT_MAX;
+-    }
+-}
++  arg = TREE_STRING_POINTER (TREE_VALUE (attr));
++  /* Check it against the list of known arguments.  */
++  for (ptr = pcs_attribute_args; ptr->arg != NULL; ptr++)
++    if (streq (arg, ptr->arg))
++      return ptr->value;
+-/* Return true if mode/type need doubleword alignment.  */
+-bool
+-arm_needs_doubleword_align (enum machine_mode mode, tree type)
+-{
+-  return (GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY
+-        || (type && TYPE_ALIGN (type) > PARM_BOUNDARY));
++  /* An unrecognized interrupt type.  */
++  return ARM_PCS_UNKNOWN;
+ }
++/* Get the PCS variant to use for this call.  TYPE is the function's type
++   specification, DECL is the specific declartion.  DECL may be null if
++   the call could be indirect or if this is a library call.  */
++static enum arm_pcs
++arm_get_pcs_model (const_tree type, const_tree decl)
++{
++  bool user_convention = false;
++  enum arm_pcs user_pcs = arm_pcs_default;
++  tree attr;
+-/* Determine where to put an argument to a function.
+-   Value is zero to push the argument on the stack,
+-   or a hard register in which to store the argument.
++  gcc_assert (type);
+-   MODE is the argument's machine mode.
+-   TYPE is the data type of the argument (as a tree).
+-    This is null for libcalls where that information may
+-    not be available.
+-   CUM is a variable of type CUMULATIVE_ARGS which gives info about
+-    the preceding args and about the function being called.
+-   NAMED is nonzero if this argument is a named parameter
+-    (otherwise it is an extra parameter matching an ellipsis).  */
++  attr = lookup_attribute ("pcs", TYPE_ATTRIBUTES (type));
++  if (attr)
++    {
++      user_pcs = arm_pcs_from_attribute (TREE_VALUE (attr));
++      user_convention = true;
++    }
++
++  if (TARGET_AAPCS_BASED)
++    {
++      /* Detect varargs functions.  These always use the base rules
++       (no argument is ever a candidate for a co-processor
++       register).  */
++      bool base_rules = (TYPE_ARG_TYPES (type) != 0
++                       && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (type)))
++                           != void_type_node));
++      
++      if (user_convention)
++      {
++        if (user_pcs > ARM_PCS_AAPCS_LOCAL)
++          sorry ("Non-AAPCS derived PCS variant");
++        else if (base_rules && user_pcs != ARM_PCS_AAPCS)
++          error ("Variadic functions must use the base AAPCS variant");
++      }
++
++      if (base_rules)
++      return ARM_PCS_AAPCS;
++      else if (user_convention)
++      return user_pcs;
++      else if (decl && flag_unit_at_a_time)
++      {
++        /* Local functions never leak outside this compilation unit,
++           so we are free to use whatever conventions are
++           appropriate.  */
++        /* FIXME: remove CONST_CAST_TREE when cgraph is constified.  */
++        struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE(decl));
++        if (i && i->local)
++          return ARM_PCS_AAPCS_LOCAL;
++      }
++    }
++  else if (user_convention && user_pcs != arm_pcs_default)
++    sorry ("PCS variant");
++
++  /* For everything else we use the target's default.  */
++  return arm_pcs_default;
++}
++
++
++static void
++aapcs_vfp_cum_init (CUMULATIVE_ARGS *pcum  ATTRIBUTE_UNUSED,
++                  const_tree fntype ATTRIBUTE_UNUSED,
++                  rtx libcall ATTRIBUTE_UNUSED, 
++                  const_tree fndecl ATTRIBUTE_UNUSED)
++{
++  /* Record the unallocated VFP registers.  */
++  pcum->aapcs_vfp_regs_free = (1 << NUM_VFP_ARG_REGS) - 1;
++  pcum->aapcs_vfp_reg_alloc = 0;
++}
++
++/* Walk down the type tree of TYPE counting consecutive base elements.
++   If *MODEP is VOIDmode, then set it to the first valid floating point
++   type.  If a non-floating point type is found, or if a floating point
++   type that doesn't match a non-VOIDmode *MODEP is found, then return -1,
++   otherwise return the count in the sub-tree.  */
++static int
++aapcs_vfp_sub_candidate (const_tree type, enum machine_mode *modep)
++{
++  enum machine_mode mode;
++  HOST_WIDE_INT size;
++
++  switch (TREE_CODE (type))
++    {
++    case REAL_TYPE:
++      mode = TYPE_MODE (type);
++      if (mode != DFmode && mode != SFmode)
++      return -1;
++
++      if (*modep == VOIDmode)
++      *modep = mode;
++
++      if (*modep == mode)
++      return 1;
++
++      break;
++
++    case COMPLEX_TYPE:
++      mode = TYPE_MODE (TREE_TYPE (type));
++      if (mode != DFmode && mode != SFmode)
++      return -1;
++
++      if (*modep == VOIDmode)
++      *modep = mode;
++
++      if (*modep == mode)
++      return 2;
++
++      break;
++
++    case VECTOR_TYPE:
++      /* Use V2SImode and V4SImode as representatives of all 64-bit
++       and 128-bit vector types, whether or not those modes are
++       supported with the present options.  */
++      size = int_size_in_bytes (type);
++      switch (size)
++      {
++      case 8:
++        mode = V2SImode;
++        break;
++      case 16:
++        mode = V4SImode;
++        break;
++      default:
++        return -1;
++      }
++
++      if (*modep == VOIDmode)
++      *modep = mode;
++
++      /* Vector modes are considered to be opaque: two vectors are
++       equivalent for the purposes of being homogeneous aggregates
++       if they are the same size.  */
++      if (*modep == mode)
++      return 1;
++
++      break;
++
++    case ARRAY_TYPE:
++      {
++      int count;
++      tree index = TYPE_DOMAIN (type);
++
++      /* Can't handle incomplete types.  */
++      if (!COMPLETE_TYPE_P(type))
++        return -1;
++
++      count = aapcs_vfp_sub_candidate (TREE_TYPE (type), modep);
++      if (count == -1
++          || !index
++          || !TYPE_MAX_VALUE (index)
++          || !host_integerp (TYPE_MAX_VALUE (index), 1)
++          || !TYPE_MIN_VALUE (index)
++          || !host_integerp (TYPE_MIN_VALUE (index), 1)
++          || count < 0)
++        return -1;
++
++      count *= (1 + tree_low_cst (TYPE_MAX_VALUE (index), 1)
++                    - tree_low_cst (TYPE_MIN_VALUE (index), 1));
++
++      /* There must be no padding.  */
++      if (!host_integerp (TYPE_SIZE (type), 1)
++          || (tree_low_cst (TYPE_SIZE (type), 1)
++              != count * GET_MODE_BITSIZE (*modep)))
++        return -1;
++
++      return count;
++      }
++      
++    case RECORD_TYPE:
++      {
++      int count = 0;
++      int sub_count;
++      tree field;
++
++      /* Can't handle incomplete types.  */
++      if (!COMPLETE_TYPE_P(type))
++        return -1;
++
++      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
++        {
++          if (TREE_CODE (field) != FIELD_DECL)
++            continue;
++
++          sub_count = aapcs_vfp_sub_candidate (TREE_TYPE (field), modep);
++          if (sub_count < 0)
++            return -1;
++          count += sub_count;
++        }
++
++      /* There must be no padding.  */
++      if (!host_integerp (TYPE_SIZE (type), 1)
++          || (tree_low_cst (TYPE_SIZE (type), 1)
++              != count * GET_MODE_BITSIZE (*modep)))
++        return -1;
++
++      return count;
++      }
++
++    case UNION_TYPE:
++    case QUAL_UNION_TYPE:
++      {
++      /* These aren't very interesting except in a degenerate case.  */
++      int count = 0;
++      int sub_count;
++      tree field;
++
++      /* Can't handle incomplete types.  */
++      if (!COMPLETE_TYPE_P(type))
++        return -1;
++
++      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
++        {
++          if (TREE_CODE (field) != FIELD_DECL)
++            continue;
++
++          sub_count = aapcs_vfp_sub_candidate (TREE_TYPE (field), modep);
++          if (sub_count < 0)
++            return -1;
++          count = count > sub_count ? count : sub_count;
++        }
++
++      /* There must be no padding.  */
++      if (!host_integerp (TYPE_SIZE (type), 1)
++          || (tree_low_cst (TYPE_SIZE (type), 1)
++              != count * GET_MODE_BITSIZE (*modep)))
++        return -1;
++
++      return count;
++      }
++
++    default:
++      break;
++    }
++
++  return -1;
++}
++
++static bool
++aapcs_vfp_is_call_or_return_candidate (enum machine_mode mode, const_tree type,
++                                     int *base_mode,
++                                     int *count)
++{
++  if (GET_MODE_CLASS (mode) == MODE_FLOAT
++      || GET_MODE_CLASS (mode) == MODE_VECTOR_INT
++      || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
++    {
++      *count = 1;
++      *base_mode = mode;
++      return true;
++    }
++  else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
++    {
++      *count = 2;
++      *base_mode = (mode == DCmode ? DFmode : SFmode);
++      return true;
++    }
++  else if (type && (mode == BLKmode || TREE_CODE (type) == VECTOR_TYPE))
++    {
++      enum machine_mode aggregate_mode = VOIDmode;
++      int ag_count = aapcs_vfp_sub_candidate (type, &aggregate_mode);
++
++      if (ag_count > 0 && ag_count <= 4)
++      {
++        *count = ag_count;
++        *base_mode = aggregate_mode;
++        return true;
++      }
++    }
++  return false;
++}
++
++static bool
++aapcs_vfp_is_return_candidate (enum arm_pcs pcs_variant,
++                             enum machine_mode mode, const_tree type)
++{
++  int count ATTRIBUTE_UNUSED;
++  int ag_mode ATTRIBUTE_UNUSED;
++
++  if (!(pcs_variant == ARM_PCS_AAPCS_VFP
++      || (pcs_variant == ARM_PCS_AAPCS_LOCAL
++          && TARGET_32BIT && TARGET_VFP && TARGET_HARD_FLOAT)))
++    return false;
++  return aapcs_vfp_is_call_or_return_candidate (mode, type, &ag_mode, &count);
++}
++
++static bool
++aapcs_vfp_is_call_candidate (CUMULATIVE_ARGS *pcum, enum machine_mode mode, 
++                           const_tree type)
++{
++  if (!(pcum->pcs_variant == ARM_PCS_AAPCS_VFP
++      || (pcum->pcs_variant == ARM_PCS_AAPCS_LOCAL
++          && TARGET_32BIT && TARGET_VFP && TARGET_HARD_FLOAT)))
++    return false;
++  return aapcs_vfp_is_call_or_return_candidate (mode, type,
++                                              &pcum->aapcs_vfp_rmode,
++                                              &pcum->aapcs_vfp_rcount);
++}
++
++static bool
++aapcs_vfp_allocate (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
++                  const_tree type  ATTRIBUTE_UNUSED)
++{
++  int shift = GET_MODE_SIZE (pcum->aapcs_vfp_rmode) / GET_MODE_SIZE (SFmode);
++  unsigned mask = (1 << (shift * pcum->aapcs_vfp_rcount)) - 1;
++  int regno;
++  
++  for (regno = 0; regno < NUM_VFP_ARG_REGS; regno += shift)
++    if (((pcum->aapcs_vfp_regs_free >> regno) & mask) == mask)
++      {
++      pcum->aapcs_vfp_reg_alloc = mask << regno;
++      if (mode == BLKmode || (mode == TImode && !TARGET_NEON))
++        {
++          int i;
++          int rcount = pcum->aapcs_vfp_rcount;
++          int rshift = shift;
++          enum machine_mode rmode = pcum->aapcs_vfp_rmode;
++          rtx par;
++          if (!TARGET_NEON)
++            {
++              /* Avoid using unsupported vector modes.  */
++              if (rmode == V2SImode)
++                rmode = DImode;
++              else if (rmode == V4SImode)
++                {
++                  rmode = DImode;
++                  rcount *= 2;
++                  rshift /= 2;
++                }
++            }
++          par = gen_rtx_PARALLEL (mode, rtvec_alloc (rcount));
++          for (i = 0; i < rcount; i++)
++            {
++              rtx tmp = gen_rtx_REG (rmode, 
++                                     FIRST_VFP_REGNUM + regno + i * rshift);
++              tmp = gen_rtx_EXPR_LIST
++                (VOIDmode, tmp, 
++                 GEN_INT (i * GET_MODE_SIZE (rmode)));
++              XVECEXP (par, 0, i) = tmp;
++            }
++
++          pcum->aapcs_reg = par;
++        }
++      else
++        pcum->aapcs_reg = gen_rtx_REG (mode, FIRST_VFP_REGNUM + regno);
++      return true;
++      }
++  return false;
++}
++
++static rtx
++aapcs_vfp_allocate_return_reg (enum arm_pcs pcs_variant ATTRIBUTE_UNUSED,
++                             enum machine_mode mode,
++                             const_tree type ATTRIBUTE_UNUSED)
++{
++  if (!(pcs_variant == ARM_PCS_AAPCS_VFP
++      || (pcs_variant == ARM_PCS_AAPCS_LOCAL
++          && TARGET_32BIT && TARGET_VFP && TARGET_HARD_FLOAT)))
++    return false;
++  if (mode == BLKmode || (mode == TImode && !TARGET_NEON))
++    {
++      int count;
++      int ag_mode;
++      int i;
++      rtx par;
++      int shift;
++      
++      aapcs_vfp_is_call_or_return_candidate (mode, type, &ag_mode, &count);
++
++      if (!TARGET_NEON)
++      {
++        if (ag_mode == V2SImode)
++          ag_mode = DImode;
++        else if (ag_mode == V4SImode)
++          {
++            ag_mode = DImode;
++            count *= 2;
++          }
++      }
++      shift = GET_MODE_SIZE(ag_mode) / GET_MODE_SIZE(SFmode);
++      par = gen_rtx_PARALLEL (mode, rtvec_alloc (count));
++      for (i = 0; i < count; i++)
++      {
++        rtx tmp = gen_rtx_REG (ag_mode, FIRST_VFP_REGNUM + i * shift);
++        tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, 
++                                 GEN_INT (i * GET_MODE_SIZE (ag_mode)));
++        XVECEXP (par, 0, i) = tmp;
++      }
++
++      return par;
++    }
++
++  return gen_rtx_REG (mode, FIRST_VFP_REGNUM);
++}
++
++static void
++aapcs_vfp_advance (CUMULATIVE_ARGS *pcum  ATTRIBUTE_UNUSED,
++                 enum machine_mode mode  ATTRIBUTE_UNUSED,
++                 const_tree type  ATTRIBUTE_UNUSED)
++{
++  pcum->aapcs_vfp_regs_free &= ~pcum->aapcs_vfp_reg_alloc;
++  pcum->aapcs_vfp_reg_alloc = 0;
++  return;
++}
++
++#define AAPCS_CP(X)                           \
++  {                                           \
++    aapcs_ ## X ## _cum_init,                 \
++    aapcs_ ## X ## _is_call_candidate,                \
++    aapcs_ ## X ## _allocate,                 \
++    aapcs_ ## X ## _is_return_candidate,      \
++    aapcs_ ## X ## _allocate_return_reg,      \
++    aapcs_ ## X ## _advance                   \
++  }
++
++/* Table of co-processors that can be used to pass arguments in
++   registers.  Idealy no arugment should be a candidate for more than
++   one co-processor table entry, but the table is processed in order
++   and stops after the first match.  If that entry then fails to put
++   the argument into a co-processor register, the argument will go on
++   the stack.  */
++static struct 
++{
++  /* Initialize co-processor related state in CUMULATIVE_ARGS structure.  */
++  void (*cum_init) (CUMULATIVE_ARGS *, const_tree, rtx, const_tree);
++
++  /* Return true if an argument of mode MODE (or type TYPE if MODE is
++     BLKmode) is a candidate for this co-processor's registers; this
++     function should ignore any position-dependent state in
++     CUMULATIVE_ARGS and only use call-type dependent information.  */
++  bool (*is_call_candidate) (CUMULATIVE_ARGS *, enum machine_mode, const_tree);
++
++  /* Return true if the argument does get a co-processor register; it
++     should set aapcs_reg to an RTX of the register allocated as is
++     required for a return from FUNCTION_ARG.  */
++  bool (*allocate) (CUMULATIVE_ARGS *, enum machine_mode, const_tree);
++
++  /* Return true if a result of mode MODE (or type TYPE if MODE is
++     BLKmode) is can be returned in this co-processor's registers.  */
++  bool (*is_return_candidate) (enum arm_pcs, enum machine_mode, const_tree);
++
++  /* Allocate and return an RTX element to hold the return type of a
++     call, this routine must not fail and will only be called if
++     is_return_candidate returned true with the same parameters.  */
++  rtx (*allocate_return_reg) (enum arm_pcs, enum machine_mode, const_tree);
++
++  /* Finish processing this argument and prepare to start processing
++     the next one.  */
++  void (*advance) (CUMULATIVE_ARGS *, enum machine_mode, const_tree);
++} aapcs_cp_arg_layout[ARM_NUM_COPROC_SLOTS] =
++  {
++    AAPCS_CP(vfp)
++  };
++
++#undef AAPCS_CP
++
++static int
++aapcs_select_call_coproc (CUMULATIVE_ARGS *pcum, enum machine_mode mode, 
++                        tree type)
++{
++  int i;
++
++  for (i = 0; i < ARM_NUM_COPROC_SLOTS; i++)
++    if (aapcs_cp_arg_layout[i].is_call_candidate (pcum, mode, type))
++      return i;
++
++  return -1;
++}
++
++static int
++aapcs_select_return_coproc (const_tree type, const_tree fntype)
++{
++  /* We aren't passed a decl, so we can't check that a call is local.
++     However, it isn't clear that that would be a win anyway, since it
++     might limit some tail-calling opportunities.  */
++  enum arm_pcs pcs_variant;
++
++  if (fntype)
++    {
++      const_tree fndecl = NULL_TREE;
++
++      if (TREE_CODE (fntype) == FUNCTION_DECL)
++      {
++        fndecl = fntype;
++        fntype = TREE_TYPE (fntype);
++      }
++
++      pcs_variant = arm_get_pcs_model (fntype, fndecl);
++    }
++  else
++    pcs_variant = arm_pcs_default;
++
++  if (pcs_variant != ARM_PCS_AAPCS)
++    {
++      int i;
++
++      for (i = 0; i < ARM_NUM_COPROC_SLOTS; i++)
++      if (aapcs_cp_arg_layout[i].is_return_candidate (pcs_variant, 
++                                                      TYPE_MODE (type),
++                                                      type))
++        return i;
++    }
++  return -1;
++}
++
++static rtx
++aapcs_allocate_return_reg (enum machine_mode mode, const_tree type,
++                         const_tree fntype)
++{
++  /* We aren't passed a decl, so we can't check that a call is local.
++     However, it isn't clear that that would be a win anyway, since it
++     might limit some tail-calling opportunities.  */
++  enum arm_pcs pcs_variant;
++
++  if (fntype)
++    {
++      const_tree fndecl = NULL_TREE;
++
++      if (TREE_CODE (fntype) == FUNCTION_DECL)
++      {
++        fndecl = fntype;
++        fntype = TREE_TYPE (fntype);
++      }
++
++      pcs_variant = arm_get_pcs_model (fntype, fndecl);
++    }
++  else
++    pcs_variant = arm_pcs_default;
++
++  /* Promote integer types.  */
++  if (type && INTEGRAL_TYPE_P (type))
++    PROMOTE_FUNCTION_MODE (mode, unsignedp, type);
++
++  if (pcs_variant != ARM_PCS_AAPCS)
++    {
++      int i;
++
++      for (i = 0; i < ARM_NUM_COPROC_SLOTS; i++)
++      if (aapcs_cp_arg_layout[i].is_return_candidate (pcs_variant, mode,
++                                                      type))
++        return aapcs_cp_arg_layout[i].allocate_return_reg (pcs_variant,
++                                                           mode, type);
++    }
++
++  /* Promotes small structs returned in a register to full-word size
++     for big-endian AAPCS.  */
++  if (type && arm_return_in_msb (type))
++    {
++      HOST_WIDE_INT size = int_size_in_bytes (type);
++      if (size % UNITS_PER_WORD != 0)
++      {
++        size += UNITS_PER_WORD - size % UNITS_PER_WORD;
++        mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
++      }
++    }
++
++  return gen_rtx_REG (mode, R0_REGNUM);
++}
++
++rtx
++aapcs_libcall_value (enum machine_mode mode)
++{
++  return aapcs_allocate_return_reg (mode, NULL_TREE, NULL_TREE);
++}
++
++/* Lay out a function argument using the AAPCS rules.  The rule
++   numbers referred to here are those in the AAPCS.  */
++static void
++aapcs_layout_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
++                tree type, int named)
++{
++  int nregs, nregs2;
++  int ncrn;
++
++  /* We only need to do this once per argument.  */
++  if (pcum->aapcs_arg_processed)
++    return;
++
++  pcum->aapcs_arg_processed = true;
++
++  /* Special case: if named is false then we are handling an incoming
++     anonymous argument which is on the stack.  */
++  if (!named)
++    return;
++  
++  /* Is this a potential co-processor register candidate?  */
++  if (pcum->pcs_variant != ARM_PCS_AAPCS)
++    {
++      pcum->aapcs_cprc_slot = aapcs_select_call_coproc (pcum, mode, type);
++
++      /* We don't have to apply any of the rules from part B of the
++       preparation phase, these are handled elsewhere in the
++       compiler.  */
++
++      if (pcum->aapcs_cprc_slot >= 0)
++      {
++        if (!pcum->aapcs_cprc_failed[pcum->aapcs_cprc_slot])
++          {
++            /* C1.cp - Try to allocate the argument to co-processor
++               registers.  */
++            if (aapcs_cp_arg_layout[pcum->aapcs_cprc_slot].allocate (pcum,
++                                                                     mode,
++                                                                     type))
++              return;
++            /* C2.cp - Put the argument on the stack and note that we
++               can't assign any more candidates in this slot.  We also
++               need to note that we have allocated stack space, so that
++               we won't later try to split a non-cprc candidate between
++               core registers and the stack.  */
++            pcum->aapcs_cprc_failed[pcum->aapcs_cprc_slot] = true;
++            pcum->can_split = false;
++            return;
++          }
++        else
++          {
++            /* Subsequent cprc candidates after one that was not
++               allocated to coprocessor registers cannot go in core
++               registers either.  */
++            pcum->can_split = false;
++            return;
++          }
++      }
++    }
++
++  /* C3 - For double-word aligned arguments, round the NCRN up to the
++     next even number.  */
++  ncrn = pcum->aapcs_ncrn;
++  if ((ncrn & 1) && arm_needs_doubleword_align (mode, type))
++    ncrn++;
++
++  nregs = ARM_NUM_REGS2(mode, type);
++
++  /* Sigh, this test should really assert that nregs > 0, but a GCC
++     extension allows empty structs and then gives them empty size; it
++     then allows such a structure to be passed by value.  For some of
++     the code below we have to pretend that such an argument has
++     non-zero size so that we 'locate' it correctly either in
++     registers or on the stack.  */
++  gcc_assert (nregs >= 0);
++
++  nregs2 = nregs ? nregs : 1;
++
++  /* C4 - Argument fits entirely in core registers.  */
++  if (ncrn + nregs2 <= NUM_ARG_REGS)
++    {
++      pcum->aapcs_reg = gen_rtx_REG (mode, ncrn);
++      pcum->aapcs_next_ncrn = ncrn + nregs;
++      return;
++    }
++
++  /* C5 - Some core registers left and there are no arguments already
++     on the stack: split this argument between the remaining core
++     registers and the stack.  */
++  if (ncrn < NUM_ARG_REGS && pcum->can_split)
++    {
++      pcum->aapcs_reg = gen_rtx_REG (mode, ncrn);
++      pcum->aapcs_next_ncrn = NUM_ARG_REGS;
++      pcum->aapcs_partial = (NUM_ARG_REGS - ncrn) * UNITS_PER_WORD;
++      return;
++    }
++
++  /* C6 - NCRN is set to 4.  */
++  pcum->aapcs_next_ncrn = NUM_ARG_REGS;
++
++  /* C7,C8 - arugment goes on the stack.  We have nothing to do here.  */
++  return;
++}
++
++/* Initialize a variable CUM of type CUMULATIVE_ARGS
++   for a call to a function whose data type is FNTYPE.
++   For a library call, FNTYPE is NULL.  */
++void
++arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
++                        rtx libname,
++                        tree fndecl ATTRIBUTE_UNUSED)
++{
++  /* Long call handling.  */
++  if (fntype)
++    pcum->pcs_variant = arm_get_pcs_model (fntype, fndecl);
++  else
++    pcum->pcs_variant = arm_pcs_default;
++
++  if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
++    {
++      /* XXX We should also detect some library calls here and handle
++       them using the base rules too; for example the floating point
++       support functions always work this way.  */
++
++      if (rtx_equal_p (libname,
++                     convert_optab_libfunc (sfix_optab, DImode, DFmode))
++        || rtx_equal_p (libname,
++                        convert_optab_libfunc (ufix_optab, DImode, DFmode))
++        || rtx_equal_p (libname,
++                        convert_optab_libfunc (sfix_optab, DImode, SFmode))
++        || rtx_equal_p (libname,
++                        convert_optab_libfunc (ufix_optab, DImode, SFmode))
++        || rtx_equal_p (libname,
++                        convert_optab_libfunc (trunc_optab, HFmode, SFmode))
++        || rtx_equal_p (libname,
++                        convert_optab_libfunc (sext_optab, SFmode, HFmode)))
++      pcum->pcs_variant = ARM_PCS_AAPCS;
++
++      pcum->aapcs_ncrn = pcum->aapcs_next_ncrn = 0;
++      pcum->aapcs_reg = NULL_RTX;
++      pcum->aapcs_partial = 0;
++      pcum->aapcs_arg_processed = false;
++      pcum->aapcs_cprc_slot = -1;
++      pcum->can_split = true;
++
++      if (pcum->pcs_variant != ARM_PCS_AAPCS)
++      {
++        int i;
++
++        for (i = 0; i < ARM_NUM_COPROC_SLOTS; i++)
++          {
++            pcum->aapcs_cprc_failed[i] = false;
++            aapcs_cp_arg_layout[i].cum_init (pcum, fntype, libname, fndecl);
++          }
++      }
++      return;
++    }
++
++  /* Legacy ABIs */
++
++  /* On the ARM, the offset starts at 0.  */
++  pcum->nregs = 0;
++  pcum->iwmmxt_nregs = 0;
++  pcum->can_split = true;
++
++  /* Varargs vectors are treated the same as long long.
++     named_count avoids having to change the way arm handles 'named' */
++  pcum->named_count = 0;
++  pcum->nargs = 0;
++
++  if (TARGET_REALLY_IWMMXT && fntype)
++    {
++      tree fn_arg;
++
++      for (fn_arg = TYPE_ARG_TYPES (fntype);
++         fn_arg;
++         fn_arg = TREE_CHAIN (fn_arg))
++      pcum->named_count += 1;
++
++      if (! pcum->named_count)
++      pcum->named_count = INT_MAX;
++    }
++}
++
++
++/* Return true if mode/type need doubleword alignment.  */
++bool
++arm_needs_doubleword_align (enum machine_mode mode, tree type)
++{
++  return (GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY
++        || (type && TYPE_ALIGN (type) > PARM_BOUNDARY));
++}
++
++
++/* Determine where to put an argument to a function.
++   Value is zero to push the argument on the stack,
++   or a hard register in which to store the argument.
++
++   MODE is the argument's machine mode.
++   TYPE is the data type of the argument (as a tree).
++    This is null for libcalls where that information may
++    not be available.
++   CUM is a variable of type CUMULATIVE_ARGS which gives info about
++    the preceding args and about the function being called.
++   NAMED is nonzero if this argument is a named parameter
++    (otherwise it is an extra parameter matching an ellipsis).  */
+ rtx
+ arm_function_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
+@@ -2925,6 +4135,17 @@ arm_function_arg (CUMULATIVE_ARGS *pcum,
+ {
+   int nregs;
++  /* Handle the special case quickly.  Pick an arbitrary value for op2 of
++     a call insn (op3 of a call_value insn).  */
++  if (mode == VOIDmode)
++    return const0_rtx;
++
++  if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
++    {
++      aapcs_layout_arg (pcum, mode, type, named);
++      return pcum->aapcs_reg;
++    }
++
+   /* Varargs vectors are treated the same as long long.
+      named_count avoids having to change the way arm handles 'named' */
+   if (TARGET_IWMMXT_ABI
+@@ -2966,10 +4187,16 @@ arm_function_arg (CUMULATIVE_ARGS *pcum,
+ static int
+ arm_arg_partial_bytes (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
+-                     tree type, bool named ATTRIBUTE_UNUSED)
++                     tree type, bool named)
+ {
+   int nregs = pcum->nregs;
++  if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
++    {
++      aapcs_layout_arg (pcum, mode, type, named);
++      return pcum->aapcs_partial;
++    }
++
+   if (TARGET_IWMMXT_ABI && arm_vector_mode_supported_p (mode))
+     return 0;
+@@ -2981,6 +4208,39 @@ arm_arg_partial_bytes (CUMULATIVE_ARGS *
+   return 0;
+ }
++void
++arm_function_arg_advance (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
++                        tree type, bool named)
++{
++  if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
++    {
++      aapcs_layout_arg (pcum, mode, type, named);
++
++      if (pcum->aapcs_cprc_slot >= 0)
++      {
++        aapcs_cp_arg_layout[pcum->aapcs_cprc_slot].advance (pcum, mode,
++                                                            type);
++        pcum->aapcs_cprc_slot = -1;
++      }
++
++      /* Generic stuff.  */
++      pcum->aapcs_arg_processed = false;
++      pcum->aapcs_ncrn = pcum->aapcs_next_ncrn;
++      pcum->aapcs_reg = NULL_RTX;
++      pcum->aapcs_partial = 0;
++    }
++  else
++    {
++      pcum->nargs += 1;
++      if (arm_vector_mode_supported_p (mode)
++        && pcum->named_count > pcum->nargs
++        && TARGET_IWMMXT_ABI)
++      pcum->iwmmxt_nregs += 1;
++      else
++      pcum->nregs += ARM_NUM_REGS2 (mode, type);
++    }
++}
++
+ /* Variable sized types are passed by reference.  This is a GCC
+    extension to the ARM ABI.  */
+@@ -3031,6 +4291,8 @@ const struct attribute_spec arm_attribut
+   /* Whereas these functions are always known to reside within the 26 bit
+      addressing range.  */
+   { "short_call",   0, 0, false, true,  true,  NULL },
++  /* Specify the procedure call conventions for a function.  */
++  { "pcs",          1, 1, false, true,  true,  arm_handle_pcs_attribute },
+   /* Interrupt Service Routines have special prologue and epilogue requirements.  */
+   { "isr",          0, 1, false, false, false, arm_handle_isr_attribute },
+   { "interrupt",    0, 1, false, false, false, arm_handle_isr_attribute },
+@@ -3133,6 +4395,21 @@ arm_handle_isr_attribute (tree *node, tr
+   return NULL_TREE;
+ }
++/* Handle a "pcs" attribute; arguments as in struct
++   attribute_spec.handler.  */
++static tree
++arm_handle_pcs_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
++                        int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
++{
++  if (arm_pcs_from_attribute (args) == ARM_PCS_UNKNOWN)
++    {
++      warning (OPT_Wattributes, "%qs attribute ignored",
++             IDENTIFIER_POINTER (name));
++      *no_add_attrs = true;
++    }
++  return NULL_TREE;
++}
++
+ #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
+ /* Handle the "notshared" attribute.  This attribute is another way of
+    requesting hidden visibility.  ARM's compiler supports
+@@ -3298,7 +4575,7 @@ arm_is_long_call_p (tree decl)
+ /* Return nonzero if it is ok to make a tail-call to DECL.  */
+ static bool
+-arm_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
++arm_function_ok_for_sibcall (tree decl, tree exp)
+ {
+   unsigned long func_type;
+@@ -3331,6 +4608,21 @@ arm_function_ok_for_sibcall (tree decl, 
+   if (IS_INTERRUPT (func_type))
+     return false;
++  if (!VOID_TYPE_P (TREE_TYPE (DECL_RESULT (cfun->decl))))
++    {
++      /* Check that the return value locations are the same.  For
++       example that we aren't returning a value from the sibling in
++       a VFP register but then need to transfer it to a core
++       register.  */
++      rtx a, b;
++
++      a = arm_function_value (TREE_TYPE (exp), decl, false);
++      b = arm_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
++                            cfun->decl, false);
++      if (!rtx_equal_p (a, b))
++      return false;
++    }
++
+   /* Never tailcall if function may be called with a misaligned SP.  */
+   if (IS_STACKALIGN (func_type))
+     return false;
+@@ -3472,10 +4764,22 @@ legitimize_pic_address (rtx orig, enum m
+         && XEXP (XEXP (orig, 0), 0) == cfun->machine->pic_reg)
+       return orig;
++      /* Handle the case where we have: const (UNSPEC_TLS).  */
+       if (GET_CODE (XEXP (orig, 0)) == UNSPEC
+         && XINT (XEXP (orig, 0), 1) == UNSPEC_TLS)
+       return orig;
++      /* Handle the case where we have:
++         const (plus (UNSPEC_TLS) (ADDEND)).  The ADDEND must be a
++         CONST_INT.  */
++      if (GET_CODE (XEXP (orig, 0)) == PLUS
++          && GET_CODE (XEXP (XEXP (orig, 0), 0)) == UNSPEC
++          && XINT (XEXP (XEXP (orig, 0), 0), 1) == UNSPEC_TLS)
++        {
++        gcc_assert (GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT);
++        return orig;
++      }
++
+       if (reg == 0)
+       {
+         gcc_assert (can_create_pseudo_p ());
+@@ -3924,6 +5228,7 @@ arm_legitimate_index_p (enum machine_mod
+   if (GET_MODE_SIZE (mode) <= 4
+       && ! (arm_arch4
+           && (mode == HImode
++              || mode == HFmode
+               || (mode == QImode && outer == SIGN_EXTEND))))
+     {
+       if (code == MULT)
+@@ -3952,13 +5257,15 @@ arm_legitimate_index_p (enum machine_mod
+      load.  */
+   if (arm_arch4)
+     {
+-      if (mode == HImode || (outer == SIGN_EXTEND && mode == QImode))
++      if (mode == HImode
++        || mode == HFmode
++        || (outer == SIGN_EXTEND && mode == QImode))
+       range = 256;
+       else
+       range = 4096;
+     }
+   else
+-    range = (mode == HImode) ? 4095 : 4096;
++    range = (mode == HImode || mode == HFmode) ? 4095 : 4096;
+   return (code == CONST_INT
+         && INTVAL (index) < range
+@@ -4129,7 +5436,8 @@ thumb1_legitimate_address_p (enum machin
+     return 1;
+   /* This is PC relative data after arm_reorg runs.  */
+-  else if (GET_MODE_SIZE (mode) >= 4 && reload_completed
++  else if ((GET_MODE_SIZE (mode) >= 4 || mode == HFmode)
++         && reload_completed
+          && (GET_CODE (x) == LABEL_REF
+              || (GET_CODE (x) == CONST
+                  && GET_CODE (XEXP (x, 0)) == PLUS
+@@ -4799,121 +6107,255 @@ thumb1_rtx_costs (rtx x, enum rtx_code c
+         return 99;
+       }
+-    default:
+-      return 99;
+-    }
+-}
++    default:
++      return 99;
++    }
++}
++
++static inline bool
++arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total)
++{
++  enum machine_mode mode = GET_MODE (x);
++  enum rtx_code subcode;
++  rtx operand;
++  enum rtx_code code = GET_CODE (x);
++  int extra_cost;
++  *total = 0;
++
++  switch (code)
++    {
++    case MEM:
++      /* Memory costs quite a lot for the first word, but subsequent words
++       load at the equivalent of a single insn each.  */
++      *total = COSTS_N_INSNS (2 + ARM_NUM_REGS (mode));
++      return true;
++
++    case DIV:
++    case MOD:
++    case UDIV:
++    case UMOD:
++      if (TARGET_HARD_FLOAT && mode == SFmode)
++      *total = COSTS_N_INSNS (2);
++      else if (TARGET_HARD_FLOAT && mode == DFmode)
++      *total = COSTS_N_INSNS (4);
++      else
++      *total = COSTS_N_INSNS (20);
++      return false;
++
++    case ROTATE:
++      if (GET_CODE (XEXP (x, 1)) == REG)
++      *total = COSTS_N_INSNS (1); /* Need to subtract from 32 */
++      else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
++      *total = rtx_cost (XEXP (x, 1), code);
++
++      /* Fall through */
++    case ROTATERT:
++      if (mode != SImode)
++      {
++        *total += COSTS_N_INSNS (4);
++        return true;
++      }
++
++      /* Fall through */
++    case ASHIFT: case LSHIFTRT: case ASHIFTRT:
++      *total += rtx_cost (XEXP (x, 0), code);
++      if (mode == DImode)
++      {
++        *total += COSTS_N_INSNS (3);
++        return true;
++      }
++
++      *total += COSTS_N_INSNS (1);
++      /* Increase the cost of complex shifts because they aren't any faster,
++         and reduce dual issue opportunities.  */
++      if (arm_tune_cortex_a9
++        && outer != SET && GET_CODE (XEXP (x, 1)) != CONST_INT)
++      ++*total;
++
++      return true;
++
++    case MINUS:
++      if (TARGET_THUMB2)
++      {
++        if (GET_MODE_CLASS (mode) == MODE_FLOAT)
++          {
++            if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
++              *total = COSTS_N_INSNS (1);
++            else
++              *total = COSTS_N_INSNS (20);
++          }
++        else
++          *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
++        /* Thumb2 does not have RSB, so all arguments must be
++           registers (subtracting a constant is canonicalized as
++           addition of the negated constant).  */
++        return false;
++      }
++
++      if (mode == DImode)
++      {
++        *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
++        if (GET_CODE (XEXP (x, 0)) == CONST_INT
++            && const_ok_for_arm (INTVAL (XEXP (x, 0))))
++          {
++            *total += rtx_cost (XEXP (x, 1), code);
++            return true;
++          }
++
++        if (GET_CODE (XEXP (x, 1)) == CONST_INT
++            && const_ok_for_arm (INTVAL (XEXP (x, 1))))
++          {
++            *total += rtx_cost (XEXP (x, 0), code);
++            return true;
++          }
++
++        return false;
++      }
++
++      if (GET_MODE_CLASS (mode) == MODE_FLOAT)
++      {
++        if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
++          {
++            *total = COSTS_N_INSNS (1);
++            if (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE
++                && arm_const_double_rtx (XEXP (x, 0)))
++              {
++                *total += rtx_cost (XEXP (x, 1), code);
++                return true;
++              }
++
++            if (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
++                && arm_const_double_rtx (XEXP (x, 1)))
++              {
++                *total += rtx_cost (XEXP (x, 0), code);
++                return true;
++              }
++
++            return false;
++          }
++        *total = COSTS_N_INSNS (20);
++        return false;
++      }
++
++      *total = COSTS_N_INSNS (1);
++      if (GET_CODE (XEXP (x, 0)) == CONST_INT
++        && const_ok_for_arm (INTVAL (XEXP (x, 0))))
++      {
++        *total += rtx_cost (XEXP (x, 1), code);
++        return true;
++      }
++      subcode = GET_CODE (XEXP (x, 1));
++      if (subcode == ASHIFT || subcode == ASHIFTRT
++        || subcode == LSHIFTRT
++        || subcode == ROTATE || subcode == ROTATERT)
++      {
++        *total += rtx_cost (XEXP (x, 0), code);
++        *total += rtx_cost (XEXP (XEXP (x, 1), 0), subcode);
++        return true;
++      }
+-/* Worker routine for arm_rtx_costs.  */
+-/* ??? This needs updating for thumb2.  */
+-static inline int
+-arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer)
+-{
+-  enum machine_mode mode = GET_MODE (x);
+-  enum rtx_code subcode;
+-  int extra_cost;
++      /* A shift as a part of RSB costs no more than RSB itself.  */
++      if (GET_CODE (XEXP (x, 0)) == MULT
++        && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
++        && ((INTVAL (XEXP (XEXP (x, 0), 1))
++             & (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0))
++      {
++        *total += rtx_cost (XEXP (XEXP (x, 0), 0), code);
++        *total += rtx_cost (XEXP (x, 1), code);
++        return true;
++      }
+-  switch (code)
+-    {
+-    case MEM:
+-      /* Memory costs quite a lot for the first word, but subsequent words
+-       load at the equivalent of a single insn each.  */
+-      return (10 + 4 * ((GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD)
+-            + (GET_CODE (x) == SYMBOL_REF
+-               && CONSTANT_POOL_ADDRESS_P (x) ? 4 : 0));
++      if (subcode == MULT
++        && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
++        && ((INTVAL (XEXP (XEXP (x, 1), 1)) &
++             (INTVAL (XEXP (XEXP (x, 1), 1)) - 1)) == 0))
++      {
++        *total += rtx_cost (XEXP (x, 0), code);
++        *total += rtx_cost (XEXP (XEXP (x, 1), 0), subcode);
++        return true;
++      }
+-    case DIV:
+-    case MOD:
+-    case UDIV:
+-    case UMOD:
+-      return optimize_size ? COSTS_N_INSNS (2) : 100;
++      if (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == RTX_COMPARE
++        || GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == RTX_COMM_COMPARE)
++      {
++        *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 0), code);
++        if (GET_CODE (XEXP (XEXP (x, 1), 0)) == REG
++            && REGNO (XEXP (XEXP (x, 1), 0)) != CC_REGNUM)
++          *total += COSTS_N_INSNS (1);
+-    case ROTATE:
+-      if (mode == SImode && GET_CODE (XEXP (x, 1)) == REG)
+-      return 4;
+-      /* Fall through */
+-    case ROTATERT:
+-      if (mode != SImode)
+-      return 8;
+-      /* Fall through */
+-    case ASHIFT: case LSHIFTRT: case ASHIFTRT:
+-      if (mode == DImode)
+-      return (8 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : 8)
+-              + ((GET_CODE (XEXP (x, 0)) == REG
+-                  || (GET_CODE (XEXP (x, 0)) == SUBREG
+-                      && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG))
+-                 ? 0 : 8));
+-      return (1 + ((GET_CODE (XEXP (x, 0)) == REG
+-                  || (GET_CODE (XEXP (x, 0)) == SUBREG
+-                      && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG))
+-                 ? 0 : 4)
+-            + ((GET_CODE (XEXP (x, 1)) == REG
+-                || (GET_CODE (XEXP (x, 1)) == SUBREG
+-                    && GET_CODE (SUBREG_REG (XEXP (x, 1))) == REG)
+-                || (GET_CODE (XEXP (x, 1)) == CONST_INT))
+-               ? 0 : 4));
++        return true;
++      }
+-    case MINUS:
+-      if (GET_CODE (XEXP (x, 1)) == MULT && mode == SImode && arm_arch_thumb2)
++      /* MLS is just as expensive as its underlying multiplication.
++       Exclude a shift by a constant, which is expressed as a
++       multiplication.  */
++      if (TARGET_32BIT && arm_arch_thumb2
++        && GET_CODE (XEXP (x, 1)) == MULT
++        && ! (GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
++              && ((INTVAL (XEXP (XEXP (x, 1), 1)) &
++                   (INTVAL (XEXP (XEXP (x, 1), 1)) - 1)) == 0)))
+       {
+-        extra_cost = rtx_cost (XEXP (x, 1), code);
+-        if (!REG_OR_SUBREG_REG (XEXP (x, 0)))
+-          extra_cost += 4 * ARM_NUM_REGS (mode);
+-        return extra_cost;
++        /* The cost comes from the cost of the multiply.  */
++        return false;
+       }
+-      if (mode == DImode)
+-      return (4 + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 8)
+-              + ((REG_OR_SUBREG_REG (XEXP (x, 0))
+-                  || (GET_CODE (XEXP (x, 0)) == CONST_INT
+-                     && const_ok_for_arm (INTVAL (XEXP (x, 0)))))
+-                 ? 0 : 8));
+-
+-      if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+-      return (2 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
+-                    || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
+-                        && arm_const_double_rtx (XEXP (x, 1))))
+-                   ? 0 : 8)
+-              + ((REG_OR_SUBREG_REG (XEXP (x, 0))
+-                  || (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE
+-                      && arm_const_double_rtx (XEXP (x, 0))))
+-                 ? 0 : 8));
+-
+-      if (((GET_CODE (XEXP (x, 0)) == CONST_INT
+-          && const_ok_for_arm (INTVAL (XEXP (x, 0)))
+-          && REG_OR_SUBREG_REG (XEXP (x, 1))))
+-        || (((subcode = GET_CODE (XEXP (x, 1))) == ASHIFT
+-             || subcode == ASHIFTRT || subcode == LSHIFTRT
+-             || subcode == ROTATE || subcode == ROTATERT
+-             || (subcode == MULT
+-                 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
+-                 && ((INTVAL (XEXP (XEXP (x, 1), 1)) &
+-                      (INTVAL (XEXP (XEXP (x, 1), 1)) - 1)) == 0)))
+-            && REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 0))
+-            && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 1))
+-                || GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT)
+-            && REG_OR_SUBREG_REG (XEXP (x, 0))))
+-      return 1;
+       /* Fall through */
+     case PLUS:
+-      if (GET_CODE (XEXP (x, 0)) == MULT)
++      if (code == PLUS && arm_arch6 && mode == SImode
++        && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
++            || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND))
++      {
++        *total = COSTS_N_INSNS (1);
++        *total += rtx_cost (XEXP (XEXP (x, 0), 0), GET_CODE (XEXP (x, 0)));
++        *total += rtx_cost (XEXP (x, 1), code);
++        return true;
++      }
++
++      /* MLA: All arguments must be registers.  We filter out
++       multiplication by a power of two, so that we fall down into
++       the code below.  */
++      if (GET_CODE (XEXP (x, 0)) == MULT
++        && ! (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
++              && ((INTVAL (XEXP (XEXP (x, 0), 1)) &
++                   (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0)))
+       {
+-        extra_cost = rtx_cost (XEXP (x, 0), code);
+-        if (!REG_OR_SUBREG_REG (XEXP (x, 1)))
+-          extra_cost += 4 * ARM_NUM_REGS (mode);
+-        return extra_cost;
++        /* The cost comes from the cost of the multiply.  */
++        return false;
+       }
+       if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+-      return (2 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8)
+-              + ((REG_OR_SUBREG_REG (XEXP (x, 1))
+-                  || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
+-                      && arm_const_double_rtx (XEXP (x, 1))))
+-                 ? 0 : 8));
++      {
++        if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
++          {
++            *total = COSTS_N_INSNS (1);
++            if (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
++                && arm_const_double_rtx (XEXP (x, 1)))
++              {
++                *total += rtx_cost (XEXP (x, 0), code);
++                return true;
++              }
++
++            return false;
++          }
++
++        *total = COSTS_N_INSNS (20);
++        return false;
++      }
++
++      if (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == RTX_COMPARE
++        || GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == RTX_COMM_COMPARE)
++      {
++        *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 1), code);
++        if (GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
++            && REGNO (XEXP (XEXP (x, 0), 0)) != CC_REGNUM)
++          *total += COSTS_N_INSNS (1);
++        return true;
++      }
+       /* Fall through */
++
+     case AND: case XOR: case IOR:
+       extra_cost = 0;
+@@ -4927,37 +6369,56 @@ arm_rtx_costs_1 (rtx x, enum rtx_code co
+          && GET_CODE (XEXP (x, 1)) != CONST_INT)
+         || (REG_OR_SUBREG_REG (XEXP (x, 0))
+             && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0)))))
+-      extra_cost = 4;
++      *total = 4;
+       if (mode == DImode)
+-      return (4 + extra_cost + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8)
+-              + ((REG_OR_SUBREG_REG (XEXP (x, 1))
+-                  || (GET_CODE (XEXP (x, 1)) == CONST_INT
+-                      && const_ok_for_op (INTVAL (XEXP (x, 1)), code)))
+-                 ? 0 : 8));
+-
+-      if (REG_OR_SUBREG_REG (XEXP (x, 0)))
+-      return (1 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : extra_cost)
+-              + ((REG_OR_SUBREG_REG (XEXP (x, 1))
+-                  || (GET_CODE (XEXP (x, 1)) == CONST_INT
+-                      && const_ok_for_op (INTVAL (XEXP (x, 1)), code)))
+-                 ? 0 : 4));
+-
+-      else if (REG_OR_SUBREG_REG (XEXP (x, 1)))
+-      return (1 + extra_cost
+-              + ((((subcode = GET_CODE (XEXP (x, 0))) == ASHIFT
+-                   || subcode == LSHIFTRT || subcode == ASHIFTRT
+-                   || subcode == ROTATE || subcode == ROTATERT
+-                   || (subcode == MULT
+-                       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+-                       && ((INTVAL (XEXP (XEXP (x, 0), 1)) &
+-                            (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0)))
+-                  && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 0)))
+-                  && ((REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 1)))
+-                      || GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
+-                 ? 0 : 4));
++      {
++        *total += COSTS_N_INSNS (2);
++        if (GET_CODE (XEXP (x, 1)) == CONST_INT
++            && const_ok_for_op (INTVAL (XEXP (x, 1)), code))
++          {
++            *total += rtx_cost (XEXP (x, 0), code);
++            return true;
++          }
+-      return 8;
++        return false;
++      }
++
++      *total += COSTS_N_INSNS (1);
++      if (GET_CODE (XEXP (x, 1)) == CONST_INT
++        && const_ok_for_op (INTVAL (XEXP (x, 1)), code))
++      {
++        *total += rtx_cost (XEXP (x, 0), code);
++        return true;
++      }
++      subcode = GET_CODE (XEXP (x, 0));
++      if (subcode == ASHIFT || subcode == ASHIFTRT
++        || subcode == LSHIFTRT
++        || subcode == ROTATE || subcode == ROTATERT)
++      {
++        *total += rtx_cost (XEXP (x, 1), code);
++        *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode);
++        return true;
++      }
++
++      if (subcode == MULT
++        && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
++        && ((INTVAL (XEXP (XEXP (x, 0), 1)) &
++             (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0))
++      {
++        *total += rtx_cost (XEXP (x, 1), code);
++        *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode);
++        return true;
++      }
++
++      if (subcode == UMIN || subcode == UMAX
++        || subcode == SMIN || subcode == SMAX)
++      {
++        *total = COSTS_N_INSNS (3);
++        return true;
++      }
++
++      return false;
+     case MULT:
+       /* This should have been handled by the CPU specific routines.  */
+@@ -4971,90 +6432,281 @@ arm_rtx_costs_1 (rtx x, enum rtx_code co
+             == GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)))
+         && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ZERO_EXTEND
+             || GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SIGN_EXTEND))
+-      return 8;
+-      return 99;
++      {
++        *total = rtx_cost (XEXP (XEXP (x, 0), 0), LSHIFTRT);
++        return true;
++      }
++      *total = COSTS_N_INSNS (2); /* Plus the cost of the MULT */
++      return false;
+     case NEG:
+       if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+-      return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 6);
++      {
++        if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
++          {
++            *total = COSTS_N_INSNS (1);
++            return false;
++          }
++        *total = COSTS_N_INSNS (2);
++        return false;
++      }
++
+       /* Fall through */
+     case NOT:
+-      if (mode == DImode)
+-      return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4);
++      *total = COSTS_N_INSNS (ARM_NUM_REGS(mode));
++      if (mode == SImode && code == NOT)
++      {
++        subcode = GET_CODE (XEXP (x, 0));
++        if (subcode == ASHIFT || subcode == ASHIFTRT
++            || subcode == LSHIFTRT
++            || subcode == ROTATE || subcode == ROTATERT
++            || (subcode == MULT
++                && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
++                && ((INTVAL (XEXP (XEXP (x, 0), 1)) & 
++                     (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0)))
++          {
++            *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode);
++            /* Register shifts cost an extra cycle.  */
++            if (GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
++              *total += COSTS_N_INSNS (1) + rtx_cost (XEXP (XEXP (x, 0), 1),
++                                                      subcode);
++            return true;
++          }
++      }
+-      return 1 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4);
++      return false;
+     case IF_THEN_ELSE:
+       if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
+-      return 14;
+-      return 2;
++      {
++        *total = COSTS_N_INSNS (4);
++        return true;
++      }
++
++      operand = XEXP (x, 0);
++
++      if (!((GET_RTX_CLASS (GET_CODE (operand)) == RTX_COMPARE
++           || GET_RTX_CLASS (GET_CODE (operand)) == RTX_COMM_COMPARE)
++          && GET_CODE (XEXP (operand, 0)) == REG
++          && REGNO (XEXP (operand, 0)) == CC_REGNUM))
++      *total += COSTS_N_INSNS (1);
++      *total += (rtx_cost (XEXP (x, 1), code)
++               + rtx_cost (XEXP (x, 2), code));
++      return true;
++
++    case NE:
++      if (mode == SImode && XEXP (x, 1) == const0_rtx)
++      {
++        *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code);
++        return true;
++      }
++      goto scc_insn;
++
++    case GE:
++      if ((GET_CODE (XEXP (x, 0)) != REG || REGNO (XEXP (x, 0)) != CC_REGNUM)
++        && mode == SImode && XEXP (x, 1) == const0_rtx)
++      {
++        *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code);
++        return true;
++      }
++      goto scc_insn;
++
++    case LT:
++      if ((GET_CODE (XEXP (x, 0)) != REG || REGNO (XEXP (x, 0)) != CC_REGNUM)
++        && mode == SImode && XEXP (x, 1) == const0_rtx)
++      {
++        *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 0), code);
++        return true;
++      }
++      goto scc_insn;
++
++    case EQ:
++    case GT:
++    case LE:
++    case GEU:
++    case LTU:
++    case GTU:
++    case LEU:
++    case UNORDERED:
++    case ORDERED:
++    case UNEQ:
++    case UNGE:
++    case UNLT:
++    case UNGT:
++    case UNLE:
++    scc_insn:
++      /* SCC insns.  In the case where the comparison has already been
++       performed, then they cost 2 instructions.  Otherwise they need
++       an additional comparison before them.  */
++      *total = COSTS_N_INSNS (2);
++      if (GET_CODE (XEXP (x, 0)) == REG && REGNO (XEXP (x, 0)) == CC_REGNUM)
++      {
++        return true;
++      }
++      /* Fall through */
+     case COMPARE:
+-      return 1;
++      if (GET_CODE (XEXP (x, 0)) == REG && REGNO (XEXP (x, 0)) == CC_REGNUM)
++      {
++        *total = 0;
++        return true;
++      }
++
++      *total += COSTS_N_INSNS (1);
++      if (GET_CODE (XEXP (x, 1)) == CONST_INT
++        && const_ok_for_op (INTVAL (XEXP (x, 1)), code))
++      {
++        *total += rtx_cost (XEXP (x, 0), code);
++        return true;
++      }
++
++      subcode = GET_CODE (XEXP (x, 0));
++      if (subcode == ASHIFT || subcode == ASHIFTRT
++        || subcode == LSHIFTRT
++        || subcode == ROTATE || subcode == ROTATERT)
++      {
++        *total += rtx_cost (XEXP (x, 1), code);
++        *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode);
++        return true;
++      }
++
++      if (subcode == MULT
++        && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
++        && ((INTVAL (XEXP (XEXP (x, 0), 1)) &
++             (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0))
++      {
++        *total += rtx_cost (XEXP (x, 1), code);
++        *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode);
++        return true;
++      }
++      
++      return false;
++
++    case UMIN:
++    case UMAX:
++    case SMIN:
++    case SMAX:
++      *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code);
++      if (GET_CODE (XEXP (x, 1)) != CONST_INT
++        || !const_ok_for_arm (INTVAL (XEXP (x, 1))))
++      *total += rtx_cost (XEXP (x, 1), code);
++      return true;
+     case ABS:
+-      return 4 + (mode == DImode ? 4 : 0);
++      if (GET_MODE_CLASS (mode == MODE_FLOAT))
++      {
++        if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
++          {
++            *total = COSTS_N_INSNS (1);
++            return false;
++          }
++        *total = COSTS_N_INSNS (20);
++        return false;
++      }
++      *total = COSTS_N_INSNS (1);
++      if (mode == DImode)
++      *total += COSTS_N_INSNS (3);
++      return false;
+     case SIGN_EXTEND:
+-      /* ??? value extensions are cheaper on armv6. */
+-      if (GET_MODE (XEXP (x, 0)) == QImode)
+-      return (4 + (mode == DImode ? 4 : 0)
+-              + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
++      if (GET_MODE_CLASS (mode) == MODE_INT)
++      {
++        *total = 0;
++        if (mode == DImode)
++          *total += COSTS_N_INSNS (1);
++
++        if (GET_MODE (XEXP (x, 0)) != SImode)
++          {
++            if (arm_arch6)
++              {
++                if (GET_CODE (XEXP (x, 0)) != MEM)
++                  *total += COSTS_N_INSNS (1);
++              }
++            else if (!arm_arch4 || GET_CODE (XEXP (x, 0)) != MEM)
++              *total += COSTS_N_INSNS (2);
++          }
++
++        return false;
++      }
++
+       /* Fall through */
+     case ZERO_EXTEND:
+-      switch (GET_MODE (XEXP (x, 0)))
++      *total = 0;
++      if (GET_MODE_CLASS (mode) == MODE_INT)
+       {
+-      case QImode:
+-        return (1 + (mode == DImode ? 4 : 0)
+-                + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
++        if (mode == DImode)
++          *total += COSTS_N_INSNS (1);
+-      case HImode:
+-        return (4 + (mode == DImode ? 4 : 0)
+-                + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
++        if (GET_MODE (XEXP (x, 0)) != SImode)
++          {
++            if (arm_arch6)
++              {
++                if (GET_CODE (XEXP (x, 0)) != MEM)
++                  *total += COSTS_N_INSNS (1);
++              }
++            else if (!arm_arch4 || GET_CODE (XEXP (x, 0)) != MEM)
++              *total += COSTS_N_INSNS (GET_MODE (XEXP (x, 0)) == QImode ?
++                                       1 : 2);
++          }
+-      case SImode:
+-        return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
++        return false;
++      }
++      switch (GET_MODE (XEXP (x, 0)))
++      {
+       case V8QImode:
+       case V4HImode:
+       case V2SImode:
+       case V4QImode:
+       case V2HImode:
+-          return 1;
++        *total = COSTS_N_INSNS (1);
++        return false;
+       default:
+         gcc_unreachable ();
+       }
+       gcc_unreachable ();
++    case ZERO_EXTRACT:
++    case SIGN_EXTRACT:
++      *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 0), code);
++      return true;
++
+     case CONST_INT:
+-      if (const_ok_for_arm (INTVAL (x)))
+-      return outer == SET ? 2 : -1;
+-      else if (outer == AND
+-             && const_ok_for_arm (~INTVAL (x)))
+-      return -1;
+-      else if ((outer == COMPARE
+-              || outer == PLUS || outer == MINUS)
+-             && const_ok_for_arm (-INTVAL (x)))
+-      return -1;
++      if (const_ok_for_arm (INTVAL (x))
++        || const_ok_for_arm (~INTVAL (x)))
++      *total = COSTS_N_INSNS (1);
+       else
+-      return 5;
++      *total = COSTS_N_INSNS (arm_gen_constant (SET, mode, NULL_RTX,
++                                                INTVAL (x), NULL_RTX,
++                                                NULL_RTX, 0, 0));
++      return true;
+     case CONST:
+     case LABEL_REF:
+     case SYMBOL_REF:
+-      return 6;
++      *total = COSTS_N_INSNS (3);
++      return true;
++
++    case HIGH:
++      *total = COSTS_N_INSNS (1);
++      return true;
++
++    case LO_SUM:
++      *total = COSTS_N_INSNS (1);
++      *total += rtx_cost (XEXP (x, 0), code);
++      return true;
+     case CONST_DOUBLE:
+-      if (arm_const_double_rtx (x) || vfp3_const_double_rtx (x))
+-      return outer == SET ? 2 : -1;
+-      else if ((outer == COMPARE || outer == PLUS)
+-             && neg_const_double_rtx_ok_for_fpa (x))
+-      return -1;
+-      return 7;
++      if (TARGET_HARD_FLOAT && vfp3_const_double_rtx (x))
++      *total = COSTS_N_INSNS (1);
++      else
++      *total = COSTS_N_INSNS (4);
++      return true;
+     default:
+-      return 99;
++      *total = COSTS_N_INSNS (4);
++      return false;
+     }
+ }
+@@ -5063,14 +6715,14 @@ static bool
+ arm_size_rtx_costs (rtx x, int code, int outer_code, int *total)
+ {
+   enum machine_mode mode = GET_MODE (x);
+-
+-  if (TARGET_THUMB)
++  if (TARGET_THUMB1)
+     {
+       /* XXX TBD.  For now, use the standard costs.  */
+       *total = thumb1_rtx_costs (x, code, outer_code);
+       return true;
+     }
++  /* FIXME: This makes no attempt to prefer narrow Thumb-2 instructions.  */
+   switch (code)
+     {
+     case MEM:
+@@ -5181,7 +6833,10 @@ arm_size_rtx_costs (rtx x, int code, int
+     case NEG:
+       if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
+-      *total = COSTS_N_INSNS (1);
++      {
++        *total = COSTS_N_INSNS (1);
++        return false;
++      }
+       /* Fall through */
+     case NOT:
+       *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
+@@ -5270,6 +6925,13 @@ arm_size_rtx_costs (rtx x, int code, int
+       *total = COSTS_N_INSNS (4);
+       return true;
++    case HIGH:
++    case LO_SUM:
++      /* We prefer constant pool entries to MOVW/MOVT pairs, so bump the
++       cost of these slightly.  */
++      *total = COSTS_N_INSNS (1) + 1;
++      return true;
++
+     default:
+       if (mode != VOIDmode)
+       *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
+@@ -5279,11 +6941,22 @@ arm_size_rtx_costs (rtx x, int code, int
+     }
+ }
++/* RTX costs when optimizing for size.  */
++static bool
++arm_rtx_costs (rtx x, int code, int outer_code, int *total)
++{
++  if (optimize_size)
++    return arm_size_rtx_costs (x, code, outer_code, total);
++  else
++    return all_cores[(int)arm_tune].rtx_costs (x, code, outer_code, total);
++}
++
+ /* RTX costs for cores with a slow MUL implementation.  Thumb-2 is not
+    supported on any "slowmul" cores, so it can be ignored.  */
+ static bool
+-arm_slowmul_rtx_costs (rtx x, int code, int outer_code, int *total)
++arm_slowmul_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
++                     int *total)
+ {
+   enum machine_mode mode = GET_MODE (x);
+@@ -5299,8 +6972,8 @@ arm_slowmul_rtx_costs (rtx x, int code, 
+       if (GET_MODE_CLASS (mode) == MODE_FLOAT
+         || mode == DImode)
+       {
+-        *total = 30;
+-        return true;
++        *total = COSTS_N_INSNS (20);
++        return false;
+       }
+       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+@@ -5316,20 +6989,19 @@ arm_slowmul_rtx_costs (rtx x, int code, 
+         for (j = 0; i && j < 32; j += booth_unit_size)
+           {
+             i >>= booth_unit_size;
+-            cost += 2;
++            cost++;
+           }
+-        *total = cost;
++        *total = COSTS_N_INSNS (cost);
++        *total += rtx_cost (XEXP (x, 0), code);
+         return true;
+       }
+-      *total = 30 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4)
+-                + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4);
+-      return true;
++      *total = COSTS_N_INSNS (20);
++      return false;
+     default:
+-      *total = arm_rtx_costs_1 (x, code, outer_code);
+-      return true;
++      return arm_rtx_costs_1 (x, outer_code, total);;
+     }
+ }
+@@ -5337,7 +7009,8 @@ arm_slowmul_rtx_costs (rtx x, int code, 
+ /* RTX cost for cores with a fast multiply unit (M variants).  */
+ static bool
+-arm_fastmul_rtx_costs (rtx x, int code, int outer_code, int *total)
++arm_fastmul_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
++                     int *total)
+ {
+   enum machine_mode mode = GET_MODE (x);
+@@ -5358,16 +7031,15 @@ arm_fastmul_rtx_costs (rtx x, int code, 
+         && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
+             || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND))
+       {
+-        *total = 8;
+-        return true;
++        *total = COSTS_N_INSNS(2);
++        return false;
+       }
+-      if (GET_MODE_CLASS (mode) == MODE_FLOAT
+-        || mode == DImode)
++      if (mode == DImode)
+       {
+-        *total = 30;
+-        return true;
++        *total = COSTS_N_INSNS (5);
++        return false;
+       }
+       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+@@ -5383,20 +7055,34 @@ arm_fastmul_rtx_costs (rtx x, int code, 
+         for (j = 0; i && j < 32; j += booth_unit_size)
+           {
+             i >>= booth_unit_size;
+-            cost += 2;
++            cost++;
+           }
+-        *total = cost;
+-        return true;
++        *total = COSTS_N_INSNS(cost);
++        return false;
+       }
+-      *total = 8 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4)
+-               + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4);
+-      return true;
++      if (mode == SImode)
++      {
++        *total = COSTS_N_INSNS (4);
++        return false;
++      }
++
++      if (GET_MODE_CLASS (mode) == MODE_FLOAT)
++      {
++        if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
++          {
++            *total = COSTS_N_INSNS (1);
++            return false;
++          }
++      }
++
++      /* Requires a lib call */
++      *total = COSTS_N_INSNS (20);
++      return false;
+     default:
+-      *total = arm_rtx_costs_1 (x, code, outer_code);
+-      return true;
++      return arm_rtx_costs_1 (x, outer_code, total);
+     }
+ }
+@@ -5405,7 +7091,7 @@ arm_fastmul_rtx_costs (rtx x, int code, 
+    so it can be ignored.  */
+ static bool
+-arm_xscale_rtx_costs (rtx x, int code, int outer_code, int *total)
++arm_xscale_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, int *total)
+ {
+   enum machine_mode mode = GET_MODE (x);
+@@ -5417,6 +7103,15 @@ arm_xscale_rtx_costs (rtx x, int code, i
+   switch (code)
+     {
++    case COMPARE:
++      if (GET_CODE (XEXP (x, 0)) != MULT)
++      return arm_rtx_costs_1 (x, outer_code, total);
++
++      /* A COMPARE of a MULT is slow on XScale; the muls instruction
++       will stall until the multiplication is complete.  */
++      *total = COSTS_N_INSNS (3);
++      return false;
++
+     case MULT:
+       /* There is no point basing this on the tuning, since it is always the
+        fast variant if it exists at all.  */
+@@ -5425,60 +7120,58 @@ arm_xscale_rtx_costs (rtx x, int code, i
+         && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
+             || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND))
+       {
+-        *total = 8;
+-        return true;
++        *total = COSTS_N_INSNS (2);
++        return false;
+       }
+-      if (GET_MODE_CLASS (mode) == MODE_FLOAT
+-        || mode == DImode)
++      if (mode == DImode)
+       {
+-        *total = 30;
+-        return true;
++        *total = COSTS_N_INSNS (5);
++        return false;
+       }
+       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+       {
+-        unsigned HOST_WIDE_INT i = (INTVAL (XEXP (x, 1))
+-                                    & (unsigned HOST_WIDE_INT) 0xffffffff);
+-        int cost, const_ok = const_ok_for_arm (i);
++        /* If operand 1 is a constant we can more accurately
++           calculate the cost of the multiply.  The multiplier can
++           retire 15 bits on the first cycle and a further 12 on the
++           second.  We do, of course, have to load the constant into
++           a register first.  */
++        unsigned HOST_WIDE_INT i = INTVAL (XEXP (x, 1));
++        /* There's a general overhead of one cycle.  */
++        int cost = 1;
+         unsigned HOST_WIDE_INT masked_const;
+-        /* The cost will be related to two insns.
+-           First a load of the constant (MOV or LDR), then a multiply.  */
+-        cost = 2;
+-        if (! const_ok)
+-          cost += 1;      /* LDR is probably more expensive because
+-                             of longer result latency.  */
++        if (i & 0x80000000)
++          i = ~i;
++
++        i &= (unsigned HOST_WIDE_INT) 0xffffffff;
++
+         masked_const = i & 0xffff8000;
+-        if (masked_const != 0 && masked_const != 0xffff8000)
++        if (masked_const != 0)
+           {
++            cost++;
+             masked_const = i & 0xf8000000;
+-            if (masked_const == 0 || masked_const == 0xf8000000)
+-              cost += 1;
+-            else
+-              cost += 2;
++            if (masked_const != 0)
++              cost++;
+           }
+-        *total = cost;
+-        return true;
++        *total = COSTS_N_INSNS (cost);
++        return false;
+       }
+-      *total = 8 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4)
+-               + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4);
+-      return true;
++      if (mode == SImode)
++      {
++        *total = COSTS_N_INSNS (3);
++        return false;
++      }
+-    case COMPARE:
+-      /* A COMPARE of a MULT is slow on XScale; the muls instruction
+-       will stall until the multiplication is complete.  */
+-      if (GET_CODE (XEXP (x, 0)) == MULT)
+-      *total = 4 + rtx_cost (XEXP (x, 0), code);
+-      else
+-      *total = arm_rtx_costs_1 (x, code, outer_code);
+-      return true;
++      /* Requires a lib call */
++      *total = COSTS_N_INSNS (20);
++      return false;
+     default:
+-      *total = arm_rtx_costs_1 (x, code, outer_code);
+-      return true;
++      return arm_rtx_costs_1 (x, outer_code, total);
+     }
+ }
+@@ -5486,11 +7179,9 @@ arm_xscale_rtx_costs (rtx x, int code, i
+ /* RTX costs for 9e (and later) cores.  */
+ static bool
+-arm_9e_rtx_costs (rtx x, int code, int outer_code, int *total)
++arm_9e_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, int *total)
+ {
+   enum machine_mode mode = GET_MODE (x);
+-  int nonreg_cost;
+-  int cost;
+   if (TARGET_THUMB1)
+     {
+@@ -5516,35 +7207,37 @@ arm_9e_rtx_costs (rtx x, int code, int o
+         && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
+             || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND))
+       {
+-        *total = 3;
+-        return true;
++        *total = COSTS_N_INSNS (2);
++        return false;
+       }
+-      if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+-      {
+-        *total = 30;
+-        return true;
+-      }
+       if (mode == DImode)
+       {
+-        cost = 7;
+-        nonreg_cost = 8;
++        *total = COSTS_N_INSNS (5);
++        return false;
+       }
+-      else
++
++      if (mode == SImode)
+       {
+-        cost = 2;
+-        nonreg_cost = 4;
++        *total = COSTS_N_INSNS (2);
++        return false;
+       }
++      if (GET_MODE_CLASS (mode) == MODE_FLOAT)
++      {
++        if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
++          {
++            *total = COSTS_N_INSNS (1);
++            return false;
++          }
++      }
+-      *total = cost + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : nonreg_cost)
+-                  + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : nonreg_cost);
+-      return true;
++      *total = COSTS_N_INSNS (20);
++      return false;
+     default:
+-      *total = arm_rtx_costs_1 (x, code, outer_code);
+-      return true;
++      return arm_rtx_costs_1 (x, outer_code, total);
+     }
+ }
+ /* All address computations that can be done are free, but rtx cost returns
+@@ -6356,10 +8049,13 @@ arm_coproc_mem_operand (rtx op, bool wb)
+ }
+ /* Return TRUE if OP is a memory operand which we can load or store a vector
+-   to/from. If CORE is true, we're moving from ARM registers not Neon
+-   registers.  */
++   to/from. TYPE is one of the following values:
++    0 - Vector load/stor (vldr)
++    1 - Core registers (ldm)
++    2 - Element/structure loads (vld1)
++ */
+ int
+-neon_vector_mem_operand (rtx op, bool core)
++neon_vector_mem_operand (rtx op, int type)
+ {
+   rtx ind;
+@@ -6392,23 +8088,15 @@ neon_vector_mem_operand (rtx op, bool co
+     return arm_address_register_rtx_p (ind, 0);
+   /* Allow post-increment with Neon registers.  */
+-  if (!core && GET_CODE (ind) == POST_INC)
++  if (type != 1 && (GET_CODE (ind) == POST_INC || GET_CODE (ind) == PRE_DEC))
+     return arm_address_register_rtx_p (XEXP (ind, 0), 0);
+-#if 0
+-  /* FIXME: We can support this too if we use VLD1/VST1.  */
+-  if (!core
+-      && GET_CODE (ind) == POST_MODIFY
+-      && arm_address_register_rtx_p (XEXP (ind, 0), 0)
+-      && GET_CODE (XEXP (ind, 1)) == PLUS
+-      && rtx_equal_p (XEXP (XEXP (ind, 1), 0), XEXP (ind, 0)))
+-    ind = XEXP (ind, 1);
+-#endif
++  /* FIXME: vld1 allows register post-modify.  */
+   /* Match:
+      (plus (reg)
+           (const)).  */
+-  if (!core
++  if (type == 0
+       && GET_CODE (ind) == PLUS
+       && GET_CODE (XEXP (ind, 0)) == REG
+       && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode)
+@@ -6475,10 +8163,17 @@ arm_eliminable_register (rtx x)
+ enum reg_class
+ coproc_secondary_reload_class (enum machine_mode mode, rtx x, bool wb)
+ {
++  if (mode == HFmode)
++    {
++      if (s_register_operand (x, mode) || neon_vector_mem_operand (x, 2))
++      return NO_REGS;
++      return GENERAL_REGS;
++    }
++
+   if (TARGET_NEON
+       && (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
+           || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
+-      && neon_vector_mem_operand (x, FALSE))
++      && neon_vector_mem_operand (x, 0))
+      return NO_REGS;
+   if (arm_coproc_mem_operand (x, wb) || s_register_operand (x, mode))
+@@ -6875,6 +8570,9 @@ load_multiple_sequence (rtx *operands, i
+   int base_reg = -1;
+   int i;
++  if (low_irq_latency)
++    return 0;
++
+   /* Can only handle 2, 3, or 4 insns at present,
+      though could be easily extended if required.  */
+   gcc_assert (nops >= 2 && nops <= 4);
+@@ -7102,6 +8800,9 @@ store_multiple_sequence (rtx *operands, 
+   int base_reg = -1;
+   int i;
++  if (low_irq_latency)
++    return 0;
++
+   /* Can only handle 2, 3, or 4 insns at present, though could be easily
+      extended if required.  */
+   gcc_assert (nops >= 2 && nops <= 4);
+@@ -7307,7 +9008,7 @@ arm_gen_load_multiple (int base_regno, i
+      As a compromise, we use ldr for counts of 1 or 2 regs, and ldm
+      for counts of 3 or 4 regs.  */
+-  if (arm_tune_xscale && count <= 2 && ! optimize_size)
++  if (low_irq_latency || (arm_tune_xscale && count <= 2 && ! optimize_size))
+     {
+       rtx seq;
+@@ -7370,7 +9071,7 @@ arm_gen_store_multiple (int base_regno, 
+   /* See arm_gen_load_multiple for discussion of
+      the pros/cons of ldm/stm usage for XScale.  */
+-  if (arm_tune_xscale && count <= 2 && ! optimize_size)
++  if (low_irq_latency || (arm_tune_xscale && count <= 2 && ! optimize_size))
+     {
+       rtx seq;
+@@ -8739,17 +10440,20 @@ add_minipool_backward_ref (Mfix *fix)
+                its maximum address (which can happen if we have
+                re-located a forwards fix); force the new fix to come
+                after it.  */
+-            min_mp = mp;
+-            min_address = mp->min_address + fix->fix_size;
++            if (ARM_DOUBLEWORD_ALIGN
++                && fix->fix_size >= 8 && mp->fix_size < 8)
++              return NULL;
++            else
++              {
++                min_mp = mp;
++                min_address = mp->min_address + fix->fix_size;
++              }
+           }
+-        /* If we are inserting an 8-bytes aligned quantity and
+-           we have not already found an insertion point, then
+-           make sure that all such 8-byte aligned quantities are
+-           placed at the start of the pool.  */
++        /* Do not insert a non-8-byte aligned quantity before 8-byte
++           aligned quantities.  */
+         else if (ARM_DOUBLEWORD_ALIGN
+-                 && min_mp == NULL
+-                 && fix->fix_size >= 8
+-                 && mp->fix_size < 8)
++                 && fix->fix_size < 8
++                 && mp->fix_size >= 8)
+           {
+             min_mp = mp;
+             min_address = mp->min_address + fix->fix_size;
+@@ -8985,7 +10689,10 @@ create_fix_barrier (Mfix *fix, HOST_WIDE
+       gcc_assert (GET_CODE (from) != BARRIER);
+       /* Count the length of this insn.  */
+-      count += get_attr_length (from);
++      if (LABEL_P (from) && (align_jumps > 0 || align_loops > 0))
++        count += MAX (align_jumps, align_loops);
++      else
++        count += get_attr_length (from);
+       /* If there is a jump table, add its length.  */
+       tmp = is_jump_table (from);
+@@ -9297,6 +11004,8 @@ arm_reorg (void)
+             insn = table;
+           }
+       }
++      else if (LABEL_P (insn) && (align_jumps > 0 || align_loops > 0))
++      address += MAX (align_jumps, align_loops);
+     }
+   fix = minipool_fix_head;
+@@ -9502,6 +11211,21 @@ static void
+ vfp_output_fldmd (FILE * stream, unsigned int base, int reg, int count)
+ {
+   int i;
++  int offset;
++
++  if (low_irq_latency)
++    {
++      /* Output a sequence of FLDD instructions.  */
++      offset = 0;
++      for (i = reg; i < reg + count; ++i, offset += 8)
++      {
++        fputc ('\t', stream);
++        asm_fprintf (stream, "fldd\td%d, [%r,#%d]\n", i, base, offset);
++      }
++      asm_fprintf (stream, "\tadd\tsp, sp, #%d\n", count * 8);
++      return;
++    }
++
+   /* Workaround ARM10 VFPr1 bug.  */
+   if (count == 2 && !arm_arch6)
+@@ -9572,6 +11296,53 @@ vfp_emit_fstmd (int base_reg, int count)
+   rtx tmp, reg;
+   int i;
++  if (low_irq_latency)
++    {
++      if (!count)
++      return 0;
++
++      int saved_size = count * GET_MODE_SIZE (DFmode);
++
++      /* Since fstd does not have postdecrement addressing mode,
++       we first decrement stack pointer and then use base+offset
++       stores for VFP registers. The ARM EABI unwind information 
++       can't easily describe base+offset loads, so we attach
++       a note for the effects of the whole block in the first insn, 
++       and  avoid marking the subsequent instructions 
++       with RTX_FRAME_RELATED_P.  */
++      rtx sp_insn = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
++                           GEN_INT (-saved_size));
++      sp_insn = emit_insn (sp_insn);
++      RTX_FRAME_RELATED_P (sp_insn) = 1;
++
++      dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (count + 1));
++      XVECEXP (dwarf, 0, 0) = 
++      gen_rtx_SET (VOIDmode, stack_pointer_rtx,
++                   plus_constant (stack_pointer_rtx, -saved_size));
++      
++      /* push double VFP registers to stack */
++      for (i = 0; i < count; ++i )
++      {
++        rtx reg;
++        rtx mem;
++        rtx addr;
++        rtx insn;
++        reg = gen_rtx_REG (DFmode, base_reg + 2*i);
++        addr = (i == 0) ? stack_pointer_rtx
++          : gen_rtx_PLUS (SImode, stack_pointer_rtx,
++                          GEN_INT (i * GET_MODE_SIZE (DFmode)));
++        mem = gen_frame_mem (DFmode, addr);
++        insn = emit_move_insn (mem, reg);
++        XVECEXP (dwarf, 0, i+1) = 
++          gen_rtx_SET (VOIDmode, mem, reg);
++      }
++
++      REG_NOTES (sp_insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
++                                             REG_NOTES (sp_insn));
++      
++      return saved_size;
++    }
++
+   /* Workaround ARM10 VFPr1 bug.  Data corruption can occur when exactly two
+      register pairs are stored by a store multiple insn.  We avoid this
+      by pushing an extra pair.  */
+@@ -9729,6 +11500,14 @@ output_call_mem (rtx *operands)
+ }
++/* Emit a MOVW/MOVT pair.  */
++void arm_emit_movpair (rtx dest, rtx src)
++{
++  emit_set_insn (dest, gen_rtx_HIGH (SImode, src));
++  emit_set_insn (dest, gen_rtx_LO_SUM (SImode, dest, src));
++}
++
++
+ /* Output a move from arm registers to an fpa registers.
+    OPERANDS[0] is an fpa register.
+    OPERANDS[1] is the first registers of an arm register pair.  */
+@@ -9862,7 +11641,11 @@ output_move_double (rtx *operands)
+       switch (GET_CODE (XEXP (operands[1], 0)))
+       {
+       case REG:
+-        output_asm_insn ("ldm%(ia%)\t%m1, %M0", operands);
++        if (TARGET_LDRD
++            && !(fix_cm3_ldrd && reg0 == REGNO(XEXP (operands[1], 0))))
++          output_asm_insn ("ldr%(d%)\t%0, [%m1]", operands);
++        else
++          output_asm_insn ("ldm%(ia%)\t%m1, %M0", operands);
+         break;
+       case PRE_INC:
+@@ -9878,7 +11661,10 @@ output_move_double (rtx *operands)
+         break;
+       case POST_INC:
+-        output_asm_insn ("ldm%(ia%)\t%m1!, %M0", operands);
++        if (TARGET_LDRD)
++          output_asm_insn ("ldr%(d%)\t%0, [%m1], #8", operands);
++        else
++          output_asm_insn ("ldm%(ia%)\t%m1!, %M0", operands);
+         break;
+       case POST_DEC:
+@@ -9888,6 +11674,10 @@ output_move_double (rtx *operands)
+       case PRE_MODIFY:
+       case POST_MODIFY:
++        /* Autoicrement addressing modes should never have overlapping
++           base and destination registers, and overlapping index registers
++           are already prohibited, so this doesn't need to worry about
++           fix_cm3_ldrd.  */
+         otherops[0] = operands[0];
+         otherops[1] = XEXP (XEXP (XEXP (operands[1], 0), 1), 0);
+         otherops[2] = XEXP (XEXP (XEXP (operands[1], 0), 1), 1);
+@@ -9902,9 +11692,9 @@ output_move_double (rtx *operands)
+               }
+             else
+               {
+-                /* IWMMXT allows offsets larger than ldrd can handle,
++                /* IWMMXT allows offsets larger than ARM ldrd can handle,
+                    fix these up with a pair of ldr.  */
+-                if (GET_CODE (otherops[2]) == CONST_INT
++                if (TARGET_ARM && GET_CODE (otherops[2]) == CONST_INT
+                     && (INTVAL(otherops[2]) <= -256
+                         || INTVAL(otherops[2]) >= 256))
+                   {
+@@ -9918,9 +11708,9 @@ output_move_double (rtx *operands)
+           }
+         else
+           {
+-            /* IWMMXT allows offsets larger than ldrd can handle,
++            /* IWMMXT allows offsets larger than ARM ldrd can handle,
+                fix these up with a pair of ldr.  */
+-            if (GET_CODE (otherops[2]) == CONST_INT
++            if (TARGET_ARM && GET_CODE (otherops[2]) == CONST_INT
+                 && (INTVAL(otherops[2]) <= -256
+                     || INTVAL(otherops[2]) >= 256))
+               {
+@@ -9937,8 +11727,15 @@ output_move_double (rtx *operands)
+       case LABEL_REF:
+       case CONST:
+-        output_asm_insn ("adr%?\t%0, %1", operands);
+-        output_asm_insn ("ldm%(ia%)\t%0, %M0", operands);
++        /* Use the second register of the pair to avoid problematic
++           overlap.  */
++        otherops[1] = operands[1];
++        output_asm_insn ("adr%?\t%0, %1", otherops);
++        operands[1] = otherops[0];
++        if (TARGET_LDRD)
++          output_asm_insn ("ldr%(d%)\t%0, [%1]", operands);
++        else
++          output_asm_insn ("ldm%(ia%)\t%1, %M0", operands);
+         break;
+         /* ??? This needs checking for thumb2.  */
+@@ -9952,7 +11749,7 @@ output_move_double (rtx *operands)
+             if (GET_CODE (XEXP (operands[1], 0)) == PLUS)
+               {
+-                if (GET_CODE (otherops[2]) == CONST_INT)
++                if (GET_CODE (otherops[2]) == CONST_INT && !TARGET_LDRD)
+                   {
+                     switch ((int) INTVAL (otherops[2]))
+                       {
+@@ -9971,30 +11768,37 @@ output_move_double (rtx *operands)
+                         return "";
+                       }
+                   }
++                otherops[0] = gen_rtx_REG(SImode, REGNO(operands[0]) + 1);
++                operands[1] = otherops[0];
+                 if (TARGET_LDRD
+                     && (GET_CODE (otherops[2]) == REG
+                         || (GET_CODE (otherops[2]) == CONST_INT
+                             && INTVAL (otherops[2]) > -256
+                             && INTVAL (otherops[2]) < 256)))
+                   {
+-                    if (reg_overlap_mentioned_p (otherops[0],
++                    if (reg_overlap_mentioned_p (operands[0],
+                                                  otherops[2]))
+                       {
++                        rtx tmp;
+                         /* Swap base and index registers over to
+                            avoid a conflict.  */
+-                        otherops[1] = XEXP (XEXP (operands[1], 0), 1);
+-                        otherops[2] = XEXP (XEXP (operands[1], 0), 0);
++                        tmp = otherops[1];
++                        otherops[1] = otherops[2];
++                        otherops[2] = tmp;
+                       }
+                     /* If both registers conflict, it will usually
+                        have been fixed by a splitter.  */
+-                    if (reg_overlap_mentioned_p (otherops[0], otherops[2]))
++                    if (reg_overlap_mentioned_p (operands[0], otherops[2])
++                        || (fix_cm3_ldrd && reg0 == REGNO (otherops[1])))
+                       {
+-                        output_asm_insn ("add%?\t%1, %1, %2", otherops);
+-                        output_asm_insn ("ldr%(d%)\t%0, [%1]",
+-                                         otherops);
++                        output_asm_insn ("add%?\t%0, %1, %2", otherops);
++                        output_asm_insn ("ldr%(d%)\t%0, [%1]", operands);
+                       }
+                     else
+-                      output_asm_insn ("ldr%(d%)\t%0, [%1, %2]", otherops);
++                      {
++                        otherops[0] = operands[0];
++                        output_asm_insn ("ldr%(d%)\t%0, [%1, %2]", otherops);
++                      }
+                     return "";
+                   }
+@@ -10011,7 +11815,10 @@ output_move_double (rtx *operands)
+             else
+               output_asm_insn ("sub%?\t%0, %1, %2", otherops);
+-            return "ldm%(ia%)\t%0, %M0";
++            if (TARGET_LDRD)
++              return "ldr%(d%)\t%0, [%1]";
++
++            return "ldm%(ia%)\t%1, %M0";
+           }
+         else
+           {
+@@ -10039,7 +11846,10 @@ output_move_double (rtx *operands)
+       switch (GET_CODE (XEXP (operands[0], 0)))
+         {
+       case REG:
+-        output_asm_insn ("stm%(ia%)\t%m0, %M1", operands);
++        if (TARGET_LDRD)
++          output_asm_insn ("str%(d%)\t%1, [%m0]", operands);
++        else
++          output_asm_insn ("stm%(ia%)\t%m0, %M1", operands);
+         break;
+         case PRE_INC:
+@@ -10055,7 +11865,10 @@ output_move_double (rtx *operands)
+         break;
+         case POST_INC:
+-        output_asm_insn ("stm%(ia%)\t%m0!, %M1", operands);
++        if (TARGET_LDRD)
++          output_asm_insn ("str%(d%)\t%1, [%m0], #8", operands);
++        else
++          output_asm_insn ("stm%(ia%)\t%m0!, %M1", operands);
+         break;
+         case POST_DEC:
+@@ -10069,9 +11882,9 @@ output_move_double (rtx *operands)
+         otherops[1] = XEXP (XEXP (XEXP (operands[0], 0), 1), 0);
+         otherops[2] = XEXP (XEXP (XEXP (operands[0], 0), 1), 1);
+-        /* IWMMXT allows offsets larger than ldrd can handle,
++        /* IWMMXT allows offsets larger than ARM ldrd can handle,
+            fix these up with a pair of ldr.  */
+-        if (GET_CODE (otherops[2]) == CONST_INT
++        if (TARGET_ARM && GET_CODE (otherops[2]) == CONST_INT
+             && (INTVAL(otherops[2]) <= -256
+                 || INTVAL(otherops[2]) >= 256))
+           {
+@@ -10099,7 +11912,7 @@ output_move_double (rtx *operands)
+       case PLUS:
+         otherops[2] = XEXP (XEXP (operands[0], 0), 1);
+-        if (GET_CODE (otherops[2]) == CONST_INT)
++        if (GET_CODE (otherops[2]) == CONST_INT && !TARGET_LDRD)
+           {
+             switch ((int) INTVAL (XEXP (XEXP (operands[0], 0), 1)))
+               {
+@@ -10145,7 +11958,7 @@ output_move_double (rtx *operands)
+ }
+ /* Output a move, load or store for quad-word vectors in ARM registers.  Only
+-   handles MEMs accepted by neon_vector_mem_operand with CORE=true.  */
++   handles MEMs accepted by neon_vector_mem_operand with TYPE=1.  */
+ const char *
+ output_move_quad (rtx *operands)
+@@ -10343,6 +12156,13 @@ output_move_neon (rtx *operands)
+       ops[1] = reg;
+       break;
++    case PRE_DEC:
++      /* FIXME: We should be using vld1/vst1 here in BE mode?  */
++      template = "v%smdb%%?\t%%0!, %%h1";
++      ops[0] = XEXP (addr, 0);
++      ops[1] = reg;
++      break;
++    
+     case POST_MODIFY:
+       /* FIXME: Not currently enabled in neon_vector_mem_operand.  */
+       gcc_unreachable ();
+@@ -10700,25 +12520,14 @@ arm_compute_save_reg0_reg12_mask (void)
+     }
+   else
+     {
+-      /* In arm mode we handle r11 (FP) as a special case.  */
+-      unsigned last_reg = TARGET_ARM ? 10 : 11;
+-      
+       /* In the normal case we only need to save those registers
+        which are call saved and which are used by this function.  */
+-      for (reg = 0; reg <= last_reg; reg++)
++      for (reg = 0; reg <= 11; reg++)
+       if (df_regs_ever_live_p (reg) && ! call_used_regs[reg])
+         save_reg_mask |= (1 << reg);
+       /* Handle the frame pointer as a special case.  */
+-      if (! TARGET_APCS_FRAME
+-        && ! frame_pointer_needed
+-        && df_regs_ever_live_p (HARD_FRAME_POINTER_REGNUM)
+-        && ! call_used_regs[HARD_FRAME_POINTER_REGNUM])
+-      save_reg_mask |= 1 << HARD_FRAME_POINTER_REGNUM;
+-      else if (! TARGET_APCS_FRAME
+-             && ! frame_pointer_needed
+-             && df_regs_ever_live_p (HARD_FRAME_POINTER_REGNUM)
+-             && ! call_used_regs[HARD_FRAME_POINTER_REGNUM])
++      if (frame_pointer_needed)
+       save_reg_mask |= 1 << HARD_FRAME_POINTER_REGNUM;
+       /* If we aren't loading the PIC register,
+@@ -10753,8 +12562,27 @@ arm_compute_save_reg0_reg12_mask (void)
+ }
++/* Compute the number of bytes used to store the static chain register on the 
++   stack, above the stack frame. We need to know this accurately to get the
++   alignment of the rest of the stack frame correct. */
++
++static int arm_compute_static_chain_stack_bytes (void)
++{
++  unsigned long func_type = arm_current_func_type ();
++  int static_chain_stack_bytes = 0;
++
++  if (TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM &&
++      IS_NESTED (func_type) &&
++      df_regs_ever_live_p (3) && current_function_pretend_args_size == 0)
++    static_chain_stack_bytes = 4;
++
++  return static_chain_stack_bytes;
++}
++
++
+ /* Compute a bit mask of which registers need to be
+-   saved on the stack for the current function.  */
++   saved on the stack for the current function.
++   This is used by arm_get_frame_offsets, which may add extra registers.  */
+ static unsigned long
+ arm_compute_save_reg_mask (void)
+@@ -10769,7 +12597,7 @@ arm_compute_save_reg_mask (void)
+   /* If we are creating a stack frame, then we must save the frame pointer,
+      IP (which will hold the old stack pointer), LR and the PC.  */
+-  if (frame_pointer_needed && TARGET_ARM)
++  if (TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM)
+     save_reg_mask |=
+       (1 << ARM_HARD_FRAME_POINTER_REGNUM)
+       | (1 << IP_REGNUM)
+@@ -10804,7 +12632,9 @@ arm_compute_save_reg_mask (void)
+   if (TARGET_REALLY_IWMMXT
+       && ((bit_count (save_reg_mask)
+-         + ARM_NUM_INTS (current_function_pretend_args_size)) % 2) != 0)
++         + ARM_NUM_INTS (current_function_pretend_args_size +
++                         arm_compute_static_chain_stack_bytes())
++         ) % 2) != 0)
+     {
+       /* The total number of registers that are going to be pushed
+        onto the stack is odd.  We need to ensure that the stack
+@@ -10882,13 +12712,33 @@ thumb1_compute_save_reg_mask (void)
+       reg = thumb_find_work_register (1 << LAST_LO_REGNUM);
+       /* Make sure the register returned by thumb_find_work_register is
+        not part of the return value.  */
+-      if (reg * UNITS_PER_WORD <= arm_size_return_regs ())
++      if (reg * UNITS_PER_WORD <= (unsigned) arm_size_return_regs ())
+       reg = LAST_LO_REGNUM;
+       if (! call_used_regs[reg])
+       mask |= 1 << reg;
+     }
++  /* The 504 below is 8 bytes less than 512 because there are two possible
++     alignment words.  We can't tell here if they will be present or not so we
++     have to play it safe and assume that they are. */
++  if ((CALLER_INTERWORKING_SLOT_SIZE +
++       ROUND_UP_WORD (get_frame_size ()) +
++       current_function_outgoing_args_size) >= 504)
++    {
++      /* This is the same as the code in thumb1_expand_prologue() which
++       determines which register to use for stack decrement. */
++      for (reg = LAST_ARG_REGNUM + 1; reg <= LAST_LO_REGNUM; reg++)
++      if (mask & (1 << reg))
++        break;
++
++      if (reg > LAST_LO_REGNUM)
++      {
++        /* Make sure we have a register available for stack decrement. */
++        mask |= 1 << LAST_LO_REGNUM;
++      }
++    }
++
+   return mask;
+ }
+@@ -10916,7 +12766,7 @@ arm_get_vfp_saved_size (void)
+             if (count > 0)
+               {
+                 /* Workaround ARM10 VFPr1 bug.  */
+-                if (count == 2 && !arm_arch6)
++                if (count == 2 && !arm_arch6 && !low_irq_latency)
+                   count++;
+                 saved += count * 8;
+               }
+@@ -10979,7 +12829,8 @@ output_return_instruction (rtx operand, 
+   return_used_this_function = 1;
+-  live_regs_mask = arm_compute_save_reg_mask ();
++  offsets = arm_get_frame_offsets ();
++  live_regs_mask = offsets->saved_regs_mask;
+   if (live_regs_mask)
+     {
+@@ -11041,7 +12892,6 @@ output_return_instruction (rtx operand, 
+           {
+             unsigned HOST_WIDE_INT stack_adjust;
+-            offsets = arm_get_frame_offsets ();
+             stack_adjust = offsets->outgoing_args - offsets->saved_regs;
+             gcc_assert (stack_adjust == 0 || stack_adjust == 4);
+@@ -11245,6 +13095,41 @@ arm_output_function_prologue (FILE *f, H
+   return_used_this_function = 0;
+ }
++/* Generate to STREAM a code sequence that pops registers identified 
++   in REGS_MASK from SP. SP is incremented as the result.
++*/
++static void
++print_pop_reg_by_ldr (FILE *stream, int regs_mask, int rfe)
++{
++  int reg;
++
++  gcc_assert (! (regs_mask & (1 << SP_REGNUM)));
++  
++  for (reg = 0; reg < PC_REGNUM; ++reg)
++    if (regs_mask & (1 << reg))
++      asm_fprintf (stream, "\tldr\t%r, [%r], #4\n",
++                 reg, SP_REGNUM); 
++
++  if (regs_mask & (1 << PC_REGNUM))
++    {
++      if (rfe)
++      /* When returning from exception, we need to
++         copy SPSR to CPSR.  There are two ways to do
++         that: the ldm instruction with "^" suffix,
++         and movs instruction.  The latter would
++         require that we load from stack to some
++         scratch register, and then move to PC.
++         Therefore, we'd need extra instruction and
++         have to make sure we actually have a spare
++         register.  Using ldm with a single register
++         is simler.  */
++      asm_fprintf (stream, "\tldm\tsp!, {pc}^\n");
++      else
++      asm_fprintf (stream, "\tldr\t%r, [%r], #4\n",
++                   PC_REGNUM, SP_REGNUM); 
++    }
++}
++
+ const char *
+ arm_output_epilogue (rtx sibling)
+ {
+@@ -11289,7 +13174,7 @@ arm_output_epilogue (rtx sibling)
+   gcc_assert (!current_function_calls_eh_return || really_return);
+   offsets = arm_get_frame_offsets ();
+-  saved_regs_mask = arm_compute_save_reg_mask ();
++  saved_regs_mask = offsets->saved_regs_mask;
+   if (TARGET_IWMMXT)
+     lrm_count = bit_count (saved_regs_mask);
+@@ -11300,7 +13185,7 @@ arm_output_epilogue (rtx sibling)
+     if (saved_regs_mask & (1 << reg))
+       floats_offset += 4;
+-  if (frame_pointer_needed && TARGET_ARM)
++  if (TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM)
+     {
+       /* This variable is for the Virtual Frame Pointer, not VFP regs.  */
+       int vfp_offset = offsets->frame;
+@@ -11446,32 +13331,88 @@ arm_output_epilogue (rtx sibling)
+     }
+   else
+     {
++      /* This branch is executed for ARM mode (non-apcs frames) and
++       Thumb-2 mode. Frame layout is essentially the same for those
++       cases, except that in ARM mode frame pointer points to the
++       first saved register, while in Thumb-2 mode the frame pointer points
++       to the last saved register.
++
++       It is possible to make frame pointer point to last saved
++       register in both cases, and remove some conditionals below.
++       That means that fp setup in prologue would be just "mov fp, sp"
++       and sp restore in epilogue would be just "mov sp, fp", whereas
++       now we have to use add/sub in those cases. However, the value
++       of that would be marginal, as both mov and add/sub are 32-bit
++       in ARM mode, and it would require extra conditionals
++       in arm_expand_prologue to distingish ARM-apcs-frame case
++       (where frame pointer is required to point at first register)
++       and ARM-non-apcs-frame. Therefore, such change is postponed
++       until real need arise.  */
+       HOST_WIDE_INT amount;
+       int rfe;
+       /* Restore stack pointer if necessary.  */
+-      if (frame_pointer_needed)
++      if (TARGET_ARM && frame_pointer_needed)
+       {
+-        /* For Thumb-2 restore sp from the frame pointer.
+-           Operand restrictions mean we have to increment FP, then copy
+-           to SP.  */
+-        amount = offsets->locals_base - offsets->saved_regs;
+-        operands[0] = hard_frame_pointer_rtx;
++        operands[0] = stack_pointer_rtx;
++        operands[1] = hard_frame_pointer_rtx;
++
++        operands[2] = GEN_INT (offsets->frame - offsets->saved_regs);
++        output_add_immediate (operands);
+       }
+       else
+       {
+-        operands[0] = stack_pointer_rtx;
+-        amount = offsets->outgoing_args - offsets->saved_regs;
+-      }
++        if (frame_pointer_needed)
++          {
++            /* For Thumb-2 restore sp from the frame pointer.
++               Operand restrictions mean we have to incrememnt FP, then copy
++               to SP.  */
++            amount = offsets->locals_base - offsets->saved_regs;
++            operands[0] = hard_frame_pointer_rtx;
++            }
++          else
++            {
++            unsigned long count;
++            operands[0] = stack_pointer_rtx;
++            amount = offsets->outgoing_args - offsets->saved_regs;
++              /* Pop call clobbered registers if it avoids a
++               separate stack adjustment.  */
++              count = offsets->saved_regs - offsets->saved_args;
++              if (optimize_size
++                && count != 0
++                && !current_function_calls_eh_return
++                && bit_count (saved_regs_mask) * 4 == count
++                && !IS_INTERRUPT (func_type)
++                && !cfun->tail_call_emit)
++              {
++                unsigned long mask;
++                mask = (1 << (arm_size_return_regs () / 4)) - 1;
++                mask ^= 0xf;
++                mask &= ~saved_regs_mask;
++                reg = 0;
++                while (bit_count (mask) * 4 > amount)
++                    {
++                      while ((mask & (1 << reg)) == 0)
++                      reg++;
++                      mask &= ~(1 << reg);
++                    }
++                if (bit_count (mask) * 4 == amount)
++                  {
++                      amount = 0;
++                      saved_regs_mask |= mask;
++                  }
++                }
++          }
+-      if (amount)
+-      {
+-        operands[1] = operands[0];
+-        operands[2] = GEN_INT (amount);
+-        output_add_immediate (operands);
++        if (amount)
++          {
++            operands[1] = operands[0];
++            operands[2] = GEN_INT (amount);
++            output_add_immediate (operands);
++          }
++        if (frame_pointer_needed)
++          asm_fprintf (f, "\tmov\t%r, %r\n",
++                       SP_REGNUM, HARD_FRAME_POINTER_REGNUM);
+       }
+-      if (frame_pointer_needed)
+-      asm_fprintf (f, "\tmov\t%r, %r\n",
+-                   SP_REGNUM, HARD_FRAME_POINTER_REGNUM);
+       if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
+       {
+@@ -11557,22 +13498,19 @@ arm_output_epilogue (rtx sibling)
+        to load use the LDR instruction - it is faster.  For Thumb-2
+        always use pop and the assembler will pick the best instruction.*/
+       if (TARGET_ARM && saved_regs_mask == (1 << LR_REGNUM)
+-        && !IS_INTERRUPT(func_type))
++        && !IS_INTERRUPT (func_type))
+       {
+         asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM);
+       }
+       else if (saved_regs_mask)
+       {
+-        if (saved_regs_mask & (1 << SP_REGNUM))
+-          /* Note - write back to the stack register is not enabled
+-             (i.e. "ldmfd sp!...").  We know that the stack pointer is
+-             in the list of registers and if we add writeback the
+-             instruction becomes UNPREDICTABLE.  */
+-          print_multi_reg (f, "ldmfd\t%r, ", SP_REGNUM, saved_regs_mask,
+-                           rfe);
+-        else if (TARGET_ARM)
+-          print_multi_reg (f, "ldmfd\t%r!, ", SP_REGNUM, saved_regs_mask,
+-                           rfe);
++        gcc_assert ( ! (saved_regs_mask & (1 << SP_REGNUM)));
++        if (TARGET_ARM)
++          if (low_irq_latency)
++            print_pop_reg_by_ldr (f, saved_regs_mask, rfe);
++          else
++            print_multi_reg (f, "ldmfd\t%r!, ", SP_REGNUM, saved_regs_mask,
++                             rfe);
+         else
+           print_multi_reg (f, "pop\t", SP_REGNUM, saved_regs_mask, 0);
+       }
+@@ -11693,6 +13631,32 @@ emit_multi_reg_push (unsigned long mask)
+   gcc_assert (num_regs && num_regs <= 16);
++  if (low_irq_latency)
++    {
++      rtx insn = 0;
++
++      /* Emit a series of ldr instructions rather rather than a single ldm.  */
++      /* TODO: Use ldrd where possible.  */
++      gcc_assert (! (mask & (1 << SP_REGNUM)));
++
++      for (i = LAST_ARM_REGNUM; i >= 0; --i)
++        {
++          if (mask & (1 << i))
++
++            {
++              rtx reg, where, mem;
++
++            reg = gen_rtx_REG (SImode, i);
++            where = gen_rtx_PRE_DEC (SImode, stack_pointer_rtx);
++            mem = gen_rtx_MEM (SImode, where);
++            insn = emit_move_insn (mem, reg);
++            RTX_FRAME_RELATED_P (insn) = 1;
++            }
++        }
++
++      return insn;
++    }
++
+   /* We don't record the PC in the dwarf frame information.  */
+   num_dwarf_regs = num_regs;
+   if (mask & (1 << PC_REGNUM))
+@@ -11930,7 +13894,8 @@ thumb_force_lr_save (void)
+ /* Calculate stack offsets.  These are used to calculate register elimination
+-   offsets and in prologue/epilogue code.  */
++   offsets and in prologue/epilogue code.  Also calculates which registers
++   should be saved.  */
+ static arm_stack_offsets *
+ arm_get_frame_offsets (void)
+@@ -11939,7 +13904,9 @@ arm_get_frame_offsets (void)
+   unsigned long func_type;
+   int leaf;
+   int saved;
++  int core_saved;
+   HOST_WIDE_INT frame_size;
++  int i;
+   offsets = &cfun->machine->stack_offsets;
+@@ -11966,13 +13933,16 @@ arm_get_frame_offsets (void)
+   offsets->saved_args = current_function_pretend_args_size;
+   /* In Thumb mode this is incorrect, but never used.  */
+-  offsets->frame = offsets->saved_args + (frame_pointer_needed ? 4 : 0);
++  offsets->frame = offsets->saved_args + (frame_pointer_needed ? 4 : 0) +
++                   arm_compute_static_chain_stack_bytes();
+   if (TARGET_32BIT)
+     {
+       unsigned int regno;
+-      saved = bit_count (arm_compute_save_reg_mask ()) * 4;
++      offsets->saved_regs_mask = arm_compute_save_reg_mask ();
++      core_saved = bit_count (offsets->saved_regs_mask) * 4;
++      saved = core_saved;
+       /* We know that SP will be doubleword aligned on entry, and we must
+        preserve that condition at any subroutine call.  We also require the
+@@ -12003,13 +13973,16 @@ arm_get_frame_offsets (void)
+     }
+   else /* TARGET_THUMB1 */
+     {
+-      saved = bit_count (thumb1_compute_save_reg_mask ()) * 4;
++      offsets->saved_regs_mask = thumb1_compute_save_reg_mask ();
++      core_saved = bit_count (offsets->saved_regs_mask) * 4;
++      saved = core_saved;
+       if (TARGET_BACKTRACE)
+       saved += 16;
+     }
+   /* Saved registers include the stack frame.  */
+-  offsets->saved_regs = offsets->saved_args + saved;
++  offsets->saved_regs = offsets->saved_args + saved +
++                        arm_compute_static_chain_stack_bytes();
+   offsets->soft_frame = offsets->saved_regs + CALLER_INTERWORKING_SLOT_SIZE;
+   /* A leaf function does not need any stack alignment if it has nothing
+      on the stack.  */
+@@ -12023,7 +13996,39 @@ arm_get_frame_offsets (void)
+   /* Ensure SFP has the correct alignment.  */
+   if (ARM_DOUBLEWORD_ALIGN
+       && (offsets->soft_frame & 7))
+-    offsets->soft_frame += 4;
++    {
++      offsets->soft_frame += 4;
++      /* Try to align stack by pushing an extra reg.  Don't bother doing this
++         when there is a stack frame as the alignment will be rolled into
++       the normal stack adjustment.  */
++      if (frame_size + current_function_outgoing_args_size == 0)
++      {
++        int reg = -1;
++
++        for (i = 4; i <= (TARGET_THUMB1 ? LAST_LO_REGNUM : 11); i++)
++          {
++            if ((offsets->saved_regs_mask & (1 << i)) == 0)
++              {
++                reg = i;
++                break;
++              }
++          }
++
++        if (reg == -1 && arm_size_return_regs () <= 12
++            && !cfun->tail_call_emit)
++          {
++            /* Push/pop an argument register (r3) if all callee saved
++               registers are already being pushed.  */
++            reg = 3;
++          }
++
++        if (reg != -1)
++          {
++            offsets->saved_regs += 4;
++            offsets->saved_regs_mask |= (1 << reg);
++          }
++      }
++    }
+   offsets->locals_base = offsets->soft_frame + frame_size;
+   offsets->outgoing_args = (offsets->locals_base
+@@ -12069,14 +14074,9 @@ arm_compute_initial_elimination_offset (
+         return offsets->soft_frame - offsets->saved_args;
+       case ARM_HARD_FRAME_POINTER_REGNUM:
+-        /* If there is no stack frame then the hard
+-           frame pointer and the arg pointer coincide.  */
+-        if (offsets->frame == offsets->saved_regs)
+-          return 0;
+-        /* FIXME:  Not sure about this.  Maybe we should always return 0 ?  */
+-        return (frame_pointer_needed
+-                && cfun->static_chain_decl != NULL
+-                && ! cfun->machine->uses_anonymous_args) ? 4 : 0;
++        /* This is only non-zero in the case where the static chain register
++           is stored above the frame.  */
++        return offsets->frame - offsets->saved_args - 4;
+       case STACK_POINTER_REGNUM:
+         /* If nothing has been pushed on the stack at all
+@@ -12229,9 +14229,20 @@ thumb_set_frame_pointer (arm_stack_offse
+   else
+     {
+       emit_insn (gen_movsi (hard_frame_pointer_rtx, GEN_INT (amount)));
+-      insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
+-                                  hard_frame_pointer_rtx,
+-                                  stack_pointer_rtx));
++      /* Thumb-2 RTL patterns expect sp as the first input.  Thumb-1
++         expects the first two operands to be the same.  */
++      if (TARGET_THUMB2)
++      {
++        insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
++                                      stack_pointer_rtx,
++                                      hard_frame_pointer_rtx));
++      }
++      else
++      {
++        insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
++                                      hard_frame_pointer_rtx,
++                                      stack_pointer_rtx));
++      }
+       dwarf = gen_rtx_SET (VOIDmode, hard_frame_pointer_rtx,
+                          plus_constant (stack_pointer_rtx, amount));
+       RTX_FRAME_RELATED_P (dwarf) = 1;
+@@ -12268,7 +14279,8 @@ arm_expand_prologue (void)
+   args_to_push = current_function_pretend_args_size;
+   /* Compute which register we will have to save onto the stack.  */
+-  live_regs_mask = arm_compute_save_reg_mask ();
++  offsets = arm_get_frame_offsets ();
++  live_regs_mask = offsets->saved_regs_mask;
+   ip_rtx = gen_rtx_REG (SImode, IP_REGNUM);
+@@ -12292,7 +14304,9 @@ arm_expand_prologue (void)
+       r0 = gen_rtx_REG (SImode, 0);
+       r1 = gen_rtx_REG (SImode, 1);
+-      dwarf = gen_rtx_UNSPEC (SImode, NULL_RTVEC, UNSPEC_STACK_ALIGN);
++      /* Use a real rtvec rather than NULL_RTVEC so the rest of the
++        compiler won't choke.  */
++      dwarf = gen_rtx_UNSPEC (SImode, rtvec_alloc (0), UNSPEC_STACK_ALIGN);
+       dwarf = gen_rtx_SET (VOIDmode, r0, dwarf);
+       insn = gen_movsi (r0, stack_pointer_rtx);
+       RTX_FRAME_RELATED_P (insn) = 1;
+@@ -12303,7 +14317,10 @@ arm_expand_prologue (void)
+       emit_insn (gen_movsi (stack_pointer_rtx, r1));
+     }
+-  if (frame_pointer_needed && TARGET_ARM)
++  /* For APCS frames, if IP register is clobbered
++     when creating frame, save that register in a special
++     way.  */
++  if (TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM)
+     {
+       if (IS_INTERRUPT (func_type))
+       {
+@@ -12347,6 +14364,9 @@ arm_expand_prologue (void)
+           insn = emit_set_insn (gen_rtx_REG (SImode, 3), ip_rtx);
+         else if (args_to_push == 0)
+           {
++            gcc_assert(arm_compute_static_chain_stack_bytes() == 4);
++            saved_regs += 4;
++
+             rtx dwarf;
+             insn = gen_rtx_PRE_DEC (SImode, stack_pointer_rtx);
+@@ -12402,13 +14422,13 @@ arm_expand_prologue (void)
+     }
+   /* If this is an interrupt service routine, and the link register
+-     is going to be pushed, and we are not creating a stack frame,
+-     (which would involve an extra push of IP and a pop in the epilogue)
++     is going to be pushed, and we're not generating extra
++     push of IP (needed when frame is needed and frame layout if apcs),
+      subtracting four from LR now will mean that the function return
+      can be done with a single instruction.  */
+   if ((func_type == ARM_FT_ISR || func_type == ARM_FT_FIQ)
+       && (live_regs_mask & (1 << LR_REGNUM)) != 0
+-      && ! frame_pointer_needed
++      && !(frame_pointer_needed && TARGET_APCS_FRAME)
+       && TARGET_ARM)
+     {
+       rtx lr = gen_rtx_REG (SImode, LR_REGNUM);
+@@ -12418,8 +14438,28 @@ arm_expand_prologue (void)
+   if (live_regs_mask)
+     {
+-      insn = emit_multi_reg_push (live_regs_mask);
+       saved_regs += bit_count (live_regs_mask) * 4;
++      if (optimize_size && !frame_pointer_needed
++        && saved_regs == offsets->saved_regs - offsets->saved_args)
++      {
++        /* If no coprocessor registers are being pushed and we don't have
++           to worry about a frame pointer then push extra registers to
++           create the stack frame.  This is done is a way that does not
++           alter teh frame layout, so is independent of the epilogue.  */
++        int n;
++        int frame;
++        n = 0;
++        while (n < 8 && (live_regs_mask & (1 << n)) == 0)
++          n++;
++        frame = offsets->outgoing_args - (offsets->saved_args + saved_regs);
++        if (frame && n * 4 >= frame)
++          {
++            n = frame / 4;
++            live_regs_mask |= (1 << n) - 1;
++            saved_regs += frame;
++          }
++      }
++      insn = emit_multi_reg_push (live_regs_mask);
+       RTX_FRAME_RELATED_P (insn) = 1;
+     }
+@@ -12429,6 +14469,7 @@ arm_expand_prologue (void)
+   if (frame_pointer_needed && TARGET_ARM)
+     {
+       /* Create the new frame pointer.  */
++      if (TARGET_APCS_FRAME)
+       {
+         insn = GEN_INT (-(4 + args_to_push + fp_offset));
+         insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, ip_rtx, insn));
+@@ -12450,9 +14491,15 @@ arm_expand_prologue (void)
+             emit_insn (gen_prologue_use (ip_rtx));
+           }
+       }
++      else
++      {
++        insn = GEN_INT (saved_regs - 4);
++        insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
++                                      stack_pointer_rtx, insn));
++        RTX_FRAME_RELATED_P (insn) = 1;
++      }
+     }
+-  offsets = arm_get_frame_offsets ();
+   if (offsets->outgoing_args != offsets->saved_args + saved_regs)
+     {
+       /* This add can produce multiple insns for a large constant, so we
+@@ -12633,10 +14680,21 @@ arm_print_operand (FILE *stream, rtx x, 
+       }
+       return;
+-    /* An integer without a preceding # sign.  */
++    /* An integer or symbol address without a preceding # sign.  */
+     case 'c':
+-      gcc_assert (GET_CODE (x) == CONST_INT);
+-      fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
++      switch (GET_CODE (x))
++      {
++      case CONST_INT:
++        fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
++        break;
++
++      case SYMBOL_REF:
++        output_addr_const (stream, x);
++        break;
++
++      default:
++        gcc_unreachable ();
++      }
+       return;
+     case 'B':
+@@ -12693,7 +14751,11 @@ arm_print_operand (FILE *stream, rtx x, 
+         {
+           fprintf (stream, ", %s ", shift);
+           if (val == -1)
+-            arm_print_operand (stream, XEXP (x, 1), 0);
++              {
++              arm_print_operand (stream, XEXP (x, 1), 0);
++                if (janus2_code)
++                  fprintf(stream, "\n\tnop");
++              }
+           else
+             fprintf (stream, "#" HOST_WIDE_INT_PRINT_DEC, val);
+         }
+@@ -13031,6 +15093,49 @@ arm_print_operand (FILE *stream, rtx x, 
+       }
+       return;
++    /* Memory operand for vld1/vst1 instruction.  */
++    case 'A':
++      {
++      rtx addr;
++      bool postinc = FALSE;
++      gcc_assert (GET_CODE (x) == MEM);
++      addr = XEXP (x, 0);
++      if (GET_CODE (addr) == POST_INC)
++        {
++          postinc = 1;
++          addr = XEXP (addr, 0);
++        }
++      asm_fprintf (stream, "[%r]", REGNO (addr));
++      if (postinc)
++        fputs("!", stream);
++      }
++      return;
++
++    /* Register specifier for vld1.16/vst1.16.  Translate the S register
++       number into a D register number and element index.  */
++    case 'z':
++      {
++        int mode = GET_MODE (x);
++        int regno;
++
++        if (GET_MODE_SIZE (mode) != 2 || GET_CODE (x) != REG)
++          {
++          output_operand_lossage ("invalid operand for code '%c'", code);
++          return;
++          }
++
++        regno = REGNO (x);
++        if (!VFP_REGNO_OK_FOR_SINGLE (regno))
++          {
++          output_operand_lossage ("invalid operand for code '%c'", code);
++          return;
++          }
++
++      regno = regno - FIRST_VFP_REGNUM;
++      fprintf (stream, "d%d[%d]", regno/2, ((regno % 2) ? 2 : 0));
++      }
++      return;
++      
+     default:
+       if (x == 0)
+       {
+@@ -13064,6 +15169,12 @@ arm_print_operand (FILE *stream, rtx x, 
+       default:
+         gcc_assert (GET_CODE (x) != NEG);
+         fputc ('#', stream);
++        if (GET_CODE (x) == HIGH)
++          {
++            fputs (":lower16:", stream);
++            x = XEXP (x, 0);
++          }
++          
+         output_addr_const (stream, x);
+         break;
+       }
+@@ -13104,28 +15215,16 @@ arm_assemble_integer (rtx x, unsigned in
+   if (arm_vector_mode_supported_p (mode))
+     {
+       int i, units;
+-      unsigned int invmask = 0, parts_per_word;
+       gcc_assert (GET_CODE (x) == CONST_VECTOR);
+       units = CONST_VECTOR_NUNITS (x);
+       size = GET_MODE_SIZE (GET_MODE_INNER (mode));
+-      /* For big-endian Neon vectors, we must permute the vector to the form
+-         which, when loaded by a VLDR or VLDM instruction, will give a vector
+-         with the elements in the right order.  */
+-      if (TARGET_NEON && WORDS_BIG_ENDIAN)
+-        {
+-          parts_per_word = UNITS_PER_WORD / size;
+-          /* FIXME: This might be wrong for 64-bit vector elements, but we don't
+-             support those anywhere yet.  */
+-          invmask = (parts_per_word == 0) ? 0 : (1 << (parts_per_word - 1)) - 1;
+-        }
+-
+       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
+         for (i = 0; i < units; i++)
+         {
+-          rtx elt = CONST_VECTOR_ELT (x, i ^ invmask);
++          rtx elt = CONST_VECTOR_ELT (x, i);
+           assemble_integer
+             (elt, size, i == 0 ? BIGGEST_ALIGNMENT : size * BITS_PER_UNIT, 1);
+         }
+@@ -13467,6 +15566,10 @@ arm_final_prescan_insn (rtx insn)
+      first insn after the following code_label if REVERSE is true.  */
+   rtx start_insn = insn;
++  /* Don't do this if we're not considering conditional execution.  */
++  if (TARGET_NO_SINGLE_COND_EXEC)
++    return;
++
+   /* If in state 4, check if the target branch is reached, in order to
+      change back to state 0.  */
+   if (arm_ccfsm_state == 4)
+@@ -13840,6 +15943,12 @@ arm_hard_regno_mode_ok (unsigned int reg
+       if (mode == DFmode)
+       return VFP_REGNO_OK_FOR_DOUBLE (regno);
++      /* VFP registers can hold HFmode values, but there is no point in
++       putting them there unless we have the NEON extensions for
++       loading/storing them, too.  */
++      if (mode == HFmode)
++      return TARGET_NEON_FP16 && VFP_REGNO_OK_FOR_SINGLE (regno);
++
+       if (TARGET_NEON)
+         return (VALID_NEON_DREG_MODE (mode) && VFP_REGNO_OK_FOR_DOUBLE (regno))
+                || (VALID_NEON_QREG_MODE (mode)
+@@ -13859,16 +15968,16 @@ arm_hard_regno_mode_ok (unsigned int reg
+       return mode == SImode;
+       if (IS_IWMMXT_REGNUM (regno))
+-      return VALID_IWMMXT_REG_MODE (mode);
++      return VALID_IWMMXT_REG_MODE (mode) && mode != SImode;
+     }
+   
+-  /* We allow any value to be stored in the general registers.
++  /* We allow almost any value to be stored in the general registers.
+      Restrict doubleword quantities to even register pairs so that we can
+-     use ldrd.  Do not allow Neon structure opaque modes in general registers;
+-     they would use too many.  */
++     use ldrd.  Do not allow very large Neon structure opaque modes in
++     general registers; they would use too many.  */
+   if (regno <= LAST_ARM_REGNUM)
+     return !(TARGET_LDRD && GET_MODE_SIZE (mode) > 4 && (regno & 1) != 0)
+-      && !VALID_NEON_STRUCT_MODE (mode);
++      && ARM_NUM_REGS (mode) <= 4;
+   if (regno == FRAME_POINTER_REGNUM
+       || regno == ARG_POINTER_REGNUM)
+@@ -14913,6 +17022,24 @@ arm_init_neon_builtins (void)
+   TYPE_PRECISION (neon_float_type_node) = FLOAT_TYPE_SIZE;
+   layout_type (neon_float_type_node);
++  /* Define typedefs which exactly correspond to the modes we are basing vector
++     types on.  If you change these names you'll need to change
++     the table used by arm_mangle_type too.  */
++  (*lang_hooks.types.register_builtin_type) (neon_intQI_type_node,
++                                           "__builtin_neon_qi");
++  (*lang_hooks.types.register_builtin_type) (neon_intHI_type_node,
++                                           "__builtin_neon_hi");
++  (*lang_hooks.types.register_builtin_type) (neon_intSI_type_node,
++                                           "__builtin_neon_si");
++  (*lang_hooks.types.register_builtin_type) (neon_float_type_node,
++                                           "__builtin_neon_sf");
++  (*lang_hooks.types.register_builtin_type) (neon_intDI_type_node,
++                                           "__builtin_neon_di");
++  (*lang_hooks.types.register_builtin_type) (neon_polyQI_type_node,
++                                           "__builtin_neon_poly8");
++  (*lang_hooks.types.register_builtin_type) (neon_polyHI_type_node,
++                                           "__builtin_neon_poly16");
++
+   intQI_pointer_node = build_pointer_type (neon_intQI_type_node);
+   intHI_pointer_node = build_pointer_type (neon_intHI_type_node);
+   intSI_pointer_node = build_pointer_type (neon_intSI_type_node);
+@@ -14965,12 +17092,32 @@ arm_init_neon_builtins (void)
+   intUSI_type_node = make_unsigned_type (GET_MODE_PRECISION (SImode));
+   intUDI_type_node = make_unsigned_type (GET_MODE_PRECISION (DImode));
++  (*lang_hooks.types.register_builtin_type) (intUQI_type_node,
++                                           "__builtin_neon_uqi");
++  (*lang_hooks.types.register_builtin_type) (intUHI_type_node,
++                                           "__builtin_neon_uhi");
++  (*lang_hooks.types.register_builtin_type) (intUSI_type_node,
++                                           "__builtin_neon_usi");
++  (*lang_hooks.types.register_builtin_type) (intUDI_type_node,
++                                           "__builtin_neon_udi");
++
+   /* Opaque integer types for structures of vectors.  */
+   intEI_type_node = make_signed_type (GET_MODE_PRECISION (EImode));
+   intOI_type_node = make_signed_type (GET_MODE_PRECISION (OImode));
+   intCI_type_node = make_signed_type (GET_MODE_PRECISION (CImode));
+   intXI_type_node = make_signed_type (GET_MODE_PRECISION (XImode));
++  (*lang_hooks.types.register_builtin_type) (intTI_type_node,
++                                           "__builtin_neon_ti");
++  (*lang_hooks.types.register_builtin_type) (intEI_type_node,
++                                           "__builtin_neon_ei");
++  (*lang_hooks.types.register_builtin_type) (intOI_type_node,
++                                           "__builtin_neon_oi");
++  (*lang_hooks.types.register_builtin_type) (intCI_type_node,
++                                           "__builtin_neon_ci");
++  (*lang_hooks.types.register_builtin_type) (intXI_type_node,
++                                           "__builtin_neon_xi");
++
+   /* Pointers to vector types.  */
+   V8QI_pointer_node = build_pointer_type (V8QI_type_node);
+   V4HI_pointer_node = build_pointer_type (V4HI_type_node);
+@@ -15014,44 +17161,6 @@ arm_init_neon_builtins (void)
+     build_function_type_list (void_type_node, V2DI_pointer_node, V2DI_type_node,
+                             V2DI_type_node, NULL);
+-  /* Define typedefs which exactly correspond to the modes we are basing vector
+-     types on.  If you change these names you'll need to change
+-     the table used by arm_mangle_type too.  */
+-  (*lang_hooks.types.register_builtin_type) (neon_intQI_type_node,
+-                                           "__builtin_neon_qi");
+-  (*lang_hooks.types.register_builtin_type) (neon_intHI_type_node,
+-                                           "__builtin_neon_hi");
+-  (*lang_hooks.types.register_builtin_type) (neon_intSI_type_node,
+-                                           "__builtin_neon_si");
+-  (*lang_hooks.types.register_builtin_type) (neon_float_type_node,
+-                                           "__builtin_neon_sf");
+-  (*lang_hooks.types.register_builtin_type) (neon_intDI_type_node,
+-                                           "__builtin_neon_di");
+-
+-  (*lang_hooks.types.register_builtin_type) (neon_polyQI_type_node,
+-                                           "__builtin_neon_poly8");
+-  (*lang_hooks.types.register_builtin_type) (neon_polyHI_type_node,
+-                                           "__builtin_neon_poly16");
+-  (*lang_hooks.types.register_builtin_type) (intUQI_type_node,
+-                                           "__builtin_neon_uqi");
+-  (*lang_hooks.types.register_builtin_type) (intUHI_type_node,
+-                                           "__builtin_neon_uhi");
+-  (*lang_hooks.types.register_builtin_type) (intUSI_type_node,
+-                                           "__builtin_neon_usi");
+-  (*lang_hooks.types.register_builtin_type) (intUDI_type_node,
+-                                           "__builtin_neon_udi");
+-
+-  (*lang_hooks.types.register_builtin_type) (intTI_type_node,
+-                                           "__builtin_neon_ti");
+-  (*lang_hooks.types.register_builtin_type) (intEI_type_node,
+-                                           "__builtin_neon_ei");
+-  (*lang_hooks.types.register_builtin_type) (intOI_type_node,
+-                                           "__builtin_neon_oi");
+-  (*lang_hooks.types.register_builtin_type) (intCI_type_node,
+-                                           "__builtin_neon_ci");
+-  (*lang_hooks.types.register_builtin_type) (intXI_type_node,
+-                                           "__builtin_neon_xi");
+-
+   dreg_types[0] = V8QI_type_node;
+   dreg_types[1] = V4HI_type_node;
+   dreg_types[2] = V2SI_type_node;
+@@ -15325,6 +17434,15 @@ arm_init_neon_builtins (void)
+ }
+ static void
++arm_init_fp16_builtins (void)
++{
++  tree fp16_type = make_node (REAL_TYPE);
++  TYPE_PRECISION (fp16_type) = 16;
++  layout_type (fp16_type);
++  (*lang_hooks.types.register_builtin_type) (fp16_type, "__fp16");
++}
++
++static void
+ arm_init_builtins (void)
+ {
+   arm_init_tls_builtins ();
+@@ -15334,6 +17452,52 @@ arm_init_builtins (void)
+   if (TARGET_NEON)
+     arm_init_neon_builtins ();
++
++  if (arm_fp16_format)
++    arm_init_fp16_builtins ();
++}
++
++/* Implement TARGET_INVALID_PARAMETER_TYPE.  */
++
++static const char *
++arm_invalid_parameter_type (const_tree t)
++{
++  if (SCALAR_FLOAT_TYPE_P (t) && TYPE_PRECISION (t) == 16)
++    return N_("function parameters cannot have __fp16 type");
++  return NULL;
++}
++
++/* Implement TARGET_INVALID_PARAMETER_TYPE.  */
++
++static const char *
++arm_invalid_return_type (const_tree t)
++{
++  if (SCALAR_FLOAT_TYPE_P (t) && TYPE_PRECISION (t) == 16)
++    return N_("functions cannot return __fp16 type");
++  return NULL;
++}
++
++/* Implement TARGET_PROMOTED_TYPE.  */
++
++static tree
++arm_promoted_type (const_tree t)
++{
++  if (SCALAR_FLOAT_TYPE_P (t) && TYPE_PRECISION (t) == 16)
++    return float_type_node;
++  return NULL_TREE;
++}
++
++/* Implement TARGET_CONVERT_TO_TYPE.  */
++static tree
++arm_convert_to_type (tree type, tree expr)
++{
++  tree fromtype = TREE_TYPE (expr);
++  if (!SCALAR_FLOAT_TYPE_P (fromtype) || !SCALAR_FLOAT_TYPE_P (type))
++    return NULL_TREE;
++  if ((TYPE_PRECISION (fromtype) == 16 && TYPE_PRECISION (type) > 32)
++      || (TYPE_PRECISION (type) == 16 && TYPE_PRECISION (fromtype) > 32))
++    return convert (type, convert (float_type_node, expr));
++  return NULL_TREE;
+ }
+ /* Errors in the source file can cause expand_expr to return const0_rtx
+@@ -16514,6 +18678,7 @@ is_called_in_ARM_mode (tree func)
+ const char *
+ thumb_unexpanded_epilogue (void)
+ {
++  arm_stack_offsets *offsets;
+   int regno;
+   unsigned long live_regs_mask = 0;
+   int high_regs_pushed = 0;
+@@ -16526,7 +18691,8 @@ thumb_unexpanded_epilogue (void)
+   if (IS_NAKED (arm_current_func_type ()))
+     return "";
+-  live_regs_mask = thumb1_compute_save_reg_mask ();
++  offsets = arm_get_frame_offsets ();
++  live_regs_mask = offsets->saved_regs_mask;
+   high_regs_pushed = bit_count (live_regs_mask & 0x0f00);
+   /* If we can deduce the registers used from the function's return value.
+@@ -16788,7 +18954,8 @@ thumb1_expand_prologue (void)
+       return;
+     }
+-  live_regs_mask = thumb1_compute_save_reg_mask ();
++  offsets = arm_get_frame_offsets ();
++  live_regs_mask = offsets->saved_regs_mask;
+   /* Load the pic register before setting the frame pointer,
+      so we can use r7 as a temporary work register.  */
+   if (flag_pic && arm_pic_register != INVALID_REGNUM)
+@@ -16798,7 +18965,6 @@ thumb1_expand_prologue (void)
+     emit_move_insn (gen_rtx_REG (Pmode, ARM_HARD_FRAME_POINTER_REGNUM),
+                   stack_pointer_rtx);
+-  offsets = arm_get_frame_offsets ();
+   amount = offsets->outgoing_args - offsets->saved_regs;
+   if (amount)
+     {
+@@ -16827,62 +18993,25 @@ thumb1_expand_prologue (void)
+            been pushed at the start of the prologue and so we can corrupt
+            it now.  */
+         for (regno = LAST_ARG_REGNUM + 1; regno <= LAST_LO_REGNUM; regno++)
+-          if (live_regs_mask & (1 << regno)
+-              && !(frame_pointer_needed
+-                   && (regno == THUMB_HARD_FRAME_POINTER_REGNUM)))
++          if (live_regs_mask & (1 << regno))
+             break;
+-        if (regno > LAST_LO_REGNUM) /* Very unlikely.  */
+-          {
+-            rtx spare = gen_rtx_REG (SImode, IP_REGNUM);
+-
+-            /* Choose an arbitrary, non-argument low register.  */
+-            reg = gen_rtx_REG (SImode, LAST_LO_REGNUM);
+-
+-            /* Save it by copying it into a high, scratch register.  */
+-            emit_insn (gen_movsi (spare, reg));
+-            /* Add a USE to stop propagate_one_insn() from barfing.  */
+-            emit_insn (gen_prologue_use (spare));
++        gcc_assert(regno <= LAST_LO_REGNUM);
+-            /* Decrement the stack.  */
+-            emit_insn (gen_movsi (reg, GEN_INT (- amount)));
+-            insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
+-                                          stack_pointer_rtx, reg));
+-            RTX_FRAME_RELATED_P (insn) = 1;
+-            dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+-                                 plus_constant (stack_pointer_rtx,
+-                                                -amount));
+-            RTX_FRAME_RELATED_P (dwarf) = 1;
+-            REG_NOTES (insn)
+-              = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
+-                                   REG_NOTES (insn));
+-
+-            /* Restore the low register's original value.  */
+-            emit_insn (gen_movsi (reg, spare));
+-
+-            /* Emit a USE of the restored scratch register, so that flow
+-               analysis will not consider the restore redundant.  The
+-               register won't be used again in this function and isn't
+-               restored by the epilogue.  */
+-            emit_insn (gen_prologue_use (reg));
+-          }
+-        else
+-          {
+-            reg = gen_rtx_REG (SImode, regno);
++        reg = gen_rtx_REG (SImode, regno);
+-            emit_insn (gen_movsi (reg, GEN_INT (- amount)));
++        emit_insn (gen_movsi (reg, GEN_INT (- amount)));
+-            insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
+-                                          stack_pointer_rtx, reg));
+-            RTX_FRAME_RELATED_P (insn) = 1;
+-            dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+-                                 plus_constant (stack_pointer_rtx,
+-                                                -amount));
+-            RTX_FRAME_RELATED_P (dwarf) = 1;
+-            REG_NOTES (insn)
+-              = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
+-                                   REG_NOTES (insn));
+-          }
++        insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
++                                      stack_pointer_rtx, reg));
++        RTX_FRAME_RELATED_P (insn) = 1;
++        dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
++                             plus_constant (stack_pointer_rtx,
++                                            -amount));
++        RTX_FRAME_RELATED_P (dwarf) = 1;
++        REG_NOTES (insn)
++          = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
++                               REG_NOTES (insn));
+       }
+     }
+@@ -16960,6 +19089,7 @@ thumb1_expand_epilogue (void)
+ static void
+ thumb1_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
+ {
++  arm_stack_offsets *offsets;
+   unsigned long live_regs_mask = 0;
+   unsigned long l_mask;
+   unsigned high_regs_pushed = 0;
+@@ -17044,7 +19174,8 @@ thumb1_output_function_prologue (FILE *f
+     }
+   /* Get the registers we are going to push.  */
+-  live_regs_mask = thumb1_compute_save_reg_mask ();
++  offsets = arm_get_frame_offsets ();
++  live_regs_mask = offsets->saved_regs_mask;
+   /* Extract a mask of the ones we can give to the Thumb's push instruction.  */
+   l_mask = live_regs_mask & 0x40ff;
+   /* Then count how many other high registers will need to be pushed.  */
+@@ -17551,14 +19682,22 @@ arm_file_start (void)
+             fpu_name = "vfp";
+             set_float_abi_attributes = 1;
+             break;
++          case FPUTYPE_VFP3D16:
++            fpu_name = "vfpv3-d16";
++            set_float_abi_attributes = 1;
++            break;
+           case FPUTYPE_VFP3:
+-            fpu_name = "vfp3";
++            fpu_name = "vfpv3";
+             set_float_abi_attributes = 1;
+             break;
+           case FPUTYPE_NEON:
+             fpu_name = "neon";
+             set_float_abi_attributes = 1;
+             break;
++          case FPUTYPE_NEON_FP16:
++            fpu_name = "neon-fp16";
++            set_float_abi_attributes = 1;
++            break;
+           default:
+             abort();
+           }
+@@ -17612,6 +19751,11 @@ arm_file_start (void)
+       val = 6;
+       asm_fprintf (asm_out_file, "\t.eabi_attribute 30, %d\n", val);
++      /* Tag_ABI_FP_16bit_format.  */
++      if (arm_fp16_format)
++      asm_fprintf (asm_out_file, "\t.eabi_attribute 38, %d\n",
++                   (int)arm_fp16_format);
++
+       if (arm_lang_output_object_attributes_hook)
+       arm_lang_output_object_attributes_hook();
+     }
+@@ -17694,12 +19838,23 @@ arm_output_mi_thunk (FILE *file, tree th
+                     ? 1 : 0);
+   if (mi_delta < 0)
+     mi_delta = - mi_delta;
+-  /* When generating 16-bit thumb code, thunks are entered in arm mode.  */
++
+   if (TARGET_THUMB1)
+     {
+       int labelno = thunk_label++;
+       ASM_GENERATE_INTERNAL_LABEL (label, "LTHUMBFUNC", labelno);
+-      fputs ("\tldr\tr12, ", file);
++      /* Thunks are entered in arm mode when avaiable.  */
++      if (TARGET_THUMB1_ONLY)
++      {
++        /* push r3 so we can use it as a temporary.  */
++        /* TODO: Omit this save if r3 is not used.  */
++        fputs ("\tpush {r3}\n", file);
++        fputs ("\tldr\tr3, ", file);
++      }
++      else
++      {
++        fputs ("\tldr\tr12, ", file);
++      }
+       assemble_name (file, label);
+       fputc ('\n', file);
+       if (flag_pic)
+@@ -17713,29 +19868,63 @@ arm_output_mi_thunk (FILE *file, tree th
+            Note that we have "+ 1" because some versions of GNU ld
+            don't set the low bit of the result for R_ARM_REL32
+-           relocations against thumb function symbols.  */
++           relocations against thumb function symbols.
++           On ARMV6M this is +4, not +8.  */
+         ASM_GENERATE_INTERNAL_LABEL (labelpc, "LTHUNKPC", labelno);
+         assemble_name (file, labelpc);
+         fputs (":\n", file);
+-        fputs ("\tadd\tr12, pc, r12\n", file);
++        if (TARGET_THUMB1_ONLY)
++          {
++            /* This is 2 insns after the start of the thunk, so we know it
++               is 4-byte aligned.  */
++            fputs ("\tadd\tr3, pc, r3\n", file);
++            fputs ("\tmov r12, r3\n", file);
++          }
++        else
++          fputs ("\tadd\tr12, pc, r12\n", file);
+       }
++      else if (TARGET_THUMB1_ONLY)
++      fputs ("\tmov r12, r3\n", file);
+     }
+-  /* TODO: Use movw/movt for large constants when available.  */
+-  while (mi_delta != 0)
++  if (TARGET_THUMB1_ONLY)
+     {
+-      if ((mi_delta & (3 << shift)) == 0)
+-        shift += 2;
+-      else
+-        {
+-          asm_fprintf (file, "\t%s\t%r, %r, #%d\n",
+-                       mi_op, this_regno, this_regno,
+-                       mi_delta & (0xff << shift));
+-          mi_delta &= ~(0xff << shift);
+-          shift += 8;
+-        }
++      if (mi_delta > 255)
++      {
++        fputs ("\tldr\tr3, ", file);
++        assemble_name (file, label);
++        fputs ("+4\n", file);
++        asm_fprintf (file, "\t%s\t%r, %r, r3\n",
++                     mi_op, this_regno, this_regno);
++      }
++      else if (mi_delta != 0)
++      {
++        asm_fprintf (file, "\t%s\t%r, %r, #%d\n",
++                     mi_op, this_regno, this_regno,
++                     mi_delta);
++      }
++    }
++  else
++    {
++      /* TODO: Use movw/movt for large constants when available.  */
++      while (mi_delta != 0)
++      {
++        if ((mi_delta & (3 << shift)) == 0)
++          shift += 2;
++        else
++          {
++            asm_fprintf (file, "\t%s\t%r, %r, #%d\n",
++                         mi_op, this_regno, this_regno,
++                         mi_delta & (0xff << shift));
++            mi_delta &= ~(0xff << shift);
++            shift += 8;
++          }
++      }
+     }
+   if (TARGET_THUMB1)
+     {
++      if (TARGET_THUMB1_ONLY)
++      fputs ("\tpop\t{r3}\n", file);
++
+       fprintf (file, "\tbx\tr12\n");
+       ASM_OUTPUT_ALIGN (file, 2);
+       assemble_name (file, label);
+@@ -17754,6 +19943,9 @@ arm_output_mi_thunk (FILE *file, tree th
+       else
+       /* Output ".word .LTHUNKn".  */
+       assemble_integer (XEXP (DECL_RTL (function), 0), 4, BITS_PER_WORD, 1);
++
++      if (TARGET_THUMB1_ONLY && mi_delta > 255)
++      assemble_integer (GEN_INT(mi_delta), 4, BITS_PER_WORD, 1);
+     }
+   else
+     {
+@@ -17793,6 +19985,23 @@ arm_emit_vector_const (FILE *file, rtx x
+   return 1;
+ }
++/* Emit a fp16 constant appropriately padded to occupy a 4-byte word.
++   HFmode constant pool entries are actually loaded with ldr.  */
++void
++arm_emit_fp16_const (rtx c)
++{
++  REAL_VALUE_TYPE r;
++  long bits;
++
++  REAL_VALUE_FROM_CONST_DOUBLE (r, c);
++  bits = real_to_target (NULL, &r, HFmode);
++  if (WORDS_BIG_ENDIAN)
++    assemble_zeros (2);
++  assemble_integer (GEN_INT (bits), 2, BITS_PER_WORD, 1);
++  if (!WORDS_BIG_ENDIAN)
++    assemble_zeros (2);
++}
++
+ const char *
+ arm_output_load_gr (rtx *operands)
+ {
+@@ -17830,19 +20039,24 @@ arm_output_load_gr (rtx *operands)
+    that way.  */
+ static void
+-arm_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
++arm_setup_incoming_varargs (CUMULATIVE_ARGS *pcum,
+                           enum machine_mode mode,
+                           tree type,
+                           int *pretend_size,
+                           int second_time ATTRIBUTE_UNUSED)
+ {
+-  int nregs = cum->nregs;
+-  if (nregs & 1
+-      && ARM_DOUBLEWORD_ALIGN
+-      && arm_needs_doubleword_align (mode, type))
+-    nregs++;
+-
++  int nregs;
++  
+   cfun->machine->uses_anonymous_args = 1;
++  if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
++    {
++      nregs = pcum->aapcs_ncrn;
++      if ((nregs & 1) && arm_needs_doubleword_align (mode, type))
++      nregs++;
++    }
++  else
++    nregs = pcum->nregs;
++  
+   if (nregs < NUM_ARG_REGS)
+     *pretend_size = (NUM_ARG_REGS - nregs) * UNITS_PER_WORD;
+ }
+@@ -17956,8 +20170,14 @@ arm_no_early_mul_dep (rtx producer, rtx 
+     op = XVECEXP (op, 0, 0);
+   op = XEXP (op, 1);
+-  return (GET_CODE (op) == PLUS
+-        && !reg_overlap_mentioned_p (value, XEXP (op, 0)));
++  if (GET_CODE (op) == PLUS || GET_CODE (op) == MINUS)
++    {
++      if (GET_CODE (XEXP (op, 0)) == MULT)
++      return !reg_overlap_mentioned_p (value, XEXP (op, 0));
++      else
++      return !reg_overlap_mentioned_p (value, XEXP (op, 1));
++    }
++  return 0;
+ }
+ /* We can't rely on the caller doing the proper promotion when
+@@ -18084,7 +20304,8 @@ arm_cxx_key_method_may_be_inline (void)
+ static void
+ arm_cxx_determine_class_data_visibility (tree decl)
+ {
+-  if (!TARGET_AAPCS_BASED)
++  if (!TARGET_AAPCS_BASED
++      || !TARGET_DLLIMPORT_DECL_ATTRIBUTES)
+     return;
+   /* In general, \S 3.2.5.5 of the ARM EABI requires that class data
+@@ -18124,7 +20345,8 @@ arm_set_return_address (rtx source, rtx 
+   rtx addr;
+   unsigned long saved_regs;
+-  saved_regs = arm_compute_save_reg_mask ();
++  offsets = arm_get_frame_offsets ();
++  saved_regs = offsets->saved_regs_mask;
+   if ((saved_regs & (1 << LR_REGNUM)) == 0)
+     emit_move_insn (gen_rtx_REG (Pmode, LR_REGNUM), source);
+@@ -18135,7 +20357,6 @@ arm_set_return_address (rtx source, rtx 
+       else
+       {
+         /* LR will be the first saved register.  */
+-        offsets = arm_get_frame_offsets ();
+         delta = offsets->outgoing_args - (offsets->frame + 4);
+@@ -18168,11 +20389,10 @@ thumb_set_return_address (rtx source, rt
+   emit_insn (gen_rtx_USE (VOIDmode, source));
+-  mask = thumb1_compute_save_reg_mask ();
++  offsets = arm_get_frame_offsets ();
++  mask = offsets->saved_regs_mask;
+   if (mask & (1 << LR_REGNUM))
+     {
+-      offsets = arm_get_frame_offsets ();
+-
+       limit = 1024;
+       /* Find the saved regs.  */
+       if (frame_pointer_needed)
+@@ -18219,9 +20439,10 @@ arm_vector_mode_supported_p (enum machin
+       || mode == V16QImode || mode == V4SFmode || mode == V2DImode))
+     return true;
+-  if ((mode == V2SImode)
+-      || (mode == V4HImode)
+-      || (mode == V8QImode))
++  if ((TARGET_NEON || TARGET_IWMMXT)
++      && ((mode == V2SImode)
++        || (mode == V4HImode)
++        || (mode == V8QImode)))
+     return true;
+   return false;
+@@ -18252,9 +20473,14 @@ arm_dbx_register_number (unsigned int re
+   if (IS_FPA_REGNUM (regno))
+     return (TARGET_AAPCS_BASED ? 96 : 16) + regno - FIRST_FPA_REGNUM;
+-  /* FIXME: VFPv3 register numbering.  */
+   if (IS_VFP_REGNUM (regno))
+-    return 64 + regno - FIRST_VFP_REGNUM;
++    {
++      /* See comment in arm_dwarf_register_span.  */
++      if (VFP_REGNO_OK_FOR_SINGLE (regno))
++        return 64 + regno - FIRST_VFP_REGNUM;
++      else
++        return 256 + (regno - FIRST_VFP_REGNUM) / 2;
++    }
+   if (IS_IWMMXT_GR_REGNUM (regno))
+     return 104 + regno - FIRST_IWMMXT_GR_REGNUM;
+@@ -18265,6 +20491,39 @@ arm_dbx_register_number (unsigned int re
+   gcc_unreachable ();
+ }
++/* Dwarf models VFPv3 registers as 32 64-bit registers.
++   GCC models tham as 64 32-bit registers, so we need to describe this to
++   the DWARF generation code.  Other registers can use the default.  */
++static rtx
++arm_dwarf_register_span(rtx rtl)
++{
++    unsigned regno;
++    int nregs;
++    int i;
++    rtx p;
++
++    regno = REGNO (rtl);
++    if (!IS_VFP_REGNUM (regno))
++      return NULL_RTX;
++
++    /* The EABI defines two VFP register ranges:
++        64-95: Legacy VFPv2 numbering for S0-S31 (obsolescent)
++        256-287: D0-D31
++       The recommended encodings for s0-s31 is a DW_OP_bit_piece of the
++       corresponding D register.  However gdb6.6 does not support this, so
++       we use the legacy encodings.  We also use these encodings for D0-D15
++       for compatibility with older debuggers.  */
++    if (VFP_REGNO_OK_FOR_SINGLE (regno))
++      return NULL_RTX;
++
++    nregs = GET_MODE_SIZE (GET_MODE (rtl)) / 8;
++    p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc(nregs));
++    regno = (regno - FIRST_VFP_REGNUM) / 2;
++    for (i = 0; i < nregs; i++)
++      XVECEXP (p, 0, i) = gen_rtx_REG (DImode, 256 + regno + i);
++
++    return p;
++}
+ #ifdef TARGET_UNWIND_INFO
+ /* Emit unwind directives for a store-multiple instruction or stack pointer
+@@ -18483,6 +20742,11 @@ arm_unwind_emit (FILE * asm_out_file, rt
+   if (!ARM_EABI_UNWIND_TABLES)
+     return;
++  if (!(flag_unwind_tables || cfun->uses_eh_lsda)
++      && (TREE_NOTHROW (current_function_decl)
++        || cfun->all_throwers_are_sibcalls))
++    return;
++
+   if (GET_CODE (insn) == NOTE || !RTX_FRAME_RELATED_P (insn))
+     return;
+@@ -18563,7 +20827,17 @@ arm_output_fn_unwind (FILE * f, bool pro
+   if (prologue)
+     fputs ("\t.fnstart\n", f);
+   else
+-    fputs ("\t.fnend\n", f);
++    {
++      /* If this function will never be unwound, then mark it as such.
++         The came condition is used in arm_unwind_emit to suppress
++       the frame annotations.  */
++      if (!(flag_unwind_tables || cfun->uses_eh_lsda)
++        && (TREE_NOTHROW (current_function_decl)
++            || cfun->all_throwers_are_sibcalls))
++      fputs("\t.cantunwind\n", f);
++
++      fputs ("\t.fnend\n", f);
++    }
+ }
+ static bool
+@@ -18757,6 +21031,17 @@ arm_mangle_type (const_tree type)
+ {
+   arm_mangle_map_entry *pos = arm_mangle_map;
++  /* Half-precision float.  */
++  if (TREE_CODE (type) == REAL_TYPE && TYPE_PRECISION (type) == 16)
++    return "Dh";
++
++  /* Although the ARM ABI documents do not specifically say that
++     "__va_list" has to be managled as if it is in the "std"
++     namespace, that is what RealView does.  */
++  if (TARGET_AAPCS_BASED 
++      && lang_hooks.types_compatible_p (type, va_list_type))
++    return "St9__va_list";
++
+   if (TREE_CODE (type) != VECTOR_TYPE)
+     return NULL;
+@@ -18779,5 +21064,91 @@ arm_mangle_type (const_tree type)
+      vector types.  */
+   return NULL;
+ }
++ 
++/* Return how many instructions the machine can issue per cycle.  */
++static int
++arm_issue_rate (void)
++{
++  switch (arm_tune)
++    {
++    case marvell_f:
++    case cortexr4:
++    case cortexr4f:
++    case cortexa8:
++    case cortexa9:
++      return 2;
++    default:
++      return 1;
++    }
++}
++
++/* Return how many instructions to look ahead for better insn
++   scheduling.  */
++static int
++arm_multipass_dfa_lookahead (void)
++{
++  return (arm_tune == marvell_f) ? 4 : 0;
++}
++
++/* Set default optimization options.  */
++void
++arm_optimization_options (int level, int size ATTRIBUTE_UNUSED)
++{
++  /* Enable section anchors by default at -O1 or higher.  */
++  flag_section_anchors = (level > 0 ? 1 : 0);
++
++  if (size)
++    {
++      /* Select optimizations that are a win for code size.  
++         
++         The inlining options set below have two important
++         consequences for functions not explicitly marked
++         inline:
++         - Static functions used once are inlined if
++         sufficiently small.  Static functions used twice
++         are not inlined.
++         - Non-static functions are never inlined.
++         So in effect, inlining will never cause two copies
++         of function bodies to be created.  */
++      /* Empirical results show that these options benefit code 
++         size on arm.  */
++      /* FIXME: -fsee seems to be broken for Thumb-2.  */
++      /* flag_see = 1; */
++      flag_move_loop_invariants = 0;
++      /* In Thumb mode the function call code size overhead is typically very
++         small, and narrow branch instructions have very limited range.  
++         Inlining even medium sized functions tends to bloat the caller and
++         require the use of long branch instructions. On average the long
++         branches cost more than eliminating the function call overhead saves,
++         so we use extremely restrictive automatic inlining heuristics.  In ARM
++         mode the results are fairly neutral, probably due to better constant 
++         pool placement. */
++      set_param_value ("max-inline-insns-single", 1);
++      set_param_value ("max-inline-insns-auto", 1);
++    }
++}
++
++/* Order of allocation of core registers for Thumb: this allocation is
++   written over the corresponding initial entries of the array
++   initialized with REG_ALLOC_ORDER.  We allocate all low registers
++   first.  Saving and restoring a low register is usually cheaper than
++   using a call-clobbered high register.  */
++
++static const int thumb_core_reg_alloc_order[] =
++{
++   3,  2,  1,  0,  4,  5,  6,  7,
++  14, 12,  8,  9, 10, 11, 13, 15
++};
++
++/* Adjust register allocation order when compiling for Thumb.  */
++
++void
++arm_adjust_reg_alloc_order (int *order)
++{
++  if (TARGET_THUMB)
++    memcpy (order, thumb_core_reg_alloc_order,
++            sizeof (thumb_core_reg_alloc_order));
++}
+ #include "gt-arm.h"
++
+--- a/gcc/config/arm/arm.h
++++ b/gcc/config/arm/arm.h
+@@ -84,6 +84,10 @@ extern char arm_arch_name[];
+         builtin_define ("__IWMMXT__");                \
+       if (TARGET_AAPCS_BASED)                         \
+         builtin_define ("__ARM_EABI__");              \
++      if (arm_tune_marvell_f)                         \
++        builtin_define ("__ARM_TUNE_MARVELL_F__");    \
++        if (low_irq_latency)                            \
++          builtin_define ("__low_irq_latency__");       \
+     } while (0)
+ /* The various ARM cores.  */
+@@ -198,6 +202,13 @@ extern void (*arm_lang_output_object_att
+ #define TARGET_AAPCS_BASED \
+     (arm_abi != ARM_ABI_APCS && arm_abi != ARM_ABI_ATPCS)
++/* True if we should avoid generating conditional execution instructions.  */
++#define TARGET_NO_COND_EXEC           (arm_tune_marvell_f && !optimize_size)
++/* Avoid most conditional instructions, but allow pairs with opposite
++   conditions and the same destination.  */
++#define TARGET_NO_SINGLE_COND_EXEC \
++  ((arm_tune_cortex_a9 || arm_tune_marvell_f) && !optimize_size)
++
+ #define TARGET_HARD_TP                        (target_thread_pointer == TP_CP15)
+ #define TARGET_SOFT_TP                        (target_thread_pointer == TP_SOFT)
+@@ -207,24 +218,36 @@ extern void (*arm_lang_output_object_att
+ #define TARGET_32BIT                  (TARGET_ARM || arm_arch_thumb2)
+ /* 32-bit Thumb-2 code.  */
+ #define TARGET_THUMB2                 (TARGET_THUMB && arm_arch_thumb2)
++/* Thumb-1 only.  */
++#define TARGET_THUMB1_ONLY            (TARGET_THUMB1 && !arm_arch_notm)
+ /* The following two macros concern the ability to execute coprocessor
+-   instructions for VFPv3 or NEON.  TARGET_VFP3 is currently only ever
+-   tested when we know we are generating for VFP hardware; we need to
+-   be more careful with TARGET_NEON as noted below.  */
++   instructions for VFPv3 or NEON.  TARGET_VFP3/TARGET_VFPD32 are currently
++   only ever tested when we know we are generating for VFP hardware; we need
++   to be more careful with TARGET_NEON as noted below.  */
++
++/* FPU is has the full VFPv3/NEON register file of 32 D registers.  */
++#define TARGET_VFPD32 (arm_fp_model == ARM_FP_MODEL_VFP \
++                     && (arm_fpu_arch == FPUTYPE_VFP3 \
++                         || arm_fpu_arch == FPUTYPE_NEON \
++                         || arm_fpu_arch == FPUTYPE_NEON_FP16))
+-/* FPU is VFPv3 (with twice the number of D registers).  Setting the FPU to
+-   Neon automatically enables VFPv3 too.  */
++/* FPU supports VFPv3 instructions.  */
+ #define TARGET_VFP3 (arm_fp_model == ARM_FP_MODEL_VFP \
+-                   && (arm_fpu_arch == FPUTYPE_VFP3 \
+-                       || arm_fpu_arch == FPUTYPE_NEON))
++                   && (arm_fpu_arch == FPUTYPE_VFP3D16 \
++                       || TARGET_VFPD32))
++
++/* FPU supports NEON/VFP half-precision floating-point.  */
++#define TARGET_NEON_FP16 (arm_fpu_arch == FPUTYPE_NEON_FP16)
++
+ /* FPU supports Neon instructions.  The setting of this macro gets
+    revealed via __ARM_NEON__ so we add extra guards upon TARGET_32BIT
+    and TARGET_HARD_FLOAT to ensure that NEON instructions are
+    available.  */
+ #define TARGET_NEON (TARGET_32BIT && TARGET_HARD_FLOAT \
+                    && arm_fp_model == ARM_FP_MODEL_VFP \
+-                   && arm_fpu_arch == FPUTYPE_NEON)
++                   && (arm_fpu_arch == FPUTYPE_NEON \
++                       || arm_fpu_arch == FPUTYPE_NEON_FP16))
+ /* "DSP" multiply instructions, eg. SMULxy.  */
+ #define TARGET_DSP_MULTIPLY \
+@@ -233,6 +256,9 @@ extern void (*arm_lang_output_object_att
+ #define TARGET_INT_SIMD \
+   (TARGET_32BIT && arm_arch6 && arm_arch_notm)
++/* Should MOVW/MOVT be used in preference to a constant pool.  */
++#define TARGET_USE_MOVT (arm_arch_thumb2 && !optimize_size)
++
+ /* We could use unified syntax for arm mode, but for now we just use it
+    for Thumb-2.  */
+ #define TARGET_UNIFIED_ASM TARGET_THUMB2
+@@ -296,10 +322,14 @@ enum fputype
+   FPUTYPE_MAVERICK,
+   /* VFP.  */
+   FPUTYPE_VFP,
++  /* VFPv3-D16.  */
++  FPUTYPE_VFP3D16,
+   /* VFPv3.  */
+   FPUTYPE_VFP3,
+   /* Neon.  */
+-  FPUTYPE_NEON
++  FPUTYPE_NEON,
++  /* Neon with half-precision float extensions.  */
++  FPUTYPE_NEON_FP16
+ };
+ /* Recast the floating point class to be the floating point attribute.  */
+@@ -324,6 +354,21 @@ extern enum float_abi_type arm_float_abi
+ #define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_SOFT
+ #endif
++/* Which __fp16 format to use.
++   The enumeration values correspond to the numbering for the
++   Tag_ABI_FP_16bit_format attribute.
++ */
++enum arm_fp16_format_type
++{
++  ARM_FP16_FORMAT_NONE = 0,
++  ARM_FP16_FORMAT_IEEE = 1,
++  ARM_FP16_FORMAT_ALTERNATIVE = 2
++};
++
++extern enum arm_fp16_format_type arm_fp16_format;
++#define LARGEST_EXPONENT_IS_NORMAL(bits) \
++    ((bits) == 16 && arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
++
+ /* Which ABI to use.  */
+ enum arm_abi_type
+ {
+@@ -376,6 +421,9 @@ extern int arm_ld_sched;
+ /* Nonzero if generating thumb code.  */
+ extern int thumb_code;
++/* Nonzero if generating Janus2 code. */
++extern int janus2_code;
++
+ /* Nonzero if this chip is a StrongARM.  */
+ extern int arm_tune_strongarm;
+@@ -391,9 +439,15 @@ extern int arm_arch_xscale;
+ /* Nonzero if tuning for XScale.  */
+ extern int arm_tune_xscale;
++/* Nonzero if tuning for Marvell Feroceon.  */
++extern int arm_tune_marvell_f;
++
+ /* Nonzero if tuning for stores via the write buffer.  */
+ extern int arm_tune_wbuf;
++/* Nonzero if tuning for Cortex-A9.  */
++extern int arm_tune_cortex_a9;
++
+ /* Nonzero if we should define __THUMB_INTERWORK__ in the
+    preprocessor.
+    XXX This is a bit of a hack, it's intended to help work around
+@@ -407,6 +461,10 @@ extern int arm_arch_thumb2;
+ /* Nonzero if chip supports integer division instruction.  */
+ extern int arm_arch_hwdiv;
++/* Nonzero if we should minimize interrupt latency of the
++   generated code.  */
++extern int low_irq_latency;
++
+ #ifndef TARGET_DEFAULT
+ #define TARGET_DEFAULT  (MASK_APCS_FRAME)
+ #endif
+@@ -417,6 +475,9 @@ extern int arm_arch_hwdiv;
+ #define OVERRIDE_OPTIONS  arm_override_options ()
++#define OPTIMIZATION_OPTIONS(LEVEL,SIZE)              \
++      arm_optimization_options ((LEVEL), (SIZE))
++
+ /* Nonzero if PIC code requires explicit qualifiers to generate
+    PLT and GOT relocs rather than the assembler doing so implicitly.
+    Subtargets can override these if required.  */
+@@ -725,12 +786,11 @@ extern int arm_structure_size_boundary;
+       fixed_regs[regno] = call_used_regs[regno] = 1;          \
+     }                                                         \
+                                                               \
+-  if (TARGET_THUMB && optimize_size)                          \
+-    {                                                         \
+-      /* When optimizing for size, it's better not to use     \
+-       the HI regs, because of the overhead of stacking       \
+-       them.  */                                              \
+-      /* ??? Is this still true for thumb2?  */                       \
++  if (TARGET_THUMB1 && optimize_size)                         \
++    {                                                           \
++      /* When optimizing for size on Thumb-1, it's better not \
++        to use the HI regs, because of the overhead of                \
++        stacking them.  */                                      \
+       for (regno = FIRST_HI_REGNUM;                           \
+          regno <= LAST_HI_REGNUM; ++regno)                    \
+       fixed_regs[regno] = call_used_regs[regno] = 1;          \
+@@ -849,6 +909,9 @@ extern int arm_structure_size_boundary;
+ /* The number of (integer) argument register available.  */
+ #define NUM_ARG_REGS          4
++/* And similarly for the VFP.  */
++#define NUM_VFP_ARG_REGS      16
++
+ /* Return the register number of the N'th (integer) argument.  */
+ #define ARG_REGISTER(N)       (N - 1)
+@@ -942,7 +1005,7 @@ extern int arm_structure_size_boundary;
+ #define FIRST_VFP_REGNUM      63
+ #define D7_VFP_REGNUM         78  /* Registers 77 and 78 == VFP reg D7.  */
+ #define LAST_VFP_REGNUM       \
+-  (TARGET_VFP3 ? LAST_HI_VFP_REGNUM : LAST_LO_VFP_REGNUM)
++  (TARGET_VFPD32 ? LAST_HI_VFP_REGNUM : LAST_LO_VFP_REGNUM)
+ #define IS_VFP_REGNUM(REGNUM) \
+   (((REGNUM) >= FIRST_VFP_REGNUM) && ((REGNUM) <= LAST_VFP_REGNUM))
+@@ -1027,7 +1090,7 @@ extern int arm_structure_size_boundary;
+   (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2))
+ #define VALID_IWMMXT_REG_MODE(MODE) \
+- (arm_vector_mode_supported_p (MODE) || (MODE) == DImode)
++ (arm_vector_mode_supported_p (MODE) || (MODE) == DImode || (MODE) == SImode)
+ /* Modes valid for Neon D registers.  */
+ #define VALID_NEON_DREG_MODE(MODE) \
+@@ -1053,7 +1116,10 @@ extern int arm_structure_size_boundary;
+    For VFP/VFPv3, allocate D16-D31 first, then caller-saved registers (D0-D7),
+    then D8-D15.  The reason for doing this is to attempt to reduce register
+    pressure when both single- and double-precision registers are used in a
+-   function.  */
++   function.
++   
++   The allocation order for Thumb differs from that given here:
++   see arm.c:adjust_reg_alloc_order.  */
+ #define REG_ALLOC_ORDER                               \
+ {                                             \
+@@ -1106,6 +1172,7 @@ enum reg_class
+   CC_REG,
+   VFPCC_REG,
+   GENERAL_REGS,
++  CORE_REGS,
+   ALL_REGS,
+   LIM_REG_CLASSES
+ };
+@@ -1131,6 +1198,7 @@ enum reg_class
+   "CC_REG",           \
+   "VFPCC_REG",                \
+   "GENERAL_REGS",     \
++  "CORE_REGS",                \
+   "ALL_REGS",         \
+ }
+@@ -1151,10 +1219,11 @@ enum reg_class
+   { 0x000000FF, 0x00000000, 0x00000000, 0x00000000 }, /* LO_REGS */   \
+   { 0x00002000, 0x00000000, 0x00000000, 0x00000000 }, /* STACK_REG */ \
+   { 0x000020FF, 0x00000000, 0x00000000, 0x00000000 }, /* BASE_REGS */ \
+-  { 0x0000FF00, 0x00000000, 0x00000000, 0x00000000 }, /* HI_REGS */   \
++  { 0x0000DF00, 0x00000000, 0x00000000, 0x00000000 }, /* HI_REGS */   \
+   { 0x01000000, 0x00000000, 0x00000000, 0x00000000 }, /* CC_REG */    \
+   { 0x00000000, 0x00000000, 0x00000000, 0x80000000 }, /* VFPCC_REG */ \
+-  { 0x0200FFFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \
++  { 0x0200DFFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \
++  { 0x0200FFFF, 0x00000000, 0x00000000, 0x00000000 }, /* CORE_REGS */ \
+   { 0xFAFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF }  /* ALL_REGS */  \
+ }
+@@ -1178,22 +1247,25 @@ enum reg_class
+      || reg_classes_intersect_p (VFP_REGS, (CLASS))   \
+    : 0)
+-/* We need to define this for LO_REGS on thumb.  Otherwise we can end up
+-   using r0-r4 for function arguments, r7 for the stack frame and don't
+-   have enough left over to do doubleword arithmetic.  */
++/* We need to define this for LO_REGS on Thumb-1.  Otherwise we can end up
++   using r0-r4 for function arguments, r7 for the stack frame and don't have
++   enough left over to do doubleword arithmetic.  For Thumb-2 all the
++   potentially problematic instructions accept high registers so this is not
++   necessary.  Care needs to be taken to avoid adding new Thumb-2 patterns
++   that require many low registers.  */
+ #define CLASS_LIKELY_SPILLED_P(CLASS) \
+-    ((TARGET_THUMB && (CLASS) == LO_REGS)     \
++    ((TARGET_THUMB1 && (CLASS) == LO_REGS)    \
+      || (CLASS) == CC_REG)
+ /* The class value for index registers, and the one for base regs.  */
+ #define INDEX_REG_CLASS  (TARGET_THUMB1 ? LO_REGS : GENERAL_REGS)
+-#define BASE_REG_CLASS   (TARGET_THUMB1 ? LO_REGS : GENERAL_REGS)
++#define BASE_REG_CLASS   (TARGET_THUMB1 ? LO_REGS : CORE_REGS)
+ /* For the Thumb the high registers cannot be used as base registers
+    when addressing quantities in QI or HI mode; if we don't know the
+    mode, then we must be conservative.  */
+ #define MODE_BASE_REG_CLASS(MODE)                                     \
+-    (TARGET_32BIT ? GENERAL_REGS :                                    \
++    (TARGET_32BIT ? (TARGET_THUMB2 ? LO_REGS : CORE_REGS) :                                   \
+      (((MODE) == SImode) ? BASE_REGS : LO_REGS))
+ /* For Thumb we can not support SP+reg addressing, so we return LO_REGS
+@@ -1213,7 +1285,8 @@ enum reg_class
+ #define PREFERRED_RELOAD_CLASS(X, CLASS)              \
+   (TARGET_ARM ? (CLASS) :                             \
+    ((CLASS) == GENERAL_REGS || (CLASS) == HI_REGS     \
+-    || (CLASS) == NO_REGS ? LO_REGS : (CLASS)))
++    || (CLASS) == NO_REGS || (CLASS) == STACK_REG     \
++   ? LO_REGS : (CLASS)))
+ /* Must leave BASE_REGS reloads alone */
+ #define THUMB_SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X)            \
+@@ -1293,6 +1366,9 @@ enum reg_class
+         else if (TARGET_MAVERICK && TARGET_HARD_FLOAT)                   \
+           /* Need to be careful, -256 is not a valid offset.  */         \
+           low = val >= 0 ? (val & 0xff) : -((-val) & 0xff);              \
++        else if (TARGET_REALLY_IWMMXT && MODE == SImode)                 \
++          /* Need to be careful, -1024 is not a valid offset.  */        \
++          low = val >= 0 ? (val & 0x3ff) : -((-val) & 0x3ff);            \
+         else if (MODE == SImode                                          \
+                  || (MODE == SFmode && TARGET_SOFT_FLOAT)                \
+                  || ((MODE == HImode || MODE == QImode) && ! arm_arch4)) \
+@@ -1438,9 +1514,10 @@ do {                                                                          \
+ /* Define how to find the value returned by a library function
+    assuming the value has mode MODE.  */
+-#define LIBCALL_VALUE(MODE)  \
+-  (TARGET_32BIT && TARGET_HARD_FLOAT_ABI && TARGET_FPA                        \
+-   && GET_MODE_CLASS (MODE) == MODE_FLOAT                             \
++#define LIBCALL_VALUE(MODE)                                           \
++  (TARGET_AAPCS_BASED ? aapcs_libcall_value (MODE)                    \
++   : (TARGET_32BIT && TARGET_HARD_FLOAT_ABI && TARGET_FPA             \
++      && GET_MODE_CLASS (MODE) == MODE_FLOAT)                         \
+    ? gen_rtx_REG (MODE, FIRST_FPA_REGNUM)                             \
+    : TARGET_32BIT && TARGET_HARD_FLOAT_ABI && TARGET_MAVERICK         \
+      && GET_MODE_CLASS (MODE) == MODE_FLOAT                           \
+@@ -1449,33 +1526,22 @@ do {                                                                         \
+    ? gen_rtx_REG (MODE, FIRST_IWMMXT_REGNUM)                          \
+    : gen_rtx_REG (MODE, ARG_REGISTER (1)))
+-/* Define how to find the value returned by a function.
+-   VALTYPE is the data type of the value (as a tree).
+-   If the precise function being called is known, FUNC is its FUNCTION_DECL;
+-   otherwise, FUNC is 0.  */
+-#define FUNCTION_VALUE(VALTYPE, FUNC) \
+-  arm_function_value (VALTYPE, FUNC);
+-
+-/* 1 if N is a possible register number for a function value.
+-   On the ARM, only r0 and f0 can return results.  */
+-/* On a Cirrus chip, mvf0 can return results.  */
+-#define FUNCTION_VALUE_REGNO_P(REGNO)  \
+-  ((REGNO) == ARG_REGISTER (1) \
+-   || (TARGET_32BIT && ((REGNO) == FIRST_CIRRUS_FP_REGNUM)            \
+-       && TARGET_HARD_FLOAT_ABI && TARGET_MAVERICK)                   \
+-   || ((REGNO) == FIRST_IWMMXT_REGNUM && TARGET_IWMMXT_ABI) \
+-   || (TARGET_32BIT && ((REGNO) == FIRST_FPA_REGNUM)                  \
++/* 1 if REGNO is a possible register number for a function value.  */
++#define FUNCTION_VALUE_REGNO_P(REGNO)                         \
++  ((REGNO) == ARG_REGISTER (1)                                        \
++   || (TARGET_AAPCS_BASED && TARGET_32BIT                     \
++       && TARGET_VFP && TARGET_HARD_FLOAT                     \
++       && (REGNO) == FIRST_VFP_REGNUM)                                \
++   || (TARGET_32BIT && ((REGNO) == FIRST_CIRRUS_FP_REGNUM)    \
++       && TARGET_HARD_FLOAT_ABI && TARGET_MAVERICK)           \
++   || ((REGNO) == FIRST_IWMMXT_REGNUM && TARGET_IWMMXT_ABI)   \
++   || (TARGET_32BIT && ((REGNO) == FIRST_FPA_REGNUM)          \
+        && TARGET_HARD_FLOAT_ABI && TARGET_FPA))
+ /* Amount of memory needed for an untyped call to save all possible return
+    registers.  */
+ #define APPLY_RESULT_SIZE arm_apply_result_size()
+-/* How large values are returned */
+-/* A C expression which can inhibit the returning of certain function values
+-   in registers, based on the type of value.  */
+-#define RETURN_IN_MEMORY(TYPE) arm_return_in_memory (TYPE)
+-
+ /* Define DEFAULT_PCC_STRUCT_RETURN to 1 if all structure and union return
+    values must be in memory.  On the ARM, they need only do so if larger
+    than a word, or if they contain elements offset from zero in the struct.  */
+@@ -1531,6 +1597,7 @@ typedef struct arm_stack_offsets GTY(())
+   int soft_frame;     /* FRAME_POINTER_REGNUM.  */
+   int locals_base;    /* THUMB_HARD_FRAME_POINTER_REGNUM.  */
+   int outgoing_args;  /* STACK_POINTER_REGNUM.  */
++  unsigned int saved_regs_mask;
+ }
+ arm_stack_offsets;
+@@ -1568,9 +1635,27 @@ machine_function;
+    that is in text_section.  */
+ extern GTY(()) rtx thumb_call_via_label[14];
++/* The number of potential ways of assigning to a co-processor.  */
++#define ARM_NUM_COPROC_SLOTS 1
++
++/* Enumeration of procedure calling standard variants.  We don't really 
++   support all of these yet.  */
++enum arm_pcs
++{
++  ARM_PCS_AAPCS,      /* Base standard AAPCS.  */
++  ARM_PCS_AAPCS_VFP,  /* Use VFP registers for floating point values.  */
++  ARM_PCS_AAPCS_IWMMXT, /* Use iWMMXT registers for vectors.  */
++  /* This must be the last AAPCS variant.  */
++  ARM_PCS_AAPCS_LOCAL,        /* Private call within this compilation unit.  */
++  ARM_PCS_ATPCS,      /* ATPCS.  */
++  ARM_PCS_APCS,               /* APCS (legacy Linux etc).  */
++  ARM_PCS_UNKNOWN
++};
++
++/* We can't define this inside a generator file because it needs enum
++   machine_mode.  */
+ /* A C type for declaring a variable that is used as the first argument of
+-   `FUNCTION_ARG' and other related values.  For some target machines, the
+-   type `int' suffices and can hold the number of bytes of argument so far.  */
++   `FUNCTION_ARG' and other related values.  */
+ typedef struct
+ {
+   /* This is the number of registers of arguments scanned so far.  */
+@@ -1579,9 +1664,33 @@ typedef struct
+   int iwmmxt_nregs;
+   int named_count;
+   int nargs;
+-  int can_split;
++  /* Which procedure call variant to use for this call.  */
++  enum arm_pcs pcs_variant;
++
++  /* AAPCS related state tracking.  */
++  int aapcs_arg_processed;  /* No need to lay out this argument again.  */
++  int aapcs_cprc_slot;      /* Index of co-processor rules to handle
++                             this argument, or -1 if using core
++                             registers.  */
++  int aapcs_ncrn;
++  int aapcs_next_ncrn;
++  rtx aapcs_reg;          /* Register assigned to this argument.  */
++  int aapcs_partial;      /* How many bytes are passed in regs (if
++                             split between core regs and stack.
++                             Zero otherwise.  */
++  int aapcs_cprc_failed[ARM_NUM_COPROC_SLOTS];
++  int can_split;          /* Argument can be split between core regs
++                             and the stack.  */
++  /* Private data for tracking VFP register allocation */
++  unsigned aapcs_vfp_regs_free;
++  unsigned aapcs_vfp_reg_alloc;
++  int aapcs_vfp_rcount;
++  /* Can't include insn-modes.h because this header is needed before we
++     generate it.  */
++  int /* enum machine_mode */ aapcs_vfp_rmode;
+ } CUMULATIVE_ARGS;
++
+ /* Define where to put the arguments to a function.
+    Value is zero to push the argument on the stack,
+    or a hard register in which to store the argument.
+@@ -1625,13 +1734,7 @@ typedef struct
+    of mode MODE and data type TYPE.
+    (TYPE is null for libcalls where that information may not be available.)  */
+ #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)  \
+-  (CUM).nargs += 1;                                   \
+-  if (arm_vector_mode_supported_p (MODE)              \
+-      && (CUM).named_count > (CUM).nargs              \
+-      && TARGET_IWMMXT_ABI)                           \
+-    (CUM).iwmmxt_nregs += 1;                          \
+-  else                                                        \
+-    (CUM).nregs += ARM_NUM_REGS2 (MODE, TYPE)
++  arm_function_arg_advance (&(CUM), (MODE), (TYPE), (NAMED))
+ /* If defined, a C expression that gives the alignment boundary, in bits, of an
+    argument with the specified mode and type.  If it is not defined,
+@@ -1643,9 +1746,11 @@ typedef struct
+ /* 1 if N is a possible register number for function argument passing.
+    On the ARM, r0-r3 are used to pass args.  */
+-#define FUNCTION_ARG_REGNO_P(REGNO)   \
+-   (IN_RANGE ((REGNO), 0, 3)          \
+-    || (TARGET_IWMMXT_ABI             \
++#define FUNCTION_ARG_REGNO_P(REGNO)                                   \
++   (IN_RANGE ((REGNO), 0, 3)                                          \
++    || (TARGET_AAPCS_BASED && TARGET_VFP && TARGET_HARD_FLOAT         \
++      && IN_RANGE ((REGNO), FIRST_VFP_REGNUM, FIRST_VFP_REGNUM + 15)) \
++    || (TARGET_IWMMXT_ABI                                             \
+       && IN_RANGE ((REGNO), FIRST_IWMMXT_REGNUM, FIRST_IWMMXT_REGNUM + 9)))
\f
+@@ -1908,12 +2013,13 @@ typedef struct
+ /* Nonzero if X can be the base register in a reg+reg addressing mode.
+    For Thumb, we can not use SP + reg, so reject SP.  */
+ #define REGNO_MODE_OK_FOR_REG_BASE_P(X, MODE) \
+-  REGNO_OK_FOR_INDEX_P (X)
++  REGNO_MODE_OK_FOR_BASE_P (X, QImode)
+ /* For ARM code, we don't care about the mode, but for Thumb, the index
+    must be suitable for use in a QImode load.  */
+ #define REGNO_OK_FOR_INDEX_P(REGNO)   \
+-  REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode)
++  (REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode) \
++   && !TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM))
+ /* Maximum number of registers that can appear in a valid memory address.
+    Shifts in addresses can't be by a register.  */
+@@ -1931,6 +2037,11 @@ typedef struct
+    SYMBOL's section.  */
+ #define ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 0
++/* Nonzero if all target requires all absolute relocations be R_ARM_ABS32.  */
++#ifndef TARGET_DEFAULT_WORD_RELOCATIONS
++#define TARGET_DEFAULT_WORD_RELOCATIONS 0
++#endif
++
+ /* Nonzero if the constant value X is a legitimate general operand.
+    It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
+@@ -2051,6 +2162,13 @@ typedef struct
+    || REGNO (X) == FRAME_POINTER_REGNUM               \
+    || REGNO (X) == ARG_POINTER_REGNUM)
++#define ARM_REG_OK_FOR_INDEX_P(X)             \
++  ((REGNO (X) <= LAST_ARM_REGNUM              \
++    && REGNO (X) != STACK_POINTER_REGNUM)     \
++   || REGNO (X) >= FIRST_PSEUDO_REGISTER      \
++   || REGNO (X) == FRAME_POINTER_REGNUM               \
++   || REGNO (X) == ARG_POINTER_REGNUM)
++
+ #define THUMB1_REG_MODE_OK_FOR_BASE_P(X, MODE)        \
+   (REGNO (X) <= LAST_LO_REGNUM                        \
+    || REGNO (X) >= FIRST_PSEUDO_REGISTER      \
+@@ -2066,6 +2184,9 @@ typedef struct
+ #define ARM_REG_OK_FOR_BASE_P(X)              \
+   ARM_REGNO_OK_FOR_BASE_P (REGNO (X))
++#define ARM_REG_OK_FOR_INDEX_P(X)             \
++  ARM_REGNO_OK_FOR_INDEX_P (REGNO (X))
++
+ #define THUMB1_REG_MODE_OK_FOR_BASE_P(X, MODE)        \
+   THUMB1_REGNO_MODE_OK_FOR_BASE_P (REGNO (X), MODE)
+@@ -2080,8 +2201,6 @@ typedef struct
+    ? THUMB1_REG_MODE_OK_FOR_BASE_P (X, MODE)  \
+    : ARM_REG_OK_FOR_BASE_P (X))
+-#define ARM_REG_OK_FOR_INDEX_P(X) ARM_REG_OK_FOR_BASE_P (X)
+-
+ /* For 16-bit Thumb, a valid index register is anything that can be used in
+    a byte load instruction.  */
+ #define THUMB1_REG_OK_FOR_INDEX_P(X) \
+@@ -2259,7 +2378,8 @@ do {                                                     \
+ /* Try to generate sequences that don't involve branches, we can then use
+    conditional instructions */
+ #define BRANCH_COST \
+-  (TARGET_32BIT ? 4 : (optimize > 0 ? 2 : 0))
++  (TARGET_32BIT ? (TARGET_THUMB2 && optimize_size ? 1 : 4) \
++              : (optimize > 0 ? 2 : 0))
\f
+ /* Position Independent Code.  */
+ /* We decide which register to use based on the compilation options and
+@@ -2339,6 +2459,19 @@ extern int making_const_table;
+       if (TARGET_ARM)                                 \
+       asm_fprintf (STREAM,"\tstmfd\t%r!,{%r}\n",      \
+                    STACK_POINTER_REGNUM, REGNO);      \
++      else if (TARGET_THUMB1                          \
++             && (REGNO) == STATIC_CHAIN_REGNUM)       \
++      {                                               \
++        /* We can't push STATIC_CHAIN_REGNUM (r12) directly with Thumb-1.
++           We know that ASM_OUTPUT_REG_PUSH will be matched with
++           ASM_OUTPUT_REG_POP, and that r7 isn't used by the function
++           profiler, so we can use it as a scratch reg.  WARNING: This isn't
++           safe in the general case!  It may be sensitive to future changes
++           in final.c:profile_function.  */           \
++        asm_fprintf (STREAM, "\tpush\t{r7}\n");       \
++        asm_fprintf (STREAM, "\tmov\tr7, %r\n", REGNO);\
++        asm_fprintf (STREAM, "\tpush\t{r7}\n");       \
++      }                                               \
+       else                                            \
+       asm_fprintf (STREAM, "\tpush {%r}\n", REGNO);   \
+     } while (0)
+@@ -2350,6 +2483,14 @@ extern int making_const_table;
+       if (TARGET_ARM)                                 \
+       asm_fprintf (STREAM, "\tldmfd\t%r!,{%r}\n",     \
+                    STACK_POINTER_REGNUM, REGNO);      \
++      else if (TARGET_THUMB1                          \
++             && (REGNO) == STATIC_CHAIN_REGNUM)       \
++      {                                               \
++        /* See comment in ASM_OUTPUT_REG_PUSH.  */    \
++        asm_fprintf (STREAM, "\tpop\t{r7}\n");        \
++        asm_fprintf (STREAM, "\tmov\t%r, r7\n", REGNO);\
++        asm_fprintf (STREAM, "\tpop\t{r7}\n");        \
++      }                                               \
+       else                                            \
+       asm_fprintf (STREAM, "\tpop {%r}\n", REGNO);    \
+     } while (0)
+@@ -2384,7 +2525,8 @@ extern int making_const_table;
+       if (TARGET_THUMB)                               \
+         {                                             \
+           if (is_called_in_ARM_mode (DECL)            \
+-            || (TARGET_THUMB1 && current_function_is_thunk))  \
++            || (TARGET_THUMB1 && !TARGET_THUMB1_ONLY  \
++                && current_function_is_thunk))        \
+             fprintf (STREAM, "\t.code 32\n") ;                \
+           else if (TARGET_THUMB1)                     \
+            fprintf (STREAM, "\t.code\t16\n\t.thumb_func\n") ; \
+@@ -2479,10 +2621,12 @@ extern int making_const_table;
+       rtx base = XEXP (X, 0);                                         \
+       rtx index = XEXP (X, 1);                                        \
+       HOST_WIDE_INT offset = 0;                                       \
+-      if (GET_CODE (base) != REG)                                     \
++      if (GET_CODE (base) != REG                                      \
++          || (GET_CODE (index) == REG && REGNO (index) == SP_REGNUM)) \
+         {                                                             \
+           /* Ensure that BASE is a register.  */                      \
+             /* (one of them must be).  */                             \
++          /* Also ensure the SP is not used as in index register.  */ \
+           rtx temp = base;                                            \
+           base = index;                                               \
+           index = temp;                                               \
+--- a/gcc/config/arm/arm.md
++++ b/gcc/config/arm/arm.md
+@@ -93,9 +93,9 @@
+    (UNSPEC_TLS      20) ; A symbol that has been treated properly for TLS usage.
+    (UNSPEC_PIC_LABEL 21) ; A label used for PIC access that does not appear in the
+                          ; instruction stream.
+-   (UNSPEC_STACK_ALIGN 20) ; Doubleword aligned stack pointer.  Used to
++   (UNSPEC_STACK_ALIGN 22) ; Doubleword aligned stack pointer.  Used to
+                          ; generate correct unwind information.
+-   (UNSPEC_PIC_OFFSET 22) ; A symbolic 12-bit OFFSET that has been treated
++   (UNSPEC_PIC_OFFSET 23) ; A symbolic 12-bit OFFSET that has been treated
+                         ; correctly for PIC usage.
+   ]
+ )
+@@ -129,6 +129,8 @@
+    (VUNSPEC_WCMP_EQ  12) ; Used by the iWMMXt WCMPEQ instructions
+    (VUNSPEC_WCMP_GTU 13) ; Used by the iWMMXt WCMPGTU instructions
+    (VUNSPEC_WCMP_GT  14) ; Used by the iwMMXT WCMPGT instructions
++   (VUNSPEC_ALIGN16  15) ; Used to force 16-byte alignment.
++   (VUNSPEC_ALIGN32  16) ; Used to force 32-byte alignment.
+    (VUNSPEC_EH_RETURN 20); Use to override the return address for exception
+                        ; handling.
+   ]
+@@ -142,6 +144,10 @@
+ ; patterns that share the same RTL in both ARM and Thumb code.
+ (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
++; FIX_JANUS is set to 'yes' when compiling for Janus2, it causes to
++; add a nop after shifts, in order to work around a Janus2 bug
++(define_attr "fix_janus" "no,yes" (const (symbol_ref "janus2_code")))
++
+ ; IS_STRONGARM is set to 'yes' when compiling for StrongARM, it affects
+ ; scheduling decisions for the load unit and the multiplier.
+ (define_attr "is_strongarm" "no,yes" (const (symbol_ref "arm_tune_strongarm")))
+@@ -156,7 +162,7 @@
+ ; Floating Point Unit.  If we only have floating point emulation, then there
+ ; is no point in scheduling the floating point insns.  (Well, for best
+ ; performance we should try and group them together).
+-(define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp"
++(define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp,vfpv3d16,vfpv3,neon,neon_fp16"
+   (const (symbol_ref "arm_fpu_attr")))
+ ; LENGTH of an instruction (in bytes)
+@@ -183,7 +189,7 @@
+ ;; scheduling information.
+ (define_attr "insn"
+-        "mov,mvn,smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals,smlawy,smuad,smuadx,smlad,smladx,smusd,smusdx,smlsd,smlsdx,smmul,smmulr,smmla,umaal,smlald,smlsld,clz,mrs,msr,xtab,other"
++        "mov,mvn,and,orr,eor,smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals,smlawy,smuad,smuadx,smlad,smladx,smusd,smusdx,smlsd,smlsdx,smmul,smmulr,smmla,smmls,umaal,smlald,smlsld,clz,mrs,msr,xtab,sdiv,udiv,other"
+         (const_string "other"))
+ ; TYPE attribute is used to detect floating point instructions which, if
+@@ -192,6 +198,8 @@
+ ; scheduling of writes.
+ ; Classification of each insn
++; Note: vfp.md has different meanings for some of these, and some further
++; types as well.  See that file for details.
+ ; alu         any alu  instruction that doesn't hit memory or fp
+ ;             regs or have a shifted source operand
+ ; alu_shift   any data instruction that doesn't hit memory or fp
+@@ -236,7 +244,7 @@
+ ;
+ (define_attr "type"
+-      "alu,alu_shift,alu_shift_reg,mult,block,float,fdivx,fdivd,fdivs,fmul,fmuls,fmuld,fmacs,fmacd,ffmul,farith,ffarith,f_flag,float_em,f_load,f_store,f_loads,f_loadd,f_stores,f_stored,f_mem_r,r_mem_f,f_2_r,r_2_f,f_cvt,branch,call,load_byte,load1,load2,load3,load4,store1,store2,store3,store4,mav_farith,mav_dmult"
++      "alu,alu_shift,alu_shift_reg,mult,block,float,fdivx,fdivd,fdivs,fmul,fmuls,fmuld,fmacs,fmacd,ffmul,farith,ffarith,f_flag,float_em,f_load,f_store,f_loads,f_loadd,f_stores,f_stored,f_mem_r,r_mem_f,f_2_r,r_2_f,f_cvt,branch,call,load_byte,load1,load2,load3,load4,store1,store2,store3,store4,mav_farith,mav_dmult,fconsts,fconstd,fadds,faddd,ffariths,ffarithd,fcmps,fcmpd,fcpys"
+       (if_then_else 
+        (eq_attr "insn" "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals")
+        (const_string "mult")
+@@ -246,6 +254,73 @@
+ ; initialized by arm_override_options() 
+ (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
++;; Classification of NEON instructions for scheduling purposes.
++(define_attr "neon_type"
++   "neon_int_1,\
++   neon_int_2,\
++   neon_int_3,\
++   neon_int_4,\
++   neon_int_5,\
++   neon_vqneg_vqabs,\
++   neon_vmov,\
++   neon_vaba,\
++   neon_vsma,\
++   neon_vaba_qqq,\
++   neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
++   neon_mul_qqq_8_16_32_ddd_32,\
++   neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\
++   neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
++   neon_mla_qqq_8_16,\
++   neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\
++   neon_mla_qqq_32_qqd_32_scalar,\
++   neon_mul_ddd_16_scalar_32_16_long_scalar,\
++   neon_mul_qqd_32_scalar,\
++   neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\
++   neon_shift_1,\
++   neon_shift_2,\
++   neon_shift_3,\
++   neon_vshl_ddd,\
++   neon_vqshl_vrshl_vqrshl_qqq,\
++   neon_vsra_vrsra,\
++   neon_fp_vadd_ddd_vabs_dd,\
++   neon_fp_vadd_qqq_vabs_qq,\
++   neon_fp_vsum,\
++   neon_fp_vmul_ddd,\
++   neon_fp_vmul_qqd,\
++   neon_fp_vmla_ddd,\
++   neon_fp_vmla_qqq,\
++   neon_fp_vmla_ddd_scalar,\
++   neon_fp_vmla_qqq_scalar,\
++   neon_fp_vrecps_vrsqrts_ddd,\
++   neon_fp_vrecps_vrsqrts_qqq,\
++   neon_bp_simple,\
++   neon_bp_2cycle,\
++   neon_bp_3cycle,\
++   neon_ldr,\
++   neon_str,\
++   neon_vld1_1_2_regs,\
++   neon_vld1_3_4_regs,\
++   neon_vld2_2_regs_vld1_vld2_all_lanes,\
++   neon_vld2_4_regs,\
++   neon_vld3_vld4,\
++   neon_vst1_1_2_regs_vst2_2_regs,\
++   neon_vst1_3_4_regs,\
++   neon_vst2_4_regs_vst3_vst4,\
++   neon_vst3_vst4,\
++   neon_vld1_vld2_lane,\
++   neon_vld3_vld4_lane,\
++   neon_vst1_vst2_lane,\
++   neon_vst3_vst4_lane,\
++   neon_vld3_vld4_all_lanes,\
++   neon_mcr,\
++   neon_mcr_2_mcrr,\
++   neon_mrc,\
++   neon_mrrc,\
++   neon_ldm_2,\
++   neon_stm_2,\
++   none"
++ (const_string "none"))
++
+ ; condition codes: this one is used by final_prescan_insn to speed up
+ ; conditionalizing instructions.  It saves having to scan the rtl to see if
+ ; it uses or alters the condition codes.
+@@ -263,13 +338,17 @@
+ ; JUMP_CLOB is used when the condition cannot be represented by a single
+ ;   instruction (UNEQ and LTGT).  These cannot be predicated.
+ ;
++; UNCONDITIONAL means the instions can not be conditionally executed.
++;
+ ; NOCOND means that the condition codes are neither altered nor affect the
+ ;   output of this insn
+-(define_attr "conds" "use,set,clob,jump_clob,nocond"
++(define_attr "conds" "use,set,clob,jump_clob,unconditional,nocond"
+       (if_then_else (eq_attr "type" "call")
+        (const_string "clob")
+-       (const_string "nocond")))
++       (if_then_else (eq_attr "neon_type" "none")
++        (const_string "nocond")
++        (const_string "unconditional"))))
+ ; Predicable means that the insn can be conditionally executed based on
+ ; an automatically added predicate (additional patterns are generated by 
+@@ -328,18 +407,26 @@
+ ;; Processor type.  This is created automatically from arm-cores.def.
+ (include "arm-tune.md")
++(define_attr "tune_cortexr4" "yes,no"
++  (const (if_then_else
++        (eq_attr "tune" "cortexr4,cortexr4f")
++        (const_string "yes")
++        (const_string "no"))))
++
+ ;; True if the generic scheduling description should be used.
+ (define_attr "generic_sched" "yes,no"
+   (const (if_then_else 
+-          (eq_attr "tune" "arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa8")
++          (ior (eq_attr "tune" "arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,marvell_f,cortexa8,cortexa9")
++             (eq_attr "tune_cortexr4" "yes"))
+           (const_string "no")
+           (const_string "yes"))))
+ (define_attr "generic_vfp" "yes,no"
+   (const (if_then_else
+         (and (eq_attr "fpu" "vfp")
+-             (eq_attr "tune" "!arm1020e,arm1022e,cortexa8"))
++             (eq_attr "tune" "!arm1020e,arm1022e,marvell_f,cortexa8,cortexa9")
++             (eq_attr "tune_cortexr4" "no"))
+         (const_string "yes")
+         (const_string "no"))))
+@@ -348,7 +435,13 @@
+ (include "arm1020e.md")
+ (include "arm1026ejs.md")
+ (include "arm1136jfs.md")
++(include "marvell-f.md")
++(include "marvell-f-vfp.md")
+ (include "cortex-a8.md")
++(include "cortex-a9.md")
++(include "cortex-r4.md")
++(include "cortex-r4f.md")
++(include "vfp11.md")
\f
+ ;;---------------------------------------------------------------------------
+@@ -516,13 +609,19 @@
+   ""
+ )
++;; The r/r/k alternative is required when reloading the address
++;;  (plus (reg rN) (reg sp)) into (reg rN).  In this case reload will
++;; put the duplicated register first, and not try the commutative version.
+ (define_insn_and_split "*arm_addsi3"
+-  [(set (match_operand:SI          0 "s_register_operand" "=r,r,r")
+-      (plus:SI (match_operand:SI 1 "s_register_operand" "%r,r,r")
+-               (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
++  [(set (match_operand:SI          0 "s_register_operand" "=r, !k, r,r, !k,r")
++      (plus:SI (match_operand:SI 1 "s_register_operand" "%rk,!k, r,rk,!k,rk")
++               (match_operand:SI 2 "reg_or_int_operand" "rI, rI,!k,L, L,?n")))]
+   "TARGET_32BIT"
+   "@
+    add%?\\t%0, %1, %2
++   add%?\\t%0, %1, %2
++   add%?\\t%0, %2, %1
++   sub%?\\t%0, %1, #%n2
+    sub%?\\t%0, %1, #%n2
+    #"
+   "TARGET_32BIT &&
+@@ -536,7 +635,7 @@
+                     operands[1], 0);
+   DONE;
+   "
+-  [(set_attr "length" "4,4,16")
++  [(set_attr "length" "4,4,4,4,4,16")
+    (set_attr "predicable" "yes")]
+ )
+@@ -545,9 +644,9 @@
+ ;; so never allow those alternatives to match if reloading is needed.
+ (define_insn "*thumb1_addsi3"
+-  [(set (match_operand:SI          0 "register_operand" "=l,l,l,*r,*h,l,!k")
++  [(set (match_operand:SI          0 "register_operand" "=l,l,l,*rk,*hk,l,!k")
+       (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k")
+-               (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*h,*r,!M,!O")))]
++               (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,!M,!O")))]
+   "TARGET_THUMB1"
+   "*
+    static const char * const asms[] = 
+@@ -759,7 +858,11 @@
+   [(set_attr "conds" "use")
+    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
+ (define_insn "*addsi3_carryin_alt1"
+@@ -991,12 +1094,13 @@
+ ; ??? Check Thumb-2 split length
+ (define_insn_and_split "*arm_subsi3_insn"
+-  [(set (match_operand:SI           0 "s_register_operand" "=r,r")
+-      (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
+-                (match_operand:SI 2 "s_register_operand" "r,r")))]
++  [(set (match_operand:SI           0 "s_register_operand" "=r,rk,r")
++      (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,!k,?n")
++                (match_operand:SI 2 "s_register_operand" "r, r, r")))]
+   "TARGET_32BIT"
+   "@
+    rsb%?\\t%0, %2, %1
++   sub%?\\t%0, %1, %2
+    #"
+   "TARGET_32BIT
+    && GET_CODE (operands[1]) == CONST_INT
+@@ -1007,7 +1111,7 @@
+                       INTVAL (operands[1]), operands[0], operands[2], 0);
+   DONE;
+   "
+-  [(set_attr "length" "4,16")
++  [(set_attr "length" "4,4,16")
+    (set_attr "predicable" "yes")]
+ )
+@@ -1236,6 +1340,49 @@
+    (set_attr "predicable" "yes")]
+ )
++; The combiner cannot combine the first and last insns in the
++; following sequence because of the intervening insn, so help the
++; combiner with this splitter.  The combiner does attempt to split
++; this particular combination but does not know this exact split.
++; Note that the combiner puts the constant at the outermost operation
++; as a part of canonicalization.
++;
++; mul r3, r2, r1
++; <add/sub> r3, r3, <constant>
++; add r3, r3, r4
++
++(define_split
++  [(set (match_operand:SI 0 "s_register_operand" "")
++      (match_operator:SI 1 "plusminus_operator"
++       [(plus:SI (mult:SI (match_operand:SI 2 "s_register_operand" "")
++                          (match_operand:SI 3 "s_register_operand" ""))
++                 (match_operand:SI 4 "s_register_operand" ""))
++        (match_operand:SI 5 "arm_immediate_operand" "")]))]
++  "TARGET_32BIT"
++  [(set (match_dup 0)
++      (plus:SI (mult:SI (match_dup 2) (match_dup 3))
++               (match_dup 4)))
++   (set (match_dup 0)
++      (match_op_dup:SI 1 [(match_dup 0) (match_dup 5)]))]
++  "")
++
++; Likewise for MLS.  MLS is available only on select architectures.
++
++(define_split
++  [(set (match_operand:SI 0 "s_register_operand" "")
++      (match_operator:SI 1 "plusminus_operator"
++       [(minus:SI (match_operand:SI 2 "s_register_operand" "")
++                  (mult:SI (match_operand:SI 3 "s_register_operand" "")
++                           (match_operand:SI 4 "s_register_operand" "")))
++        (match_operand:SI 5 "arm_immediate_operand" "")]))]
++  "TARGET_32BIT && arm_arch_thumb2"
++  [(set (match_dup 0)
++      (minus:SI (match_dup 2)
++                (mult:SI (match_dup 3) (match_dup 4))))
++   (set (match_dup 0)
++      (match_op_dup:SI 1 [(match_dup 0) (match_dup 5)]))]
++  "")
++
+ (define_insn "*mulsi3addsi_compare0"
+   [(set (reg:CC_NOOV CC_REGNUM)
+       (compare:CC_NOOV
+@@ -1864,6 +2011,7 @@
+   DONE;
+   "
+   [(set_attr "length" "4,4,16")
++   (set_attr "insn" "and")
+    (set_attr "predicable" "yes")]
+ )
+@@ -1873,7 +2021,8 @@
+               (match_operand:SI 2 "register_operand" "l")))]
+   "TARGET_THUMB1"
+   "and\\t%0, %0, %2"
+-  [(set_attr "length" "2")]
++  [(set_attr "length" "2")
++   (set_attr "insn" "and")]
+ )
+ (define_insn "*andsi3_compare0"
+@@ -1888,7 +2037,8 @@
+   "@
+    and%.\\t%0, %1, %2
+    bic%.\\t%0, %1, #%B2"
+-  [(set_attr "conds" "set")]
++  [(set_attr "conds" "set")
++   (set_attr "insn" "and,*")]
+ )
+ (define_insn "*andsi3_compare0_scratch"
+@@ -2140,13 +2290,12 @@
+ ;;; the value before we insert.  This loses some of the advantage of having
+ ;;; this insv pattern, so this pattern needs to be reevalutated.
+-; ??? Use Thumb-2 bitfield insert/extract instructions
+ (define_expand "insv"
+   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
+                          (match_operand:SI 1 "general_operand" "")
+                          (match_operand:SI 2 "general_operand" ""))
+         (match_operand:SI 3 "reg_or_int_operand" ""))]
+-  "TARGET_ARM"
++  "TARGET_ARM || arm_arch_thumb2"
+   "
+   {
+     int start_bit = INTVAL (operands[2]);
+@@ -2154,7 +2303,38 @@
+     HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
+     rtx target, subtarget;
+-    target = operands[0];
++    if (arm_arch_thumb2)
++      {
++      bool use_bfi = TRUE;
++
++      if (GET_CODE (operands[3]) == CONST_INT)
++        {
++          HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
++
++          if (val == 0)
++            {
++              emit_insn (gen_insv_zero (operands[0], operands[1],
++                                        operands[2]));
++              DONE;
++            }
++
++          /* See if the set can be done with a single orr instruction.  */
++          if (val == mask && const_ok_for_arm (val << start_bit))
++            use_bfi = FALSE;
++        }
++        
++      if (use_bfi)
++        {
++          if (GET_CODE (operands[3]) != REG)
++            operands[3] = force_reg (SImode, operands[3]);
++
++          emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
++                                  operands[3]));
++          DONE;
++        }
++      }
++
++    target = copy_rtx (operands[0]);
+     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
+        subreg as the final target.  */
+     if (GET_CODE (target) == SUBREG)
+@@ -2277,6 +2457,28 @@
+   }"
+ )
++(define_insn "insv_zero"
++  [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
++                         (match_operand:SI 1 "const_int_operand" "M")
++                         (match_operand:SI 2 "const_int_operand" "M"))
++        (const_int 0))]
++  "arm_arch_thumb2"
++  "bfc%?\t%0, %2, %1"
++  [(set_attr "length" "4")
++   (set_attr "predicable" "yes")]
++)
++
++(define_insn "insv_t2"
++  [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
++                         (match_operand:SI 1 "const_int_operand" "M")
++                         (match_operand:SI 2 "const_int_operand" "M"))
++        (match_operand:SI 3 "s_register_operand" "r"))]
++  "arm_arch_thumb2"
++  "bfi%?\t%0, %3, %2, %1"
++  [(set_attr "length" "4")
++   (set_attr "predicable" "yes")]
++)
++
+ ; constants for op 2 will never be given to these patterns.
+ (define_insn_and_split "*anddi_notdi_di"
+   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
+@@ -2380,7 +2582,11 @@
+    (set_attr "shift" "2")
+    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
+ (define_insn "*andsi_notsi_si_compare0"
+@@ -2428,6 +2634,7 @@
+    orr%?\\t%Q0, %Q1, %2
+    #"
+   [(set_attr "length" "4,8")
++   (set_attr "insn" "orr")
+    (set_attr "predicable" "yes")]
+ )
+@@ -2490,7 +2697,8 @@
+               (match_operand:SI 2 "register_operand" "l")))]
+   "TARGET_THUMB1"
+   "orr\\t%0, %0, %2"
+-  [(set_attr "length" "2")]
++  [(set_attr "length" "2")
++   (set_attr "insn" "orr")]
+ )
+ (define_peephole2
+@@ -2515,7 +2723,8 @@
+       (ior:SI (match_dup 1) (match_dup 2)))]
+   "TARGET_32BIT"
+   "orr%.\\t%0, %1, %2"
+-  [(set_attr "conds" "set")]
++  [(set_attr "conds" "set")
++   (set_attr "insn" "orr")]
+ )
+ (define_insn "*iorsi3_compare0_scratch"
+@@ -2526,7 +2735,8 @@
+    (clobber (match_scratch:SI 0 "=r"))]
+   "TARGET_32BIT"
+   "orr%.\\t%0, %1, %2"
+-  [(set_attr "conds" "set")]
++  [(set_attr "conds" "set")
++   (set_attr "insn" "orr")]
+ )
+ (define_insn "xordi3"
+@@ -2549,7 +2759,8 @@
+    eor%?\\t%Q0, %Q1, %2
+    #"
+   [(set_attr "length" "4,8")
+-   (set_attr "predicable" "yes")]
++   (set_attr "predicable" "yes")
++   (set_attr "insn" "eor")]
+ )
+ (define_insn "*xordi_sesidi_di"
+@@ -2580,7 +2791,8 @@
+               (match_operand:SI 2 "arm_rhs_operand" "rI")))]
+   "TARGET_32BIT"
+   "eor%?\\t%0, %1, %2"
+-  [(set_attr "predicable" "yes")]
++  [(set_attr "predicable" "yes")
++   (set_attr "insn" "eor")]
+ )
+ (define_insn "*thumb1_xorsi3"
+@@ -2589,7 +2801,8 @@
+               (match_operand:SI 2 "register_operand" "l")))]
+   "TARGET_THUMB1"
+   "eor\\t%0, %0, %2"
+-  [(set_attr "length" "2")]
++  [(set_attr "length" "2")
++   (set_attr "insn" "eor")]
+ )
+ (define_insn "*xorsi3_compare0"
+@@ -2601,7 +2814,8 @@
+       (xor:SI (match_dup 1) (match_dup 2)))]
+   "TARGET_32BIT"
+   "eor%.\\t%0, %1, %2"
+-  [(set_attr "conds" "set")]
++  [(set_attr "conds" "set")
++   (set_attr "insn" "eor")]
+ )
+ (define_insn "*xorsi3_compare0_scratch"
+@@ -2758,7 +2972,7 @@
+        (smax:SI (match_operand:SI 1 "s_register_operand" "")
+                 (match_operand:SI 2 "arm_rhs_operand" "")))
+     (clobber (reg:CC CC_REGNUM))])]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   "
+   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
+     {
+@@ -2785,7 +2999,8 @@
+                (const_int -1)))]
+   "TARGET_32BIT"
+   "orr%?\\t%0, %1, %1, asr #31"
+-  [(set_attr "predicable" "yes")]
++  [(set_attr "predicable" "yes")
++   (set_attr "insn" "orr")]
+ )
+ (define_insn "*arm_smax_insn"
+@@ -2793,7 +3008,7 @@
+       (smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
+                (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_COND_EXEC"
+   "@
+    cmp\\t%1, %2\;movlt\\t%0, %2
+    cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
+@@ -2807,7 +3022,7 @@
+        (smin:SI (match_operand:SI 1 "s_register_operand" "")
+                 (match_operand:SI 2 "arm_rhs_operand" "")))
+     (clobber (reg:CC CC_REGNUM))])]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   "
+   if (operands[2] == const0_rtx)
+     {
+@@ -2825,7 +3040,8 @@
+                (const_int 0)))]
+   "TARGET_32BIT"
+   "and%?\\t%0, %1, %1, asr #31"
+-  [(set_attr "predicable" "yes")]
++  [(set_attr "predicable" "yes")
++   (set_attr "insn" "and")]
+ )
+ (define_insn "*arm_smin_insn"
+@@ -2833,7 +3049,7 @@
+       (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
+                (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM  && !TARGET_NO_COND_EXEC"
+   "@
+    cmp\\t%1, %2\;movge\\t%0, %2
+    cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
+@@ -2847,7 +3063,7 @@
+        (umax:SI (match_operand:SI 1 "s_register_operand" "")
+                 (match_operand:SI 2 "arm_rhs_operand" "")))
+     (clobber (reg:CC CC_REGNUM))])]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   ""
+ )
+@@ -2856,7 +3072,7 @@
+       (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
+                (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM  && !TARGET_NO_COND_EXEC"
+   "@
+    cmp\\t%1, %2\;movcc\\t%0, %2
+    cmp\\t%1, %2\;movcs\\t%0, %1
+@@ -2871,7 +3087,7 @@
+        (umin:SI (match_operand:SI 1 "s_register_operand" "")
+                 (match_operand:SI 2 "arm_rhs_operand" "")))
+     (clobber (reg:CC CC_REGNUM))])]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   ""
+ )
+@@ -2880,7 +3096,7 @@
+       (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
+                (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_COND_EXEC"
+   "@
+    cmp\\t%1, %2\;movcs\\t%0, %2
+    cmp\\t%1, %2\;movcc\\t%0, %1
+@@ -2895,7 +3111,7 @@
+        [(match_operand:SI 1 "s_register_operand" "r")
+         (match_operand:SI 2 "s_register_operand" "r")]))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   "*
+   operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
+                               operands[1], operands[2]);
+@@ -3015,11 +3231,23 @@
+   [(set (match_operand:SI            0 "register_operand" "=l,l")
+       (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
+                  (match_operand:SI 2 "nonmemory_operand" "N,l")))]
+-  "TARGET_THUMB1"
++  "TARGET_THUMB1 && !janus2_code"
+   "lsl\\t%0, %1, %2"
+   [(set_attr "length" "2")]
+ )
++(define_insn "*thumb1_ashlsi3_janus2"
++  [(set (match_operand:SI            0 "register_operand" "=l,l")
++        (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
++                   (match_operand:SI 2 "nonmemory_operand" "N,l")))]
++  "TARGET_THUMB1 && janus2_code"
++  "@
++  lsl\\t%0, %1, %2
++  lsl\\t%0, %1, %2\;nop"
++  [(set_attr "length" "2,4")]
++)
++
++
+ (define_expand "ashrdi3"
+   [(set (match_operand:DI              0 "s_register_operand" "")
+         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
+@@ -3052,6 +3280,7 @@
+   "TARGET_32BIT"
+   "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
+   [(set_attr "conds" "clob")
++   (set_attr "insn" "mov")
+    (set_attr "length" "8")]
+ )
+@@ -3071,11 +3300,22 @@
+   [(set (match_operand:SI              0 "register_operand" "=l,l")
+       (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
+                    (match_operand:SI 2 "nonmemory_operand" "N,l")))]
+-  "TARGET_THUMB1"
++  "TARGET_THUMB1 && !janus2_code"
+   "asr\\t%0, %1, %2"
+   [(set_attr "length" "2")]
+ )
++(define_insn "*thumb1_ashrsi3_janus2"
++  [(set (match_operand:SI              0 "register_operand" "=l,l")
++        (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
++                     (match_operand:SI 2 "nonmemory_operand" "N,l")))]
++  "TARGET_THUMB1 && janus2_code"
++  "@
++  asr\\t%0, %1, %2
++  asr\\t%0, %1, %2\;nop"
++  [(set_attr "length" "2,4")]
++)
++
+ (define_expand "lshrdi3"
+   [(set (match_operand:DI              0 "s_register_operand" "")
+         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
+@@ -3108,6 +3348,7 @@
+   "TARGET_32BIT"
+   "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
+   [(set_attr "conds" "clob")
++   (set_attr "insn" "mov")
+    (set_attr "length" "8")]
+ )
+@@ -3130,11 +3371,22 @@
+   [(set (match_operand:SI              0 "register_operand" "=l,l")
+       (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
+                    (match_operand:SI 2 "nonmemory_operand" "N,l")))]
+-  "TARGET_THUMB1"
++  "TARGET_THUMB1 && !janus2_code"
+   "lsr\\t%0, %1, %2"
+   [(set_attr "length" "2")]
+ )
++(define_insn "*thumb1_lshrsi3_janus2"
++  [(set (match_operand:SI              0 "register_operand" "=l,l")
++        (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
++                     (match_operand:SI 2 "nonmemory_operand" "N,l")))]
++  "TARGET_THUMB1 && janus2_code"
++  "@
++  lsr\\t%0, %1, %2
++  lsr\\t%0, %1, %2; nop"
++  [(set_attr "length" "2,4")]
++)
++
+ (define_expand "rotlsi3"
+   [(set (match_operand:SI              0 "s_register_operand" "")
+       (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
+@@ -3176,11 +3428,20 @@
+   [(set (match_operand:SI              0 "register_operand" "=l")
+       (rotatert:SI (match_operand:SI 1 "register_operand" "0")
+                    (match_operand:SI 2 "register_operand" "l")))]
+-  "TARGET_THUMB1"
++  "TARGET_THUMB1 && !janus2_code"
+   "ror\\t%0, %0, %2"
+   [(set_attr "length" "2")]
+ )
++(define_insn "*thumb1_rotrsi3_janus2"
++  [(set (match_operand:SI              0 "register_operand" "=l")
++        (rotatert:SI (match_operand:SI 1 "register_operand" "0")
++                     (match_operand:SI 2 "register_operand" "l")))]
++  "TARGET_THUMB1 && janus2_code"
++  "ror\\t%0, %0, %2; nop"
++  [(set_attr "length" "4")]
++)
++
+ (define_insn "*arm_shiftsi3"
+   [(set (match_operand:SI   0 "s_register_operand" "=r")
+       (match_operator:SI  3 "shift_operator"
+@@ -3192,7 +3453,11 @@
+    (set_attr "shift" "1")
+    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
+ (define_insn "*shiftsi3_compare0"
+@@ -3209,7 +3474,11 @@
+    (set_attr "shift" "1")
+    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
+ (define_insn "*shiftsi3_compare0_scratch"
+@@ -3222,7 +3491,11 @@
+   "TARGET_32BIT"
+   "* return arm_output_shift(operands, 1);"
+   [(set_attr "conds" "set")
+-   (set_attr "shift" "1")]
++   (set_attr "shift" "1")
++   (set (attr "length") (if_then_else (and (match_operand 2 "s_register_operand" "")
++                                           (eq_attr "fix_janus" "yes"))
++                                      (const_int 8)
++                                      (const_int 4)))]
+ )
+ (define_insn "*arm_notsi_shiftsi"
+@@ -3234,9 +3507,14 @@
+   "mvn%?\\t%0, %1%S3"
+   [(set_attr "predicable" "yes")
+    (set_attr "shift" "1")
++   (set_attr "insn" "mvn")
+    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
+ (define_insn "*arm_notsi_shiftsi_compare0"
+@@ -3251,9 +3529,14 @@
+   "mvn%.\\t%0, %1%S3"
+   [(set_attr "conds" "set")
+    (set_attr "shift" "1")
++   (set_attr "insn" "mvn")
+    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
+ (define_insn "*arm_not_shiftsi_compare0_scratch"
+@@ -3267,9 +3550,14 @@
+   "mvn%.\\t%0, %1%S3"
+   [(set_attr "conds" "set")
+    (set_attr "shift" "1")
++   (set_attr "insn" "mvn")
+    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
+ ;; We don't really have extzv, but defining this using shifts helps
+@@ -3282,12 +3570,19 @@
+    (set (match_operand:SI              0 "register_operand" "")
+       (lshiftrt:SI (match_dup 4)
+                    (match_operand:SI 3 "const_int_operand" "")))]
+-  "TARGET_THUMB1"
++  "TARGET_THUMB1 || arm_arch_thumb2"
+   "
+   {
+     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
+     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
+     
++    if (arm_arch_thumb2)
++      {
++      emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
++                               operands[3]));
++      DONE;
++      }
++
+     operands[3] = GEN_INT (rshift);
+     
+     if (lshift == 0)
+@@ -3301,6 +3596,28 @@
+   }"
+ )
++(define_insn "extv"
++  [(set (match_operand:SI 0 "s_register_operand" "=r")
++      (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
++                         (match_operand:SI 2 "const_int_operand" "M")
++                         (match_operand:SI 3 "const_int_operand" "M")))]
++  "arm_arch_thumb2"
++  "sbfx%?\t%0, %1, %3, %2"
++  [(set_attr "length" "4")
++   (set_attr "predicable" "yes")]
++)
++
++(define_insn "extzv_t2"
++  [(set (match_operand:SI 0 "s_register_operand" "=r")
++      (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
++                         (match_operand:SI 2 "const_int_operand" "M")
++                         (match_operand:SI 3 "const_int_operand" "M")))]
++  "arm_arch_thumb2"
++  "ubfx%?\t%0, %1, %3, %2"
++  [(set_attr "length" "4")
++   (set_attr "predicable" "yes")]
++)
++
\f
+ ;; Unary arithmetic insns
+@@ -3378,7 +3695,7 @@
+ ;; abssi2 doesn't really clobber the condition codes if a different register
+ ;; is being set.  To keep things simple, assume during rtl manipulations that
+-;; it does, but tell the final scan operator the truth.  Similarly for
++;; it does, and the splitter will eliminate it.  Similarly for
+ ;; (neg (abs...))
+ (define_expand "abssi2"
+@@ -3390,22 +3707,28 @@
+   "
+   if (TARGET_THUMB1)
+     operands[2] = gen_rtx_SCRATCH (SImode);
++  else if (TARGET_NO_SINGLE_COND_EXEC)
++    {
++      emit_insn(gen_rtx_SET(VOIDmode, operands[0],
++                          gen_rtx_ABS(SImode, operands[1])));
++      DONE;
++    }
+   else
+     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
+ ")
+ (define_insn "*arm_abssi2"
+-  [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
+-      (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
++  [(set (match_operand:SI         0 "s_register_operand" "=r")
++      (abs:SI (match_operand:SI 1 "s_register_operand" "r")))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
+-  "@
+-   cmp\\t%0, #0\;rsblt\\t%0, %0, #0
+-   eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
+-  [(set_attr "conds" "clob,*")
+-   (set_attr "shift" "1")
++  "TARGET_32BIT && !TARGET_NO_SINGLE_COND_EXEC"
++  "#"
++  [(set_attr "shift" "1")
+    ;; predicable can't be set based on the variant, so left as no
+-   (set_attr "length" "8")]
++   (set (attr "length")
++      (if_then_else (eq_attr "is_thumb" "yes")
++                    (const_int 10)
++                    (const_int 8)))]
+ )
+ (define_insn_and_split "*thumb1_abssi2"
+@@ -3423,17 +3746,17 @@
+ )
+ (define_insn "*arm_neg_abssi2"
+-  [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
+-      (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
++  [(set (match_operand:SI 0 "s_register_operand" "=r")
++      (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "r"))))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
+-  "@
+-   cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
+-   eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
+-  [(set_attr "conds" "clob,*")
+-   (set_attr "shift" "1")
++  "TARGET_32BIT && !TARGET_NO_SINGLE_COND_EXEC"
++  "#"
++  [(set_attr "shift" "1")
+    ;; predicable can't be set based on the variant, so left as no
+-   (set_attr "length" "8")]
++   (set (attr "length")
++      (if_then_else (eq_attr "is_thumb" "yes")
++                    (const_int 10)
++                    (const_int 8)))]
+ )
+ (define_insn_and_split "*thumb1_neg_abssi2"
+@@ -3450,6 +3773,93 @@
+   [(set_attr "length" "6")]
+ )
++;; Simplified version for when avoiding conditional execution
++(define_insn "*arm_nocond_abssi2"
++  [(set (match_operand:SI         0 "s_register_operand" "=&r")
++      (abs:SI (match_operand:SI 1 "s_register_operand" "r")))]
++  "TARGET_32BIT && TARGET_NO_SINGLE_COND_EXEC"
++  "#"
++  [(set_attr "shift" "1")
++   (set_attr "length" "8")
++   (set_attr "predicable" "yes")]
++)
++
++(define_insn "*arm_nocond_neg_abssi2"
++  [(set (match_operand:SI         0 "s_register_operand" "=&r")
++      (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "r"))))]
++  "TARGET_32BIT && TARGET_NO_SINGLE_COND_EXEC"
++  "#"
++  [(set_attr "shift" "1")
++   (set_attr "length" "8")
++   (set_attr "predicable" "yes")]
++)
++
++;; Splitters for ABS patterns.
++
++(define_split
++  [(set (match_operand:SI         0 "s_register_operand" "")
++      (abs:SI (match_operand:SI 1 "s_register_operand" "")))
++   (clobber (reg:CC CC_REGNUM))]
++  "TARGET_32BIT && reload_completed && rtx_equal_p(operands[0], operands[1])"
++  [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
++   (cond_exec (lt (reg:CC CC_REGNUM) (const_int 0))
++            (set (match_dup 0) (neg:SI (match_dup 1))))]
++)
++
++(define_split
++  [(set (match_operand:SI         0 "s_register_operand" "")
++      (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" ""))))
++   (clobber (reg:CC CC_REGNUM))]
++  "TARGET_32BIT && reload_completed && rtx_equal_p(operands[0], operands[1])"
++  [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
++   (cond_exec (gt (reg:CC CC_REGNUM) (const_int 0))
++            (set (match_dup 0) (neg:SI (match_dup 1))))]
++)
++
++;; GCC does not add/remove clobbers when matching splitters, so we need
++;; variants with and without the CC clobber.
++(define_split
++  [(set (match_operand:SI         0 "s_register_operand" "")
++      (abs:SI (match_operand:SI 1 "s_register_operand" "")))]
++  "TARGET_32BIT && reload_completed && !rtx_equal_p(operands[0], operands[1])"
++  [(set (match_dup 0) (xor:SI (ashiftrt:SI (match_dup 1) (const_int 31))
++                            (match_dup 1)))
++   (set (match_dup 0) (minus:SI (match_dup 0)
++                              (ashiftrt:SI (match_dup 1) (const_int 31))))]
++)
++
++(define_split
++  [(set (match_operand:SI         0 "s_register_operand" "")
++      (abs:SI (match_operand:SI 1 "s_register_operand" "")))
++   (clobber (reg:CC CC_REGNUM))]
++  "TARGET_32BIT && reload_completed && !rtx_equal_p(operands[0], operands[1])"
++  [(set (match_dup 0) (xor:SI (ashiftrt:SI (match_dup 1) (const_int 31))
++                            (match_dup 1)))
++   (set (match_dup 0) (minus:SI (match_dup 0)
++                              (ashiftrt:SI (match_dup 1) (const_int 31))))]
++)
++
++(define_split
++  [(set (match_operand:SI         0 "s_register_operand" "")
++      (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" ""))))]
++  "TARGET_32BIT && reload_completed && !rtx_equal_p(operands[0], operands[1])"
++  [(set (match_dup 0) (xor:SI (ashiftrt:SI (match_dup 1) (const_int 31))
++                            (match_dup 1)))
++   (set (match_dup 0) (minus:SI (ashiftrt:SI (match_dup 1) (const_int 31))
++                              (match_dup 0)))]
++)
++
++(define_split
++  [(set (match_operand:SI         0 "s_register_operand" "")
++      (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" ""))))
++   (clobber (reg:CC CC_REGNUM))]
++  "TARGET_32BIT && reload_completed && !rtx_equal_p(operands[0], operands[1])"
++  [(set (match_dup 0) (xor:SI (ashiftrt:SI (match_dup 1) (const_int 31))
++                            (match_dup 1)))
++   (set (match_dup 0) (minus:SI (ashiftrt:SI (match_dup 1) (const_int 31))
++                              (match_dup 0)))]
++)
++
+ (define_expand "abssf2"
+   [(set (match_operand:SF         0 "s_register_operand" "")
+       (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
+@@ -3505,7 +3915,8 @@
+       (not:SI (match_operand:SI 1 "s_register_operand"  "r")))]
+   "TARGET_32BIT"
+   "mvn%?\\t%0, %1"
+-  [(set_attr "predicable" "yes")]
++  [(set_attr "predicable" "yes")
++   (set_attr "insn" "mvn")]
+ )
+ (define_insn "*thumb1_one_cmplsi2"
+@@ -3513,7 +3924,8 @@
+       (not:SI (match_operand:SI 1 "register_operand"  "l")))]
+   "TARGET_THUMB1"
+   "mvn\\t%0, %1"
+-  [(set_attr "length" "2")]
++  [(set_attr "length" "2")
++   (set_attr "insn" "mvn")]
+ )
+ (define_insn "*notsi_compare0"
+@@ -3524,7 +3936,8 @@
+       (not:SI (match_dup 1)))]
+   "TARGET_32BIT"
+   "mvn%.\\t%0, %1"
+-  [(set_attr "conds" "set")]
++  [(set_attr "conds" "set")
++   (set_attr "insn" "mvn")]
+ )
+ (define_insn "*notsi_compare0_scratch"
+@@ -3534,11 +3947,40 @@
+    (clobber (match_scratch:SI 0 "=r"))]
+   "TARGET_32BIT"
+   "mvn%.\\t%0, %1"
+-  [(set_attr "conds" "set")]
++  [(set_attr "conds" "set")
++   (set_attr "insn" "mvn")]
+ )
\f
+ ;; Fixed <--> Floating conversion insns
++(define_expand "floatsihf2"
++  [(set (match_operand:HF           0 "general_operand" "")
++      (float:HF (match_operand:SI 1 "general_operand" "")))]
++  "TARGET_EITHER"
++  "
++  {
++    rtx op1 = gen_reg_rtx (SFmode);
++    expand_float (op1, operands[1], 0);
++    op1 = convert_to_mode (HFmode, op1, 0);
++    emit_move_insn (operands[0], op1);
++    DONE;
++  }"
++)
++
++(define_expand "floatdihf2"
++  [(set (match_operand:HF           0 "general_operand" "")
++      (float:HF (match_operand:DI 1 "general_operand" "")))]
++  "TARGET_EITHER"
++  "
++  {
++    rtx op1 = gen_reg_rtx (SFmode);
++    expand_float (op1, operands[1], 0);
++    op1 = convert_to_mode (HFmode, op1, 0);
++    emit_move_insn (operands[0], op1);
++    DONE;
++  }"
++)
++
+ (define_expand "floatsisf2"
+   [(set (match_operand:SF           0 "s_register_operand" "")
+       (float:SF (match_operand:SI 1 "s_register_operand" "")))]
+@@ -3563,6 +4005,30 @@
+     }
+ ")
++(define_expand "fix_trunchfsi2"
++  [(set (match_operand:SI         0 "general_operand" "")
++      (fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
++  "TARGET_EITHER"
++  "
++  {
++    rtx op1 = convert_to_mode (SFmode, operands[1], 0);
++    expand_fix (operands[0], op1, 0);
++    DONE;
++  }"
++)
++
++(define_expand "fix_trunchfdi2"
++  [(set (match_operand:DI         0 "general_operand" "")
++      (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
++  "TARGET_EITHER"
++  "
++  {
++    rtx op1 = convert_to_mode (SFmode, operands[1], 0);
++    expand_fix (operands[0], op1, 0);
++    DONE;
++  }"
++)
++
+ (define_expand "fix_truncsfsi2"
+   [(set (match_operand:SI         0 "s_register_operand" "")
+       (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
+@@ -3602,6 +4068,22 @@
+   "TARGET_32BIT && TARGET_HARD_FLOAT"
+   ""
+ )
++
++/* DFmode -> HFmode conversions have to go through SFmode.  */
++(define_expand "truncdfhf2"
++  [(set (match_operand:HF  0 "general_operand" "")
++      (float_truncate:HF
++       (match_operand:DF 1 "general_operand" "")))]
++  "TARGET_EITHER"
++  "
++  {
++    rtx op1;
++    op1 = convert_to_mode (SFmode, operands[1], 0);
++    op1 = convert_to_mode (HFmode, op1, 0);
++    emit_move_insn (operands[0], op1);
++    DONE;
++  }"
++)
\f
+ ;; Zero and sign extension instructions.
+@@ -3623,6 +4105,7 @@
+     return \"mov%?\\t%R0, #0\";
+   "
+   [(set_attr "length" "8")
++   (set_attr "insn" "mov")
+    (set_attr "predicable" "yes")]
+ )
+@@ -3666,6 +4149,7 @@
+   "
+   [(set_attr "length" "8")
+    (set_attr "shift" "1")
++   (set_attr "insn" "mov")
+    (set_attr "predicable" "yes")]
+ )
+@@ -4464,6 +4948,21 @@
+   "TARGET_32BIT && TARGET_HARD_FLOAT"
+   ""
+ )
++
++/* HFmode -> DFmode conversions have to go through SFmode.  */
++(define_expand "extendhfdf2"
++  [(set (match_operand:DF                  0 "general_operand" "")
++      (float_extend:DF (match_operand:HF 1 "general_operand"  "")))]
++  "TARGET_EITHER"
++  "
++  {
++    rtx op1;
++    op1 = convert_to_mode (SFmode, operands[1], 0);
++    op1 = convert_to_mode (DFmode, op1, 0);
++    emit_insn (gen_movdf (operands[0], op1));
++    DONE;
++  }"
++)
\f
+ ;; Move insns (including loads and stores)
+@@ -4699,6 +5198,7 @@
+   }"
+   [(set_attr "length" "4,4,6,2,2,6,4,4")
+    (set_attr "type" "*,*,*,load2,store2,load2,store2,*")
++   (set_attr "insn" "*,mov,*,*,*,*,*,mov")
+    (set_attr "pool_range" "*,*,*,*,*,1020,*,*")]
+ )
+@@ -4785,23 +5285,38 @@
+   "
+ )
++;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
++;; LO_SUM adds in the high bits.  Fortunately these are opaque opearsions
++;; so this does not matter.
++(define_insn "*arm_movt"
++  [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
++      (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
++                 (match_operand:SI 2 "general_operand"      "i")))]
++  "TARGET_32BIT"
++  "movt%?\t%0, #:upper16:%c2"
++  [(set_attr "predicable" "yes")
++   (set_attr "length" "4")]
++)
++
+ (define_insn "*arm_movsi_insn"
+-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r, m")
+-      (match_operand:SI 1 "general_operand"      "rI,K,N,mi,r"))]
++  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
++      (match_operand:SI 1 "general_operand"      " rk,I,K,j,mi,rk"))]
+   "TARGET_ARM && ! TARGET_IWMMXT
+    && !(TARGET_HARD_FLOAT && TARGET_VFP)
+    && (   register_operand (operands[0], SImode)
+        || register_operand (operands[1], SImode))"
+   "@
+    mov%?\\t%0, %1
++   mov%?\\t%0, %1
+    mvn%?\\t%0, #%B1
+    movw%?\\t%0, %1
+    ldr%?\\t%0, %1
+    str%?\\t%1, %0"
+-  [(set_attr "type" "*,*,*,load1,store1")
++  [(set_attr "type" "*,*,*,*,load1,store1")
++   (set_attr "insn" "mov,mov,mvn,mov,*,*")
+    (set_attr "predicable" "yes")
+-   (set_attr "pool_range" "*,*,*,4096,*")
+-   (set_attr "neg_pool_range" "*,*,*,4084,*")]
++   (set_attr "pool_range" "*,*,*,*,4096,*")
++   (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
+ )
+ (define_split
+@@ -4818,9 +5333,22 @@
+   "
+ )
++(define_split
++  [(set (match_operand:SI 0 "arm_general_register_operand" "")
++      (match_operand:SI 1 "general_operand" ""))]
++  "TARGET_32BIT
++   && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
++   && !flag_pic && !target_word_relocations
++   && !arm_tls_referenced_p (operands[1])"
++  [(clobber (const_int 0))]
++{
++  arm_emit_movpair (operands[0], operands[1]);
++  DONE;
++})
++
+ (define_insn "*thumb1_movsi_insn"
+-  [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*lh")
+-      (match_operand:SI 1 "general_operand"      "l, I,J,K,>,l,mi,l,*lh"))]
++  [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*lhk")
++      (match_operand:SI 1 "general_operand"      "l, I,J,K,>,l,mi,l,*lhk"))]
+   "TARGET_THUMB1
+    && (   register_operand (operands[0], SImode) 
+        || register_operand (operands[1], SImode))"
+@@ -5418,6 +5946,7 @@
+    ldr%(h%)\\t%0, %1\\t%@ movhi"
+   [(set_attr "type" "*,*,store1,load1")
+    (set_attr "predicable" "yes")
++   (set_attr "insn" "mov,mvn,*,*")
+    (set_attr "pool_range" "*,*,*,256")
+    (set_attr "neg_pool_range" "*,*,*,244")]
+ )
+@@ -5429,7 +5958,8 @@
+   "@
+    mov%?\\t%0, %1\\t%@ movhi
+    mvn%?\\t%0, #%B1\\t%@ movhi"
+-  [(set_attr "predicable" "yes")]
++  [(set_attr "predicable" "yes")
++   (set_attr "insn" "mov,mvn")]
+ )
+ (define_expand "thumb_movhi_clobber"
+@@ -5560,6 +6090,7 @@
+    ldr%(b%)\\t%0, %1
+    str%(b%)\\t%1, %0"
+   [(set_attr "type" "*,*,load1,store1")
++   (set_attr "insn" "mov,mvn,*,*")
+    (set_attr "predicable" "yes")]
+ )
+@@ -5578,9 +6109,111 @@
+    mov\\t%0, %1"
+   [(set_attr "length" "2")
+    (set_attr "type" "*,load1,store1,*,*,*")
++   (set_attr "insn" "*,*,*,mov,mov,mov")
+    (set_attr "pool_range" "*,32,*,*,*,*")]
+ )
++;; HFmode moves
++(define_expand "movhf"
++  [(set (match_operand:HF 0 "general_operand" "")
++      (match_operand:HF 1 "general_operand" ""))]
++  "TARGET_EITHER"
++  "
++  if (TARGET_32BIT)
++    {
++      if (GET_CODE (operands[0]) == MEM)
++        operands[1] = force_reg (HFmode, operands[1]);
++    }
++  else /* TARGET_THUMB1 */
++    {
++      if (can_create_pseudo_p ())
++        {
++           if (GET_CODE (operands[0]) != REG)
++           operands[1] = force_reg (HFmode, operands[1]);
++        }
++    }
++  "
++)
++
++(define_insn "*arm32_movhf"
++  [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
++      (match_operand:HF 1 "general_operand"      " m,r,r,F"))]
++  "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_NEON_FP16)
++   && (         s_register_operand (operands[0], HFmode)
++       || s_register_operand (operands[1], HFmode))"
++  "*
++  switch (which_alternative)
++    {
++    case 0:   /* ARM register from memory */
++      return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
++    case 1:   /* memory from ARM register */
++      return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
++    case 2:   /* ARM register from ARM register */
++      return \"mov%?\\t%0, %1\\t%@ __fp16\";
++    case 3:   /* ARM register from constant */
++      {
++      REAL_VALUE_TYPE r;
++      long bits;
++      rtx ops[4];
++
++      REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
++      bits = real_to_target (NULL, &r, HFmode);
++      ops[0] = operands[0];
++      ops[1] = GEN_INT (bits);
++      ops[2] = GEN_INT (bits & 0xff00);
++      ops[3] = GEN_INT (bits & 0x00ff);
++
++      if (arm_arch_thumb2)
++        output_asm_insn (\"movw%?\\t%0, %1\", ops);
++      else
++        output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
++      return \"\";
++       }
++    default:
++      gcc_unreachable ();
++    }
++  "
++  [(set_attr "conds" "unconditional")
++   (set_attr "type" "load1,store1,*,*")
++   (set_attr "length" "4,4,4,8")
++   (set_attr "predicable" "yes")
++   ]
++)
++
++(define_insn "*thumb1_movhf"
++  [(set (match_operand:HF     0 "nonimmediate_operand" "=l,l,m,*r,*h")
++      (match_operand:HF     1 "general_operand"      "l,mF,l,*h,*r"))]
++  "TARGET_THUMB1
++   && (         s_register_operand (operands[0], HFmode) 
++       || s_register_operand (operands[1], HFmode))"
++  "*
++  switch (which_alternative)
++    {
++    case 1:
++      {
++      rtx addr;
++      gcc_assert (GET_CODE(operands[1]) == MEM);
++      addr = XEXP (operands[1], 0);
++      if (GET_CODE (addr) == LABEL_REF
++          || (GET_CODE (addr) == CONST
++              && GET_CODE (XEXP (addr, 0)) == PLUS
++              && GET_CODE (XEXP (XEXP (addr, 0), 0)) == LABEL_REF
++              && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT))
++        {
++          /* Constant pool entry.  */
++          return \"ldr\\t%0, %1\";
++        }
++      return \"ldrh\\t%0, %1\";
++      }
++    case 2: return \"strh\\t%1, %0\";
++    default: return \"mov\\t%0, %1\";
++    }
++  "
++  [(set_attr "length" "2")
++   (set_attr "type" "*,load1,store1,*,*")
++   (set_attr "pool_range" "*,1020,*,*,*")]
++)
++
+ (define_expand "movsf"
+   [(set (match_operand:SF 0 "general_operand" "")
+       (match_operand:SF 1 "general_operand" ""))]
+@@ -5633,6 +6266,7 @@
+   [(set_attr "length" "4,4,4")
+    (set_attr "predicable" "yes")
+    (set_attr "type" "*,load1,store1")
++   (set_attr "insn" "mov,*,*")
+    (set_attr "pool_range" "*,4096,*")
+    (set_attr "neg_pool_range" "*,4084,*")]
+ )
+@@ -6088,7 +6722,7 @@
+    (match_operand:BLK 1 "general_operand" "")
+    (match_operand:SI 2 "const_int_operand" "")
+    (match_operand:SI 3 "const_int_operand" "")]
+-  "TARGET_EITHER"
++  "TARGET_EITHER && !low_irq_latency"
+   "
+   if (TARGET_32BIT)
+     {
+@@ -7298,7 +7932,11 @@
+    (set_attr "shift" "1")
+    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
+ (define_insn "*arm_cmpsi_shiftsi_swp"
+@@ -7313,7 +7951,11 @@
+    (set_attr "shift" "1")
+    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
+ (define_insn "*arm_cmpsi_negshiftsi_si"
+@@ -7328,7 +7970,11 @@
+   [(set_attr "conds" "set")
+    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
+                                   (const_string "alu_shift")
+-                                  (const_string "alu_shift_reg")))]
++                                    (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
+ ;; Cirrus SF compare instruction
+@@ -7670,77 +8316,77 @@
+ (define_expand "seq"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (eq:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
+ )
+ (define_expand "sne"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (ne:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
+ )
+ (define_expand "sgt"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (gt:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
+ )
+ (define_expand "sle"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (le:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
+ )
+ (define_expand "sge"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (ge:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
+ )
+ (define_expand "slt"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (lt:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
+ )
+ (define_expand "sgtu"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (gtu:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
+ )
+ (define_expand "sleu"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (leu:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
+ )
+ (define_expand "sgeu"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (geu:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
+ )
+ (define_expand "sltu"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (ltu:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
+ )
+ (define_expand "sunordered"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (unordered:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
++  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP) && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
+                                     arm_compare_op1);"
+ )
+@@ -7748,7 +8394,7 @@
+ (define_expand "sordered"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (ordered:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
++  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP) && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
+                                     arm_compare_op1);"
+ )
+@@ -7756,7 +8402,7 @@
+ (define_expand "sungt"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (ungt:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
++  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP) && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
+                                     arm_compare_op1);"
+ )
+@@ -7764,7 +8410,7 @@
+ (define_expand "sunge"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (unge:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
++  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP) && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
+                                     arm_compare_op1);"
+ )
+@@ -7772,7 +8418,7 @@
+ (define_expand "sunlt"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (unlt:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
++  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP) && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
+                                     arm_compare_op1);"
+ )
+@@ -7780,7 +8426,7 @@
+ (define_expand "sunle"
+   [(set (match_operand:SI 0 "s_register_operand" "")
+       (unle:SI (match_dup 1) (const_int 0)))]
+-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
++  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP) && !TARGET_NO_COND_EXEC"
+   "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
+                                     arm_compare_op1);"
+ )
+@@ -7809,6 +8455,7 @@
+   "TARGET_ARM"
+   "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
+   [(set_attr "conds" "use")
++   (set_attr "insn" "mov")
+    (set_attr "length" "8")]
+ )
+@@ -7819,6 +8466,7 @@
+   "TARGET_ARM"
+   "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
+   [(set_attr "conds" "use")
++   (set_attr "insn" "mov")
+    (set_attr "length" "8")]
+ )
+@@ -7829,6 +8477,7 @@
+   "TARGET_ARM"
+   "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
+   [(set_attr "conds" "use")
++   (set_attr "insn" "mov")
+    (set_attr "length" "8")]
+ )
+@@ -8032,7 +8681,7 @@
+       (if_then_else:SI (match_operand 1 "arm_comparison_operator" "")
+                        (match_operand:SI 2 "arm_not_operand" "")
+                        (match_operand:SI 3 "arm_not_operand" "")))]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   "
+   {
+     enum rtx_code code = GET_CODE (operands[1]);
+@@ -8051,7 +8700,7 @@
+       (if_then_else:SF (match_operand 1 "arm_comparison_operator" "")
+                        (match_operand:SF 2 "s_register_operand" "")
+                        (match_operand:SF 3 "nonmemory_operand" "")))]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_COND_EXEC"
+   "
+   {
+     enum rtx_code code = GET_CODE (operands[1]);
+@@ -8076,7 +8725,7 @@
+       (if_then_else:DF (match_operand 1 "arm_comparison_operator" "")
+                        (match_operand:DF 2 "s_register_operand" "")
+                        (match_operand:DF 3 "arm_float_add_operand" "")))]
+-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
++  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP) && !TARGET_NO_COND_EXEC"
+   "
+   {
+     enum rtx_code code = GET_CODE (operands[1]);
+@@ -8108,7 +8757,8 @@
+    mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
+    mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
+   [(set_attr "length" "4,4,4,4,8,8,8,8")
+-   (set_attr "conds" "use")]
++   (set_attr "conds" "use")
++   (set_attr "insn" "mov,mvn,mov,mvn,mov,mov,mvn,mvn")]
+ )
+ (define_insn "*movsfcc_soft_insn"
+@@ -8121,7 +8771,8 @@
+   "@
+    mov%D3\\t%0, %2
+    mov%d3\\t%0, %1"
+-  [(set_attr "conds" "use")]
++  [(set_attr "conds" "use")
++   (set_attr "insn" "mov")]
+ )
\f
+@@ -8524,7 +9175,7 @@
+                      [(match_operand 1 "cc_register" "") (const_int 0)])
+                       (return)
+                       (pc)))]
+-  "TARGET_ARM && USE_RETURN_INSN (TRUE)"
++  "TARGET_ARM && USE_RETURN_INSN (TRUE) && !TARGET_NO_COND_EXEC"
+   "*
+   {
+     if (arm_ccfsm_state == 2)
+@@ -8545,7 +9196,7 @@
+                      [(match_operand 1 "cc_register" "") (const_int 0)])
+                       (pc)
+                     (return)))]
+-  "TARGET_ARM && USE_RETURN_INSN (TRUE)"
++  "TARGET_ARM && USE_RETURN_INSN (TRUE) && !TARGET_NO_COND_EXEC"
+   "*
+   {
+     if (arm_ccfsm_state == 2)
+@@ -8864,7 +9515,11 @@
+    (set_attr "shift" "4")
+    (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
+ (define_split
+@@ -8902,7 +9557,11 @@
+    (set_attr "shift" "4")
+    (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
+ (define_insn "*arith_shiftsi_compare0_scratch"
+@@ -8920,7 +9579,11 @@
+    (set_attr "shift" "4")
+    (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
+ (define_insn "*sub_shiftsi"
+@@ -8935,7 +9598,11 @@
+    (set_attr "shift" "3")
+    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
+ (define_insn "*sub_shiftsi_compare0"
+@@ -8955,7 +9622,11 @@
+    (set_attr "shift" "3")
+    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
+ (define_insn "*sub_shiftsi_compare0_scratch"
+@@ -8973,7 +9644,11 @@
+    (set_attr "shift" "3")
+    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 8)
++                                        (const_int 4)))]
+ )
\f
+@@ -8986,6 +9661,7 @@
+   "TARGET_ARM"
+   "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
+   [(set_attr "conds" "use")
++   (set_attr "insn" "mov")
+    (set_attr "length" "8")]
+ )
+@@ -8999,6 +9675,7 @@
+    orr%d2\\t%0, %1, #1
+    mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
+   [(set_attr "conds" "use")
++   (set_attr "insn" "orr")
+    (set_attr "length" "4,8")]
+ )
+@@ -9008,7 +9685,7 @@
+        [(match_operand:SI 2 "s_register_operand" "r,r")
+         (match_operand:SI 3 "arm_add_operand" "rI,L")]))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_COND_EXEC"
+   "*
+     if (operands[3] == const0_rtx)
+       {
+@@ -9063,6 +9740,7 @@
+     return \"\";
+   "
+   [(set_attr "conds" "use")
++   (set_attr "insn" "mov")
+    (set_attr "length" "4,4,8")]
+ )
+@@ -9074,7 +9752,7 @@
+           (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
+           (match_operand:SI 1 "s_register_operand" "0,?r")]))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
+   "*
+     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
+       return \"%i5\\t%0, %1, %2, lsr #31\";
+@@ -9470,7 +10148,7 @@
+        (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
+        (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_COND_EXEC"
+   "*
+   if (GET_CODE (operands[5]) == LT
+       && (operands[4] == const0_rtx))
+@@ -9536,7 +10214,7 @@
+                         (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
+                        (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
+   "#"
+   [(set_attr "conds" "clob")
+    (set_attr "length" "8,12")]
+@@ -9572,7 +10250,7 @@
+                         (match_operand:SI 2 "s_register_operand" "r,r")
+                         (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
+   "#"
+   [(set_attr "conds" "clob")
+    (set_attr "length" "8,12")]
+@@ -9610,7 +10288,7 @@
+                         [(match_operand:SI 3 "s_register_operand" "r")
+                          (match_operand:SI 4 "arm_rhs_operand" "rI")])))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
+   "#"
+   [(set_attr "conds" "clob")
+    (set_attr "length" "12")]
+@@ -9760,7 +10438,7 @@
+        (not:SI
+         (match_operand:SI 2 "s_register_operand" "r,r"))))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
+   "#"
+   [(set_attr "conds" "clob")
+    (set_attr "length" "8,12")]
+@@ -9779,6 +10457,7 @@
+    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
+    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
+   [(set_attr "conds" "use")
++   (set_attr "insn" "mvn")
+    (set_attr "length" "4,8,8")]
+ )
+@@ -9792,7 +10471,7 @@
+         (match_operand:SI 2 "s_register_operand" "r,r"))
+        (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
+   "#"
+   [(set_attr "conds" "clob")
+    (set_attr "length" "8,12")]
+@@ -9811,6 +10490,7 @@
+    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
+    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
+   [(set_attr "conds" "use")
++   (set_attr "insn" "mvn")
+    (set_attr "length" "4,8,8")]
+ )
+@@ -9825,7 +10505,7 @@
+          (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
+        (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
+   "#"
+   [(set_attr "conds" "clob")
+    (set_attr "length" "8,12")]
+@@ -9847,10 +10527,23 @@
+    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
+   [(set_attr "conds" "use")
+    (set_attr "shift" "2")
+-   (set_attr "length" "4,8,8")
++   (set_attr "insn" "mov")
+    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set_attr_alternative "length"
++           [(if_then_else (and (eq_attr "type" "alu_shift_reg")
++                               (eq_attr "fix_janus" "yes"))
++                          (const_int 8)
++                          (const_int 4))
++            (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                               (eq_attr "fix_janus" "yes"))
++                          (const_int 12)
++                          (const_int 8))
++            (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                               (eq_attr "fix_janus" "yes"))
++                          (const_int 12)
++                          (const_int 8))])]
+ )
+ (define_insn "*ifcompare_move_shift"
+@@ -9864,7 +10557,7 @@
+         [(match_operand:SI 2 "s_register_operand" "r,r")
+          (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
+   "#"
+   [(set_attr "conds" "clob")
+    (set_attr "length" "8,12")]
+@@ -9886,10 +10579,24 @@
+    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
+   [(set_attr "conds" "use")
+    (set_attr "shift" "2")
+-   (set_attr "length" "4,8,8")
++   (set_attr "insn" "mov")
+    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set_attr_alternative "length"
++        [(if_then_else (and (eq_attr "type" "alu_shift_reg")
++                            (eq_attr "fix_janus" "yes"))
++                       (const_int 8)
++                       (const_int 4))
++         (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                            (eq_attr "fix_janus" "yes"))
++                       (const_int 12)
++                       (const_int 8))
++         (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                            (eq_attr "fix_janus" "yes"))
++                       (const_int 12)
++                       (const_int 8))])
++     (set_attr "insn" "mov")]
+ )
+ (define_insn "*ifcompare_shift_shift"
+@@ -9905,7 +10612,7 @@
+         [(match_operand:SI 3 "s_register_operand" "r")
+          (match_operand:SI 4 "arm_rhs_operand" "rM")])))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
+   "#"
+   [(set_attr "conds" "clob")
+    (set_attr "length" "12")]
+@@ -9926,12 +10633,16 @@
+   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
+   [(set_attr "conds" "use")
+    (set_attr "shift" "1")
+-   (set_attr "length" "8")
++   (set_attr "insn" "mov")
+    (set (attr "type") (if_then_else
+                       (and (match_operand 2 "const_int_operand" "")
+                              (match_operand 4 "const_int_operand" ""))
+                     (const_string "alu_shift")
+-                    (const_string "alu_shift_reg")))]
++                      (const_string "alu_shift_reg")))
++     (set (attr "length") (if_then_else (and (eq_attr "type" "alu_shift_reg")
++                                             (eq_attr "fix_janus" "yes"))
++                                        (const_int 16)
++                                        (const_int 8)))]
+ )
+ (define_insn "*ifcompare_not_arith"
+@@ -9945,7 +10656,7 @@
+         [(match_operand:SI 2 "s_register_operand" "r")
+          (match_operand:SI 3 "arm_rhs_operand" "rI")])))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
+   "#"
+   [(set_attr "conds" "clob")
+    (set_attr "length" "12")]
+@@ -9963,6 +10674,7 @@
+   "TARGET_ARM"
+   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
+   [(set_attr "conds" "use")
++   (set_attr "insn" "mvn")
+    (set_attr "length" "8")]
+ )
+@@ -9977,7 +10689,7 @@
+          (match_operand:SI 3 "arm_rhs_operand" "rI")])
+        (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
+   "#"
+   [(set_attr "conds" "clob")
+    (set_attr "length" "12")]
+@@ -9995,6 +10707,7 @@
+   "TARGET_ARM"
+   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
+   [(set_attr "conds" "use")
++   (set_attr "insn" "mvn")
+    (set_attr "length" "8")]
+ )
+@@ -10007,7 +10720,7 @@
+        (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
+        (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
+   "#"
+   [(set_attr "conds" "clob")
+    (set_attr "length" "8,12")]
+@@ -10038,7 +10751,7 @@
+        (match_operand:SI 1 "arm_not_operand" "0,?rIK")
+        (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM"
++  "TARGET_ARM && !TARGET_NO_SINGLE_COND_EXEC"
+   "#"
+   [(set_attr "conds" "clob")
+    (set_attr "length" "8,12")]
+@@ -10181,13 +10894,13 @@
+ ; reversed, check that the memory references aren't volatile.
+ (define_peephole
+-  [(set (match_operand:SI 0 "s_register_operand" "=r")
++  [(set (match_operand:SI 0 "s_register_operand" "=rk")
+         (match_operand:SI 4 "memory_operand" "m"))
+-   (set (match_operand:SI 1 "s_register_operand" "=r")
++   (set (match_operand:SI 1 "s_register_operand" "=rk")
+         (match_operand:SI 5 "memory_operand" "m"))
+-   (set (match_operand:SI 2 "s_register_operand" "=r")
++   (set (match_operand:SI 2 "s_register_operand" "=rk")
+         (match_operand:SI 6 "memory_operand" "m"))
+-   (set (match_operand:SI 3 "s_register_operand" "=r")
++   (set (match_operand:SI 3 "s_register_operand" "=rk")
+         (match_operand:SI 7 "memory_operand" "m"))]
+   "TARGET_ARM && load_multiple_sequence (operands, 4, NULL, NULL, NULL)"
+   "*
+@@ -10196,11 +10909,11 @@
+ )
+ (define_peephole
+-  [(set (match_operand:SI 0 "s_register_operand" "=r")
++  [(set (match_operand:SI 0 "s_register_operand" "=rk")
+         (match_operand:SI 3 "memory_operand" "m"))
+-   (set (match_operand:SI 1 "s_register_operand" "=r")
++   (set (match_operand:SI 1 "s_register_operand" "=rk")
+         (match_operand:SI 4 "memory_operand" "m"))
+-   (set (match_operand:SI 2 "s_register_operand" "=r")
++   (set (match_operand:SI 2 "s_register_operand" "=rk")
+         (match_operand:SI 5 "memory_operand" "m"))]
+   "TARGET_ARM && load_multiple_sequence (operands, 3, NULL, NULL, NULL)"
+   "*
+@@ -10209,9 +10922,9 @@
+ )
+ (define_peephole
+-  [(set (match_operand:SI 0 "s_register_operand" "=r")
++  [(set (match_operand:SI 0 "s_register_operand" "=rk")
+         (match_operand:SI 2 "memory_operand" "m"))
+-   (set (match_operand:SI 1 "s_register_operand" "=r")
++   (set (match_operand:SI 1 "s_register_operand" "=rk")
+         (match_operand:SI 3 "memory_operand" "m"))]
+   "TARGET_ARM && load_multiple_sequence (operands, 2, NULL, NULL, NULL)"
+   "*
+@@ -10221,13 +10934,13 @@
+ (define_peephole
+   [(set (match_operand:SI 4 "memory_operand" "=m")
+-        (match_operand:SI 0 "s_register_operand" "r"))
++        (match_operand:SI 0 "s_register_operand" "rk"))
+    (set (match_operand:SI 5 "memory_operand" "=m")
+-        (match_operand:SI 1 "s_register_operand" "r"))
++        (match_operand:SI 1 "s_register_operand" "rk"))
+    (set (match_operand:SI 6 "memory_operand" "=m")
+-        (match_operand:SI 2 "s_register_operand" "r"))
++        (match_operand:SI 2 "s_register_operand" "rk"))
+    (set (match_operand:SI 7 "memory_operand" "=m")
+-        (match_operand:SI 3 "s_register_operand" "r"))]
++        (match_operand:SI 3 "s_register_operand" "rk"))]
+   "TARGET_ARM && store_multiple_sequence (operands, 4, NULL, NULL, NULL)"
+   "*
+   return emit_stm_seq (operands, 4);
+@@ -10236,11 +10949,11 @@
+ (define_peephole
+   [(set (match_operand:SI 3 "memory_operand" "=m")
+-        (match_operand:SI 0 "s_register_operand" "r"))
++        (match_operand:SI 0 "s_register_operand" "rk"))
+    (set (match_operand:SI 4 "memory_operand" "=m")
+-        (match_operand:SI 1 "s_register_operand" "r"))
++        (match_operand:SI 1 "s_register_operand" "rk"))
+    (set (match_operand:SI 5 "memory_operand" "=m")
+-        (match_operand:SI 2 "s_register_operand" "r"))]
++        (match_operand:SI 2 "s_register_operand" "rk"))]
+   "TARGET_ARM && store_multiple_sequence (operands, 3, NULL, NULL, NULL)"
+   "*
+   return emit_stm_seq (operands, 3);
+@@ -10249,9 +10962,9 @@
+ (define_peephole
+   [(set (match_operand:SI 2 "memory_operand" "=m")
+-        (match_operand:SI 0 "s_register_operand" "r"))
++        (match_operand:SI 0 "s_register_operand" "rk"))
+    (set (match_operand:SI 3 "memory_operand" "=m")
+-        (match_operand:SI 1 "s_register_operand" "r"))]
++        (match_operand:SI 1 "s_register_operand" "rk"))]
+   "TARGET_ARM && store_multiple_sequence (operands, 2, NULL, NULL, NULL)"
+   "*
+   return emit_stm_seq (operands, 2);
+@@ -10406,7 +11119,7 @@
+                        (match_dup 0)
+                        (match_operand 4 "" "")))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM && reload_completed"
++  "TARGET_ARM && reload_completed && !TARGET_NO_SINGLE_COND_EXEC"
+   [(set (match_dup 5) (match_dup 6))
+    (cond_exec (match_dup 7)
+             (set (match_dup 0) (match_dup 4)))]
+@@ -10434,7 +11147,7 @@
+                        (match_operand 4 "" "")
+                        (match_dup 0)))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM && reload_completed"
++  "TARGET_ARM && reload_completed && !TARGET_NO_SINGLE_COND_EXEC"
+   [(set (match_dup 5) (match_dup 6))
+    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
+             (set (match_dup 0) (match_dup 4)))]
+@@ -10455,7 +11168,7 @@
+                        (match_operand 4 "" "")
+                        (match_operand 5 "" "")))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM && reload_completed"
++  "TARGET_ARM && reload_completed && !TARGET_NO_SINGLE_COND_EXEC"
+   [(set (match_dup 6) (match_dup 7))
+    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
+             (set (match_dup 0) (match_dup 4)))
+@@ -10487,7 +11200,7 @@
+                        (not:SI
+                         (match_operand:SI 5 "s_register_operand" ""))))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_ARM && reload_completed"
++  "TARGET_ARM && reload_completed && !TARGET_NO_SINGLE_COND_EXEC"
+   [(set (match_dup 6) (match_dup 7))
+    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
+             (set (match_dup 0) (match_dup 4)))
+@@ -10522,6 +11235,7 @@
+    mvn%D4\\t%0, %2
+    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
+   [(set_attr "conds" "use")
++   (set_attr "insn" "mvn")
+    (set_attr "length" "4,8")]
+ )
+@@ -10610,8 +11324,8 @@
+ (define_insn "stack_tie"
+   [(set (mem:BLK (scratch))
+-      (unspec:BLK [(match_operand:SI 0 "s_register_operand" "r")
+-                   (match_operand:SI 1 "s_register_operand" "r")]
++      (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
++                   (match_operand:SI 1 "s_register_operand" "rk")]
+                   UNSPEC_PRLG_STK))]
+   ""
+   ""
+@@ -10656,6 +11370,24 @@
+   "
+ )
++(define_insn "align_16"
++  [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN16)]
++  "TARGET_EITHER"
++  "*
++  assemble_align (128);
++  return \"\";
++  "
++)
++
++(define_insn "align_32"
++  [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN32)]
++  "TARGET_EITHER"
++  "*
++  assemble_align (256);
++  return \"\";
++  "
++)
++
+ (define_insn "consttable_end"
+   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
+   "TARGET_EITHER"
+@@ -10682,6 +11414,7 @@
+   "TARGET_THUMB1"
+   "*
+   making_const_table = TRUE;
++  gcc_assert (GET_MODE_CLASS (GET_MODE (operands[0])) != MODE_FLOAT);
+   assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
+   assemble_zeros (2);
+   return \"\";
+@@ -10694,18 +11427,29 @@
+   "TARGET_EITHER"
+   "*
+   {
++    rtx x = operands[0];
+     making_const_table = TRUE;
+-    switch (GET_MODE_CLASS (GET_MODE (operands[0])))
++    switch (GET_MODE_CLASS (GET_MODE (x)))
+       {
+       case MODE_FLOAT:
+-      {
+-        REAL_VALUE_TYPE r;
+-        REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
+-        assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
+-        break;
+-      }
++      if (GET_MODE (x) == HFmode)
++        arm_emit_fp16_const (x);
++      else
++        {
++          REAL_VALUE_TYPE r;
++          REAL_VALUE_FROM_CONST_DOUBLE (r, x);
++          assemble_real (r, GET_MODE (x), BITS_PER_WORD);
++        }
++      break;
+       default:
+-        assemble_integer (operands[0], 4, BITS_PER_WORD, 1);
++      /* XXX: Sometimes gcc does something really dumb and ends up with
++         a HIGH in a constant pool entry, usually because it's trying to
++         load into a VFP register.  We know this will always be used in
++         combination with a LO_SUM which ignores the high bits, so just
++         strip off the HIGH.  */
++      if (GET_CODE (x) == HIGH)
++        x = XEXP (x, 0);
++        assemble_integer (x, 4, BITS_PER_WORD, 1);
+         break;
+       }
+     return \"\";
+@@ -10808,13 +11552,15 @@
+   "TARGET_32BIT && arm_arch5e"
+   "pld\\t%a0")
+-;; General predication pattern
++;; General predication pattern.
++;; Conditional branches are available as both arm_cond_branch and
++;; predicated arm_jump, so it doesn't matter if we disable the latter.
+ (define_cond_exec
+   [(match_operator 0 "arm_comparison_operator"
+     [(match_operand 1 "cc_register" "")
+      (const_int 0)])]
+-  "TARGET_32BIT"
++  "TARGET_32BIT && !TARGET_NO_SINGLE_COND_EXEC"
+   ""
+ )
+--- a/gcc/config/arm/arm.opt
++++ b/gcc/config/arm/arm.opt
+@@ -78,6 +78,10 @@ Specify if floating point hardware shoul
+ mfp=
+ Target RejectNegative Joined Undocumented Var(target_fpe_name)
++mfp16-format=
++Target RejectNegative Joined Var(target_fp16_format_name)
++Specify the __fp16 floating-point format
++
+ ;; Now ignored.
+ mfpe
+ Target RejectNegative Mask(FPE) Undocumented
+@@ -93,6 +97,10 @@ mhard-float
+ Target RejectNegative
+ Alias for -mfloat-abi=hard
++mfix-janus-2cc
++Target Report Mask(FIX_JANUS)
++Work around hardware errata for Avalent Janus 2CC cores.
++
+ mlittle-endian
+ Target Report RejectNegative InverseMask(BIG_END)
+ Assume target CPU is configured as little endian
+@@ -101,6 +109,10 @@ mlong-calls
+ Target Report Mask(LONG_CALLS)
+ Generate call insns as indirect calls, if necessary
++mmarvell-div
++Target Report Mask(MARVELL_DIV)
++Generate hardware integer division instructions supported by some Marvell cores.
++
+ mpic-register=
+ Target RejectNegative Joined Var(arm_pic_register_string)
+ Specify the register to be used for PIC addressing
+@@ -156,3 +168,16 @@ Assume big endian bytes, little endian w
+ mvectorize-with-neon-quad
+ Target Report Mask(NEON_VECTORIZE_QUAD)
+ Use Neon quad-word (rather than double-word) registers for vectorization
++
++mlow-irq-latency
++Target Report Var(low_irq_latency)
++Try to reduce interrupt latency of the generated code
++
++mword-relocations
++Target Report Var(target_word_relocations) Init(TARGET_DEFAULT_WORD_RELOCATIONS)
++Only generate absolute relocations on word sized values.
++
++mfix-cortex-m3-ldrd
++Target Report Var(fix_cm3_ldrd) Init(2)
++Avoid overlapping destination and address registers on LDRD instructions
++that may trigger Cortex-M3 errata.
+--- a/gcc/config/arm/arm1020e.md
++++ b/gcc/config/arm/arm1020e.md
+@@ -281,12 +281,12 @@
+ ;; first execute state.  We model this by using 1020a_e in the first cycle.
+ (define_insn_reservation "v10_ffarith" 5
+  (and (eq_attr "vfp10" "yes")
+-      (eq_attr "type" "ffarith"))
++      (eq_attr "type" "fcpys,ffariths,ffarithd,fcmps,fcmpd"))
+  "1020a_e+v10_fmac")
+ (define_insn_reservation "v10_farith" 5
+  (and (eq_attr "vfp10" "yes")
+-      (eq_attr "type" "farith"))
++      (eq_attr "type" "faddd,fadds"))
+  "1020a_e+v10_fmac")
+ (define_insn_reservation "v10_cvt" 5
+--- a/gcc/config/arm/arm_neon.h
++++ b/gcc/config/arm/arm_neon.h
+@@ -39,7 +39,11 @@
+ extern "C" {
+ #endif
++#if defined (__vxworks) && defined (_WRS_KERNEL)
++#include <vxWorks.h>
++#else
+ #include <stdint.h>
++#endif
+ typedef __builtin_neon_qi int8x8_t    __attribute__ ((__vector_size__ (8)));
+ typedef __builtin_neon_hi int16x4_t   __attribute__ ((__vector_size__ (8)));
+--- /dev/null
++++ b/gcc/config/arm/bpabi-v6m.S
+@@ -0,0 +1,325 @@
++/* Miscellaneous BPABI functions.  ARMv6M implementation
++
++   Copyright (C) 2006  Free Software Foundation, Inc.
++   Contributed by CodeSourcery, LLC.
++
++   This file is free software; you can redistribute it and/or modify it
++   under the terms of the GNU General Public License as published by the
++   Free Software Foundation; either version 2, or (at your option) any
++   later version.
++
++   In addition to the permissions in the GNU General Public License, the
++   Free Software Foundation gives you unlimited permission to link the
++   compiled version of this file into combinations with other programs,
++   and to distribute those combinations without any restriction coming
++   from the use of this file.  (The General Public License restrictions
++   do apply in other respects; for example, they cover modification of
++   the file, and distribution when not linked into a combine
++   executable.)
++
++   This file is distributed in the hope that it will be useful, but
++   WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program; see the file COPYING.  If not, write to
++   the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++   Boston, MA 02110-1301, USA.  */
++
++#ifdef __ARMEB__
++#define xxh r0
++#define xxl r1
++#define yyh r2
++#define yyl r3
++#else
++#define xxh r1
++#define xxl r0
++#define yyh r3
++#define yyl r2
++#endif        
++      
++#ifdef L_aeabi_lcmp
++
++FUNC_START aeabi_lcmp
++      cmp     xxh, yyh
++      beq     1f
++      bgt     2f
++      mov     r0, #1
++      neg     r0, r0
++      RET
++2:
++      mov     r0, #1
++      RET
++1:
++      sub     r0, xxl, yyl
++      beq     1f
++      bhi     2f
++      mov     r0, #1
++      neg     r0, r0
++      RET
++2:
++      mov     r0, #1
++1:
++      RET
++      FUNC_END aeabi_lcmp
++
++#endif /* L_aeabi_lcmp */
++      
++#ifdef L_aeabi_ulcmp
++
++FUNC_START aeabi_ulcmp
++      cmp     xxh, yyh
++      bne     1f
++      sub     r0, xxl, yyl
++      beq     2f
++1:
++      bcs     1f
++      mov     r0, #1
++      neg     r0, r0
++      RET
++1:
++      mov     r0, #1
++2:
++      RET
++      FUNC_END aeabi_ulcmp
++
++#endif /* L_aeabi_ulcmp */
++
++.macro test_div_by_zero signed
++      cmp     yyh, #0
++      bne     7f
++      cmp     yyl, #0
++      bne     7f
++      cmp     xxh, #0
++      bne     2f
++      cmp     xxl, #0
++2:
++      .ifc    \signed, unsigned
++      beq     3f
++      mov     xxh, #0
++      mvn     xxh, xxh                @ 0xffffffff
++      mov     xxl, xxh
++3:
++      .else
++      beq     5f
++      blt     6f
++      mov     xxl, #0
++      mvn     xxl, xxl                @ 0xffffffff
++      lsr     xxh, xxl, #1            @ 0x7fffffff
++      b       5f
++6:    mov     xxh, #0x80
++      lsl     xxh, xxh, #24           @ 0x80000000
++      mov     xxl, #0
++5:
++      .endif
++      @ tailcalls are tricky on v6-m.
++      push    {r0, r1, r2}
++      ldr     r0, 1f
++      adr     r1, 1f
++      add     r0, r1
++      str     r0, [sp, #8]
++      @ We know we are not on armv4t, so pop pc is safe.
++      pop     {r0, r1, pc}
++      .align  2
++1:
++      .word   __aeabi_ldiv0 - 1b
++7:
++.endm
++
++#ifdef L_aeabi_ldivmod
++
++FUNC_START aeabi_ldivmod
++      test_div_by_zero signed
++
++      push {r0, r1}
++      mov r0, sp
++      push {r0, lr}
++      ldr r0, [sp, #8]
++      bl SYM(__gnu_ldivmod_helper)
++      ldr r3, [sp, #4]
++      mov lr, r3
++      add sp, sp, #8
++      pop {r2, r3}
++      RET
++      FUNC_END aeabi_ldivmod
++
++#endif /* L_aeabi_ldivmod */
++
++#ifdef L_aeabi_uldivmod
++
++FUNC_START aeabi_uldivmod
++      test_div_by_zero unsigned
++
++      push {r0, r1}
++      mov r0, sp
++      push {r0, lr}
++      ldr r0, [sp, #8]
++      bl SYM(__gnu_uldivmod_helper)
++      ldr r3, [sp, #4]
++      mov lr, r3
++      add sp, sp, #8
++      pop {r2, r3}
++      RET
++      FUNC_END aeabi_uldivmod
++      
++#endif /* L_aeabi_uldivmod */
++
++#ifdef L_arm_addsubsf3
++
++FUNC_START aeabi_frsub
++
++      push    {r4, lr}
++      mov     r4, #1
++      lsl     r4, #31
++      eor     r0, r0, r4
++      bl      __aeabi_fadd
++      pop     {r4, pc}
++
++      FUNC_END aeabi_frsub
++
++#endif /* L_arm_addsubsf3 */
++
++#ifdef L_arm_cmpsf2
++
++FUNC_START aeabi_cfrcmple
++
++      mov     ip, r0
++      mov     r0, r1
++      mov     r1, ip
++      b       6f
++
++FUNC_START aeabi_cfcmpeq
++FUNC_ALIAS aeabi_cfcmple aeabi_cfcmpeq
++
++      @ The status-returning routines are required to preserve all
++      @ registers except ip, lr, and cpsr.
++6:    push    {r0, r1, r2, r3, r4, lr}
++      bl      __lesf2
++      @ Set the Z flag correctly, and the C flag unconditionally.
++      cmp     r0, #0
++      @ Clear the C flag if the return value was -1, indicating
++      @ that the first operand was smaller than the second.
++      bmi 1f
++      mov     r1, #0
++      cmn     r0, r1
++1:
++      pop     {r0, r1, r2, r3, r4, pc}
++
++      FUNC_END aeabi_cfcmple
++      FUNC_END aeabi_cfcmpeq
++      FUNC_END aeabi_cfrcmple
++
++FUNC_START    aeabi_fcmpeq
++
++      push    {r4, lr}
++      bl      __eqsf2
++      neg     r0, r0
++      add     r0, r0, #1
++      pop     {r4, pc}
++
++      FUNC_END aeabi_fcmpeq
++
++.macro COMPARISON cond, helper, mode=sf2
++FUNC_START    aeabi_fcmp\cond
++
++      push    {r4, lr}
++      bl      __\helper\mode
++      cmp     r0, #0
++      b\cond  1f
++      mov     r0, #0
++      pop     {r4, pc}
++1:
++      mov     r0, #1
++      pop     {r4, pc}
++
++      FUNC_END aeabi_fcmp\cond
++.endm
++
++COMPARISON lt, le
++COMPARISON le, le
++COMPARISON gt, ge
++COMPARISON ge, ge
++
++#endif /* L_arm_cmpsf2 */
++
++#ifdef L_arm_addsubdf3
++
++FUNC_START aeabi_drsub
++
++      push    {r4, lr}
++      mov     r4, #1
++      lsl     r4, #31
++      eor     xxh, xxh, r4
++      bl      __aeabi_dadd
++      pop     {r4, pc}
++
++      FUNC_END aeabi_drsub
++
++#endif /* L_arm_addsubdf3 */
++
++#ifdef L_arm_cmpdf2
++
++FUNC_START aeabi_cdrcmple
++
++      mov     ip, r0
++      mov     r0, r2
++      mov     r2, ip
++      mov     ip, r1
++      mov     r1, r3
++      mov     r3, ip
++      b       6f
++
++FUNC_START aeabi_cdcmpeq
++FUNC_ALIAS aeabi_cdcmple aeabi_cdcmpeq
++
++      @ The status-returning routines are required to preserve all
++      @ registers except ip, lr, and cpsr.
++6:    push    {r0, r1, r2, r3, r4, lr}
++      bl      __ledf2
++      @ Set the Z flag correctly, and the C flag unconditionally.
++      cmp     r0, #0
++      @ Clear the C flag if the return value was -1, indicating
++      @ that the first operand was smaller than the second.
++      bmi 1f
++      mov     r1, #0
++      cmn     r0, r1
++1:
++      pop     {r0, r1, r2, r3, r4, pc}
++
++      FUNC_END aeabi_cdcmple
++      FUNC_END aeabi_cdcmpeq
++      FUNC_END aeabi_cdrcmple
++
++FUNC_START    aeabi_dcmpeq
++
++      push    {r4, lr}
++      bl      __eqdf2
++      neg     r0, r0
++      add     r0, r0, #1
++      pop     {r4, pc}
++
++      FUNC_END aeabi_dcmpeq
++
++.macro COMPARISON cond, helper, mode=df2
++FUNC_START    aeabi_dcmp\cond
++
++      push    {r4, lr}
++      bl      __\helper\mode
++      cmp     r0, #0
++      b\cond  1f
++      mov     r0, #0
++      pop     {r4, pc}
++1:
++      mov     r0, #1
++      pop     {r4, pc}
++
++      FUNC_END aeabi_dcmp\cond
++.endm
++
++COMPARISON lt, le
++COMPARISON le, le
++COMPARISON gt, ge
++COMPARISON ge, ge
++
++#endif /* L_arm_cmpdf2 */
+--- a/gcc/config/arm/bpabi.S
++++ b/gcc/config/arm/bpabi.S
+@@ -81,20 +81,69 @@ ARM_FUNC_START aeabi_ulcmp
+ #endif /* L_aeabi_ulcmp */
++.macro test_div_by_zero signed
++/* Tail-call to divide-by-zero handlers which may be overridden by the user,
++   so unwinding works properly.  */
++#if defined(__thumb2__)
++      cbnz    yyh, 1f
++      cbnz    yyl, 1f
++      cmp     xxh, #0
++      do_it   eq
++      cmpeq   xxl, #0
++      .ifc \signed, unsigned
++      beq     2f
++      mov     xxh, #0xffffffff
++      mov     xxl, xxh
++2:
++      .else
++      do_it   lt, t
++      movlt   xxl, #0
++      movlt   xxh, #0x80000000
++      do_it   gt, t
++      movgt   xxh, #0x7fffffff
++      movgt   xxl, #0xffffffff
++      .endif
++      b       SYM (__aeabi_ldiv0) __PLT__
++1:
++#else
++      /* Note: Thumb-1 code calls via an ARM shim on processors which
++         support ARM mode.  */
++      cmp     yyh, #0
++      cmpeq   yyl, #0
++      bne     2f
++      cmp     xxh, #0
++      cmpeq   xxl, #0
++      .ifc \signed, unsigned
++      movne   xxh, #0xffffffff
++      movne   xxl, #0xffffffff
++      .else
++      movlt   xxh, #0x80000000
++      movlt   xxl, #0
++      movgt   xxh, #0x7fffffff
++      movgt   xxl, #0xffffffff
++      .endif
++      b       SYM (__aeabi_ldiv0) __PLT__
++2:
++#endif
++.endm
++
+ #ifdef L_aeabi_ldivmod
+ ARM_FUNC_START aeabi_ldivmod
++      test_div_by_zero signed
++
+       sub sp, sp, #8
+-#if defined(__thumb2__)
++/* Low latency and Thumb-2 do_push implementations can't push sp directly.  */
++#if defined(__thumb2__) || defined(__irq_low_latency__)
+       mov ip, sp
+-      push {ip, lr}
++      do_push (ip, lr)
+ #else
+-      do_push {sp, lr}
++      stmfd sp!, {sp, lr}
+ #endif
+       bl SYM(__gnu_ldivmod_helper) __PLT__
+       ldr lr, [sp, #4]
+       add sp, sp, #8
+-      do_pop {r2, r3}
++      do_pop (r2, r3)
+       RET
+       
+ #endif /* L_aeabi_ldivmod */
+@@ -102,17 +151,20 @@ ARM_FUNC_START aeabi_ldivmod
+ #ifdef L_aeabi_uldivmod
+ ARM_FUNC_START aeabi_uldivmod
++      test_div_by_zero unsigned
++
+       sub sp, sp, #8
+-#if defined(__thumb2__)
++/* Low latency and Thumb-2 do_push implementations can't push sp directly.  */
++#if defined(__thumb2__) || defined(__irq_low_latency__)
+       mov ip, sp
+-      push {ip, lr}
++      do_push (ip, lr)
+ #else
+-      do_push {sp, lr}
++      stmfd sp!, {sp, lr}
+ #endif
+       bl SYM(__gnu_uldivmod_helper) __PLT__
+       ldr lr, [sp, #4]
+       add sp, sp, #8
+-      do_pop {r2, r3}
++      do_pop (r2, r3)
+       RET
+       
+ #endif /* L_aeabi_divmod */
+--- a/gcc/config/arm/bpabi.h
++++ b/gcc/config/arm/bpabi.h
+@@ -51,15 +51,25 @@
+ /* The BPABI integer comparison routines return { -1, 0, 1 }.  */
+ #define TARGET_LIB_INT_CMP_BIASED !TARGET_BPABI
++#define TARGET_FIX_V4BX_SPEC " %{mcpu=arm8|mcpu=arm810|mcpu=strongarm*|march=armv4:--fix-v4bx}"
++
++#define BE8_LINK_SPEC " %{mbig-endian:%{march=armv7-a|mcpu=cortex-a8|mcpu=cortex-a9:%{!r:--be8}}}"
++
+ /* Tell the assembler to build BPABI binaries.  */
+ #undef  SUBTARGET_EXTRA_ASM_SPEC
+-#define SUBTARGET_EXTRA_ASM_SPEC "%{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu;:-meabi=4}"
++#define SUBTARGET_EXTRA_ASM_SPEC "%{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu;:-meabi=5}" TARGET_FIX_V4BX_SPEC
++
++#ifndef SUBTARGET_EXTRA_LINK_SPEC
++#define SUBTARGET_EXTRA_LINK_SPEC ""
++#endif
+ /* The generic link spec in elf.h does not support shared libraries.  */
+ #undef  LINK_SPEC
+ #define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} "         \
+   "%{static:-Bstatic} %{shared:-shared} %{symbolic:-Bsymbolic} "      \
+-  "-X"
++   "-X" SUBTARGET_EXTRA_LINK_SPEC TARGET_FIX_V4BX_SPEC                        \
++   BE8_LINK_SPEC                                                      \
++   " %{mfix-janus-2cc:--fix-janus-2cc}"
+ #if defined (__thumb__)
+ #define RENAME_LIBRARY_SET ".thumb_set"
+@@ -81,16 +91,22 @@
+ #define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (muldi3, lmul)
+ #endif
+ #ifdef L_fixdfdi
+-#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixdfdi, d2lz)
++#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixdfdi, d2lz) \
++  extern DWtype __fixdfdi (DFtype) __attribute__((pcs("aapcs"))); \
++  extern UDWtype __fixunsdfdi (DFtype) __asm__("__aeabi_d2ulz") __attribute__((pcs("aapcs")));
+ #endif
+ #ifdef L_fixunsdfdi
+-#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunsdfdi, d2ulz)
++#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunsdfdi, d2ulz) \
++  extern UDWtype __fixunsdfdi (DFtype) __attribute__((pcs("aapcs")));
+ #endif
+ #ifdef L_fixsfdi
+-#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixsfdi, f2lz)
++#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixsfdi, f2lz) \
++  extern DWtype __fixsfdi (SFtype) __attribute__((pcs("aapcs"))); \
++  extern UDWtype __fixunssfdi (SFtype) __asm__("__aeabi_f2ulz") __attribute__((pcs("aapcs")));
+ #endif
+ #ifdef L_fixunssfdi
+-#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunssfdi, f2ulz)
++#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunssfdi, f2ulz) \
++  extern UDWtype __fixunssfdi (SFtype) __attribute__((pcs("aapcs")));
+ #endif
+ #ifdef L_floatdidf
+ #define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdidf, l2d)
+@@ -99,6 +115,21 @@
+ #define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdisf, l2f)
+ #endif
++/* These renames are needed on ARMv6M.  Other targets get them from
++   assembly routines.  */
++#ifdef L_fixunsdfsi
++#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunsdfsi, d2uiz)
++#endif
++#ifdef L_fixunssfsi
++#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunssfsi, f2uiz)
++#endif
++#ifdef L_floatundidf
++#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatundidf, ul2d)
++#endif
++#ifdef L_floatundisf
++#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatundisf, ul2f)
++#endif
++
+ /* The BPABI requires that we always use an out-of-line implementation
+    of RTTI comparison, even if the target supports weak symbols,
+    because the same object file might be used on a target that does
+@@ -123,3 +154,26 @@
+ #undef FINI_SECTION_ASM_OP
+ #define INIT_ARRAY_SECTION_ASM_OP ARM_EABI_CTORS_SECTION_OP
+ #define FINI_ARRAY_SECTION_ASM_OP ARM_EABI_DTORS_SECTION_OP
++
++/* The legacy _mcount implementation assumes r11 points to a
++    4-word APCS frame.  This is generally not true for EABI targets,
++    particularly not in Thumb mode.  We assume the mcount
++    implementation does not require a counter variable (No Counter).
++    Note that __gnu_mcount_nc will be entered with a misaligned stack.
++    This is OK because it uses a special calling convention anyway.  */
++
++#undef  NO_PROFILE_COUNTERS
++#define NO_PROFILE_COUNTERS 1
++#undef  ARM_FUNCTION_PROFILER
++#define ARM_FUNCTION_PROFILER(STREAM, LABELNO)                        \
++{                                                                     \
++  fprintf (STREAM, "\tpush\t{lr}\n");                                 \
++  fprintf (STREAM, "\tbl\t__gnu_mcount_nc\n");                                \
++}
++
++#undef SUBTARGET_FRAME_POINTER_REQUIRED
++#define SUBTARGET_FRAME_POINTER_REQUIRED 0
++
++/* __gnu_mcount_nc restores the original LR value before returning.  Ensure
++   that there is no unnecessary hook set up.  */
++#undef PROFILE_HOOK
+--- a/gcc/config/arm/constraints.md
++++ b/gcc/config/arm/constraints.md
+@@ -20,19 +20,19 @@
+ ;; The following register constraints have been used:
+ ;; - in ARM/Thumb-2 state: f, t, v, w, x, y, z
+-;; - in Thumb state: h, k, b
+-;; - in both states: l, c
++;; - in Thumb state: h, b
++;; - in both states: l, c, k
+ ;; In ARM state, 'l' is an alias for 'r'
+ ;; The following normal constraints have been used:
+-;; in ARM/Thumb-2 state: G, H, I, J, K, L, M
++;; in ARM/Thumb-2 state: G, H, I, j, J, K, L, M
+ ;; in Thumb-1 state: I, J, K, L, M, N, O
+ ;; The following multi-letter normal constraints have been used:
+ ;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv
+ ;; The following memory constraints have been used:
+-;; in ARM/Thumb-2 state: Q, Ut, Uv, Uy, Un, Us
++;; in ARM/Thumb-2 state: Q, Ut, Uv, Uy, Un, Um, Us
+ ;; in ARM state: Uq
+@@ -46,7 +46,7 @@
+  "The Cirrus Maverick co-processor registers.")
+ (define_register_constraint "w"
+-  "TARGET_32BIT ? (TARGET_VFP3 ? VFP_REGS : VFP_LO_REGS) : NO_REGS"
++  "TARGET_32BIT ? (TARGET_VFPD32 ? VFP_REGS : VFP_LO_REGS) : NO_REGS"
+  "The VFP registers @code{d0}-@code{d15}, or @code{d0}-@code{d31} for VFPv3.")
+ (define_register_constraint "x" "TARGET_32BIT ? VFP_D0_D7_REGS : NO_REGS"
+@@ -65,9 +65,15 @@
+ (define_register_constraint "h" "TARGET_THUMB ? HI_REGS : NO_REGS"
+  "In Thumb state the core registers @code{r8}-@code{r15}.")
+-(define_register_constraint "k" "TARGET_THUMB ? STACK_REG : NO_REGS"
+- "@internal
+-  Thumb only.  The stack register.")
++(define_constraint "j"
++ "A constant suitable for a MOVW instruction. (ARM/Thumb-2)"
++ (and (match_test "TARGET_32BIT && arm_arch_thumb2")
++      (ior (match_code "high")
++         (and (match_code "const_int")
++                (match_test "(ival & 0xffff0000) == 0")))))
++
++(define_register_constraint "k" "STACK_REG"
++ "@internal The stack register.")
+ (define_register_constraint "b" "TARGET_THUMB ? BASE_REGS : NO_REGS"
+  "@internal
+@@ -117,11 +123,9 @@
+                  : ((ival >= 0 && ival <= 1020) && ((ival & 3) == 0))")))
+ (define_constraint "N"
+- "In ARM/Thumb-2 state a constant suitable for a MOVW instruction.
+-  In Thumb-1 state a constant in the range 0-31."
++ "Thumb-1 state a constant in the range 0-31."
+  (and (match_code "const_int")
+-      (match_test "TARGET_32BIT ? arm_arch_thumb2 && ((ival & 0xffff0000) == 0)
+-                              : (ival >= 0 && ival <= 31)")))
++      (match_test "!TARGET_32BIT && (ival >= 0 && ival <= 31)")))
+ (define_constraint "O"
+  "In Thumb-1 state a constant that is a multiple of 4 in the range
+@@ -215,17 +219,24 @@
+ (define_memory_constraint "Un"
+  "@internal
++  In ARM/Thumb-2 state a valid address for Neon doubleword vector
++  load/store instructions."
++ (and (match_code "mem")
++      (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 0)")))
++
++(define_memory_constraint "Um"
++ "@internal
+   In ARM/Thumb-2 state a valid address for Neon element and structure
+   load/store instructions."
+  (and (match_code "mem")
+-      (match_test "TARGET_32BIT && neon_vector_mem_operand (op, FALSE)")))
++      (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2)")))
+ (define_memory_constraint "Us"
+  "@internal
+   In ARM/Thumb-2 state a valid address for non-offset loads/stores of
+   quad-word values in four ARM registers."
+  (and (match_code "mem")
+-      (match_test "TARGET_32BIT && neon_vector_mem_operand (op, TRUE)")))
++      (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 1)")))
+ (define_memory_constraint "Uq"
+  "@internal
+--- a/gcc/config/arm/cortex-a8-neon.md
++++ b/gcc/config/arm/cortex-a8-neon.md
+@@ -134,7 +134,7 @@
+ (define_insn_reservation "cortex_a8_vfp_add_sub" 10
+   (and (eq_attr "tune" "cortexa8")
+-       (eq_attr "type" "farith"))
++       (eq_attr "type" "fconsts,fconstd,fadds,faddd"))
+   "cortex_a8_vfp,cortex_a8_vfplite*9")
+ (define_insn_reservation "cortex_a8_vfp_muls" 12
+@@ -172,7 +172,7 @@
+ ;; take four cycles, we pick that latency.
+ (define_insn_reservation "cortex_a8_vfp_farith" 4
+   (and (eq_attr "tune" "cortexa8")
+-       (eq_attr "type" "ffarith"))
++       (eq_attr "type" "fcpys,ffariths,ffarithd,fconsts,fconstd,fcmps,fcmpd"))
+   "cortex_a8_vfp,cortex_a8_vfplite*3")
+ (define_insn_reservation "cortex_a8_vfp_cvt" 7
+--- /dev/null
++++ b/gcc/config/arm/cortex-a9.md
+@@ -0,0 +1,65 @@
++;; ARM Cortex-A9 VFP pipeline description
++;; Copyright (C) 2008 Free Software Foundation, Inc.
++;; Written by CodeSourcery.
++;;
++;; This file is part of GCC.
++;;
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published by
++;; the Free Software Foundation; either version 3, or (at your option)
++;; any later version.
++;;
++;; GCC is distributed in the hope that it will be useful, but
++;; WITHOUT ANY WARRANTY; without even the implied warranty of
++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++;; General Public License for more details.
++;;
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING3.  If not see
++;; <http://www.gnu.org/licenses/>.
++
++(define_automaton "cortex_a9")
++
++;; FIXME: We model aingle pipeline for all instructions.
++;; Is dual-issue possible, and do we have other pipelines?
++(define_cpu_unit "cortex_a9_vfp" "cortex_a9")
++
++(define_insn_reservation "cortex_a9_ffarith" 1
++ (and (eq_attr "tune" "cortexa9")
++      (eq_attr "type" "fcpys,ffariths,ffarithd,fcmps,fcmpd,fconsts,fconstd"))
++ "cortex_a9_vfp")
++
++(define_insn_reservation "cortex_a9_fadd" 4
++ (and (eq_attr "tune" "cortexa9")
++      (eq_attr "type" "fadds,faddd,f_cvt"))
++ "cortex_a9_vfp")
++
++(define_insn_reservation "cortex_a9_fmuls" 5
++ (and (eq_attr "tune" "cortexa9")
++      (eq_attr "type" "fmuls"))
++ "cortex_a9_vfp")
++
++(define_insn_reservation "cortex_a9_fmuld" 6
++ (and (eq_attr "tune" "cortexa9")
++      (eq_attr "type" "fmuld"))
++ "cortex_a9_vfp*2")
++
++(define_insn_reservation "cortex_a9_fmacs" 8
++ (and (eq_attr "tune" "cortexa9")
++      (eq_attr "type" "fmacs"))
++ "cortex_a9_vfp")
++
++(define_insn_reservation "cortex_a9_fmacd" 8
++ (and (eq_attr "tune" "cortexa9")
++      (eq_attr "type" "fmacd"))
++ "cortex_a9_vfp*2")
++
++(define_insn_reservation "cortex_a9_fdivs" 15
++ (and (eq_attr "tune" "cortexa9")
++      (eq_attr "type" "fdivs"))
++ "cortex_a9_vfp*10")
++
++(define_insn_reservation "cortex_a9_fdivd" 25
++ (and (eq_attr "tune" "cortexa9")
++      (eq_attr "type" "fdivd"))
++ "cortex_a9_vfp*20")
+--- /dev/null
++++ b/gcc/config/arm/cortex-r4.md
+@@ -0,0 +1,292 @@
++;; ARM Cortex-R4 scheduling description.
++;; Copyright (C) 2007 Free Software Foundation, Inc.
++;; Contributed by CodeSourcery.
++
++;; This file is part of GCC.
++
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published
++;; by the Free Software Foundation; either version 3, or (at your
++;; option) any later version.
++
++;; GCC is distributed in the hope that it will be useful, but WITHOUT
++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
++;; License for more details.
++
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING3.  If not see
++;; <http://www.gnu.org/licenses/>.
++
++(define_automaton "cortex_r4")
++
++;; We approximate the dual-issue constraints of this core using four
++;; "issue units" and a reservation matrix as follows.  The numbers indicate
++;; the instruction groups' preferences in order.  Multiple entries for
++;; the same numbered preference indicate units that must be reserved
++;; together.
++;;
++;; Issue unit:                A       B       C       ALU
++;;
++;; ALU w/o reg shift  1st     2nd             1st and 2nd
++;; ALU w/ reg shift   1st     2nd     2nd     1st and 2nd
++;; Moves              1st     2nd             2nd
++;; Multiplication     1st                     1st
++;; Division           1st                     1st
++;; Load/store single  1st             1st
++;; Other load/store   1st     1st
++;; Branches                   1st
++
++(define_cpu_unit "cortex_r4_issue_a" "cortex_r4")
++(define_cpu_unit "cortex_r4_issue_b" "cortex_r4")
++(define_cpu_unit "cortex_r4_issue_c" "cortex_r4")
++(define_cpu_unit "cortex_r4_issue_alu" "cortex_r4")
++
++(define_reservation "cortex_r4_alu"
++                    "(cortex_r4_issue_a+cortex_r4_issue_alu)|\
++                     (cortex_r4_issue_b+cortex_r4_issue_alu)")
++(define_reservation "cortex_r4_alu_shift_reg"
++                    "(cortex_r4_issue_a+cortex_r4_issue_alu)|\
++                     (cortex_r4_issue_b+cortex_r4_issue_c+\
++                      cortex_r4_issue_alu)")
++(define_reservation "cortex_r4_mov"
++                    "cortex_r4_issue_a|(cortex_r4_issue_b+\
++                     cortex_r4_issue_alu)")
++(define_reservation "cortex_r4_mul" "cortex_r4_issue_a+cortex_r4_issue_alu")
++(define_reservation "cortex_r4_mul_2"
++                    "(cortex_r4_issue_a+cortex_r4_issue_alu)*2")
++;; Division instructions execute out-of-order with respect to the
++;; rest of the pipeline and only require reservations on their first and
++;; final cycles.
++(define_reservation "cortex_r4_div_9"
++                    "cortex_r4_issue_a+cortex_r4_issue_alu,\
++                     nothing*7,\
++                     cortex_r4_issue_a+cortex_r4_issue_alu")
++(define_reservation "cortex_r4_div_10"
++                    "cortex_r4_issue_a+cortex_r4_issue_alu,\
++                     nothing*8,\
++                     cortex_r4_issue_a+cortex_r4_issue_alu")
++(define_reservation "cortex_r4_load_store"
++                    "cortex_r4_issue_a+cortex_r4_issue_c")
++(define_reservation "cortex_r4_load_store_2"
++                    "(cortex_r4_issue_a+cortex_r4_issue_b)*2")
++(define_reservation "cortex_r4_branch" "cortex_r4_issue_b")
++
++;; We assume that all instructions are unconditional.
++
++;; Data processing instructions.  Moves without shifts are kept separate
++;; for the purposes of the dual-issue constraints above.
++(define_insn_reservation "cortex_r4_alu" 2
++  (and (eq_attr "tune_cortexr4" "yes")
++       (and (eq_attr "type" "alu")
++            (not (eq_attr "insn" "mov"))))
++  "cortex_r4_alu")
++
++(define_insn_reservation "cortex_r4_mov" 2
++  (and (eq_attr "tune_cortexr4" "yes")
++       (and (eq_attr "type" "alu")
++            (eq_attr "insn" "mov")))
++  "cortex_r4_mov")
++
++(define_insn_reservation "cortex_r4_alu_shift" 2
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "type" "alu_shift"))
++  "cortex_r4_alu")
++
++(define_insn_reservation "cortex_r4_alu_shift_reg" 2
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "type" "alu_shift_reg"))
++  "cortex_r4_alu_shift_reg")
++
++;; An ALU instruction followed by an ALU instruction with no early dep.
++(define_bypass 1 "cortex_r4_alu,cortex_r4_alu_shift,cortex_r4_alu_shift_reg,\
++                  cortex_r4_mov"
++               "cortex_r4_alu")
++(define_bypass 1 "cortex_r4_alu,cortex_r4_alu_shift,cortex_r4_alu_shift_reg,\
++                  cortex_r4_mov"
++               "cortex_r4_alu_shift"
++               "arm_no_early_alu_shift_dep")
++(define_bypass 1 "cortex_r4_alu,cortex_r4_alu_shift,cortex_r4_alu_shift_reg,\
++                  cortex_r4_mov"
++               "cortex_r4_alu_shift_reg"
++               "arm_no_early_alu_shift_value_dep")
++
++;; In terms of availabilities, a consumer mov could theoretically be
++;; issued together with a producer ALU instruction, without stalls.
++;; In practice this cannot happen because mov;add (in that order) is not
++;; eligible for dual issue and furthermore dual issue is not permitted
++;; when a dependency is involved.  We therefore note it as latency one.
++;; A mov followed by another of the same is also latency one.
++(define_bypass 1 "cortex_r4_alu,cortex_r4_alu_shift,cortex_r4_alu_shift_reg,\
++                  cortex_r4_mov"
++               "cortex_r4_mov")
++
++;; qadd, qdadd, qsub and qdsub are not currently emitted, and neither are
++;; media data processing instructions nor sad instructions.
++
++;; Multiplication instructions.
++
++(define_insn_reservation "cortex_r4_mul_4" 4
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "insn" "mul,smmul"))
++  "cortex_r4_mul_2")
++
++(define_insn_reservation "cortex_r4_mul_3" 3
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "insn" "smulxy,smulwy,smuad,smusd"))
++  "cortex_r4_mul")
++
++(define_insn_reservation "cortex_r4_mla_4" 4
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "insn" "mla,smmla,smmls"))
++  "cortex_r4_mul_2")
++
++(define_insn_reservation "cortex_r4_mla_3" 3
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "insn" "smlaxy,smlawy,smlad,smlsd"))
++  "cortex_r4_mul")
++
++(define_insn_reservation "cortex_r4_smlald" 3
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "insn" "smlald,smlsld"))
++  "cortex_r4_mul")
++
++(define_insn_reservation "cortex_r4_mull" 4
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "insn" "smull,umull,umlal,umaal"))
++  "cortex_r4_mul_2")
++
++;; A multiply or an MLA with a single-register result, followed by an
++;; MLA with an accumulator dependency, has its result forwarded.
++(define_bypass 2 "cortex_r4_mul_3,cortex_r4_mla_3"
++               "cortex_r4_mla_3,cortex_r4_mla_4"
++               "arm_mac_accumulator_is_mul_result")
++
++(define_bypass 3 "cortex_r4_mul_4,cortex_r4_mla_4"
++               "cortex_r4_mla_3,cortex_r4_mla_4"
++               "arm_mac_accumulator_is_mul_result")
++
++;; A multiply followed by an ALU instruction needing the multiply
++;; result only at ALU has lower latency than one needing it at Shift.
++(define_bypass 2 "cortex_r4_mul_3,cortex_r4_mla_3,cortex_r4_smlald"
++               "cortex_r4_alu")
++(define_bypass 2 "cortex_r4_mul_3,cortex_r4_mla_3,cortex_r4_smlald"
++               "cortex_r4_alu_shift"
++               "arm_no_early_alu_shift_dep")
++(define_bypass 2 "cortex_r4_mul_3,cortex_r4_mla_3,cortex_r4_smlald"
++               "cortex_r4_alu_shift_reg"
++               "arm_no_early_alu_shift_value_dep")
++(define_bypass 3 "cortex_r4_mul_4,cortex_r4_mla_4,cortex_r4_mull"
++               "cortex_r4_alu")
++(define_bypass 3 "cortex_r4_mul_4,cortex_r4_mla_4,cortex_r4_mull"
++               "cortex_r4_alu_shift"
++               "arm_no_early_alu_shift_dep")
++(define_bypass 3 "cortex_r4_mul_4,cortex_r4_mla_4,cortex_r4_mull"
++               "cortex_r4_alu_shift_reg"
++               "arm_no_early_alu_shift_value_dep")
++
++;; A multiply followed by a mov has one cycle lower latency again.
++(define_bypass 1 "cortex_r4_mul_3,cortex_r4_mla_3,cortex_r4_smlald"
++               "cortex_r4_mov")
++(define_bypass 2 "cortex_r4_mul_4,cortex_r4_mla_4,cortex_r4_mull"
++               "cortex_r4_mov")
++
++;; We guess that division of A/B using sdiv or udiv, on average,
++;; is performed with B having ten more leading zeros than A.
++;; This gives a latency of nine for udiv and ten for sdiv.
++(define_insn_reservation "cortex_r4_udiv" 9
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "insn" "udiv"))
++  "cortex_r4_div_9")
++
++(define_insn_reservation "cortex_r4_sdiv" 10
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "insn" "sdiv"))
++  "cortex_r4_div_10")
++
++;; Branches.  We assume correct prediction.
++
++(define_insn_reservation "cortex_r4_branch" 0
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "type" "branch"))
++  "cortex_r4_branch")
++
++;; Call latencies are not predictable.  A semi-arbitrary very large
++;; number is used as "positive infinity" so that everything should be
++;; finished by the time of return.
++(define_insn_reservation "cortex_r4_call" 32
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "type" "call"))
++  "nothing")
++
++;; Status register access instructions are not currently emitted.
++
++;; Load instructions.
++;; We do not model the "addr_md_3cycle" cases and assume that
++;; accesses following are correctly aligned.
++
++(define_insn_reservation "cortex_r4_load_1_2" 3
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "type" "load1,load2"))
++  "cortex_r4_load_store")
++
++(define_insn_reservation "cortex_r4_load_3_4" 4
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "type" "load3,load4"))
++  "cortex_r4_load_store_2")
++
++;; If a producing load is followed by an instruction consuming only
++;; as a Normal Reg, there is one fewer cycle of latency.
++
++(define_bypass 2 "cortex_r4_load_1_2"
++               "cortex_r4_alu")
++(define_bypass 2 "cortex_r4_load_1_2"
++               "cortex_r4_alu_shift"
++               "arm_no_early_alu_shift_dep")
++(define_bypass 2 "cortex_r4_load_1_2"
++               "cortex_r4_alu_shift_reg"
++               "arm_no_early_alu_shift_value_dep")
++
++(define_bypass 3 "cortex_r4_load_3_4"
++               "cortex_r4_alu")
++(define_bypass 3 "cortex_r4_load_3_4"
++               "cortex_r4_alu_shift"
++               "arm_no_early_alu_shift_dep")
++(define_bypass 3 "cortex_r4_load_3_4"
++               "cortex_r4_alu_shift_reg"
++               "arm_no_early_alu_shift_value_dep")
++
++;; If a producing load is followed by an instruction consuming only
++;; as a Late Reg, there are two fewer cycles of latency.  Such consumer
++;; instructions are moves and stores.
++
++(define_bypass 1 "cortex_r4_load_1_2"
++               "cortex_r4_mov,cortex_r4_store_1_2,cortex_r4_store_3_4")
++(define_bypass 2 "cortex_r4_load_3_4"
++               "cortex_r4_mov,cortex_r4_store_1_2,cortex_r4_store_3_4")
++
++;; If a producer's result is required as the base or offset of a load,
++;; there is an extra cycle latency.
++
++(define_bypass 3 "cortex_r4_alu,cortex_r4_mov,cortex_r4_alu_shift,\
++                  cortex_r4_alu_shift_reg"
++               "cortex_r4_load_1_2,cortex_r4_load_3_4")
++
++(define_bypass 4 "cortex_r4_mul_3,cortex_r4_mla_3,cortex_r4_smlald"
++               "cortex_r4_load_1_2,cortex_r4_load_3_4")
++
++(define_bypass 5 "cortex_r4_mul_4,cortex_r4_mla_4,cortex_r4_mull"
++               "cortex_r4_load_1_2,cortex_r4_load_3_4")
++
++;; Store instructions.
++
++(define_insn_reservation "cortex_r4_store_1_2" 0
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "type" "store1,store2"))
++  "cortex_r4_load_store")
++
++(define_insn_reservation "cortex_r4_store_3_4" 0
++  (and (eq_attr "tune_cortexr4" "yes")
++       (eq_attr "type" "store3,store4"))
++  "cortex_r4_load_store_2")
++
+--- /dev/null
++++ b/gcc/config/arm/cortex-r4f.md
+@@ -0,0 +1,161 @@
++;; ARM Crotex-R4F VFP pipeline description
++;; Copyright (C) 2007 Free Software Foundation, Inc.
++;; Written by CodeSourcery.
++;;
++;; This file is part of GCC.
++;;
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published by
++;; the Free Software Foundation; either version 3, or (at your option)
++;; any later version.
++;;
++;; GCC is distributed in the hope that it will be useful, but
++;; WITHOUT ANY WARRANTY; without even the implied warranty of
++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++;; General Public License for more details.
++;;
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING3.  If not see
++;; <http://www.gnu.org/licenses/>.
++
++;; With the exception of simple VMOV <freg>, <freg> instructions and
++;; the accululate operand of a multiply-accumulate instruction, all
++;; registers are early registers.  Thus base latencies are 1 more than
++;; those listed in the TRM.
++
++;; We use the A, B abd C units from the integer core, plus two additional
++;; units to enforce VFP dual issue constraints.
++
++;;              A B C     V1  VMLA
++;; fcpy                 1 2
++;; farith       1 2       1
++;; fmrc                 1 2
++;; fconst       1 2 *     *
++;; ffarith      1 2 *     *
++;; fmac                 1 2       1   2
++;; fdiv                 1 2       *
++;; f_loads      *   *     *
++;; f_stores     *   *         *
++
++(define_cpu_unit "cortex_r4_v1" "cortex_r4")
++
++(define_cpu_unit "cortex_r4_vmla" "cortex_r4")
++
++(define_reservation "cortex_r4_issue_ab"
++                  "(cortex_r4_issue_a|cortex_r4_issue_b)")
++(define_reservation "cortex_r4_single_issue"
++                  "cortex_r4_issue_a+cortex_r4_issue_b")
++
++(define_insn_reservation "cortex_r4_fcpys" 2
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "fcpys"))
++ "cortex_r4_issue_ab")
++
++(define_insn_reservation "cortex_r4_ffariths" 2
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "ffariths,fconsts,fcmps"))
++ "cortex_r4_issue_ab+cortex_r4_issue_c+cortex_r4_v1")
++
++(define_insn_reservation "cortex_r4_fariths" 3
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "fadds,fmuls"))
++ "(cortex_r4_issue_a+cortex_r4_v1)|cortex_r4_issue_b")
++
++(define_insn_reservation "cortex_r4_fmacs" 6
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "fmacs"))
++ "(cortex_r4_issue_a+cortex_r4_v1)|(cortex_r4_issue_b+cortex_r4_vmla)")
++
++(define_insn_reservation "cortex_r4_fdivs" 17
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "fdivs"))
++ "cortex_r4_issue_ab+cortex_r4_v1,cortex_r4_issue_a+cortex_r4_v1")
++
++(define_insn_reservation "cortex_r4_floads" 2
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "f_loads"))
++ "cortex_r4_issue_a+cortex_r4_issue_c+cortex_r4_v1")
++
++(define_insn_reservation "cortex_r4_fstores" 1
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "f_stores"))
++ "cortex_r4_issue_a+cortex_r4_issue_c+cortex_r4_vmla")
++
++(define_insn_reservation "cortex_r4_mcr" 2
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "r_2_f"))
++ "cortex_r4_issue_ab")
++
++(define_insn_reservation "cortex_r4_mrc" 3
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "f_2_r"))
++ "cortex_r4_issue_ab")
++
++;; Bypasses for normal (not early) regs.
++(define_bypass 1 "cortex_r4_ffariths,cortex_r4_fcpys,cortex_r4_mcr"
++               "cortex_r4_fcpys")
++(define_bypass 2 "cortex_r4_fariths"
++               "cortex_r4_fcpys")
++(define_bypass 5 "cortex_r4_fmacs"
++               "cortex_r4_fcpys")
++(define_bypass 16 "cortex_r4_fdivs"
++                "cortex_r4_fcpys")
++
++(define_bypass 1 "cortex_r4_ffariths,cortex_r4_fcpys,cortex_r4_mcr"
++               "cortex_r4_fmacs"
++               "arm_no_early_mul_dep")
++(define_bypass 2 "cortex_r4_fariths"
++               "cortex_r4_fmacs"
++               "arm_no_early_mul_dep")
++;; mac->mac has an extra forwarding path.
++(define_bypass 3 "cortex_r4_fmacs"
++               "cortex_r4_fmacs"
++               "arm_no_early_mul_dep")
++(define_bypass 16 "cortex_r4_fdivs"
++                "cortex_r4_fmacs"
++                "arm_no_early_mul_dep")
++
++;; Double precision operations.  These can not dual issue.
++
++(define_insn_reservation "cortex_r4_fmacd" 20
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "fmacd"))
++ "cortex_r4_single_issue*13")
++
++(define_insn_reservation "cortex_r4_farith" 10
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "faddd,fmuld"))
++ "cortex_r4_single_issue*3")
++
++;; FIXME: The short cycle count suggests these instructions complete
++;; out of order.  Chances are this is not a pipelined operation.
++(define_insn_reservation "cortex_r4_fdivd" 97
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "fdivd"))
++ "cortex_r4_single_issue*3")
++
++(define_insn_reservation "cortex_r4_ffarithd" 2
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "ffarithd,fconstd"))
++ "cortex_r4_single_issue")
++
++(define_insn_reservation "cortex_r4_fcmpd" 2
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "fcmpd"))
++ "cortex_r4_single_issue*2")
++
++(define_insn_reservation "cortex_r4_f_cvt" 8
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "f_cvt"))
++ "cortex_r4_single_issue*3")
++
++(define_insn_reservation "cortex_r4_f_memd" 8
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "f_loadd,f_stored"))
++ "cortex_r4_single_issue")
++
++(define_insn_reservation "cortex_r4_f_flag" 1
++ (and (eq_attr "tune_cortexr4" "yes")
++      (eq_attr "type" "f_stores"))
++ "cortex_r4_single_issue")
++
+--- a/gcc/config/arm/crti.asm
++++ b/gcc/config/arm/crti.asm
+@@ -64,8 +64,6 @@
+ #endif
+ .endm
+               
+-      .file           "crti.asm"
+-
+       .section        ".init"
+       .align 2
+       .global _init
+--- a/gcc/config/arm/crtn.asm
++++ b/gcc/config/arm/crtn.asm
+@@ -72,8 +72,6 @@
+ .endm
+               
+       
+-      .file           "crtn.asm"
+-
+       .section        ".init"
+       ;;
+       FUNC_END
+--- a/gcc/config/arm/elf.h
++++ b/gcc/config/arm/elf.h
+@@ -145,3 +145,17 @@
+     }                                                 \
+   while (0)
++/* Horrible hack: We want to prevent some libgcc routines being included
++   for some multilibs.  */
++#ifndef __ARM_ARCH_6M__
++#undef L_fixdfsi
++#undef L_fixunsdfsi
++#undef L_truncdfsf2
++#undef L_fixsfsi
++#undef L_fixunssfsi
++#undef L_floatdidf
++#undef L_floatdisf
++#undef L_floatundidf
++#undef L_floatundisf
++#endif
++
+--- /dev/null
++++ b/gcc/config/arm/fp16.c
+@@ -0,0 +1,150 @@
++/* Half-float conversion routines.
++
++   Copyright (C) 2008 Free Software Foundation, Inc.
++   Contributed by CodeSourcery.
++
++   This file is free software; you can redistribute it and/or modify it
++   under the terms of the GNU General Public License as published by the
++   Free Software Foundation; either version 2, or (at your option) any
++   later version.
++
++   In addition to the permissions in the GNU General Public License, the
++   Free Software Foundation gives you unlimited permission to link the
++   compiled version of this file into combinations with other programs,
++   and to distribute those combinations without any restriction coming
++   from the use of this file.  (The General Public License restrictions
++   do apply in other respects; for example, they cover modification of
++   the file, and distribution when not linked into a combine
++   executable.)
++
++   This file is distributed in the hope that it will be useful, but
++   WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program; see the file COPYING.  If not, write to
++   the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++   Boston, MA 02110-1301, USA.  */
++
++static inline unsigned short
++__gnu_f2h_internal(unsigned int a, int ieee)
++{
++  unsigned short sign = (a >> 16) & 0x8000;
++  int aexp = (a >> 23) & 0xff;
++  unsigned int mantissa = a & 0x007fffff;
++  unsigned int mask;
++  unsigned int increment;
++
++  if (aexp == 0xff)
++    {
++      if (!ieee)
++      return sign;
++      return sign | 0x7e00 | (mantissa >> 13);
++    }
++  
++  if (aexp == 0 && mantissa == 0)
++    return sign;
++
++  aexp -= 127;
++
++  /* Decimal point between bits 22 and 23.  */
++  mantissa |= 0x00800000;
++  if (aexp < -14)
++    {
++      mask = 0x007fffff;
++      if (aexp < -25)
++      aexp = -26;
++      else if (aexp != -25)
++      mask >>= 24 + aexp;
++    }
++  else
++    mask = 0x00001fff;
++
++  /* Round.  */
++  if (mantissa & mask)
++    {
++      increment = (mask + 1) >> 1;
++      if ((mantissa & mask) == increment)
++      increment = mantissa & (increment << 1);
++      mantissa += increment;
++      if (mantissa >= 0x01000000)
++              {
++        mantissa >>= 1;
++        aexp++;
++      }
++    }
++
++  if (ieee)
++    {
++      if (aexp > 15)
++      return sign | 0x7c00;
++    }
++  else
++    {
++      if (aexp > 16)
++      return sign | 0x7fff;
++    }
++
++  if (aexp < -24)
++    return sign;
++
++  if (aexp < -14)
++    {
++      mantissa >>= -14 - aexp;
++      aexp = -14;
++    }
++
++  /* We leave the leading 1 in the mantissa, and subtract one
++     from the exponent bias to compensate.  */
++  return sign | (((aexp + 14) << 10) + (mantissa >> 13));
++}
++
++unsigned int
++__gnu_h2f_internal(unsigned short a, int ieee)
++{
++  unsigned int sign = (unsigned int)(a & 0x8000) << 16;
++  int aexp = (a >> 10) & 0x1f;
++  unsigned int mantissa = a & 0x3ff;
++
++  if (aexp == 0x1f && ieee)
++    return sign | 0x7f800000 | (mantissa << 13);
++
++  if (aexp == 0)
++    {
++      int shift;
++
++      if (mantissa == 0)
++      return sign;
++
++      shift = __builtin_clz(mantissa) - 21;
++      mantissa <<= shift;
++      aexp = -shift;
++    }
++
++  return sign | (((aexp + 0x70) << 23) + (mantissa << 13));
++}
++
++unsigned short
++__gnu_f2h_ieee(unsigned int a)
++{
++  return __gnu_f2h_internal(a, 1);
++}
++
++unsigned int
++__gnu_h2f_ieee(unsigned short a)
++{
++  return __gnu_h2f_internal(a, 1);
++}
++
++unsigned short
++__gnu_f2h_alternative(unsigned int x)
++{
++  return __gnu_f2h_internal(x, 0);
++}
++
++unsigned int
++__gnu_h2f_alternative(unsigned short a)
++{
++  return __gnu_h2f_internal(a, 0);
++}
+--- /dev/null
++++ b/gcc/config/arm/hwdiv.md
+@@ -0,0 +1,40 @@
++;; ARM instruction patterns for hardware division 
++;; Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
++;; Written by CodeSourcery, LLC.
++;;
++;; This file is part of GCC.
++
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published
++;; by the Free Software Foundation; either version 3, or (at your
++;; option) any later version.
++
++;; GCC is distributed in the hope that it will be useful, but WITHOUT
++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
++;; License for more details.
++
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING3.  If not see
++;; <http://www.gnu.org/licenses/>.
++
++(define_insn "divsi3"
++  [(set (match_operand:SI       0 "s_register_operand" "=r")
++      (div:SI (match_operand:SI 1 "s_register_operand"  "r")
++              (match_operand:SI 2 "s_register_operand"  "r")))]
++  "arm_arch_hwdiv"
++  "sdiv%?\t%0, %1, %2"
++  [(set_attr "predicable" "yes")
++   (set_attr "insn" "sdiv")]
++)
++
++(define_insn "udivsi3"
++  [(set (match_operand:SI        0 "s_register_operand" "=r")
++      (udiv:SI (match_operand:SI 1 "s_register_operand"  "r")
++               (match_operand:SI 2 "s_register_operand"  "r")))]
++  "arm_arch_hwdiv"
++  "udiv%?\t%0, %1, %2"
++  [(set_attr "predicable" "yes")
++   (set_attr "insn" "udiv")]
++)
++
+--- a/gcc/config/arm/ieee754-df.S
++++ b/gcc/config/arm/ieee754-df.S
+@@ -56,7 +56,7 @@
+ #endif
+-#ifdef L_negdf2
++#ifdef L_arm_negdf2
+ ARM_FUNC_START negdf2
+ ARM_FUNC_ALIAS aeabi_dneg negdf2
+@@ -70,7 +70,7 @@ ARM_FUNC_ALIAS aeabi_dneg negdf2
+ #endif
+-#ifdef L_addsubdf3
++#ifdef L_arm_addsubdf3
+ ARM_FUNC_START aeabi_drsub
+@@ -88,7 +88,7 @@ ARM_FUNC_ALIAS aeabi_dsub subdf3
+ ARM_FUNC_START adddf3
+ ARM_FUNC_ALIAS aeabi_dadd adddf3
+-1:    do_push {r4, r5, lr}
++1:    do_push (r4, r5, lr)
+       @ Look for zeroes, equal values, INF, or NAN.
+       shift1  lsl, r4, xh, #1
+@@ -432,7 +432,7 @@ ARM_FUNC_ALIAS aeabi_ui2d floatunsidf
+       do_it   eq, t
+       moveq   r1, #0
+       RETc(eq)
+-      do_push {r4, r5, lr}
++      do_push (r4, r5, lr)
+       mov     r4, #0x400              @ initial exponent
+       add     r4, r4, #(52-1 - 1)
+       mov     r5, #0                  @ sign bit is 0
+@@ -452,7 +452,7 @@ ARM_FUNC_ALIAS aeabi_i2d floatsidf
+       do_it   eq, t
+       moveq   r1, #0
+       RETc(eq)
+-      do_push {r4, r5, lr}
++      do_push (r4, r5, lr)
+       mov     r4, #0x400              @ initial exponent
+       add     r4, r4, #(52-1 - 1)
+       ands    r5, r0, #0x80000000     @ sign bit in r5
+@@ -486,7 +486,7 @@ ARM_FUNC_ALIAS aeabi_f2d extendsfdf2
+       RETc(eq)                        @ we are done already.
+       @ value was denormalized.  We can normalize it now.
+-      do_push {r4, r5, lr}
++      do_push (r4, r5, lr)
+       mov     r4, #0x380              @ setup corresponding exponent
+       and     r5, xh, #0x80000000     @ move sign bit in r5
+       bic     xh, xh, #0x80000000
+@@ -513,9 +513,9 @@ ARM_FUNC_ALIAS aeabi_ul2d floatundidf
+       @ compatibility.
+       adr     ip, LSYM(f0_ret)
+       @ Push pc as well so that RETLDM works correctly.
+-      do_push {r4, r5, ip, lr, pc}
++      do_push (r4, r5, ip, lr, pc)
+ #else
+-      do_push {r4, r5, lr}
++      do_push (r4, r5, lr)
+ #endif
+       mov     r5, #0
+@@ -539,9 +539,9 @@ ARM_FUNC_ALIAS aeabi_l2d floatdidf
+       @ compatibility.
+       adr     ip, LSYM(f0_ret)
+       @ Push pc as well so that RETLDM works correctly.
+-      do_push {r4, r5, ip, lr, pc}
++      do_push (r4, r5, ip, lr, pc)
+ #else
+-      do_push {r4, r5, lr}
++      do_push (r4, r5, lr)
+ #endif
+       ands    r5, ah, #0x80000000     @ sign bit in r5
+@@ -590,7 +590,7 @@ ARM_FUNC_ALIAS aeabi_l2d floatdidf
+       @ Legacy code expects the result to be returned in f0.  Copy it
+       @ there as well.
+ LSYM(f0_ret):
+-      do_push {r0, r1}
++      do_push (r0, r1)
+       ldfd    f0, [sp], #8
+       RETLDM
+@@ -603,11 +603,11 @@ LSYM(f0_ret):
+ #endif /* L_addsubdf3 */
+-#ifdef L_muldivdf3
++#ifdef L_arm_muldivdf3
+ ARM_FUNC_START muldf3
+ ARM_FUNC_ALIAS aeabi_dmul muldf3
+-      do_push {r4, r5, r6, lr}
++      do_push (r4, r5, r6, lr)
+       @ Mask out exponents, trap any zero/denormal/INF/NAN.
+       mov     ip, #0xff
+@@ -840,7 +840,7 @@ LSYM(Lml_d):
+       orr     xh, xh, r6
+       teq     r5, #0
+       do_it   ne
+-      movne   pc, lr
++      RETc(ne)
+ 2:    and     r6, yh, #0x80000000
+ 3:    movs    yl, yl, lsl #1
+       adc     yh, yh, yh
+@@ -849,7 +849,7 @@ LSYM(Lml_d):
+       subeq   r5, r5, #1
+       beq     3b
+       orr     yh, yh, r6
+-      mov     pc, lr
++      RET
+ LSYM(Lml_s):
+       @ Isolate the INF and NAN cases away
+@@ -915,7 +915,7 @@ LSYM(Lml_n):
+ ARM_FUNC_START divdf3
+ ARM_FUNC_ALIAS aeabi_ddiv divdf3
+       
+-      do_push {r4, r5, r6, lr}
++      do_push (r4, r5, r6, lr)
+       @ Mask out exponents, trap any zero/denormal/INF/NAN.
+       mov     ip, #0xff
+@@ -1103,7 +1103,7 @@ LSYM(Ldv_s):
+ #endif /* L_muldivdf3 */
+-#ifdef L_cmpdf2
++#ifdef L_arm_cmpdf2
+ @ Note: only r0 (return value) and ip are clobbered here.
+@@ -1122,7 +1122,7 @@ ARM_FUNC_ALIAS nedf2 cmpdf2
+ ARM_FUNC_ALIAS eqdf2 cmpdf2
+       mov     ip, #1                  @ how should we specify unordered here?
+-1:    str     ip, [sp, #-4]
++1:    str     ip, [sp, #-4]!
+       @ Trap any INF/NAN first.
+       mov     ip, xh, lsl #1
+@@ -1134,7 +1134,8 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2
+       @ Test for equality.
+       @ Note that 0.0 is equal to -0.0.
+-2:    orrs    ip, xl, xh, lsl #1      @ if x == 0.0 or -0.0
++2:    add     sp, sp, #4
++      orrs    ip, xl, xh, lsl #1      @ if x == 0.0 or -0.0
+       do_it   eq, e
+       COND(orr,s,eq)  ip, yl, yh, lsl #1      @ and y == 0.0 or -0.0
+       teqne   xh, yh                  @ or xh == yh
+@@ -1173,7 +1174,7 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2
+       bne     2b
+       orrs    ip, yl, yh, lsl #12
+       beq     2b                      @ y is not NAN
+-5:    ldr     r0, [sp, #-4]           @ unordered return code
++5:    ldr     r0, [sp], #4            @ unordered return code
+       RET
+       FUNC_END gedf2
+@@ -1199,7 +1200,7 @@ ARM_FUNC_ALIAS aeabi_cdcmple aeabi_cdcmp
+       @ The status-returning routines are required to preserve all
+       @ registers except ip, lr, and cpsr.
+-6:    do_push {r0, lr}
++6:    do_push (r0, lr)
+       ARM_CALL cmpdf2
+       @ Set the Z flag correctly, and the C flag unconditionally.
+       cmp     r0, #0
+@@ -1271,7 +1272,7 @@ ARM_FUNC_START   aeabi_dcmpgt
+ #endif /* L_cmpdf2 */
+-#ifdef L_unorddf2
++#ifdef L_arm_unorddf2
+ ARM_FUNC_START unorddf2
+ ARM_FUNC_ALIAS aeabi_dcmpun unorddf2
+@@ -1297,7 +1298,7 @@ ARM_FUNC_ALIAS aeabi_dcmpun unorddf2
+ #endif /* L_unorddf2 */
+-#ifdef L_fixdfsi
++#ifdef L_arm_fixdfsi
+ ARM_FUNC_START fixdfsi
+ ARM_FUNC_ALIAS aeabi_d2iz fixdfsi
+@@ -1339,7 +1340,7 @@ ARM_FUNC_ALIAS aeabi_d2iz fixdfsi
+ #endif /* L_fixdfsi */
+-#ifdef L_fixunsdfsi
++#ifdef L_arm_fixunsdfsi
+ ARM_FUNC_START fixunsdfsi
+ ARM_FUNC_ALIAS aeabi_d2uiz fixunsdfsi
+@@ -1377,7 +1378,7 @@ ARM_FUNC_ALIAS aeabi_d2uiz fixunsdfsi
+ #endif /* L_fixunsdfsi */
+-#ifdef L_truncdfsf2
++#ifdef L_arm_truncdfsf2
+ ARM_FUNC_START truncdfsf2
+ ARM_FUNC_ALIAS aeabi_d2f truncdfsf2
+--- a/gcc/config/arm/ieee754-sf.S
++++ b/gcc/config/arm/ieee754-sf.S
+@@ -38,7 +38,7 @@
+  * if necessary without impacting performances.
+  */
+-#ifdef L_negsf2
++#ifdef L_arm_negsf2
+       
+ ARM_FUNC_START negsf2
+ ARM_FUNC_ALIAS aeabi_fneg negsf2
+@@ -51,7 +51,7 @@ ARM_FUNC_ALIAS aeabi_fneg negsf2
+ #endif
+-#ifdef L_addsubsf3
++#ifdef L_arm_addsubsf3
+ ARM_FUNC_START aeabi_frsub
+@@ -448,7 +448,7 @@ LSYM(f0_ret):
+ #endif /* L_addsubsf3 */
+-#ifdef L_muldivsf3
++#ifdef L_arm_muldivsf3
+ ARM_FUNC_START mulsf3
+ ARM_FUNC_ALIAS aeabi_fmul mulsf3
+@@ -486,7 +486,7 @@ LSYM(Lml_x):
+       and     r3, ip, #0x80000000
+       @ Well, no way to make it shorter without the umull instruction.
+-      do_push {r3, r4, r5}
++      do_push (r3, r4, r5)
+       mov     r4, r0, lsr #16
+       mov     r5, r1, lsr #16
+       bic     r0, r0, r4, lsl #16
+@@ -497,7 +497,7 @@ LSYM(Lml_x):
+       mla     r0, r4, r1, r0
+       adds    r3, r3, r0, lsl #16
+       adc     r1, ip, r0, lsr #16
+-      do_pop  {r0, r4, r5}
++      do_pop  (r0, r4, r5)
+ #else
+@@ -795,7 +795,7 @@ LSYM(Ldv_s):
+ #endif /* L_muldivsf3 */
+-#ifdef L_cmpsf2
++#ifdef L_arm_cmpsf2
+       @ The return value in r0 is
+       @
+@@ -827,7 +827,7 @@ ARM_FUNC_ALIAS nesf2 cmpsf2
+ ARM_FUNC_ALIAS eqsf2 cmpsf2
+       mov     ip, #1                  @ how should we specify unordered here?
+-1:    str     ip, [sp, #-4]
++1:    str     ip, [sp, #-4]!
+       @ Trap any INF/NAN first.
+       mov     r2, r0, lsl #1
+@@ -839,7 +839,8 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2
+       @ Compare values.
+       @ Note that 0.0 is equal to -0.0.
+-2:    orrs    ip, r2, r3, lsr #1      @ test if both are 0, clear C flag
++2:    add     sp, sp, #4
++      orrs    ip, r2, r3, lsr #1      @ test if both are 0, clear C flag
+       do_it   ne
+       teqne   r0, r1                  @ if not 0 compare sign
+       do_it   pl
+@@ -863,7 +864,7 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2
+       bne     2b
+       movs    ip, r1, lsl #9
+       beq     2b                      @ r1 is not NAN
+-5:    ldr     r0, [sp, #-4]           @ return unordered code.
++5:    ldr     r0, [sp], #4            @ return unordered code.
+       RET
+       FUNC_END gesf2
+@@ -886,7 +887,7 @@ ARM_FUNC_ALIAS aeabi_cfcmple aeabi_cfcmp
+       @ The status-returning routines are required to preserve all
+       @ registers except ip, lr, and cpsr.
+-6:    do_push {r0, r1, r2, r3, lr}
++6:    do_push (r0, r1, r2, r3, lr)
+       ARM_CALL cmpsf2
+       @ Set the Z flag correctly, and the C flag unconditionally.
+       cmp     r0, #0
+@@ -958,7 +959,7 @@ ARM_FUNC_START     aeabi_fcmpgt
+ #endif /* L_cmpsf2 */
+-#ifdef L_unordsf2
++#ifdef L_arm_unordsf2
+ ARM_FUNC_START unordsf2
+ ARM_FUNC_ALIAS aeabi_fcmpun unordsf2
+@@ -983,7 +984,7 @@ ARM_FUNC_ALIAS aeabi_fcmpun unordsf2
+ #endif /* L_unordsf2 */
+-#ifdef L_fixsfsi
++#ifdef L_arm_fixsfsi
+ ARM_FUNC_START fixsfsi
+ ARM_FUNC_ALIAS aeabi_f2iz fixsfsi
+@@ -1025,7 +1026,7 @@ ARM_FUNC_ALIAS aeabi_f2iz fixsfsi
+ #endif /* L_fixsfsi */
+-#ifdef L_fixunssfsi
++#ifdef L_arm_fixunssfsi
+ ARM_FUNC_START fixunssfsi
+ ARM_FUNC_ALIAS aeabi_f2uiz fixunssfsi
+--- a/gcc/config/arm/iwmmxt.md
++++ b/gcc/config/arm/iwmmxt.md
+@@ -105,8 +105,8 @@
+ )
+ (define_insn "*iwmmxt_movsi_insn"
+-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m,z,r,?z,Uy,z")
+-      (match_operand:SI 1 "general_operand"      "rI,K,mi,r,r,z,Uy,z,z"))]
++  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,rk, m,z,r,?z,Uy,z")
++      (match_operand:SI 1 "general_operand"      "rk, I,K,mi,rk,r,z,Uy,z, z"))]
+   "TARGET_REALLY_IWMMXT
+    && (   register_operand (operands[0], SImode)
+        || register_operand (operands[1], SImode))"
+@@ -114,19 +114,20 @@
+    switch (which_alternative)
+    {
+    case 0: return \"mov\\t%0, %1\";
+-   case 1: return \"mvn\\t%0, #%B1\";
+-   case 2: return \"ldr\\t%0, %1\";
+-   case 3: return \"str\\t%1, %0\";
+-   case 4: return \"tmcr\\t%0, %1\";
+-   case 5: return \"tmrc\\t%0, %1\";
+-   case 6: return arm_output_load_gr (operands);
+-   case 7: return \"wstrw\\t%1, %0\";
++   case 1: return \"mov\\t%0, %1\";
++   case 2: return \"mvn\\t%0, #%B1\";
++   case 3: return \"ldr\\t%0, %1\";
++   case 4: return \"str\\t%1, %0\";
++   case 5: return \"tmcr\\t%0, %1\";
++   case 6: return \"tmrc\\t%0, %1\";
++   case 7: return arm_output_load_gr (operands);
++   case 8: return \"wstrw\\t%1, %0\";
+    default:return \"wstrw\\t%1, [sp, #-4]!\;wldrw\\t%0, [sp], #4\\t@move CG reg\";
+   }"
+-  [(set_attr "type"           "*,*,load1,store1,*,*,load1,store1,*")
+-   (set_attr "length"         "*,*,*,        *,*,*,  16,     *,8")
+-   (set_attr "pool_range"     "*,*,4096,     *,*,*,1024,     *,*")
+-   (set_attr "neg_pool_range" "*,*,4084,     *,*,*,   *,  1012,*")
++  [(set_attr "type"           "*,*,*,load1,store1,*,*,load1,store1,*")
++   (set_attr "length"         "*,*,*,*,        *,*,*,  16,     *,8")
++   (set_attr "pool_range"     "*,*,*,4096,     *,*,*,1024,     *,*")
++   (set_attr "neg_pool_range" "*,*,*,4084,     *,*,*,   *,  1012,*")
+    ;; Note - the "predicable" attribute is not allowed to have alternatives.
+    ;; Since the wSTRw wCx instruction is not predicable, we cannot support
+    ;; predicating any of the alternatives in this template.  Instead,
+@@ -166,9 +167,9 @@
+    (set_attr "neg_pool_range" "*,*,4084,     *,*,*")]
+ )
+-(define_insn "movv8qi_internal"
+-  [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r,?r,?m")
+-      (match_operand:V8QI 1 "general_operand"       "y,y,mi,y,r,r,mi,r"))]
++(define_insn "mov<mode>_internal"
++  [(set (match_operand:VMMX 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r,?r,?m")
++      (match_operand:VMMX 1 "general_operand"       "y,y,mi,y,r,r,mi,r"))]
+   "TARGET_REALLY_IWMMXT"
+   "*
+    switch (which_alternative)
+@@ -187,64 +188,6 @@
+    (set_attr "pool_range"     "*,     *, 256,*,*,*, 256,*")
+    (set_attr "neg_pool_range" "*,     *, 244,*,*,*, 244,*")])
+-(define_insn "movv4hi_internal"
+-  [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r,?r,?m")
+-      (match_operand:V4HI 1 "general_operand"       "y,y,mi,y,r,r,mi,r"))]
+-  "TARGET_REALLY_IWMMXT"
+-  "*
+-   switch (which_alternative)
+-   {
+-   case 0: return \"wmov%?\\t%0, %1\";
+-   case 1: return \"wstrd%?\\t%1, %0\";
+-   case 2: return \"wldrd%?\\t%0, %1\";
+-   case 3: return \"tmrrc%?\\t%Q0, %R0, %1\";
+-   case 4: return \"tmcrr%?\\t%0, %Q1, %R1\";
+-   case 5: return \"#\";
+-   default: return output_move_double (operands);
+-   }"
+-  [(set_attr "predicable" "yes")
+-   (set_attr "length"         "4,     4,   4,4,4,8,   8,8")
+-   (set_attr "type"           "*,store1,load1,*,*,*,load1,store1")
+-   (set_attr "pool_range"     "*,     *, 256,*,*,*, 256,*")
+-   (set_attr "neg_pool_range" "*,     *, 244,*,*,*, 244,*")])
+-
+-(define_insn "movv2si_internal"
+-  [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r,?r,?m")
+-      (match_operand:V2SI 1 "general_operand"       "y,y,mi,y,r,r,mi,r"))]
+-  "TARGET_REALLY_IWMMXT"
+-  "*
+-   switch (which_alternative)
+-   {
+-   case 0: return \"wmov%?\\t%0, %1\";
+-   case 1: return \"wstrd%?\\t%1, %0\";
+-   case 2: return \"wldrd%?\\t%0, %1\";
+-   case 3: return \"tmrrc%?\\t%Q0, %R0, %1\";
+-   case 4: return \"tmcrr%?\\t%0, %Q1, %R1\";
+-   case 5: return \"#\";
+-   default: return output_move_double (operands);
+-   }"
+-  [(set_attr "predicable" "yes")
+-   (set_attr "length"         "4,     4,   4,4,4,8,  24,8")
+-   (set_attr "type"           "*,store1,load1,*,*,*,load1,store1")
+-   (set_attr "pool_range"     "*,     *, 256,*,*,*, 256,*")
+-   (set_attr "neg_pool_range" "*,     *, 244,*,*,*, 244,*")])
+-
+-;; This pattern should not be needed.  It is to match a
+-;; wierd case generated by GCC when no optimizations are
+-;; enabled.  (Try compiling gcc/testsuite/gcc.c-torture/
+-;; compile/simd-5.c at -O0).  The mode for operands[1] is
+-;; deliberately omitted.
+-(define_insn "movv2si_internal_2"
+-  [(set (match_operand:V2SI 0 "nonimmediate_operand" "=?r")
+-      (match_operand      1 "immediate_operand"      "mi"))]
+-  "TARGET_REALLY_IWMMXT"
+-  "* return output_move_double (operands);"
+-  [(set_attr "predicable"     "yes")
+-   (set_attr "length"         "8")
+-   (set_attr "type"           "load1")
+-   (set_attr "pool_range"     "256")
+-   (set_attr "neg_pool_range" "244")])
+-
+ ;; Vector add/subtract
+ (define_insn "*add<mode>3_iwmmxt"
+--- a/gcc/config/arm/lib1funcs.asm
++++ b/gcc/config/arm/lib1funcs.asm
+@@ -94,7 +94,8 @@ Boston, MA 02110-1301, USA.  */
+ #if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+       || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
+-      || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
++      || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
++      || defined(__ARM_ARCH_6M__)
+ # define __ARM_ARCH__ 6
+ #endif
+@@ -237,8 +238,8 @@ LSYM(Lend_fde):
+ .macro shift1 op, arg0, arg1, arg2
+       \op     \arg0, \arg1, \arg2
+ .endm
+-#define do_push       push
+-#define do_pop        pop
++#define do_push(...)  push {__VA_ARGS__}
++#define do_pop(...)   pop {__VA_ARGS__}
+ #define COND(op1, op2, cond) op1 ## op2 ## cond
+ /* Perform an arithmetic operation with a variable shift operand.  This
+    requires two instructions and a scratch register on Thumb-2.  */
+@@ -252,24 +253,133 @@ LSYM(Lend_fde):
+ .macro shift1 op, arg0, arg1, arg2
+       mov     \arg0, \arg1, \op \arg2
+ .endm
+-#define do_push       stmfd sp!,
+-#define do_pop        ldmfd sp!,
++#if defined(__low_irq_latency__)        
++#define do_push(...) \
++  _buildN1(do_push, _buildC1(__VA_ARGS__))( __VA_ARGS__)
++#define _buildN1(BASE, X)     _buildN2(BASE, X)
++#define _buildN2(BASE, X)     BASE##X
++#define _buildC1(...)         _buildC2(__VA_ARGS__,9,8,7,6,5,4,3,2,1)
++#define _buildC2(a1,a2,a3,a4,a5,a6,a7,a8,a9,c,...) c
++        
++#define do_push1(r1) str r1, [sp, #-4]!
++#define do_push2(r1, r2) str r2, [sp, #-4]! ; str r1, [sp, #-4]!
++#define do_push3(r1, r2, r3) str r3, [sp, #-4]! ; str r2, [sp, #-4]!; str r1, [sp, #-4]!
++#define do_push4(r1, r2, r3, r4) \
++        do_push3 (r2, r3, r4);\
++        do_push1 (r1)
++#define do_push5(r1, r2, r3, r4, r5) \
++        do_push4 (r2, r3, r4, r5);\
++        do_push1 (r1)
++        
++#define do_pop(...) \
++_buildN1(do_pop, _buildC1(__VA_ARGS__))( __VA_ARGS__)
++        
++#define do_pop1(r1) ldr r1, [sp], #4
++#define do_pop2(r1, r2) ldr r1, [sp], #4 ; ldr r2, [sp], #4
++#define do_pop3(r1, r2, r3) ldr r1, [sp], #4 ; str r2, [sp], #4; str r3, [sp], #4
++#define do_pop4(r1, r2, r3, r4) \
++        do_pop1 (r1);\
++        do_pup3 (r2, r3, r4)
++#define do_pop5(r1, r2, r3, r4, r5) \
++        do_pop1 (r1);\
++        do_pop4 (r2, r3, r4, r5)
++#else
++#define do_push(...)    stmfd sp!, { __VA_ARGS__}
++#define do_pop(...)     ldmfd sp!, {__VA_ARGS__}
++#endif
++
++        
+ #define COND(op1, op2, cond) op1 ## cond ## op2
+ .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
+       \name \dest, \src1, \src2, \shiftop \shiftreg
+ .endm
+ #endif
+-.macro ARM_LDIV0 name
++#ifdef __ARM_EABI__
++.macro ARM_LDIV0 name signed
++      cmp     r0, #0
++      .ifc    \signed, unsigned
++      movne   r0, #0xffffffff
++      .else
++      movgt   r0, #0x7fffffff
++      movlt   r0, #0x80000000
++      .endif
++      b       SYM (__aeabi_idiv0) __PLT__
++.endm
++#else
++.macro ARM_LDIV0 name signed
+       str     lr, [sp, #-8]!
+ 98:   cfi_push 98b - __\name, 0xe, -0x8, 0x8
+       bl      SYM (__div0) __PLT__
+       mov     r0, #0                  @ About as wrong as it could be.
+       RETLDM  unwind=98b
+ .endm
++#endif
+-.macro THUMB_LDIV0 name
++#ifdef __ARM_EABI__
++.macro THUMB_LDIV0 name signed
++#if defined(__ARM_ARCH_6M__)
++      .ifc \signed, unsigned
++      cmp     r0, #0
++      beq     1f
++      mov     r0, #0
++      mvn     r0, r0          @ 0xffffffff
++1:
++      .else
++      cmp     r0, #0
++      beq     2f
++      blt     3f
++      mov     r0, #0
++      mvn     r0, r0
++      lsr     r0, r0, #1      @ 0x7fffffff
++      b       2f
++3:    mov     r0, #0x80
++      lsl     r0, r0, #24     @ 0x80000000
++2:
++      .endif
++      push    {r0, r1, r2}
++      ldr     r0, 4f
++      adr     r1, 4f
++      add     r0, r1
++      str     r0, [sp, #8]
++      @ We know we are not on armv4t, so pop pc is safe.
++      pop     {r0, r1, pc}
++      .align  2
++4:
++      .word   __aeabi_idiv0 - 4b
++#elif defined(__thumb2__)
++      .syntax unified
++      .ifc \signed, unsigned
++      cbz     r0, 1f
++      mov     r0, #0xffffffff
++1:
++      .else
++      cmp     r0, #0
++      do_it   gt
++      movgt   r0, #0x7fffffff
++      do_it   lt
++      movlt   r0, #0x80000000
++      .endif
++      b.w     SYM(__aeabi_idiv0) __PLT__
++#else
++      .align  2
++      bx      pc
++      nop
++      .arm
++      cmp     r0, #0
++      .ifc    \signed, unsigned
++      movne   r0, #0xffffffff
++      .else
++      movgt   r0, #0x7fffffff
++      movlt   r0, #0x80000000
++      .endif
++      b       SYM(__aeabi_idiv0) __PLT__
++      .thumb
++#endif
++.endm
++#else
++.macro THUMB_LDIV0 name signed
+       push    { r1, lr }
+ 98:   cfi_push 98b - __\name, 0xe, -0x4, 0x8
+       bl      SYM (__div0)
+@@ -281,18 +391,19 @@ LSYM(Lend_fde):
+       pop     { r1, pc }
+ #endif
+ .endm
++#endif
+ .macro FUNC_END name
+       SIZE (__\name)
+ .endm
+-.macro DIV_FUNC_END name
++.macro DIV_FUNC_END name signed
+       cfi_start       __\name, LSYM(Lend_div0)
+ LSYM(Ldiv0):
+ #ifdef __thumb__
+-      THUMB_LDIV0 \name
++      THUMB_LDIV0 \name \signed
+ #else
+-      ARM_LDIV0 \name
++      ARM_LDIV0 \name \signed
+ #endif
+       cfi_end LSYM(Lend_div0)
+       FUNC_END \name
+@@ -367,6 +478,9 @@ _L__\name:         
+ #else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
++#ifdef __ARM_ARCH_6M__
++#define EQUIV .thumb_set
++#else
+ .macro        ARM_FUNC_START name
+       .text
+       .globl SYM (__\name)
+@@ -379,6 +493,7 @@ SYM (__\name):
+ .macro  ARM_CALL name
+       bl      __\name
+ .endm
++#endif
+ #endif
+@@ -391,6 +506,7 @@ SYM (__\name):
+ #endif
+ .endm
++#ifndef __ARM_ARCH_6M__
+ .macro        ARM_FUNC_ALIAS new old
+       .globl  SYM (__\new)
+       EQUIV   SYM (__\new), SYM (__\old)
+@@ -398,6 +514,13 @@ SYM (__\name):
+       .set    SYM (_L__\new), SYM (_L__\old)
+ #endif
+ .endm
++#endif
++
++#ifdef __ARM_EABI__
++.macro        WEAK name
++      .weak SYM (__\name)
++.endm
++#endif
+ #ifdef __thumb__
+ /* Register aliases.  */
+@@ -423,6 +546,23 @@ pc                .req    r15
+ #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
++#if defined(__ARM_TUNE_MARVELL_F__)
++      clz     \curbit, \dividend
++      clz     \result, \divisor
++      sub     \curbit, \result, \curbit
++      mov     \divisor, \divisor, lsl \curbit
++      rsb     \curbit, \curbit, #31
++      mov     \curbit, \curbit, lsl #2
++      mov     \result, #0
++      add     pc, pc, \curbit, lsl #2
++      nop
++      .rept   32
++      cmp     \dividend, \divisor
++      subcs   \dividend, \dividend, \divisor
++      mov     \divisor, \divisor, lsr #1
++      adc     \result, \result, \result
++      .endr
++#else  /* ! defined(__ARM_TUNE_MARVELL_F__) */
+       clz     \curbit, \dividend
+       clz     \result, \divisor
+       sub     \curbit, \result, \curbit
+@@ -438,6 +578,7 @@ pc         .req    r15
+       adc     \result, \result, \result
+       subcs   \dividend, \dividend, \divisor, lsl #shift
+       .endr
++#endif /* defined(__ARM_TUNE_MARVELL_F__) */
+ #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
+ #if __ARM_ARCH__ >= 5
+@@ -792,6 +933,7 @@ LSYM(Lgot_result):
+       cmp     divisor, #0
+       beq     LSYM(Ldiv0)
++LSYM(udivsi3_nodiv0):
+       mov     curbit, #1
+       mov     result, #0
+       
+@@ -807,6 +949,9 @@ LSYM(Lgot_result):
+ #else /* ARM version.  */
++      /* Note: if called via udivsi3_nodiv0, this will unnecessarily check
++         for division-by-zero a second time.  */
++LSYM(udivsi3_nodiv0):
+       subs    r2, r1, #1
+       RETc(eq)
+       bcc     LSYM(Ldiv0)
+@@ -831,19 +976,23 @@ LSYM(Lgot_result):
+ #endif /* ARM version */
+-      DIV_FUNC_END udivsi3
++      DIV_FUNC_END udivsi3 unsigned
+ FUNC_START aeabi_uidivmod
+ #ifdef __thumb__
++      cmp     r1, #0
++      beq     LSYM(Ldiv0)
+       push    {r0, r1, lr}
+-      bl      SYM(__udivsi3)
++      bl      LSYM(udivsi3_nodiv0)
+       POP     {r1, r2, r3}
+       mul     r2, r0
+       sub     r1, r1, r2
+       bx      r3
+ #else
++      cmp     r1, #0
++      beq     LSYM(Ldiv0)
+       stmfd   sp!, { r0, r1, lr }
+-      bl      SYM(__udivsi3)
++      bl      LSYM(udivsi3_nodiv0)
+       ldmfd   sp!, { r1, r2, lr }
+       mul     r3, r2, r0
+       sub     r1, r1, r3
+@@ -890,7 +1039,7 @@ LSYM(Lover10):
+ #endif /* ARM version.  */
+       
+-      DIV_FUNC_END umodsi3
++      DIV_FUNC_END umodsi3 unsigned
+ #endif /* L_umodsi3 */
+ /* ------------------------------------------------------------------------ */
+@@ -902,7 +1051,7 @@ LSYM(Lover10):
+ #ifdef __thumb__
+       cmp     divisor, #0
+       beq     LSYM(Ldiv0)
+-      
++LSYM(divsi3_nodiv0):
+       push    { work }
+       mov     work, dividend
+       eor     work, divisor           @ Save the sign of the result.
+@@ -934,8 +1083,9 @@ LSYM(Lover12):
+ #else /* ARM version.  */
+       
+       cmp     r1, #0
+-      eor     ip, r0, r1                      @ save the sign of the result.
+       beq     LSYM(Ldiv0)
++LSYM(divsi3_nodiv0):
++      eor     ip, r0, r1                      @ save the sign of the result.
+       rsbmi   r1, r1, #0                      @ loops below use unsigned.
+       subs    r2, r1, #1                      @ division by 1 or -1 ?
+       beq     10f
+@@ -970,19 +1120,23 @@ LSYM(Lover12):
+ #endif /* ARM version */
+       
+-      DIV_FUNC_END divsi3
++      DIV_FUNC_END divsi3 signed
+ FUNC_START aeabi_idivmod
+ #ifdef __thumb__
++      cmp     r1, #0
++      beq     LSYM(Ldiv0)
+       push    {r0, r1, lr}
+-      bl      SYM(__divsi3)
++      bl      LSYM(divsi3_nodiv0)
+       POP     {r1, r2, r3}
+       mul     r2, r0
+       sub     r1, r1, r2
+       bx      r3
+ #else
++      cmp     r1, #0
++      beq     LSYM(Ldiv0)
+       stmfd   sp!, { r0, r1, lr }
+-      bl      SYM(__divsi3)
++      bl      LSYM(divsi3_nodiv0)
+       ldmfd   sp!, { r1, r2, lr }
+       mul     r3, r2, r0
+       sub     r1, r1, r3
+@@ -1048,21 +1202,25 @@ LSYM(Lover12):
+ #endif /* ARM version */
+       
+-      DIV_FUNC_END modsi3
++      DIV_FUNC_END modsi3 signed
+ #endif /* L_modsi3 */
+ /* ------------------------------------------------------------------------ */
+ #ifdef L_dvmd_tls
+-      FUNC_START div0
+-      FUNC_ALIAS aeabi_idiv0 div0
+-      FUNC_ALIAS aeabi_ldiv0 div0
+-
++#ifdef __ARM_EABI__
++      WEAK aeabi_idiv0
++      WEAK aeabi_ldiv0
++      FUNC_START aeabi_idiv0
++      FUNC_START aeabi_ldiv0
+       RET
+-
+       FUNC_END aeabi_ldiv0
+       FUNC_END aeabi_idiv0
++#else
++      FUNC_START div0
++      RET
+       FUNC_END div0
++#endif
+       
+ #endif /* L_divmodsi_tools */
+ /* ------------------------------------------------------------------------ */
+@@ -1072,14 +1230,26 @@ LSYM(Lover12):
+ /* Constant taken from <asm/signal.h>.  */
+ #define SIGFPE        8
++#ifdef __ARM_EABI__
++      WEAK aeabi_idiv0
++      WEAK aeabi_ldiv0
++      ARM_FUNC_START aeabi_idiv0
++      ARM_FUNC_START aeabi_ldiv0
++#else
+       ARM_FUNC_START div0
++#endif
+-      do_push {r1, lr}
++      do_push (r1, lr)
+       mov     r0, #SIGFPE
+       bl      SYM(raise) __PLT__
+       RETLDM  r1
++#ifdef __ARM_EABI__
++      FUNC_END aeabi_ldiv0
++      FUNC_END aeabi_idiv0
++#else
+       FUNC_END div0
++#endif
+       
+ #endif /* L_dvmd_lnx */
+ /* ------------------------------------------------------------------------ */
+@@ -1256,8 +1426,8 @@ LSYM(Lover12):
+ #endif /* L_call_via_rX */
+ /* Don't bother with the old interworking routines for Thumb-2.  */
+-/* ??? Maybe only omit these on v7m.  */
+-#ifndef __thumb2__
++/* ??? Maybe only omit these on "m" variants.  */
++#if !defined(__thumb2__) && !defined(__ARM_ARCH_6M__)
+ #if defined L_interwork_call_via_rX
+@@ -1387,7 +1557,11 @@ LSYM(Lchange_\register):
+ #endif /* Arch supports thumb.  */
+ #ifndef __symbian__
++#ifndef __ARM_ARCH_6M__
+ #include "ieee754-df.S"
+ #include "ieee754-sf.S"
+ #include "bpabi.S"
+-#endif /* __symbian__ */
++#else /* __ARM_ARCH_6M__ */
++#include "bpabi-v6m.S"
++#endif /* __ARM_ARCH_6M__ */
++#endif /* !__symbian__ */
+--- a/gcc/config/arm/libunwind.S
++++ b/gcc/config/arm/libunwind.S
+@@ -53,6 +53,119 @@
+ #endif
+ #endif
++#ifdef __ARM_ARCH_6M__
++
++/* r0 points to a 16-word block.  Upload these values to the actual core
++   state.  */
++FUNC_START restore_core_regs
++      mov r1, r0
++      add r1, r1, #52
++      ldmia r1!, {r3, r4, r5}
++      sub r3, r3, #4
++      mov ip, r3
++      str r5, [r3]
++      mov lr, r4
++      /* Restore r8-r11.  */
++      mov r1, r0
++      add r1, r1, #32
++      ldmia r1!, {r2, r3, r4, r5}
++      mov r8, r2
++      mov r9, r3
++      mov sl, r4
++      mov fp, r5
++      mov r1, r0
++      add r1, r1, #8
++      ldmia r1!, {r2, r3, r4, r5, r6, r7}
++      ldr r1, [r0, #4]
++      ldr r0, [r0]
++      mov sp, ip
++      pop {pc}
++      FUNC_END restore_core_regs
++      UNPREFIX restore_core_regs
++
++/* ARMV6M does not have coprocessors, so these should never be used.  */
++FUNC_START gnu_Unwind_Restore_VFP
++      RET
++
++/* Store VFR regsters d0-d15 to the address in r0.  */
++FUNC_START gnu_Unwind_Save_VFP
++      RET
++
++/* Load VFP registers d0-d15 from the address in r0.
++   Use this to load from FSTMD format.  */
++FUNC_START gnu_Unwind_Restore_VFP_D
++      RET
++
++/* Store VFP registers d0-d15 to the address in r0.
++   Use this to store in FLDMD format.  */
++FUNC_START gnu_Unwind_Save_VFP_D
++      RET
++
++/* Load VFP registers d16-d31 from the address in r0.
++   Use this to load from FSTMD (=VSTM) format.  Needs VFPv3.  */
++FUNC_START gnu_Unwind_Restore_VFP_D_16_to_31
++      RET
++
++/* Store VFP registers d16-d31 to the address in r0.
++   Use this to store in FLDMD (=VLDM) format.  Needs VFPv3.  */
++FUNC_START gnu_Unwind_Save_VFP_D_16_to_31
++      RET
++
++FUNC_START gnu_Unwind_Restore_WMMXD
++      RET
++
++FUNC_START gnu_Unwind_Save_WMMXD
++      RET
++
++FUNC_START gnu_Unwind_Restore_WMMXC
++      RET
++
++FUNC_START gnu_Unwind_Save_WMMXC
++      RET
++
++.macro  UNWIND_WRAPPER name nargs
++      FUNC_START \name
++      /* Create a phase2_vrs structure.  */
++      /* Save r0 in the PC slot so we can use it as a scratch register.  */
++      push {r0}
++      add r0, sp, #4
++      push {r0, lr} /* Push original SP and LR.  */
++      /* Make space for r8-r12.  */
++      sub sp, sp, #20
++      /* Save low registers.  */
++      push {r0, r1, r2, r3, r4, r5, r6, r7}
++      /* Save high registers.  */
++      add r0, sp, #32
++      mov r1, r8
++      mov r2, r9
++      mov r3, sl
++      mov r4, fp
++      mov r5, ip
++      stmia r0!, {r1, r2, r3, r4, r5}
++      /* Restore original low register values.  */
++      add r0, sp, #4
++      ldmia r0!, {r1, r2, r3, r4, r5}
++      /* Restore orginial r0.  */
++      ldr r0, [sp, #60]
++      str r0, [sp]
++      /* Demand-save flags, plus an extra word for alignment.  */
++      mov r3, #0
++      push {r2, r3}
++      /* Point r1 at the block.  Pass r[0..nargs) unchanged.  */
++      add r\nargs, sp, #4
++
++      bl SYM (__gnu\name)
++
++      ldr r3, [sp, #64]
++      add sp, sp, #72
++      bx r3
++
++      FUNC_END \name
++      UNPREFIX \name
++.endm
++
++#else /* !__ARM_ARCH_6M__ */
++
+ /* r0 points to a 16-word block.  Upload these values to the actual core
+    state.  */
+ ARM_FUNC_START restore_core_regs
+@@ -233,6 +346,8 @@ ARM_FUNC_START gnu_Unwind_Save_WMMXC
+       UNPREFIX \name
+ .endm
++#endif /* !__ARM_ARCH_6M__ */
++
+ UNWIND_WRAPPER _Unwind_RaiseException 1
+ UNWIND_WRAPPER _Unwind_Resume 1
+ UNWIND_WRAPPER _Unwind_Resume_or_Rethrow 1
+--- /dev/null
++++ b/gcc/config/arm/linux-atomic.c
+@@ -0,0 +1,280 @@
++/* Linux-specific atomic operations for ARM EABI.
++   Copyright (C) 2008 Free Software Foundation, Inc.
++   Contributed by CodeSourcery.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify it under
++the terms of the GNU General Public License as published by the Free
++Software Foundation; either version 2, or (at your option) any later
++version.
++
++In addition to the permissions in the GNU General Public License, the
++Free Software Foundation gives you unlimited permission to link the
++compiled version of this file into combinations with other programs,
++and to distribute those combinations without any restriction coming
++from the use of this file.  (The General Public License restrictions
++do apply in other respects; for example, they cover modification of
++the file, and distribution when not linked into a combine
++executable.)
++
++GCC is distributed in the hope that it will be useful, but WITHOUT ANY
++WARRANTY; without even the implied warranty of MERCHANTABILITY or
++FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING.  If not, write to the Free
++Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
++02110-1301, USA.  */
++
++/* Kernel helper for compare-and-exchange.  */
++typedef int (__kernel_cmpxchg_t) (int oldval, int newval, int *ptr);
++#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0)
++
++/* Kernel helper for memory barrier.  */
++typedef void (__kernel_dmb_t) (void);
++#define __kernel_dmb (*(__kernel_dmb_t *) 0xffff0fa0)
++
++/* Note: we implement byte, short and int versions of atomic operations using
++   the above kernel helpers, but there is no support for "long long" (64-bit)
++   operations as yet.  */
++
++#define HIDDEN __attribute__ ((visibility ("hidden")))
++
++#ifdef __ARMEL__
++#define INVERT_MASK_1 0
++#define INVERT_MASK_2 0
++#else
++#define INVERT_MASK_1 24
++#define INVERT_MASK_2 16
++#endif
++
++#define MASK_1 0xffu
++#define MASK_2 0xffffu
++
++#define FETCH_AND_OP_WORD(OP, PFX_OP, INF_OP)                         \
++  int HIDDEN                                                          \
++  __sync_fetch_and_##OP##_4 (int *ptr, int val)                               \
++  {                                                                   \
++    int failure, tmp;                                                 \
++                                                                      \
++    do {                                                              \
++      tmp = *ptr;                                                     \
++      failure = __kernel_cmpxchg (tmp, PFX_OP tmp INF_OP val, ptr);   \
++    } while (failure != 0);                                           \
++                                                                      \
++    return tmp;                                                               \
++  }
++
++FETCH_AND_OP_WORD (add,   , +)
++FETCH_AND_OP_WORD (sub,   , -)
++FETCH_AND_OP_WORD (or,    , |)
++FETCH_AND_OP_WORD (and,   , &)
++FETCH_AND_OP_WORD (xor,   , ^)
++FETCH_AND_OP_WORD (nand, ~, &)
++
++#define NAME_oldval(OP, WIDTH) __sync_fetch_and_##OP##_##WIDTH
++#define NAME_newval(OP, WIDTH) __sync_##OP##_and_fetch_##WIDTH
++
++/* Implement both __sync_<op>_and_fetch and __sync_fetch_and_<op> for
++   subword-sized quantities.  */
++
++#define SUBWORD_SYNC_OP(OP, PFX_OP, INF_OP, TYPE, WIDTH, RETURN)      \
++  TYPE HIDDEN                                                         \
++  NAME##_##RETURN (OP, WIDTH) (TYPE *ptr, TYPE val)                   \
++  {                                                                   \
++    int *wordptr = (int *) ((unsigned int) ptr & ~3);                 \
++    unsigned int mask, shift, oldval, newval;                         \
++    int failure;                                                      \
++                                                                      \
++    shift = (((unsigned int) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH;    \
++    mask = MASK_##WIDTH << shift;                                     \
++                                                                      \
++    do {                                                              \
++      oldval = *wordptr;                                              \
++      newval = ((PFX_OP ((oldval & mask) >> shift)                    \
++                 INF_OP (unsigned int) val) << shift) & mask;         \
++      newval |= oldval & ~mask;                                               \
++      failure = __kernel_cmpxchg (oldval, newval, wordptr);           \
++    } while (failure != 0);                                           \
++                                                                      \
++    return (RETURN & mask) >> shift;                                  \
++  }
++
++SUBWORD_SYNC_OP (add,   , +, short, 2, oldval)
++SUBWORD_SYNC_OP (sub,   , -, short, 2, oldval)
++SUBWORD_SYNC_OP (or,    , |, short, 2, oldval)
++SUBWORD_SYNC_OP (and,   , &, short, 2, oldval)
++SUBWORD_SYNC_OP (xor,   , ^, short, 2, oldval)
++SUBWORD_SYNC_OP (nand, ~, &, short, 2, oldval)
++
++SUBWORD_SYNC_OP (add,   , +, char, 1, oldval)
++SUBWORD_SYNC_OP (sub,   , -, char, 1, oldval)
++SUBWORD_SYNC_OP (or,    , |, char, 1, oldval)
++SUBWORD_SYNC_OP (and,   , &, char, 1, oldval)
++SUBWORD_SYNC_OP (xor,   , ^, char, 1, oldval)
++SUBWORD_SYNC_OP (nand, ~, &, char, 1, oldval)
++
++#define OP_AND_FETCH_WORD(OP, PFX_OP, INF_OP)                         \
++  int HIDDEN                                                          \
++  __sync_##OP##_and_fetch_4 (int *ptr, int val)                               \
++  {                                                                   \
++    int tmp, failure;                                                 \
++                                                                      \
++    do {                                                              \
++      tmp = *ptr;                                                     \
++      failure = __kernel_cmpxchg (tmp, PFX_OP tmp INF_OP val, ptr);   \
++    } while (failure != 0);                                           \
++                                                                      \
++    return PFX_OP tmp INF_OP val;                                     \
++  }
++
++OP_AND_FETCH_WORD (add,   , +)
++OP_AND_FETCH_WORD (sub,   , -)
++OP_AND_FETCH_WORD (or,    , |)
++OP_AND_FETCH_WORD (and,   , &)
++OP_AND_FETCH_WORD (xor,   , ^)
++OP_AND_FETCH_WORD (nand, ~, &)
++
++SUBWORD_SYNC_OP (add,   , +, short, 2, newval)
++SUBWORD_SYNC_OP (sub,   , -, short, 2, newval)
++SUBWORD_SYNC_OP (or,    , |, short, 2, newval)
++SUBWORD_SYNC_OP (and,   , &, short, 2, newval)
++SUBWORD_SYNC_OP (xor,   , ^, short, 2, newval)
++SUBWORD_SYNC_OP (nand, ~, &, short, 2, newval)
++
++SUBWORD_SYNC_OP (add,   , +, char, 1, newval)
++SUBWORD_SYNC_OP (sub,   , -, char, 1, newval)
++SUBWORD_SYNC_OP (or,    , |, char, 1, newval)
++SUBWORD_SYNC_OP (and,   , &, char, 1, newval)
++SUBWORD_SYNC_OP (xor,   , ^, char, 1, newval)
++SUBWORD_SYNC_OP (nand, ~, &, char, 1, newval)
++
++int HIDDEN
++__sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval)
++{
++  int actual_oldval, fail;
++    
++  while (1)
++    {
++      actual_oldval = *ptr;
++
++      if (oldval != actual_oldval)
++      return actual_oldval;
++
++      fail = __kernel_cmpxchg (actual_oldval, newval, ptr);
++  
++      if (!fail)
++        return oldval;
++    }
++}
++
++#define SUBWORD_VAL_CAS(TYPE, WIDTH)                                  \
++  TYPE HIDDEN                                                         \
++  __sync_val_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval,                \
++                                     TYPE newval)                     \
++  {                                                                   \
++    int *wordptr = (int *)((unsigned int) ptr & ~3), fail;            \
++    unsigned int mask, shift, actual_oldval, actual_newval;           \
++                                                                      \
++    shift = (((unsigned int) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH;    \
++    mask = MASK_##WIDTH << shift;                                     \
++                                                                      \
++    while (1)                                                         \
++      {                                                                       \
++      actual_oldval = *wordptr;                                       \
++                                                                      \
++      if (((actual_oldval & mask) >> shift) != (unsigned int) oldval) \
++          return (actual_oldval & mask) >> shift;                     \
++                                                                      \
++      actual_newval = (actual_oldval & ~mask)                         \
++                      | (((unsigned int) newval << shift) & mask);    \
++                                                                      \
++      fail = __kernel_cmpxchg (actual_oldval, actual_newval,          \
++                               wordptr);                              \
++                                                                      \
++      if (!fail)                                                      \
++          return oldval;                                              \
++      }                                                                       \
++  }
++
++SUBWORD_VAL_CAS (short, 2)
++SUBWORD_VAL_CAS (char,  1)
++
++typedef unsigned char bool;
++
++bool HIDDEN
++__sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval)
++{
++  int failure = __kernel_cmpxchg (oldval, newval, ptr);
++  return (failure == 0);
++}
++
++#define SUBWORD_BOOL_CAS(TYPE, WIDTH)                                 \
++  bool HIDDEN                                                         \
++  __sync_bool_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval,               \
++                                      TYPE newval)                    \
++  {                                                                   \
++    TYPE actual_oldval                                                        \
++      = __sync_val_compare_and_swap_##WIDTH (ptr, oldval, newval);    \
++    return (oldval == actual_oldval);                                 \
++  }
++
++SUBWORD_BOOL_CAS (short, 2)
++SUBWORD_BOOL_CAS (char,  1)
++
++void HIDDEN
++__sync_synchronize (void)
++{
++  __kernel_dmb ();
++}
++
++int HIDDEN
++__sync_lock_test_and_set_4 (int *ptr, int val)
++{
++  int failure, oldval;
++
++  do {
++    oldval = *ptr;
++    failure = __kernel_cmpxchg (oldval, val, ptr);
++  } while (failure != 0);
++
++  return oldval;
++}
++
++#define SUBWORD_TEST_AND_SET(TYPE, WIDTH)                             \
++  TYPE HIDDEN                                                         \
++  __sync_lock_test_and_set_##WIDTH (TYPE *ptr, TYPE val)              \
++  {                                                                   \
++    int failure;                                                      \
++    unsigned int oldval, newval, shift, mask;                         \
++    int *wordptr = (int *) ((unsigned int) ptr & ~3);                 \
++                                                                      \
++    shift = (((unsigned int) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH;    \
++    mask = MASK_##WIDTH << shift;                                     \
++                                                                      \
++    do {                                                              \
++      oldval = *wordptr;                                              \
++      newval = (oldval & ~mask)                                               \
++             | (((unsigned int) val << shift) & mask);                \
++      failure = __kernel_cmpxchg (oldval, newval, wordptr);           \
++    } while (failure != 0);                                           \
++                                                                      \
++    return (oldval & mask) >> shift;                                  \
++  }
++
++SUBWORD_TEST_AND_SET (short, 2)
++SUBWORD_TEST_AND_SET (char,  1)
++
++#define SYNC_LOCK_RELEASE(TYPE, WIDTH)                                        \
++  void HIDDEN                                                         \
++  __sync_lock_release_##WIDTH (TYPE *ptr)                             \
++  {                                                                   \
++    *ptr = 0;                                                         \
++    __kernel_dmb ();                                                  \
++  }
++
++SYNC_LOCK_RELEASE (int,   4)
++SYNC_LOCK_RELEASE (short, 2)
++SYNC_LOCK_RELEASE (char,  1)
+--- a/gcc/config/arm/linux-eabi.h
++++ b/gcc/config/arm/linux-eabi.h
+@@ -66,7 +66,7 @@
+ /* At this point, bpabi.h will have clobbered LINK_SPEC.  We want to
+    use the GNU/Linux version, not the generic BPABI version.  */
+ #undef  LINK_SPEC
+-#define LINK_SPEC LINUX_TARGET_LINK_SPEC
++#define LINK_SPEC LINUX_TARGET_LINK_SPEC BE8_LINK_SPEC
+ /* Use the default LIBGCC_SPEC, not the version in linux-elf.h, as we
+    do not use -lfloat.  */
+--- /dev/null
++++ b/gcc/config/arm/marvell-f-vfp.md
+@@ -0,0 +1,157 @@
++;; Marvell 2850 VFP pipeline description
++;; Copyright (C) 2007 Free Software Foundation, Inc.
++;; Written by CodeSourcery, Inc.
++
++;; This file is part of GCC.
++
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published
++;; by the Free Software Foundation; either version 3, or (at your
++;; option) any later version.
++
++;; GCC is distributed in the hope that it will be useful, but WITHOUT
++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
++;; License for more details.
++
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING3.  If not see
++;; <http://www.gnu.org/licenses/>.
++
++;; This automaton provides a pipeline description for the Marvell
++;; 2850 core.
++;;
++;; The model given here assumes that the condition for all conditional
++;; instructions is "true", i.e., that all of the instructions are
++;; actually executed.
++
++(define_automaton "marvell_f_vfp")
++
++;; This is a single-issue VFPv2 implementation with the following execution
++;; units:
++;;
++;; 1. Addition/subtraction unit; takes three cycles, pipelined.
++;; 2. Multiplication unit; takes four cycles, pipelined.
++;; 3. Add buffer, used for multiply-accumulate (see below).
++;; 4. Divide/square root unit, not pipelined.
++;;    For single-precision: takes sixteen cycles, can accept another insn
++;;                        after fifteen cycles.
++;;    For double-precision: takes thirty-one cycles, can accept another insn
++;;                        after thirty cycles.
++;; 5. Single-cycle unit, pipelined.
++;;    This does absolute value/copy/negate/compare in one cycle and
++;;    conversion in two cycles.
++;;
++;; When all three operands of a multiply-accumulate instruction are ready,
++;; one is issued to the add buffer (which can hold six operands in a FIFO)
++;; and the two to be multiplied are issued to the multiply unit.  After
++;; four cycles in the multiply unit, one cycle is taken to issue the
++;; operand from the add buffer plus the multiplication result to the
++;; addition/subtraction unit.  That issue takes priority over any add/sub
++;; instruction waiting at the normal issue stage, but may be performed in
++;; parallel with the issue of a non-add/sub instruction.  The total time
++;; for a multiply-accumulate instruction to pass through the execution
++;; units is hence eight cycles.
++;;
++;; We do not need to explicitly model the add buffer because it can
++;; always issue the instruction at the head of its FIFO (due to the above
++;; priority rule) and there are more spaces in the add buffer (six) than
++;; there are stages (four) in the multiplication unit.
++;;
++;; Two instructions may be retired at once from the head of an 8-entry
++;; reorder buffer.  Data from these first two instructions only may be
++;; forwarded to the inputs of the issue unit.  We assume that the
++;; pressure on the reorder buffer will be sufficiently low that every
++;; instruction entering it will be eligible for data forwarding.  Since
++;; data is forwarded to the issue unit and not the execution units (so
++;; for example single-cycle instructions cannot be issued back-to-back),
++;; the latencies given below are the cycle counts above plus one.
++
++(define_cpu_unit "mf_vfp_issue" "marvell_f_vfp")
++(define_cpu_unit "mf_vfp_add" "marvell_f_vfp")
++(define_cpu_unit "mf_vfp_mul" "marvell_f_vfp")
++(define_cpu_unit "mf_vfp_div" "marvell_f_vfp")
++(define_cpu_unit "mf_vfp_single_cycle" "marvell_f_vfp")
++
++;; An attribute to indicate whether our reservations are applicable.
++
++(define_attr "marvell_f_vfp" "yes,no"
++  (const (if_then_else (and (eq_attr "tune" "marvell_f")
++                            (eq_attr "fpu" "vfp"))
++                       (const_string "yes") (const_string "no"))))
++
++;; Reservations of functional units.  The nothing*2 reservations at the
++;; start of many of the reservation strings correspond to the decode
++;; stages.  We need to have these reservations so that we can correctly
++;; reserve parts of the core's A1 pipeline for loads and stores.  For
++;; that case (since loads skip E1) the pipelines line up thus:
++;;    A1 pipe:        Issue   E2      OF      WR      WB       ...
++;;    VFP pipe:       Fetch   Decode1 Decode2 Issue   Execute1 ...
++;; For a load, we need to make a reservation of E2, and thus we must
++;; use Decode1 as the starting point for all VFP reservations here.
++;;
++;; For reservations of pipelined VFP execution units we only reserve
++;; the execution unit for the first execution cycle, omitting any trailing
++;; "nothing" reservations.
++
++(define_insn_reservation "marvell_f_vfp_add" 4
++  (and (eq_attr "marvell_f_vfp" "yes")
++       (eq_attr "type" "fadds,faddd"))
++  "nothing*2,mf_vfp_issue,mf_vfp_add")
++
++(define_insn_reservation "marvell_f_vfp_mul" 5
++  (and (eq_attr "marvell_f_vfp" "yes")
++       (eq_attr "type" "fmuls,fmuld"))
++  "nothing*2,mf_vfp_issue,mf_vfp_mul")
++
++(define_insn_reservation "marvell_f_vfp_divs" 17
++  (and (eq_attr "marvell_f_vfp" "yes")
++       (eq_attr "type" "fdivs"))
++  "nothing*2,mf_vfp_issue,mf_vfp_div*15")
++
++(define_insn_reservation "marvell_f_vfp_divd" 32
++  (and (eq_attr "marvell_f_vfp" "yes")
++       (eq_attr "type" "fdivd"))
++  "nothing*2,mf_vfp_issue,mf_vfp_div*30")
++
++;; The DFA lookahead is small enough that the "add" reservation here
++;; will always take priority over any addition/subtraction instruction
++;; issued five cycles after the multiply-accumulate instruction, as
++;; required.
++(define_insn_reservation "marvell_f_vfp_mac" 9
++  (and (eq_attr "marvell_f_vfp" "yes")
++       (eq_attr "type" "fmacs,fmacd"))
++  "nothing*2,mf_vfp_issue,mf_vfp_mul,nothing*4,mf_vfp_add")
++
++(define_insn_reservation "marvell_f_vfp_single" 2
++  (and (eq_attr "marvell_f_vfp" "yes")
++       (eq_attr "type" "fcpys,ffariths,ffarithd,fcmps,fcmpd"))
++  "nothing*2,mf_vfp_issue,mf_vfp_single_cycle")
++
++(define_insn_reservation "marvell_f_vfp_convert" 3
++  (and (eq_attr "marvell_f_vfp" "yes")
++       (eq_attr "type" "f_cvt"))
++  "nothing*2,mf_vfp_issue,mf_vfp_single_cycle")
++
++(define_insn_reservation "marvell_f_vfp_load" 2
++  (and (eq_attr "marvell_f_vfp" "yes")
++       (eq_attr "type" "f_loads,f_loadd"))
++  "a1_e2+sram,a1_of,a1_wr+mf_vfp_issue,a1_wb+mf_vfp_single_cycle")
++
++(define_insn_reservation "marvell_f_vfp_from_core" 2
++  (and (eq_attr "marvell_f_vfp" "yes")
++       (eq_attr "type" "r_2_f"))
++  "a1_e2,a1_of,a1_wr+mf_vfp_issue,a1_wb+mf_vfp_single_cycle")
++
++;; The interaction between the core and VFP pipelines during VFP
++;; store operations and core <-> VFP moves is not clear, so we guess.
++(define_insn_reservation "marvell_f_vfp_store" 3
++  (and (eq_attr "marvell_f_vfp" "yes")
++       (eq_attr "type" "f_stores,f_stored"))
++  "a1_e2,a1_of,mf_vfp_issue,a1_wr+sram+mf_vfp_single_cycle")
++
++(define_insn_reservation "marvell_f_vfp_to_core" 4
++  (and (eq_attr "marvell_f_vfp" "yes")
++       (eq_attr "type" "f_2_r"))
++  "a1_e2,a1_of,a1_wr+mf_vfp_issue,a1_wb+mf_vfp_single_cycle")
++
+--- /dev/null
++++ b/gcc/config/arm/marvell-f.md
+@@ -0,0 +1,364 @@
++;; Marvell 2850 pipeline description
++;; Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
++;; Written by Marvell and CodeSourcery, Inc.
++
++;; This file is part of GCC.
++
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published
++;; by the Free Software Foundation; either version 3, or (at your
++;; option) any later version.
++
++;; GCC is distributed in the hope that it will be useful, but WITHOUT
++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
++;; License for more details.
++
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING3.  If not see
++;; <http://www.gnu.org/licenses/>.
++
++;; This automaton provides a pipeline description for the Marvell
++;; 2850 core.
++;;
++;; The model given here assumes that the condition for all conditional
++;; instructions is "true", i.e., that all of the instructions are
++;; actually executed.
++
++(define_automaton "marvell_f")
++
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;; Pipelines
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++
++;; This is a dual-issue processor with three pipelines:
++;;
++;; 1. Arithmetic and load/store pipeline A1.
++;;    Issue | E1 | E2 | OF | WR | WB  for load-store instructions
++;;    Issue | E1 | E2 | WB  for arithmetic instructions
++;;
++;; 2. Arithmetic pipeline A2.
++;;    Issue | E1 | E2 | WB
++;;
++;; 3. Multiply and multiply-accumulate pipeline.
++;;    Issue | MAC1 | MAC2 | MAC3 | WB
++;;
++;; There are various bypasses modelled to a greater or lesser extent.
++;;
++;; Latencies in this file correspond to the number of cycles after
++;; the issue stage that it takes for the result of the instruction to
++;; be computed, or for its side-effects to occur.
++
++(define_cpu_unit "a1_e1,a1_e2,a1_of,a1_wr,a1_wb" "marvell_f") ; ALU 1
++(define_cpu_unit "a2_e1,a2_e2,a2_wb" "marvell_f")             ; ALU 2
++(define_cpu_unit "m_1,m_2,m_3,m_wb" "marvell_f")              ; MAC
++
++;; We define an SRAM cpu unit to enable us to describe conflicts
++;; between loads at the E2 stage and stores at the WR stage.
++
++(define_cpu_unit "sram" "marvell_f")
++
++;; Handling of dual-issue constraints.
++;;
++;; Certain pairs of instructions can be issued in parallel, and certain
++;; pairs cannot.  We divide a subset of the instructions into groups as
++;; follows.
++;;
++;; - data processing 1 (mov, mvn);
++;; - data processing 2 (adc, add, and, bic, cmn, cmp, eor, orr, rsb,
++;;                      rsc, sbc, sub, teq, tst);
++;; - load single (ldr, ldrb, ldrbt, ldrt, ldrh, ldrsb, ldrsh);
++;; - store single (str, strb, strbt, strt, strh);
++;; - swap (swp, swpb);
++;; - pld;
++;; - count leading zeros and DSP add/sub (clz, qadd, qdadd, qsub, qdsub);
++;; - multiply 2 (mul, muls, smull, umull, smulxy, smulls, umulls);
++;; - multiply 3 (mla, mlas, smlal, umlal, smlaxy, smlalxy, smlawx,
++;;               smlawy, smlals, umlals);
++;; - branches (b, bl, blx, bx).
++;;
++;; Ignoring conditional execution, it is a good approximation to the core
++;; to model that two instructions may only be issued in parallel if the
++;; following conditions are met.
++;; I.   The instructions both fall into one of the above groups and their
++;;      corresponding groups have a entry in the matrix below that is not X.
++;; II.  The second instruction does not read any register updated by the
++;;      first instruction (already enforced by the GCC scheduler).
++;; III. The second instruction does not need the carry flag updated by the
++;;      first instruction.  Currently we do not model this.
++;;
++;; First      Second instruction group
++;; insn
++;;            DP1  DP2  L    S    SWP  PLD  CLZ  M2   M3   B
++;;
++;;    DP1     ok   ok   ok   ok   ok   ok   ok   ok   ok   ok
++;;    DP2(1)  ok   ok   ok   ok   ok   ok   ok   ok   ok   ok
++;;    DP2(2)  ok   (2)  ok   (4)  ok   ok   ok   ok   X    ok
++;;    L   }
++;;    SWP }   ok   ok   X    X    X    X    ok   ok   ok   ok
++;;    PLD }
++;;      S(3)  ok   ok   X    X    X    X    ok   ok   ok   ok
++;;      S(4)  ok   (2)  X    X    X    X    ok   ok   X    ok
++;;    CLZ     ok   ok   ok   ok   ok   ok   ok   ok   ok   ok
++;;    M2      ok   ok   ok   ok   ok   ok   ok   X    X    ok
++;;    M3      ok   (2)  ok   (4)  ok   ok   ok   X    X    ok
++;;    B       ok   ok   ok   ok   ok   ok   ok   ok   ok   ok
++;;
++;; (1) without register shift
++;; (2) with register shift
++;; (3) with immediate offset
++;; (4) with register offset
++;;
++;; We define a fake cpu unit "reg_shift_lock" to enforce constraints
++;; between instructions in groups DP2(2) and M3.  All other
++;; constraints are enforced automatically by virtue of the limited
++;; number of pipelines available for the various operations, with
++;; the exception of constraints involving S(4) that we do not model.
++
++(define_cpu_unit "reg_shift_lock" "marvell_f")
++
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;; ALU instructions
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++
++;; 1. Certain logic operations can be retired after the E1 stage if
++;; the pipeline is not already retiring another instruction.  In this
++;; model we assume this behaviour always holds for mov, mvn, and, orr, eor
++;; instructions.  If a register shift is involved and the instruction is
++;; not mov or mvn, then a dual-issue constraint must be enforced.
++
++;; The first two cases are separate so they can be identified for
++;; bypasses below.
++
++(define_insn_reservation "marvell_f_alu_early_retire" 1
++  (and (eq_attr "tune" "marvell_f")
++       (and (eq_attr "type" "alu")
++            (eq_attr "insn" "mov,mvn,and,orr,eor")))
++  "(a1_e1,a1_wb)|(a2_e1,a2_wb)")
++
++(define_insn_reservation "marvell_f_alu_early_retire_shift" 1
++  (and (eq_attr "tune" "marvell_f")
++       (and (eq_attr "type" "alu_shift_reg")
++            (eq_attr "insn" "mov,mvn,and,orr,eor")))
++  "(a1_e1,a1_wb)|(a2_e1,a2_wb)")
++
++(define_insn_reservation "marvell_f_alu_early_retire_reg_shift1" 1
++  (and (eq_attr "tune" "marvell_f")
++       (and (eq_attr "type" "alu_shift_reg")
++            (eq_attr "insn" "mov,mvn")))
++  "(a1_e1,a1_wb)|(a2_e1,a2_wb)")
++
++(define_insn_reservation "marvell_f_alu_early_retire_reg_shift2" 1
++  (and (eq_attr "tune" "marvell_f")
++       (and (eq_attr "type" "alu_shift_reg")
++            (eq_attr "insn" "and,orr,eor")))
++  "(reg_shift_lock+a1_e1,a1_wb)|(reg_shift_lock+a2_e1,a2_wb)")
++
++;; 2. ALU operations with no shifted operand.  These bypass the E1 stage if
++;; the E2 stage of the corresponding pipeline is clear; here, we always
++;; model this scenario [*].  We give the operation a latency of 1 yet reserve
++;; both E1 and E2 for it (thus preventing the GCC scheduler, in the case
++;; where both E1 and E2 of one pipeline are clear, from issuing one
++;; instruction to each).
++;;
++;; [*] The non-bypass case is a latency of two, reserving E1 on the first
++;;     cycle and E2 on the next.  Due to the way the scheduler works we
++;;     have to choose between taking this as the default and taking the
++;;     above case (with latency one) as the default; we choose the latter.
++
++(define_insn_reservation "marvell_f_alu_op_bypass_e1" 1
++  (and (eq_attr "tune" "marvell_f")
++       (and (eq_attr "type" "alu")
++            (not (eq_attr "insn" "mov,mvn,and,orr,eor"))))
++  "(a1_e1+a1_e2,a1_wb)|(a2_e1+a2_e2,a2_wb)")
++
++;; 3. ALU operations with a shift-by-constant operand.
++
++(define_insn_reservation "marvell_f_alu_shift_op" 2
++  (and (eq_attr "tune" "marvell_f")
++       (and (eq_attr "type" "alu_shift")
++            (not (eq_attr "insn" "mov,mvn,and,orr,eor"))))
++  "(a1_e1,a1_e2,a1_wb)|(a2_e1,a2_e2,a2_wb)")
++
++;; 4. ALU operations with a shift-by-register operand.  Since the
++;; instruction is never mov or mvn, a dual-issue constraint must
++;; be enforced.
++
++(define_insn_reservation "marvell_f_alu_shift_reg_op" 2
++  (and (eq_attr "tune" "marvell_f")
++       (and (eq_attr "type" "alu_shift_reg")
++            (not (eq_attr "insn" "mov,mvn,and,orr,eor"))))
++  "(reg_shift_lock+a1_e1,a1_e2,a1_wb)|(reg_shift_lock+a2_e1,a2_e2,a2_wb)")
++
++;; Given an ALU operation with shift (I1) followed by another ALU
++;; operation (I2), with I2 depending on the destination register Rd of I1
++;; and with I2 not using that value as the amount or the starting value for
++;; a shift, then I1 and I2 may be issued to the same pipeline on
++;; consecutive cycles.  In terms of this model that corresponds to I1
++;; having a latency of one cycle.  There are three cases for various
++;; I1 and I2 as follows.
++
++;; (a) I1 has a constant or register shift and I2 doesn't have a shift at all.
++(define_bypass 1 "marvell_f_alu_shift_op,\
++                marvell_f_alu_shift_reg_op"
++             "marvell_f_alu_op_bypass_e1,marvell_f_alu_early_retire")
++
++;; (b) I1 has a constant or register shift and I2 has a constant shift.
++;; Rd must not provide the starting value for the shift.
++(define_bypass 1 "marvell_f_alu_shift_op,\
++                marvell_f_alu_shift_reg_op"
++             "marvell_f_alu_shift_op,marvell_f_alu_early_retire_shift"
++             "arm_no_early_alu_shift_value_dep")
++
++;; (c) I1 has a constant or register shift and I2 has a register shift.
++;; Rd must not provide the amount by which to shift.
++(define_bypass 1 "marvell_f_alu_shift_op,\
++                marvell_f_alu_shift_reg_op"
++             "marvell_f_alu_shift_reg_op,\
++              marvell_f_alu_early_retire_reg_shift1,\
++              marvell_f_alu_early_retire_reg_shift2"
++             "arm_no_early_alu_shift_dep")
++
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;; Multiplication instructions
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++
++;; Multiplication instructions in group "Multiply 2".
++
++(define_insn_reservation "marvell_f_multiply_2" 3
++  (and (eq_attr "tune" "marvell_f")
++       (eq_attr "insn" "mul,muls,smull,umull,smulxy,smulls,umulls"))
++  "m_1,m_2,m_3,m_wb")
++
++;; Multiplication instructions in group "Multiply 3".  There is a
++;; dual-issue constraint with non-multiplication ALU instructions
++;; to be respected here.
++
++(define_insn_reservation "marvell_f_multiply_3" 3
++  (and (eq_attr "tune" "marvell_f")
++       (eq_attr "insn" "mla,mlas,smlal,umlal,smlaxy,smlalxy,smlawx,\
++                        smlawy,smlals,umlals"))
++  "reg_shift_lock+m_1,m_2,m_3,m_wb")
++
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;; Branch instructions
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++
++;; Conditional backward b instructions can have a zero-cycle penalty, and
++;; other conditional b and bl instructions have a one-cycle penalty if
++;; predicted correctly.  Currently we model the zero-cycle case for all
++;; branches.
++
++(define_insn_reservation "marvell_f_branches" 0
++ (and (eq_attr "tune" "marvell_f")
++      (eq_attr "type" "branch"))
++ "nothing")
++
++;; Call latencies are not predictable; a semi-arbitrary very large
++;; number is used as "positive infinity" for such latencies.
++
++(define_insn_reservation "marvell_f_call" 32 
++ (and (eq_attr "tune" "marvell_f")
++      (eq_attr "type" "call"))
++ "nothing")
++
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;; Load/store instructions
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++
++;; The models for load/store instructions do not accurately describe
++;; the difference between operations with a base register writeback.
++;; These models assume that all memory references hit in dcache.
++
++;; 1. Load/store for single registers.
++
++;; The worst case for a load is when the load result is needed in E1
++;; (for example for a register shift), giving a latency of four.  Loads
++;; skip E1 and access memory at the E2 stage.
++
++(define_insn_reservation "marvell_f_load1" 4
++ (and (eq_attr "tune" "marvell_f")
++      (eq_attr "type" "load1,load_byte"))
++ "a1_e2+sram,a1_of,a1_wr,a1_wb")
++
++;; The result for a load may be bypassed (to be available at the same
++;; time as the load arrives in the WR stage, so effectively at the OF
++;; stage) to the Rn operand at E2 with a latency of two.  The result may
++;; be bypassed to a non-Rn operand at E2 with a latency of three.  For
++;; instructions without shifts, detection of an Rn bypass situation is
++;; difficult (because some of the instruction patterns switch their
++;; operands), and so we do not model that here.  For instructions with
++;; shifts, the operand used at E2 will always be Rn, and so we can
++;; model the latency-two bypass for these.
++
++(define_bypass 2 "marvell_f_load1"
++               "marvell_f_alu_shift_op"
++             "arm_no_early_alu_shift_value_dep")
++
++(define_bypass 2 "marvell_f_load1"
++               "marvell_f_alu_shift_reg_op"
++             "arm_no_early_alu_shift_dep")
++
++;; Stores write at the WR stage and loads read at the E2 stage, giving
++;; a store latency of three.
++
++(define_insn_reservation "marvell_f_store1" 3
++ (and (eq_attr "tune" "marvell_f")
++      (eq_attr "type" "store1"))
++ "a1_e2,a1_of,a1_wr+sram,a1_wb")
++
++;; 2. Load/store for two consecutive registers.  These may be dealt
++;; with in the same number of cycles as single loads and stores.
++
++(define_insn_reservation "marvell_f_load2" 4
++ (and (eq_attr "tune" "marvell_f")
++      (eq_attr "type" "load2"))
++ "a1_e2+sram,a1_of,a1_wr,a1_wb")
++
++(define_insn_reservation "marvell_f_store2" 3
++ (and (eq_attr "tune" "marvell_f")
++      (eq_attr "type" "store2"))
++ "a1_e2,a1_of,a1_wr+sram,a1_wb")
++
++;; The first word of a doubleword load is eligible for the latency-two
++;; bypass described above for single loads, but this is not modelled here.
++;; We do however assume that either word may also be bypassed with
++;; latency three for ALU operations with shifts (where the shift value and
++;; amount do not depend on the loaded value) and latency four for ALU
++;; operations without shifts.  The latency four case is of course the default.
++
++(define_bypass 3 "marvell_f_load2"
++               "marvell_f_alu_shift_op"
++             "arm_no_early_alu_shift_value_dep")
++
++(define_bypass 3 "marvell_f_load2"
++               "marvell_f_alu_shift_reg_op"
++             "arm_no_early_alu_shift_dep")
++
++;; 3. Load/store for more than two registers.
++
++;; These instructions stall for an extra cycle in the decode stage;
++;; individual load/store instructions for each register are then issued.
++;; The load/store multiple instruction itself is removed from the decode
++;; stage at the same time as the final load/store instruction is issued.
++;; To complicate matters, pairs of loads/stores referencing two
++;; consecutive registers will be issued together as doubleword operations.
++;; We model a 3-word load as an LDR plus an LDRD, and a 4-word load
++;; as two LDRDs; thus, these are allocated the same latencies (the
++;; latency for two consecutive loads plus one for the setup stall).
++;; The extra stall is modelled by reserving E1.
++
++(define_insn_reservation "marvell_f_load3_4" 6
++ (and (eq_attr "tune" "marvell_f")
++      (eq_attr "type" "load3,load4"))
++ "a1_e1,a1_e1+a1_e2+sram,a1_e2+sram+a1_of,a1_of+a1_wr,a1_wr+a1_wb,a1_wb")
++
++;; Bypasses are possible for ldm as for single loads, but we do not
++;; model them here since the order of the constituent loads is
++;; difficult to predict.
++
++(define_insn_reservation "marvell_f_store3_4" 5
++ (and (eq_attr "tune" "marvell_f")
++      (eq_attr "type" "store3,store4"))
++ "a1_e1,a1_e1+a1_e2,a1_e2+a1_of,a1_of+a1_wr+sram,a1_wr+sram+a1_wb,a1_wb")
++
+--- /dev/null
++++ b/gcc/config/arm/montavista-linux.h
+@@ -0,0 +1,33 @@
++/* MontaVista GNU/Linux Configuration.
++   Copyright (C) 2009
++   Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 3, or (at your option)
++any later version.
++
++GCC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++/* Add -tarmv6 and -tthumb2 options for convenience in generating multilibs.
++*/
++#undef CC1_SPEC
++#define CC1_SPEC "                                                    \
++ %{tarmv6:      -march=armv6 -mfloat-abi=softfp ;                     \
++   tthumb2:     -mthumb -march=armv7-a -mfloat-abi=softfp ;             \
++   :            -march=armv5t}"
++
++/* The various C libraries each have their own subdirectory.  */
++#undef SYSROOT_SUFFIX_SPEC
++#define SYSROOT_SUFFIX_SPEC                                   \
++  "%{tarmv6:/armv6 ;                                          \
++     tthumb2:/thumb2}"
+--- a/gcc/config/arm/neon-gen.ml
++++ b/gcc/config/arm/neon-gen.ml
+@@ -402,7 +402,11 @@ let _ =
+ "extern \"C\" {";
+ "#endif";
+ "";
++"#if defined (__vxworks) && defined (_WRS_KERNEL)";
++"#include <vxWorks.h>";
++"#else";
+ "#include <stdint.h>";
++"#endif";
+ ""];
+   deftypes ();
+   arrtypes ();
+--- a/gcc/config/arm/neon-testgen.ml
++++ b/gcc/config/arm/neon-testgen.ml
+@@ -51,8 +51,8 @@ let emit_prologue chan test_name =
+   Printf.fprintf chan "/* This file was autogenerated by neon-testgen.  */\n\n";
+   Printf.fprintf chan "/* { dg-do assemble } */\n";
+   Printf.fprintf chan "/* { dg-require-effective-target arm_neon_ok } */\n";
+-  Printf.fprintf chan
+-                 "/* { dg-options \"-save-temps -O0 -mfpu=neon -mfloat-abi=softfp\" } */\n";
++  Printf.fprintf chan "/* { dg-options \"-save-temps -O0\" } */\n";
++  Printf.fprintf chan "/* { dg-add-options arm_neon } */\n";
+   Printf.fprintf chan "\n#include \"arm_neon.h\"\n\n";
+   Printf.fprintf chan "void test_%s (void)\n{\n" test_name
+--- a/gcc/config/arm/neon.md
++++ b/gcc/config/arm/neon.md
+@@ -159,7 +159,8 @@
+    (UNSPEC_VUZP1              201)
+    (UNSPEC_VUZP2              202)
+    (UNSPEC_VZIP1              203)
+-   (UNSPEC_VZIP2              204)])
++   (UNSPEC_VZIP2              204)
++   (UNSPEC_MISALIGNED_ACCESS  205)])
+ ;; Double-width vector modes.
+ (define_mode_iterator VD [V8QI V4HI V2SI V2SF])
+@@ -427,76 +428,7 @@
+ ;; neon_type attribute definitions.
+ (define_attr "vqh_mnem" "vadd,vmin,vmax" (const_string "vadd"))
+-;; Classification of NEON instructions for scheduling purposes.
+-;; Do not set this attribute and the "type" attribute together in
+-;; any one instruction pattern.
+-(define_attr "neon_type"
+-   "neon_int_1,\
+-   neon_int_2,\
+-   neon_int_3,\
+-   neon_int_4,\
+-   neon_int_5,\
+-   neon_vqneg_vqabs,\
+-   neon_vmov,\
+-   neon_vaba,\
+-   neon_vsma,\
+-   neon_vaba_qqq,\
+-   neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+-   neon_mul_qqq_8_16_32_ddd_32,\
+-   neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\
+-   neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+-   neon_mla_qqq_8_16,\
+-   neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\
+-   neon_mla_qqq_32_qqd_32_scalar,\
+-   neon_mul_ddd_16_scalar_32_16_long_scalar,\
+-   neon_mul_qqd_32_scalar,\
+-   neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\
+-   neon_shift_1,\
+-   neon_shift_2,\
+-   neon_shift_3,\
+-   neon_vshl_ddd,\
+-   neon_vqshl_vrshl_vqrshl_qqq,\
+-   neon_vsra_vrsra,\
+-   neon_fp_vadd_ddd_vabs_dd,\
+-   neon_fp_vadd_qqq_vabs_qq,\
+-   neon_fp_vsum,\
+-   neon_fp_vmul_ddd,\
+-   neon_fp_vmul_qqd,\
+-   neon_fp_vmla_ddd,\
+-   neon_fp_vmla_qqq,\
+-   neon_fp_vmla_ddd_scalar,\
+-   neon_fp_vmla_qqq_scalar,\
+-   neon_fp_vrecps_vrsqrts_ddd,\
+-   neon_fp_vrecps_vrsqrts_qqq,\
+-   neon_bp_simple,\
+-   neon_bp_2cycle,\
+-   neon_bp_3cycle,\
+-   neon_ldr,\
+-   neon_str,\
+-   neon_vld1_1_2_regs,\
+-   neon_vld1_3_4_regs,\
+-   neon_vld2_2_regs_vld1_vld2_all_lanes,\
+-   neon_vld2_4_regs,\
+-   neon_vld3_vld4,\
+-   neon_vst1_1_2_regs_vst2_2_regs,\
+-   neon_vst1_3_4_regs,\
+-   neon_vst2_4_regs_vst3_vst4,\
+-   neon_vst3_vst4,\
+-   neon_vld1_vld2_lane,\
+-   neon_vld3_vld4_lane,\
+-   neon_vst1_vst2_lane,\
+-   neon_vst3_vst4_lane,\
+-   neon_vld3_vld4_all_lanes,\
+-   neon_mcr,\
+-   neon_mcr_2_mcrr,\
+-   neon_mrc,\
+-   neon_mrrc,\
+-   neon_ldm_2,\
+-   neon_stm_2,\
+-   none"
+- (const_string "none"))
+-
+-;; Predicates used for setting the above attribute.
++;; Predicates used for setting neon_type
+ (define_mode_attr Is_float_mode [(V8QI "false") (V16QI "false")
+                                (V4HI "false") (V8HI "false")
+@@ -550,7 +482,7 @@
+   /* FIXME: If the memory layout is changed in big-endian mode, output_move_vfp
+      below must be changed to output_move_neon (which will use the
+-     element/structure loads/stores), and the constraint changed to 'Un' instead
++     element/structure loads/stores), and the constraint changed to 'Um' instead
+      of 'Uv'.  */
+   switch (which_alternative)
+@@ -639,7 +571,8 @@
+     default: gcc_unreachable ();
+     }
+ }
+-  [(set_attr "length" "<V_slen>,<V_slen>,<V_slen>")])
++  [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_ldm_2")
++   (set_attr "length" "<V_slen>,<V_slen>,<V_slen>")])
+ (define_split
+   [(set (match_operand:EI 0 "s_register_operand" "")
+@@ -726,6 +659,41 @@
+   neon_disambiguate_copy (operands, dest, src, 4);
+ })
++(define_expand "movmisalign<mode>"
++  [(set (match_operand:VDQX 0 "nonimmediate_operand"         "")
++      (unspec:VDQX [(match_operand:VDQX 1 "general_operand" "")]
++                   UNSPEC_MISALIGNED_ACCESS))]
++  "TARGET_NEON && !BYTES_BIG_ENDIAN"
++{
++  if (!s_register_operand (operands[0], <MODE>mode)
++      && !s_register_operand (operands[1], <MODE>mode))
++    FAIL;
++})
++
++(define_insn "*movmisalign<mode>_neon"
++  [(set (match_operand:VDX 0 "nonimmediate_operand"         "=Um,w")
++      (unspec:VDX [(match_operand:VDX 1 "general_operand" " w, Um")]
++                  UNSPEC_MISALIGNED_ACCESS))]
++  "TARGET_NEON && !BYTES_BIG_ENDIAN
++   && (   s_register_operand (operands[0], <MODE>mode)
++       || s_register_operand (operands[1], <MODE>mode))"
++  "@
++  vst1.<V_sz_elem>\t{%P1}, %A0
++  vld1.<V_sz_elem>\t{%P0}, %A1"
++  [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs,neon_vld1_1_2_regs")])
++
++(define_insn "*movmisalign<mode>_neon"
++  [(set (match_operand:VQX 0 "nonimmediate_operand"         "=Um,w")
++      (unspec:VQX [(match_operand:VQX 1 "general_operand" " w, Um")]
++                  UNSPEC_MISALIGNED_ACCESS))]
++  "TARGET_NEON && !BYTES_BIG_ENDIAN
++   && (   s_register_operand (operands[0], <MODE>mode)
++       || s_register_operand (operands[1], <MODE>mode))"
++  "@
++  vst1.<V_sz_elem>\t{%q1}, %A0
++  vld1.<V_sz_elem>\t{%q0}, %A1"
++  [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs,neon_vld1_1_2_regs")])
++
+ (define_insn "vec_set<mode>_internal"
+   [(set (match_operand:VD 0 "s_register_operand" "=w")
+         (vec_merge:VD
+@@ -735,7 +703,10 @@
+           (match_operand:SI 2 "immediate_operand" "i")))]
+   "TARGET_NEON"
+ {
+-  operands[2] = GEN_INT (ffs ((int) INTVAL (operands[2]) - 1));
++  int elt = ffs ((int) INTVAL (operands[2]) - 1);
++  if (BYTES_BIG_ENDIAN)
++    elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
++  operands[2] = GEN_INT (elt);
+   
+   return "vmov%?.<V_uf_sclr>\t%P0[%c2], %1";
+ }
+@@ -757,6 +728,9 @@
+   int hi = (elem / half_elts) * 2;
+   int regno = REGNO (operands[0]);
++  if (BYTES_BIG_ENDIAN)
++    elt = half_elts - 1 - elt;
++
+   operands[0] = gen_rtx_REG (<V_HALF>mode, regno + hi);
+   operands[2] = GEN_INT (elt);
+@@ -804,7 +778,15 @@
+           (match_operand:VD 1 "s_register_operand" "w")
+           (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
+   "TARGET_NEON"
+-  "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]"
++{
++  if (BYTES_BIG_ENDIAN)
++    {
++      int elt = INTVAL (operands[2]);
++      elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
++      operands[2] = GEN_INT (elt);
++    }
++  return "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]";
++}
+   [(set_attr "predicable" "yes")
+    (set_attr "neon_type" "neon_bp_simple")]
+ )
+@@ -821,6 +803,9 @@
+   int hi = (INTVAL (operands[2]) / half_elts) * 2;
+   int regno = REGNO (operands[1]);
++  if (BYTES_BIG_ENDIAN)
++    elt = half_elts - 1 - elt;
++
+   operands[1] = gen_rtx_REG (<V_HALF>mode, regno + hi);
+   operands[2] = GEN_INT (elt);
+@@ -913,6 +898,50 @@
+                                     (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
+ )
++(define_insn "*mul<mode>3add<mode>_neon"
++  [(set (match_operand:VDQ 0 "s_register_operand" "=w")
++        (plus:VDQ (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
++                            (match_operand:VDQ 3 "s_register_operand" "w"))
++                (match_operand:VDQ 1 "s_register_operand" "0")))]
++  "TARGET_NEON"
++  "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
++  [(set (attr "neon_type")
++      (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
++                    (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
++                                  (const_string "neon_fp_vmla_ddd")
++                                  (const_string "neon_fp_vmla_qqq"))
++                    (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
++                                  (if_then_else
++                                    (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
++                                    (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
++                                    (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
++                                  (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
++                                    (const_string "neon_mla_qqq_8_16")
++                                    (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
++)
++
++(define_insn "*mul<mode>3neg<mode>add<mode>_neon"
++  [(set (match_operand:VDQ 0 "s_register_operand" "=w")
++        (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "0")
++                   (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
++                             (match_operand:VDQ 3 "s_register_operand" "w"))))]
++  "TARGET_NEON"
++  "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
++  [(set (attr "neon_type")
++      (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
++                    (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
++                                  (const_string "neon_fp_vmla_ddd")
++                                  (const_string "neon_fp_vmla_qqq"))
++                    (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
++                                  (if_then_else
++                                    (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
++                                    (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
++                                    (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
++                                  (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
++                                    (const_string "neon_mla_qqq_8_16")
++                                    (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
++)
++
+ (define_insn "ior<mode>3"
+   [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
+       (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
+@@ -2413,7 +2442,15 @@
+           (match_operand:VD 1 "s_register_operand" "w")
+           (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
+   "TARGET_NEON"
+-  "vmov%?.s<V_sz_elem>\t%0, %P1[%c2]"
++{
++  if (BYTES_BIG_ENDIAN)
++    {
++      int elt = INTVAL (operands[2]);
++      elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
++      operands[2] = GEN_INT (elt);
++    }
++  return "vmov%?.s<V_sz_elem>\t%0, %P1[%c2]";
++}
+   [(set_attr "predicable" "yes")
+    (set_attr "neon_type" "neon_bp_simple")]
+ )
+@@ -2425,7 +2462,15 @@
+           (match_operand:VD 1 "s_register_operand" "w")
+           (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
+   "TARGET_NEON"
+-  "vmov%?.u<V_sz_elem>\t%0, %P1[%c2]"
++{
++  if (BYTES_BIG_ENDIAN)
++    {
++      int elt = INTVAL (operands[2]);
++      elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
++      operands[2] = GEN_INT (elt);
++    }
++  return "vmov%?.u<V_sz_elem>\t%0, %P1[%c2]";
++}
+   [(set_attr "predicable" "yes")
+    (set_attr "neon_type" "neon_bp_simple")]
+ )
+@@ -2442,10 +2487,14 @@
+   int regno = REGNO (operands[1]);
+   unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
+   unsigned int elt = INTVAL (operands[2]);
++  unsigned int elt_adj = elt % halfelts;
++
++  if (BYTES_BIG_ENDIAN)
++    elt_adj = halfelts - 1 - elt_adj;
+   ops[0] = operands[0];
+   ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
+-  ops[2] = GEN_INT (elt % halfelts);
++  ops[2] = GEN_INT (elt_adj);
+   output_asm_insn ("vmov%?.s<V_sz_elem>\t%0, %P1[%c2]", ops);
+   return "";
+@@ -2466,10 +2515,14 @@
+   int regno = REGNO (operands[1]);
+   unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
+   unsigned int elt = INTVAL (operands[2]);
++  unsigned int elt_adj = elt % halfelts;
++
++  if (BYTES_BIG_ENDIAN)
++    elt_adj = halfelts - 1 - elt_adj;
+   ops[0] = operands[0];
+   ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
+-  ops[2] = GEN_INT (elt % halfelts);
++  ops[2] = GEN_INT (elt_adj);
+   output_asm_insn ("vmov%?.u<V_sz_elem>\t%0, %P1[%c2]", ops);
+   return "";
+@@ -2490,6 +2543,20 @@
+   neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<MODE>mode));
++  if (BYTES_BIG_ENDIAN)
++    {
++      /* The intrinsics are defined in terms of a model where the
++       element ordering in memory is vldm order, whereas the generic
++       RTL is defined in terms of a model where the element ordering
++       in memory is array order.  Convert the lane number to conform
++       to this model.  */
++      unsigned int elt = INTVAL (operands[2]);
++      unsigned int reg_nelts
++      = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
++      elt ^= reg_nelts - 1;
++      operands[2] = GEN_INT (elt);
++    }
++
+   if ((magic & 3) == 3 || GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) == 32)
+     insn = gen_vec_extract<mode> (operands[0], operands[1], operands[2]);
+   else
+--- a/gcc/config/arm/netbsd.h
++++ b/gcc/config/arm/netbsd.h
+@@ -101,7 +101,7 @@
+ /* Although not normally relevant (since by default, all aggregates
+    are returned in memory) compiling some parts of libc requires
+    non-APCS style struct returns.  */
+-#undef RETURN_IN_MEMORY
++#undef TARGET_RETURN_IN_MEMORY
+ /* VERY BIG NOTE : Change of structure alignment for RiscBSD.
+    There are consequences you should be aware of...
+--- /dev/null
++++ b/gcc/config/arm/nocrt0.h
+@@ -0,0 +1,24 @@
++/* Definitions for generic libgloss based cofigs where crt0 is supplied by
++   the linker script.
++   Copyright (C) 2006 Free Software Foundation, Inc.
++
++   This file is part of GCC.
++
++   GCC is free software; you can redistribute it and/or modify it
++   under the terms of the GNU General Public License as published
++   by the Free Software Foundation; either version 3, or (at your
++   option) any later version.
++
++   GCC is distributed in the hope that it will be useful, but WITHOUT
++   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
++   License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with GCC; see the file COPYING3.  If not see
++   <http://www.gnu.org/licenses/>.  */
++
++#undef  STARTFILE_SPEC
++#define STARTFILE_SPEC        " crti%O%s crtbegin%O%s"
++
++#define LIB_SPEC "-lc"
+--- a/gcc/config/arm/predicates.md
++++ b/gcc/config/arm/predicates.md
+@@ -168,6 +168,11 @@
+   (and (match_code "plus,minus,ior,xor,and")
+        (match_test "mode == GET_MODE (op)")))
++;; True for plus/minus operators
++(define_special_predicate "plusminus_operator"
++  (and (match_code "plus,minus")
++       (match_test "mode == GET_MODE (op)")))
++
+ ;; True for logical binary operators.
+ (define_special_predicate "logical_binary_operator"
+   (and (match_code "ior,xor,and")
+@@ -291,6 +296,9 @@
+   HOST_WIDE_INT i = 1, base = 0;
+   rtx elt;
++  if (low_irq_latency)
++    return false;
++
+   if (count <= 1
+       || GET_CODE (XVECEXP (op, 0, 0)) != SET)
+     return false;
+@@ -348,6 +356,9 @@
+   HOST_WIDE_INT i = 1, base = 0;
+   rtx elt;
++  if (low_irq_latency)
++    return false;
++
+   if (count <= 1
+       || GET_CODE (XVECEXP (op, 0, 0)) != SET)
+     return false;
+--- /dev/null
++++ b/gcc/config/arm/sfp-machine.h
+@@ -0,0 +1,100 @@
++#define _FP_W_TYPE_SIZE               32
++#define _FP_W_TYPE            unsigned long
++#define _FP_WS_TYPE           signed long
++#define _FP_I_TYPE            long
++
++#define _FP_MUL_MEAT_S(R,X,Y)                         \
++  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
++#define _FP_MUL_MEAT_D(R,X,Y)                         \
++  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
++#define _FP_MUL_MEAT_Q(R,X,Y)                         \
++  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
++
++#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y)
++#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
++#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
++
++#define _FP_NANFRAC_H         ((_FP_QNANBIT_H << 1) - 1)
++#define _FP_NANFRAC_S         ((_FP_QNANBIT_S << 1) - 1)
++#define _FP_NANFRAC_D         ((_FP_QNANBIT_D << 1) - 1), -1
++#define _FP_NANFRAC_Q         ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
++#define _FP_NANSIGN_H         0
++#define _FP_NANSIGN_S         0
++#define _FP_NANSIGN_D         0
++#define _FP_NANSIGN_Q         0
++
++#define _FP_KEEPNANFRACP 1
++
++/* Someone please check this.  */
++#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                    \
++  do {                                                                \
++    if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)                \
++      && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs))     \
++      {                                                               \
++      R##_s = Y##_s;                                          \
++      _FP_FRAC_COPY_##wc(R,Y);                                \
++      }                                                               \
++    else                                                      \
++      {                                                               \
++      R##_s = X##_s;                                          \
++      _FP_FRAC_COPY_##wc(R,X);                                \
++      }                                                               \
++    R##_c = FP_CLS_NAN;                                               \
++  } while (0)
++
++#define       __LITTLE_ENDIAN 1234
++#define       __BIG_ENDIAN    4321
++
++#if defined __ARMEB__
++# define __BYTE_ORDER __BIG_ENDIAN
++#else
++# define __BYTE_ORDER __LITTLE_ENDIAN
++#endif
++
++
++/* Define ALIASNAME as a strong alias for NAME.  */
++# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
++# define _strong_alias(name, aliasname) \
++  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
++
++#ifdef __ARM_EABI__
++/* Rename functions to their EABI names.  */
++/* The comparison functions need wrappers for EABI semantics, so
++   leave them unmolested.  */
++#define __negsf2      __aeabi_fneg
++#define __subsf3      __aeabi_fsub
++#define __addsf3      __aeabi_fadd
++#define __floatunsisf __aeabi_ui2f
++#define __floatsisf   __aeabi_i2f
++#define __floatundisf __aeabi_ul2f
++#define __floatdisf   __aeabi_l2f
++#define __mulsf3      __aeabi_fmul
++#define __divsf3      __aeabi_fdiv
++#define __unordsf2    __aeabi_fcmpun
++#define __fixsfsi     __aeabi_f2iz
++#define __fixunssfsi  __aeabi_f2uiz
++#define __fixsfdi     __aeabi_f2lz
++#define __fixunssfdi  __aeabi_f2ulz
++#define __floatdisf   __aeabi_l2f
++
++#define __negdf2      __aeabi_dneg
++#define __subdf3      __aeabi_dsub
++#define __adddf3      __aeabi_dadd
++#define __floatunsidf __aeabi_ui2d
++#define __floatsidf   __aeabi_i2d
++#define __extendsfdf2 __aeabi_f2d
++#define __truncdfsf2  __aeabi_d2f
++#define __floatundidf __aeabi_ul2d
++#define __floatdidf   __aeabi_l2d
++#define __muldf3      __aeabi_dmul
++#define __divdf3      __aeabi_ddiv
++#define __unorddf2    __aeabi_dcmpun
++#define __fixdfsi     __aeabi_d2iz
++#define __fixunsdfsi  __aeabi_d2uiz
++#define __fixdfdi     __aeabi_d2lz
++#define __fixunsdfdi  __aeabi_d2ulz
++#define __floatdidf   __aeabi_l2d
++#define __extendhfsf2 __gnu_h2f_ieee
++#define __truncsfhf2  __gnu_f2h_ieee
++
++#endif /* __ARM_EABI__ */
+--- a/gcc/config/arm/symbian.h
++++ b/gcc/config/arm/symbian.h
+@@ -101,3 +101,5 @@
+ /* SymbianOS cannot merge entities with vague linkage at runtime.  */
+ #define TARGET_ARM_DYNAMIC_VAGUE_LINKAGE_P false
++
++#define TARGET_DEFAULT_WORD_RELOCATIONS 1
+--- a/gcc/config/arm/t-arm
++++ b/gcc/config/arm/t-arm
+@@ -13,7 +13,9 @@ MD_INCLUDES=         $(srcdir)/config/arm/arm-t
+               $(srcdir)/config/arm/iwmmxt.md \
+               $(srcdir)/config/arm/vfp.md \
+               $(srcdir)/config/arm/neon.md \
+-              $(srcdir)/config/arm/thumb2.md
++              $(srcdir)/config/arm/thumb2.md \
++              $(srcdir)/config/arm/marvell-f.md \
++              $(srcdir)/config/arm/hwdiv.md
+ s-config s-conditions s-flags s-codes s-constants s-emit s-recog s-preds \
+       s-opinit s-extract s-peep s-attr s-attrtab s-output: $(MD_INCLUDES)
+--- a/gcc/config/arm/t-arm-elf
++++ b/gcc/config/arm/t-arm-elf
+@@ -1,25 +1,68 @@
+ LIB1ASMSRC = arm/lib1funcs.asm
++# For most CPUs we have an assembly soft-float implementations.
++# However this is not true for ARMv6M.  Here we want to use the soft-fp C
++# implementation.  The soft-fp code is only build for ARMv6M.  This pulls
++# in the asm implementation for other CPUs.
+ LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func \
+       _call_via_rX _interwork_call_via_rX \
+       _lshrdi3 _ashrdi3 _ashldi3 \
+-      _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
+-      _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
+-      _fixsfsi _fixunssfsi _floatdidf _floatdisf _floatundidf _floatundisf
++      _arm_negdf2 _arm_addsubdf3 _arm_muldivdf3 _arm_cmpdf2 _arm_unorddf2 \
++      _arm_fixdfsi _arm_fixunsdfsi \
++      _arm_truncdfsf2 _arm_negsf2 _arm_addsubsf3 _arm_muldivsf3 \
++      _arm_cmpsf2 _arm_unordsf2 _arm_fixsfsi _arm_fixunssfsi \
++      _arm_floatdidf _arm_floatdisf _arm_floatundidf _arm_floatundisf
++
++# We build 4 multilibs:
++#  ./           (default)
++#  thumb/       -mthumb
++#  thumb2/      -mthumb -march=armv7
++#  armv6-m/     -mthumb -march=armv6-m
+-MULTILIB_OPTIONS     = marm/mthumb
+-MULTILIB_DIRNAMES    = arm thumb
++MULTILIB_OPTIONS     = mthumb
++MULTILIB_DIRNAMES    = thumb
+ MULTILIB_EXCEPTIONS  = 
+ MULTILIB_MATCHES     =
+-#MULTILIB_OPTIONS      += march=armv7
+-#MULTILIB_DIRNAMES     += thumb2
+-#MULTILIB_EXCEPTIONS   += march=armv7* marm/*march=armv7*
+-#MULTILIB_MATCHES      += march?armv7=march?armv7-a
+-#MULTILIB_MATCHES      += march?armv7=march?armv7-r
+-#MULTILIB_MATCHES      += march?armv7=march?armv7-m
+-#MULTILIB_MATCHES      += march?armv7=mcpu?cortex-a8
+-#MULTILIB_MATCHES      += march?armv7=mcpu?cortex-r4
+-#MULTILIB_MATCHES      += march?armv7=mcpu?cortex-m3
++MULTILIB_OPTIONS      += march=armv7/march=armv6-m
++MULTILIB_DIRNAMES     += v7 v6-m
++MULTILIB_EXCEPTIONS   += march=armv7*
++MULTILIB_MATCHES      += march?armv7=march?armv7-a
++MULTILIB_MATCHES      += march?armv7=march?armv7-r
++MULTILIB_MATCHES      += march?armv7=march?armv7-m
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-a9
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-a8
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-r4
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-r4f
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-m3
++
++MULTILIB_EXCEPTIONS   += march=armv6-m
++MULTILIB_MATCHES      += march?armv6-m=mcpu?cortex-m1
++MULTILIB_MATCHES      += march?armv6-m=mcpu?cortex-m0
++
++# FIXME: We need a sane way of doing this.
++# This isn't really a multilib, it's a hack to add an extra option
++# to the v7-m multilib.
++MULTILIB_OPTIONS      += mfix-cortex-m3-ldrd
++MULTILIB_DIRNAMES     += broken_ldrd
++
++MULTILIB_EXCEPTIONS   += mfix-cortex-m3-ldrd
++MULTILIB_EXCEPTIONS   += mthumb/mfix-cortex-m3-ldrd
++MULTILIB_EXCEPTIONS   += *march=armv6-m*mfix-cortex-m3-ldrd
++
++MULTILIB_ALIASES      += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7
++
++# As of at least 4.2, gcc passes the wrong -L options if some multilibs are
++# omitted from MULTILIB_OSDIRNAMES
++MULTILIB_OSDIRNAMES    = mthumb=!thumb
++MULTILIB_OSDIRNAMES   += mthumb/march.armv7/mfix-cortex-m3-ldrd=!thumb2
++MULTILIB_OSDIRNAMES   += mthumb/march.armv6-m=!armv6-m
++
++# Not quite true.  We can support hard-vfp calling in Thumb2, but how do we
++# express that here?  Also, we really need architecture v5e or later
++# (mcrr etc).
++# MULTILIB_OPTIONS       += mfloat-abi=hard
++# MULTILIB_DIRNAMES      += fpu
++# MULTILIB_EXCEPTIONS    += *mthumb/*mfloat-abi=hard*
+ # MULTILIB_OPTIONS    += mcpu=ep9312
+ # MULTILIB_DIRNAMES   += ep9312
+--- /dev/null
++++ b/gcc/config/arm/t-arm-softfp
+@@ -0,0 +1,11 @@
++softfp_float_modes := sf df
++softfp_int_modes := si di
++softfp_extensions := sfdf
++softfp_truncations := dfsf
++softfp_machine_header := arm/sfp-machine.h
++softfp_exclude_libgcc2 := y
++softfp_wrap_start := '\#ifdef __ARM_ARCH_6M__'
++softfp_wrap_end := '\#endif'
++
++# softfp seems to be missing a whole bunch of prototypes.
++TARGET_LIBGCC2_CFLAGS += -Wno-missing-prototypes
+--- /dev/null
++++ b/gcc/config/arm/t-asa
+@@ -0,0 +1,45 @@
++# Overrides for ASA
++
++# Here is the expected output from xgcc -print-multi-lib.
++#
++# .;@fno-omit-frame-pointer@mapcs-frame
++# armv4t;@march=armv4t@fno-omit-frame-pointer@mapcs-frame
++# armv6;@march=armv6@fno-omit-frame-pointer@mapcs-frame
++# armv7a;@march=armv7-a@fno-omit-frame-pointer@mapcs-frame
++# armv6f;@march=armv6@mfloat-abi=softfp@fno-omit-frame-pointer@mapcs-frame
++# armv7af;@march=armv7-a@mfpu=neon@mfloat-abi=softfp@fno-omit-frame-pointer@mapcs-frame
++# thumb2;@mthumb@march=armv7-a@fno-omit-frame-pointer@mapcs-frame
++# thumb2f;@mthumb@march=armv7-a@mfpu=neon@mfloat-abi=softfp@fno-omit-frame-pointer@mapcs-frame
++
++MULTILIB_OPTIONS = mthumb march=armv4t/march=armv6/march=armv7-a mfpu=neon mfloat-abi=softfp
++MULTILIB_DIRNAMES = thumb v4t v6 v7a neon softfp
++MULTILIB_MATCHES =
++
++MULTILIB_EXTRA_OPTS = fno-omit-frame-pointer mapcs-frame
++
++MULTILIB_EXCEPTIONS  = mthumb
++MULTILIB_EXCEPTIONS += mfpu=neon*
++MULTILIB_EXCEPTIONS += mfloat-abi=softfp
++MULTILIB_EXCEPTIONS += *march=armv4t*/*mfpu=neon*
++MULTILIB_EXCEPTIONS += *march=armv4t*/*mfloat-abi=softfp*
++MULTILIB_EXCEPTIONS += march=armv6/*mfpu=neon*
++MULTILIB_EXCEPTIONS += mthumb/mfpu=neon
++MULTILIB_EXCEPTIONS += mthumb/mfloat-abi=softfp
++MULTILIB_EXCEPTIONS += mthumb/mfpu=neon*
++MULTILIB_EXCEPTIONS += mthumb/march=armv6/mfpu=neon*
++
++MULTILIB_OSDIRNAMES  = march.armv4t=!armv4t
++MULTILIB_OSDIRNAMES += march.armv6=!armv6
++MULTILIB_OSDIRNAMES += march.armv6/mfloat-abi.softfp=!armv6f
++MULTILIB_OSDIRNAMES += march.armv7-a=!armv7a
++MULTILIB_OSDIRNAMES += march.armv7-a/mfpu.neon/mfloat-abi.softfp=!armv7af
++MULTILIB_OSDIRNAMES += mthumb/march.armv7-a=!thumb2
++MULTILIB_OSDIRNAMES += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.softfp=!thumb2f
++
++MULTILIB_ALIASES  = march?armv4t=mthumb/march?armv4t
++MULTILIB_ALIASES += march?armv6=mthumb/march?armv6
++MULTILIB_ALIASES += march?armv6/mfloat-abi?softfp=mthumb/march?armv6/mfloat-abi?softfp
++MULTILIB_ALIASES += march?armv7-a/mfpu?neon/mfloat-abi?softfp=march?armv7-a/mfpu?neon
++MULTILIB_ALIASES += march?armv7-a/mfpu?neon/mfloat-abi?softfp=march?armv7-a/mfloat-abi?softfp
++MULTILIB_ALIASES += mthumb/march?armv7-a/mfpu?neon/mfloat-abi?softfp=mthumb/march?armv7-a/mfpu?neon
++MULTILIB_ALIASES += mthumb/march?armv7-a/mfpu?neon/mfloat-abi?softfp=mthumb/march?armv7-a/mfloat-abi?softfp
+--- a/gcc/config/arm/t-bpabi
++++ b/gcc/config/arm/t-bpabi
+@@ -1,10 +1,13 @@
+ # Add the bpabi.S functions.
+-LIB1ASMFUNCS += _aeabi_lcmp _aeabi_ulcmp _aeabi_ldivmod _aeabi_uldivmod
++LIB1ASMFUNCS += _aeabi_lcmp _aeabi_ulcmp _aeabi_ldivmod _aeabi_uldivmod \
++              _aeabi_idiv0 _aeabi_ldiv0
+ # Add the BPABI C functions.
+ LIB2FUNCS_EXTRA = $(srcdir)/config/arm/bpabi.c \
+                 $(srcdir)/config/arm/unaligned-funcs.c
++LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/arm/fp16.c
++
+ UNWIND_H = $(srcdir)/config/arm/unwind-arm.h
+ LIB2ADDEH = $(srcdir)/config/arm/unwind-arm.c \
+   $(srcdir)/config/arm/libunwind.S \
+--- /dev/null
++++ b/gcc/config/arm/t-cs-eabi
+@@ -0,0 +1,193 @@
++# Multilibs for SourceryG++ arm-none-eabi
++
++MULTILIB_OPTIONS     = mthumb
++MULTILIB_DIRNAMES    = t
++MULTILIB_EXCEPTIONS  = 
++MULTILIB_MATCHES     =
++MULTILIB_ALIASES     =
++
++MULTILIB_OPTIONS      += march=armv7/march=armv7-a/march=armv5t/march=armv6-m
++MULTILIB_DIRNAMES     += v7 v7a v5t v6m
++MULTILIB_MATCHES      += march?armv7-a=march?armv7a
++MULTILIB_MATCHES      += march?armv7=march?armv7r
++MULTILIB_MATCHES      += march?armv7=march?armv7m
++MULTILIB_MATCHES      += march?armv7=march?armv7-r
++MULTILIB_MATCHES      += march?armv7=march?armv7-m
++MULTILIB_MATCHES      += march?armv7-a=mcpu?cortex-a9
++MULTILIB_MATCHES      += march?armv7-a=mcpu?cortex-a8
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-r4
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-r4f
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-m3
++MULTILIB_MATCHES      += march?armv6-m=mcpu?cortex-m1
++MULTILIB_MATCHES      += march?armv6-m=mcpu?cortex-m0
++MULTILIB_MATCHES      += march?armv5t=march?armv5te
++MULTILIB_MATCHES      += march?armv5t=march?armv6
++MULTILIB_MATCHES      += march?armv5t=march?armv6j
++MULTILIB_MATCHES      += march?armv5t=march?armv6k
++MULTILIB_MATCHES      += march?armv5t=march?armv6z
++MULTILIB_MATCHES      += march?armv5t=march?armv6zk
++MULTILIB_MATCHES      += march?armv5t=march?armv6t2
++MULTILIB_MATCHES      += march?armv5t=march?iwmmxt
++MULTILIB_MATCHES      += march?armv5t=march?iwmmxt2
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm10tdmi
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm1020t
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm9e
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm946e-s
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm966e-s
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm968e-s
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm10e
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm1020e
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm1022e
++MULTILIB_MATCHES      += march?armv5t=mcpu?xscale
++MULTILIB_MATCHES      += march?armv5t=mcpu?iwmmxt
++MULTILIB_MATCHES      += march?armv5t=mcpu?iwmmxt2
++MULTILIB_MATCHES      += march?armv5t=mcpu?marvell-f
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm926ej-s
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm1026ej-s
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm1136j-s
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm1136jf-s
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm1176jz-s
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm1176jzf-s
++MULTILIB_MATCHES      += march?armv5t=mcpu?mpcorenovfp
++MULTILIB_MATCHES      += march?armv5t=mcpu?mpcore
++MULTILIB_MATCHES      += march?armv5t=mcpu?arm1156t2-s
++
++MULTILIB_OPTIONS      += mfloat-abi=softfp/mfloat-abi=hard
++MULTILIB_DIRNAMES     += softfp hard
++MULTILIB_MATCHES      += mfloat-abi?hard=mhard-float
++
++MULTILIB_OPTIONS      += mfpu=neon
++MULTILIB_DIRNAMES     += neon
++MULTILIB_EXCEPTIONS   += mfpu=neon
++MULTILIB_MATCHES      += mfpu?neon=mfpu?neon-fp16
++
++MULTILIB_ALIASES      += mthumb=mthumb/mfpu?neon
++MULTILIB_ALIASES      += mthumb=mthumb/march?armv5t/mfpu?neon
++MULTILIB_ALIASES      += mbig-endian=mthumb/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mfloat-abi?softfp=mthumb/mfloat-abi?softfp/mfpu?neon
++MULTILIB_ALIASES      += mfloat-abi?softfp=mfloat-abi?softfp/mfpu?neon
++MULTILIB_ALIASES      += mfloat-abi?softfp/mbig-endian=mfloat-abi?softfp/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mfloat-abi?softfp/mbig-endian=mthumb/mfloat-abi?softfp/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7-a/mfpu?neon
++MULTILIB_ALIASES      += mthumb/march?armv7/mbig-endian=mthumb/march?armv7-a/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += march?armv7-a/mfloat-abi?softfp/mfpu?neon=mthumb/march?armv7-a/mfloat-abi?softfp/mfpu?neon
++MULTILIB_ALIASES      += march?armv7-a/mfloat-abi?hard/mfpu?neon=mthumb/march?armv7-a/mfloat-abi?hard/mfpu?neon
++
++MULTILIB_OPTIONS      += mbig-endian
++MULTILIB_DIRNAMES     += be
++MULTILIB_ALIASES      += mbig-endian=mfpu?neon/mbig-endian
++
++# ARMv6-M  does not have ARM mode.
++MULTILIB_EXCEPTIONS   += march=armv6-m
++
++# Some ARMv7 variants have ARM mode.  Use the ARM libraries.
++MULTILIB_EXCEPTIONS   += march=armv7 march=armv7/*
++MULTILIB_ALIASES      += mbig-endian=march?armv7/mbig-endian
++MULTILIB_ALIASES      += mfloat-abi?softfp=march?armv7/mfloat-abi?softfp
++MULTILIB_ALIASES      += mfloat-abi?softfp=march?armv7/mfloat-abi?softfp/mfpu?neon
++MULTILIB_ALIASES      += mfloat-abi?softfp/mbig-endian=march?armv7/mfloat-abi?softfp/mbig-endian
++MULTILIB_ALIASES      += mfloat-abi?softfp/mbig-endian=march?armv7/mfloat-abi?softfp/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mbig-endian=march?armv7/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7/mfloat-abi?softfp/mfpu?neon
++MULTILIB_ALIASES      += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7/mfpu?neon
++MULTILIB_ALIASES      += mthumb/march?armv7/mbig-endian=mthumb/march?armv7/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mthumb/march?armv7/mbig-endian=mthumb/march?armv7/mfloat-abi?softfp/mfpu?neon/mbig-endian
++
++# ARMv7-A is specially useful used with VFPv3 (enabled by NEON). Rest of the cases behaves as ARMv7.
++MULTILIB_ALIASES      += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7-a
++MULTILIB_ALIASES      += mbig-endian=march?armv7-a/mbig-endian
++MULTILIB_ALIASES      += mfloat-abi?softfp/mbig-endian=march?armv7-a/mfloat-abi?softfp/mbig-endian
++MULTILIB_ALIASES      += mfloat-abi?softfp/mbig-endian=march?armv7-a/mfloat-abi?softfp/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7-a/mfloat-abi?softfp
++MULTILIB_ALIASES      += mthumb/march?armv7/mbig-endian=mthumb/march?armv7-a/mbig-endian
++MULTILIB_ALIASES      += mthumb/march?armv7/mbig-endian=mthumb/march?armv7-a/mfloat-abi?softfp/mbig-endian
++MULTILIB_ALIASES      += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7/mfloat-abi?softfp             
++MULTILIB_ALIASES      += march?armv5t=march?armv7-a
++MULTILIB_ALIASES      += march?armv5t=march?armv7-a/mfloat-abi?softfp
++MULTILIB_ALIASES      += march?armv5t=march?armv7-a/mfpu?neon
++MULTILIB_ALIASES      += mbig-endian=march?armv7-a/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mthumb/march?armv7/mbig-endian=mthumb/march?armv7-a/mfloat-abi?softfp/mfpu?neon/mbig-endian
++
++# ARMv5T thumb uses the ARMv5T ARM libraries (with or without VFP).
++MULTILIB_ALIASES      += mthumb=mthumb/march?armv5t
++MULTILIB_ALIASES      += march?armv5t/mfloat-abi?softfp=mthumb/march?armv5t/mfloat-abi?softfp
++MULTILIB_ALIASES      += march?armv5t/mfloat-abi?softfp=march?armv5t/mfloat-abi?softfp/mfpu?neon
++MULTILIB_ALIASES      += march?armv5t/mfloat-abi?softfp=mthumb/march?armv5t/mfloat-abi?softfp/mfpu?neon
++MULTILIB_ALIASES      += march?armv5t=march?armv5t/mfpu?neon
++MULTILIB_ALIASES      += mbig-endian=march?armv5t/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mbig-endian=march?armv5t/mfloat-abi?softfp/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mbig-endian=mthumb/march?armv5t/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mbig-endian=mthumb/march?armv5t/mfloat-abi?softfp/mfpu?neon/mbig-endian
++
++# ARMv6-M and VFP are incompatible.
++# FIXME:  The compiler should probably error.
++MULTILIB_EXCEPTIONS   += *march=armv6-m/mfloat-abi=softfp
++MULTILIB_ALIASES      += mthumb/march?armv6-m=mthumb/march?armv6-m/mfpu?neon
++MULTILIB_EXCEPTIONS   += march=armv6-m*mfpu=neon
++MULTILIB_EXCEPTIONS   += mthumb/march=armv6-m/mfloat-abi=softfp/mfpu=neon
++
++# Thumb-1 VFP isn't really a meaningful combination.  Use the ARM VFP.
++MULTILIB_ALIASES      += mfloat-abi?softfp=mthumb/mfloat-abi?softfp
++MULTILIB_ALIASES      += mfloat-abi?softfp/mbig-endian=mthumb/mfloat-abi?softfp/mbig-endian
++
++# We don't have a big-endian ARMv6-M compatible multilibs.
++MULTILIB_EXCEPTIONS   += *march=armv6-m*mbig-endian
++
++# Use the generic libraries for big-endian ARMv5T
++MULTILIB_ALIASES      += mbig-endian=march?armv5t/mbig-endian
++MULTILIB_ALIASES      += mbig-endian=march?armv5t/mfloat-abi?softfp/mbig-endian
++MULTILIB_ALIASES      += mbig-endian=mthumb/march?armv5t/mbig-endian
++MULTILIB_ALIASES      += mbig-endian=mthumb/march?armv5t/mfloat-abi?softfp/mbig-endian
++
++# Use ARM libraries for big-endian Thumb.
++MULTILIB_ALIASES      += mbig-endian=mthumb/mbig-endian
++
++# Don't bother with big-endian Thumb-2 VFP.  Use the soft-float libraries
++# for now.
++MULTILIB_ALIASES      += mthumb/march?armv7/mbig-endian=mthumb/march?armv7/mfloat-abi?softfp/mbig-endian
++
++# The only -mfloat-abi=hard libraries provided are for little-endian
++# v7-A NEON.
++MULTILIB_EXCEPTIONS   += mfloat-abi=hard*
++MULTILIB_EXCEPTIONS   += *march=armv5t*mfloat-abi=hard*
++MULTILIB_EXCEPTIONS   += *march=armv7/*mfloat-abi=hard*
++MULTILIB_EXCEPTIONS   += *march=armv6-m*mfloat-abi=hard*
++MULTILIB_EXCEPTIONS   += mthumb/mfloat-abi=hard*
++MULTILIB_EXCEPTIONS   += *mfloat-abi=hard*mbig-endian
++MULTILIB_EXCEPTIONS   += *mfloat-abi=hard
++
++# FIXME: We need a sane way of doing this.
++# This isn't really a multilib, it's a hack to add an extra option
++# to the v7-m multilib.
++MULTILIB_OPTIONS      += mfix-cortex-m3-ldrd
++MULTILIB_DIRNAMES     += broken_ldrd
++
++MULTILIB_EXCEPTIONS   += mfix-cortex-m3-ldrd
++MULTILIB_EXCEPTIONS   += mthumb/mfix-cortex-m3-ldrd
++MULTILIB_EXCEPTIONS   += *march=armv6-m*mfix-cortex-m3-ldrd
++MULTILIB_EXCEPTIONS   += *march=armv7-a*mfix-cortex-m3-ldrd
++MULTILIB_EXCEPTIONS   += *mcpu=*mfix-cortex-m3-ldrd
++MULTILIB_EXCEPTIONS   += *mbig-endian*mfix-cortex-m3-ldrd
++MULTILIB_EXCEPTIONS   += *mfloat-abi=softfp*mfix-cortex-m3-ldrd
++MULTILIB_EXCEPTIONS   += mfloat-abi=softfp*mfpu=neon*
++MULTILIB_EXCEPTIONS   += *march=armv5t*mfix-cortex-m3-ldrd
++MULTILIB_EXCEPTIONS   += *mfpu=neon*mfix-cortex-m3-ldrd
++
++MULTILIB_ALIASES      += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7
++MULTILIB_ALIASES      += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7-a/mfix-cortex-m3-ldrd
++MULTILIB_ALIASES      += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7/mfpu?neon/mfix-cortex-m3-ldrd
++MULTILIB_ALIASES      += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7-a/mfpu?neon/mfix-cortex-m3-ldrd
++
++# As of at least 4.2, gcc passes the wrong -L options if some multilibs are
++# omitted from MULTILIB_OSDIRNAMES
++MULTILIB_OSDIRNAMES    = mthumb=!thumb
++MULTILIB_OSDIRNAMES   += mbig-endian=!be
++MULTILIB_OSDIRNAMES   += mfloat-abi.softfp=!vfp
++MULTILIB_OSDIRNAMES   += mfloat-abi.softfp/mbig-endian=!vfp-be
++MULTILIB_OSDIRNAMES   += march.armv5t=!armv5t
++MULTILIB_OSDIRNAMES   += march.armv5t/mfloat-abi.softfp=!armv5t-vfp
++MULTILIB_OSDIRNAMES   += mthumb/march.armv7/mfix-cortex-m3-ldrd=!thumb2
++MULTILIB_OSDIRNAMES   += march.armv7-a/mfloat-abi.softfp/mfpu.neon=!armv7-a-neon
++MULTILIB_OSDIRNAMES   += march.armv7-a/mfloat-abi.hard/mfpu.neon=!armv7-a-hard
++MULTILIB_OSDIRNAMES   += mthumb/march.armv7/mbig-endian=!thumb2-be
++MULTILIB_OSDIRNAMES   += mthumb/march.armv6-m=!armv6-m
+--- /dev/null
++++ b/gcc/config/arm/t-cs-linux
+@@ -0,0 +1,106 @@
++# Multilibs for SourceryG++ arm-none-linux-gnueabi
++
++MULTILIB_OPTIONS     = mthumb
++MULTILIB_DIRNAMES    = t
++MULTILIB_EXCEPTIONS  = 
++MULTILIB_MATCHES     =
++MULTILIB_ALIASES     =
++
++MULTILIB_OPTIONS      += march=armv4t/march=armv7-a
++MULTILIB_DIRNAMES     += v4t v7a
++
++MULTILIB_MATCHES      += march?armv7-a=march?armv7a
++MULTILIB_MATCHES      += march?armv7-a=mcpu?cortex-a9
++MULTILIB_MATCHES      += march?armv7-a=mcpu?cortex-a8
++MULTILIB_MATCHES      += march?armv4t=march?ep9312
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm7tdmi
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm7tdmi-s
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm710t
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm720t
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm740t
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm9
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm9tdmi
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm920
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm920t
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm922t
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm940t
++MULTILIB_MATCHES      += march?armv4t=mcpu?ep9312
++
++MULTILIB_OPTIONS      += mfloat-abi=softfp/mfloat-abi=hard
++MULTILIB_DIRNAMES     += softfp hard
++MULTILIB_MATCHES      += mfloat-abi?hard=mhard-float
++
++MULTILIB_OPTIONS      += mfpu=neon
++MULTILIB_DIRNAMES     += neon
++MULTILIB_EXCEPTIONS   += mfpu=neon
++MULTILIB_MATCHES      += mfpu?neon=mfpu?neon-fp16
++MULTILIB_ALIASES      += mfloat-abi?softfp=mfloat-abi?softfp/mfpu?neon
++MULTILIB_ALIASES      += mfloat-abi?softfp=mthumb/mfloat-abi?softfp/mfpu?neon
++MULTILIB_ALIASES      += march?armv7-a/mfloat-abi?hard/mfpu?neon=mthumb/march?armv7-a/mfloat-abi?hard/mfpu?neon
++
++MULTILIB_OPTIONS      += mbig-endian
++MULTILIB_DIRNAMES     += be
++MULTILIB_ALIASES      += mbig-endian=mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mfloat-abi?softfp/mbig-endian=mfloat-abi?softfp/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mbig-endian=mthumb/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mfloat-abi?softfp/mbig-endian=mthumb/mfloat-abi?softfp/mfpu?neon/mbig-endian
++
++# Do not build Thumb libraries.
++MULTILIB_EXCEPTIONS   += mthumb
++MULTILIB_EXCEPTIONS   += mthumb/mfpu=neon
++
++# Use ARM libraries for ARMv4t Thumb and VFP.
++MULTILIB_ALIASES      += march?armv4t=mthumb/march?armv4t
++MULTILIB_ALIASES      += march?armv4t=march?armv4t/mfloat-abi?softfp
++MULTILIB_ALIASES      += march?armv4t=mthumb/march?armv4t/mfloat-abi?softfp
++MULTILIB_ALIASES      += march?armv4t=march?armv4t/mfpu?neon
++MULTILIB_ALIASES      += march?armv4t=march?armv4t/mfloat-abi?softfp/mfpu?neon
++MULTILIB_ALIASES      += march?armv4t=mthumb/march?armv4t/mfpu?neon
++MULTILIB_ALIASES      += march?armv4t=mthumb/march?armv4t/mfloat-abi?softfp/mfpu?neon
++
++# We do not support ARMv4t big-endian.
++MULTILIB_EXCEPTIONS   += *march=armv4t*mbig-endian
++
++# Behave ARMv7-A as ARMv7 for some cases.
++MULTILIB_EXCEPTIONS   += march=armv7-a
++MULTILIB_EXCEPTIONS   += march=armv7-a/mfpu=neon
++MULTILIB_ALIASES      += mfloat-abi?softfp=march?armv7-a/mfloat-abi?softfp
++MULTILIB_ALIASES      += mbig-endian=march?armv7-a/mbig-endian
++MULTILIB_ALIASES      += mbig-endian=march?armv7-a/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mfloat-abi?softfp/mbig-endian=march?armv7-a/mfloat-abi?softfp/mbig-endian
++MULTILIB_ALIASES      += mfloat-abi?softfp/mbig-endian=march?armv7-a/mfloat-abi?softfp/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mthumb/march?armv7-a=mthumb/march?armv7-a/mfpu?neon
++MULTILIB_ALIASES      += mthumb/march?armv7-a/mbig-endian=mthumb/march?armv7-a/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += mthumb/march?armv7-a/mbig-endian=mthumb/march?armv7-a/mfloat-abi?softfp/mfpu?neon/mbig-endian
++MULTILIB_ALIASES      += march?armv7-a/mfloat-abi?softfp/mfpu?neon=mthumb/march?armv7-a/mfloat-abi?softfp/mfpu?neon
++MULTILIB_ALIASES      += mthumb/march?armv7-a=mthumb/march?armv7-a/mfloat-abi?softfp
++
++# Thumb-1 VFP isn't really a meaningful combination.  Use the ARM VFP.
++MULTILIB_ALIASES      += mfloat-abi?softfp=mthumb/mfloat-abi?softfp
++MULTILIB_ALIASES      += mfloat-abi?softfp/mbig-endian=mthumb/mfloat-abi?softfp/mbig-endian
++
++# Use ARM libraries for big-endian Thumb.
++MULTILIB_ALIASES      += mbig-endian=mthumb/mbig-endian
++
++# Don't bother with big-endian Thumb-2 VFP.  Use the soft-float libraries
++# for now.
++MULTILIB_ALIASES      += mthumb/march?armv7-a/mbig-endian=mthumb/march?armv7-a/mfloat-abi?softfp/mbig-endian
++
++# The only -mfloat-abi=hard libraries provided are for little-endian
++# v7-A NEON.
++MULTILIB_EXCEPTIONS   += mfloat-abi=hard*
++MULTILIB_EXCEPTIONS   += *march=armv4t*mfloat-abi=hard*
++MULTILIB_EXCEPTIONS   += mthumb/mfloat-abi=hard*
++MULTILIB_EXCEPTIONS   += *mfloat-abi=hard*mbig-endian
++MULTILIB_EXCEPTIONS   += *mfloat-abi=hard
++
++# As of at least 4.2, gcc passes the wrong -L options if some multilibs are
++# omitted from MULTILIB_OSDIRNAMES
++MULTILIB_OSDIRNAMES    = march.armv4t=!armv4t
++MULTILIB_OSDIRNAMES   += mbig-endian=!be
++MULTILIB_OSDIRNAMES   += mfloat-abi.softfp=!vfp
++MULTILIB_OSDIRNAMES   += mfloat-abi.softfp/mbig-endian=!vfp-be
++MULTILIB_OSDIRNAMES   += mthumb/march.armv7-a=!thumb2
++MULTILIB_OSDIRNAMES   += march.armv7-a/mfloat-abi.softfp/mfpu.neon=!armv7-a-neon
++MULTILIB_OSDIRNAMES   += march.armv7-a/mfloat-abi.hard/mfpu.neon=!armv7-a-hard
++MULTILIB_OSDIRNAMES   += mthumb/march.armv7-a/mbig-endian=!thumb2-be
+--- a/gcc/config/arm/t-linux-eabi
++++ b/gcc/config/arm/t-linux-eabi
+@@ -1,10 +1,48 @@
+ # These functions are included in shared libraries.
+ TARGET_LIBGCC2_CFLAGS = -fPIC
+-# We do not build a Thumb multilib for Linux because the definition of
+-# CLEAR_INSN_CACHE in linux-gas.h does not work in Thumb mode.
+-MULTILIB_OPTIONS      =
+-MULTILIB_DIRNAMES     =
++# We build 3 multilibs:
++#  ./           (default)
++#  armv4t/      -march=armv4t [-mthumb]
++#  thumb2/      -mthumb -march=armv7
++MULTILIB_OPTIONS     = mthumb
++MULTILIB_DIRNAMES    = thumb
++MULTILIB_OPTIONS    += march=armv4t/march=armv7
++MULTILIB_DIRNAMES   += v4t v7
++MULTILIB_EXCEPTIONS += march=armv7
++MULTILIB_EXCEPTIONS += mthumb
++
++MULTILIB_ALIASES     = march?armv4t=mthumb/march?armv4t
++
++# As of at least 4.2, gcc passes the wrong -L options if some multilibs are
++# omitted from MULTILIB_OSDIRNAMES
++MULTILIB_OSDIRNAMES    = march.armv4t=!armv4t
++MULTILIB_OSDIRNAMES   += mthumb/march.armv7=!thumb2
++
++MULTILIB_MATCHES      += march?armv7=march?armv7a
++MULTILIB_MATCHES      += march?armv7=march?armv7r
++MULTILIB_MATCHES      += march?armv7=march?armv7m
++MULTILIB_MATCHES      += march?armv7=march?armv7-a
++MULTILIB_MATCHES      += march?armv7=march?armv7-r
++MULTILIB_MATCHES      += march?armv7=march?armv7-m
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-a9
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-a8
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-r4
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-r4f
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-m3
++MULTILIB_MATCHES      += march?armv4t=march?ep9312
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm7tdmi
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm7tdmi-s
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm710t
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm720t
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm740t
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm9
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm9tdmi
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm920
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm920t
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm922t
++MULTILIB_MATCHES      += march?armv4t=mcpu?arm940t
++MULTILIB_MATCHES      += march?armv4t=mcpu?ep9312
+ # Use a version of div0 which raises SIGFPE.
+ LIB1ASMFUNCS := $(filter-out _dvmd_tls,$(LIB1ASMFUNCS)) _dvmd_lnx
+@@ -12,3 +50,5 @@ LIB1ASMFUNCS := $(filter-out _dvmd_tls,$
+ # Multilib the standard Linux files.  Don't include crti.o or crtn.o,
+ # which are provided by glibc.
+ EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
++
++LIB2FUNCS_STATIC_EXTRA += $(srcdir)/config/arm/linux-atomic.c
+--- /dev/null
++++ b/gcc/config/arm/t-montavista-linux
+@@ -0,0 +1,33 @@
++# MontaVista GNU/Linux Configuration.
++# Copyright (C) 2009
++# Free Software Foundation, Inc.
++#
++# This file is part of GCC.
++#
++# GCC is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3, or (at your option)
++# any later version.
++# 
++# GCC is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with GCC; see the file COPYING3.  If not see
++# <http://www.gnu.org/licenses/>.
++
++MULTILIB_OPTIONS = tarmv6/tthumb2
++MULTILIB_DIRNAMES = armv6 thumb2
++
++MULTILIB_EXCEPTIONS =
++
++MULTILIB_OSDIRNAMES =
++
++MULTILIB_ALIASES =
++
++MULTILIB_MATCHES =
++
++# These files must be built for each multilib.
++EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
+--- a/gcc/config/arm/t-symbian
++++ b/gcc/config/arm/t-symbian
+@@ -17,12 +17,18 @@ UNWIND_H = $(srcdir)/config/arm/unwind-a
+ LIB2ADDEH = $(srcdir)/unwind-c.c $(srcdir)/config/arm/pr-support.c
+ LIB2ADDEHDEP = $(UNWIND_H)
++# Include half-float helpers.
++LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/arm/fp16.c
++
+ # Create a multilib for processors with VFP floating-point, and a
+ # multilib for those without -- using the soft-float ABI in both
+ # cases.  Symbian OS object should be compiled with interworking
+ # enabled, so there are no separate thumb-mode libraries.
+ MULTILIB_OPTIONS     = mfloat-abi=softfp
+ MULTILIB_DIRNAMES    = softfp
++MULTILIB_EXCEPTIONS  = 
++MULTILIB_MATCHES     =
++MULTILIB_ALIASES     =
+ # There is no C library to link against on Symbian OS -- at least when 
+ # building GCC.
+--- /dev/null
++++ b/gcc/config/arm/t-timesys
+@@ -0,0 +1,10 @@
++# Overrides for timesys
++
++MULTILIB_OPTIONS = march=armv5t/march=armv6/mcpu=xscale mbig-endian
++MULTILIB_DIRNAMES = armv5t armv6 xscale be
++MULTILIB_MATCHES = mbig-endian=mbe
++MULTILIB_EXCEPTIONS = mbig-endian march=*/mbig-endian mcpu=xscale
++MULTILIB_OSDIRNAMES  = march.armv5t=!armv5t
++MULTILIB_OSDIRNAMES += march.armv6=!armv6
++MULTILIB_OSDIRNAMES += mcpu.xscale/mbig-endian=!xscale/be
++MULTILIB_ALIASES =
+--- /dev/null
++++ b/gcc/config/arm/t-uclinux-eabi
+@@ -0,0 +1,53 @@
++# EABI uClinux multilib selection.  Other setting are inherited from t-arm-elf
++
++# We build 3 multilibs:
++#  .      (default)
++#  thumb2/  -mthumb -march=armv7 -mfix-cortex-m3-ldrd
++#  armv6-m/ -mthumb -march=armv6-m
++
++MULTILIB_OPTIONS     = mthumb
++MULTILIB_DIRNAMES    = thumb
++MULTILIB_EXCEPTIONS  = 
++MULTILIB_MATCHES     =
++
++MULTILIB_OPTIONS      += march=armv7/march=armv6-m
++MULTILIB_DIRNAMES     += armv7 armv6-m
++
++MULTILIB_EXCEPTIONS   += mthumb
++
++MULTILIB_EXCEPTIONS   += march=armv7
++MULTILIB_MATCHES      += march?armv7=march?armv7a
++MULTILIB_MATCHES      += march?armv7=march?armv7r
++MULTILIB_MATCHES      += march?armv7=march?armv7m
++MULTILIB_MATCHES      += march?armv7=march?armv7-a
++MULTILIB_MATCHES      += march?armv7=march?armv7-r
++MULTILIB_MATCHES      += march?armv7=march?armv7-m
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-a9
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-a8
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-r4
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-r4f
++MULTILIB_MATCHES      += march?armv7=mcpu?cortex-m3
++
++MULTILIB_EXCEPTIONS   += march=armv6-m
++MULTILIB_MATCHES      += march?armv6-m=mcpu?cortex-m1
++MULTILIB_MATCHES      += march?armv6-m=mcpu?cortex-m0
++
++MULTILIB_ALIASES       =
++
++# FIXME: We need a sane way of doing this.
++# This isn't really a multilib, it's a hack to add an extra option
++# to the v7-m multilib.
++MULTILIB_OPTIONS      += mfix-cortex-m3-ldrd
++MULTILIB_DIRNAMES     += broken_ldrd
++
++MULTILIB_EXCEPTIONS   += mfix-cortex-m3-ldrd
++MULTILIB_EXCEPTIONS   += mthumb/mfix-cortex-m3-ldrd
++MULTILIB_EXCEPTIONS   += march=armv7/mfix-cortex-m3-ldrd
++MULTILIB_EXCEPTIONS   += *march=armv6-m*mfix-cortex-m3-ldrd
++
++MULTILIB_ALIASES      += mthumb/march?armv7/mfix-cortex-m3-ldrd=mthumb/march?armv7
++
++
++MULTILIB_OSDIRNAMES    = mthumb/march.armv7/mfix-cortex-m3-ldrd=!thumb2
++MULTILIB_OSDIRNAMES   += mthumb/march.armv6-m=!armv6-m
++
+--- /dev/null
++++ b/gcc/config/arm/t-wrs-linux
+@@ -0,0 +1,43 @@
++# Wind River GNU/Linux Configuration.
++# Copyright (C) 2006, 2007, 2008
++# Free Software Foundation, Inc.
++#
++# This file is part of GCC.
++#
++# GCC is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3, or (at your option)
++# any later version.
++# 
++# GCC is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with GCC; see the file COPYING3.  If not see
++# <http://www.gnu.org/licenses/>.
++
++MULTILIB_OPTIONS = muclibc
++MULTILIB_OPTIONS += tarm926ej-s/tiwmmxt/txscale/tarm920t/tthumb2/tcortex-a8-be8
++MULTILIB_OPTIONS += mfloat-abi=softfp
++MULTILIB_DIRNAMES = uclibc
++MULTILIB_DIRNAMES += tarm926ej-s tiwmmxt txscale tarm920t thumb2 cortex-a8-be8
++MULTILIB_DIRNAMES += softfp
++
++MULTILIB_EXCEPTIONS = *muclibc*/*tarm920t*
++MULTILIB_EXCEPTIONS += *muclibc*/*cortex-a8-be8*
++
++MULTILIB_EXCEPTIONS += *tiwmmxt*/*mfloat-abi=softfp*
++MULTILIB_EXCEPTIONS += *txscale*/*mfloat-abi=softfp*
++MULTILIB_EXCEPTIONS += *tarm920t*/*mfloat-abi=softfp*
++MULTILIB_EXCEPTIONS += *thumb2*/*mfloat-abi=softfp*
++
++MULTILIB_MATCHES = tiwmmxt=tiwmmxt2
++
++MULTILIB_ALIASES = tcortex-a8-be8=tcortex-a8-be8/mfloat-abi?softfp
++MULTILIB_OSDIRNAMES =
++
++# These files must be built for each multilib.
++EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
++
+--- a/gcc/config/arm/thumb2.md
++++ b/gcc/config/arm/thumb2.md
+@@ -1,5 +1,5 @@
+ ;; ARM Thumb-2 Machine Description
+-;; Copyright (C) 2007 Free Software Foundation, Inc.
++;; Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ ;; Written by CodeSourcery, LLC.
+ ;;
+ ;; This file is part of GCC.
+@@ -24,6 +24,8 @@
+ ;; changes made in armv5t as "thumb2".  These are considered part
+ ;; the 16-bit Thumb-1 instruction set.
++(include "hwdiv.md")
++
+ (define_insn "*thumb2_incscc"
+   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
+         (plus:SI (match_operator:SI 2 "arm_comparison_operator"
+@@ -172,34 +174,6 @@
+    (set_attr "length" "8")]
+ )
+-(define_insn "*thumb2_abssi2"
+-  [(set (match_operand:SI         0 "s_register_operand" "=r,&r")
+-      (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
+-   (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_THUMB2"
+-  "@
+-   cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0
+-   eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
+-  [(set_attr "conds" "clob,*")
+-   (set_attr "shift" "1")
+-   ;; predicable can't be set based on the variant, so left as no
+-   (set_attr "length" "10,8")]
+-)
+-
+-(define_insn "*thumb2_neg_abssi2"
+-  [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
+-      (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
+-   (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_THUMB2"
+-  "@
+-   cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0
+-   eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
+-  [(set_attr "conds" "clob,*")
+-   (set_attr "shift" "1")
+-   ;; predicable can't be set based on the variant, so left as no
+-   (set_attr "length" "10,8")]
+-)
+-
+ (define_insn "*thumb2_movdi"
+   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
+       (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,r"))]
+@@ -223,23 +197,31 @@
+    (set_attr "neg_pool_range" "*,*,*,0,*")]
+ )
++;; We have two alternatives here for memory loads (and similarly for stores)
++;; to reflect the fact that the permissible constant pool ranges differ
++;; between ldr instructions taking low regs and ldr instructions taking high
++;; regs.  The high register alternatives are not taken into account when
++;; choosing register preferences in order to reflect their expense.
+ (define_insn "*thumb2_movsi_insn"
+-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r, m")
+-      (match_operand:SI 1 "general_operand"      "rI,K,N,mi,r"))]
++  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,l,*hk,m,*m")
++        (match_operand:SI 1 "general_operand"      "rk ,I,K,j,mi,*mi,l,*hk"))]
+   "TARGET_THUMB2 && ! TARGET_IWMMXT
+    && !(TARGET_HARD_FLOAT && TARGET_VFP)
+    && (   register_operand (operands[0], SImode)
+        || register_operand (operands[1], SImode))"
+   "@
+    mov%?\\t%0, %1
++   mov%?\\t%0, %1
+    mvn%?\\t%0, #%B1
+    movw%?\\t%0, %1
+    ldr%?\\t%0, %1
++   ldr%?\\t%0, %1
++   str%?\\t%1, %0
+    str%?\\t%1, %0"
+-  [(set_attr "type" "*,*,*,load1,store1")
++  [(set_attr "type" "*,*,*,*,load1,load1,store1,store1")
+    (set_attr "predicable" "yes")
+-   (set_attr "pool_range" "*,*,*,4096,*")
+-   (set_attr "neg_pool_range" "*,*,*,0,*")]
++   (set_attr "pool_range" "*,*,*,*,1020,4096,*,*")
++   (set_attr "neg_pool_range" "*,*,*,*,0,0,*,*")]
+ )
+ ;; ??? We can probably do better with thumb2
+@@ -754,15 +736,12 @@
+    (clobber (reg:CC CC_REGNUM))]
+   "TARGET_THUMB2"
+   "*
+-  if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
++  if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
+     return \"asr\\t%0, %1, #31\";
+   if (GET_CODE (operands[3]) == NE)
+     return \"subs\\t%0, %1, %2\;it\\tne\;mvnne\\t%0, #0\";
+-  if (GET_CODE (operands[3]) == GT)
+-    return \"subs\\t%0, %1, %2\;it\\tne\;mvnne\\t%0, %0, asr #31\";
+-
+   output_asm_insn (\"cmp\\t%1, %2\", operands);
+   output_asm_insn (\"ite\\t%D3\", operands);
+   output_asm_insn (\"mov%D3\\t%0, #0\", operands);
+@@ -951,7 +930,7 @@
+                                (label_ref (match_operand 2 "" ""))))
+               (label_ref (match_operand 3 "" ""))))
+             (clobber (reg:CC CC_REGNUM))
+-            (clobber (match_scratch:SI 4 "=r"))
++            (clobber (match_scratch:SI 4 "=&r"))
+             (use (label_ref (match_dup 2)))])]
+   "TARGET_THUMB2 && !flag_pic"
+   "* return thumb2_output_casesi(operands);"
+@@ -968,7 +947,7 @@
+                                (label_ref (match_operand 2 "" ""))))
+               (label_ref (match_operand 3 "" ""))))
+             (clobber (reg:CC CC_REGNUM))
+-            (clobber (match_scratch:SI 4 "=r"))
++            (clobber (match_scratch:SI 4 "=&r"))
+             (clobber (match_scratch:SI 5 "=r"))
+             (use (label_ref (match_dup 2)))])]
+   "TARGET_THUMB2 && flag_pic"
+@@ -1001,7 +980,10 @@
+         (match_operator:SI 3 "thumb_16bit_operator"
+        [(match_operand:SI 1  "low_register_operand" "")
+         (match_operand:SI 2 "low_register_operand" "")]))]
+-  "TARGET_THUMB2 && rtx_equal_p(operands[0], operands[1])
++  "TARGET_THUMB2
++   && (rtx_equal_p(operands[0], operands[1])
++       || GET_CODE(operands[3]) == PLUS
++       || GET_CODE(operands[3]) == MINUS)
+    && peep2_regno_dead_p(0, CC_REGNUM)"
+   [(parallel
+     [(set (match_dup 0)
+@@ -1018,7 +1000,9 @@
+        [(match_operand:SI 1 "s_register_operand" "0")
+         (match_operand:SI 2 "s_register_operand" "l")]))
+    (clobber (reg:CC CC_REGNUM))]
+-  "TARGET_THUMB2 && reload_completed"
++  "TARGET_THUMB2 && reload_completed
++   && GET_CODE(operands[3]) != PLUS
++   && GET_CODE(operands[3]) != MINUS"
+   "%I3%!\\t%0, %1, %2"
+   [(set_attr "predicable" "yes")
+    (set_attr "length" "2")]
+@@ -1104,16 +1088,20 @@
+   ""
+ )
+-(define_insn "*thumb2_addsi_shortim"
++(define_insn "*thumb2_addsi_short"
+   [(set (match_operand:SI 0 "low_register_operand" "=l")
+       (plus:SI (match_operand:SI 1 "low_register_operand" "l")
+-               (match_operand:SI 2 "const_int_operand" "IL")))
++               (match_operand:SI 2 "low_reg_or_int_operand" "lIL")))
+    (clobber (reg:CC CC_REGNUM))]
+   "TARGET_THUMB2 && reload_completed"
+   "*
+     HOST_WIDE_INT val;
+-    val = INTVAL(operands[2]);
++    if (GET_CODE (operands[2]) == CONST_INT)
++      val = INTVAL(operands[2]);
++    else
++      val = 0;
++
+     /* We prefer eg. subs rn, rn, #1 over adds rn, rn, #0xffffffff.  */
+     if (val < 0 && const_ok_for_arm(ARM_SIGN_EXTEND (-val)))
+       return \"sub%!\\t%0, %1, #%n2\";
+@@ -1124,24 +1112,82 @@
+    (set_attr "length" "2")]
+ )
+-(define_insn "divsi3"
+-  [(set (match_operand:SI       0 "s_register_operand" "=r")
+-      (div:SI (match_operand:SI 1 "s_register_operand"  "r")
+-              (match_operand:SI 2 "s_register_operand"  "r")))]
+-  "TARGET_THUMB2 && arm_arch_hwdiv"
+-  "sdiv%?\t%0, %1, %2"
+-  [(set_attr "predicable" "yes")]
+-)
+-
+-(define_insn "udivsi3"
+-  [(set (match_operand:SI        0 "s_register_operand" "=r")
+-      (udiv:SI (match_operand:SI 1 "s_register_operand"  "r")
+-               (match_operand:SI 2 "s_register_operand"  "r")))]
+-  "TARGET_THUMB2 && arm_arch_hwdiv"
+-  "udiv%?\t%0, %1, %2"
+-  [(set_attr "predicable" "yes")]
++(define_insn "*thumb2_subsi_short"
++  [(set (match_operand:SI 0 "low_register_operand" "=l")
++      (minus:SI (match_operand:SI 1 "low_register_operand" "l")
++                (match_operand:SI 2 "low_register_operand" "l")))
++   (clobber (reg:CC CC_REGNUM))]
++  "TARGET_THUMB2 && reload_completed"
++  "sub%!\\t%0, %1, %2"
++  [(set_attr "predicable" "yes")
++   (set_attr "length" "2")]
++)
++
++;; 16-bit encodings of "muls" and "mul<c>".  We only use these when
++;; optimizing for size since "muls" is slow on all known
++;; implementations and since "mul<c>" will be generated by
++;; "*arm_mulsi3_v6" anyhow.  The assembler will use a 16-bit encoding
++;; for "mul<c>" whenever possible anyhow.
++(define_peephole2
++  [(set (match_operand:SI 0 "low_register_operand" "")
++        (mult:SI (match_operand:SI 1 "low_register_operand" "")
++                 (match_dup 0)))]
++  "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)"
++  [(parallel
++    [(set (match_dup 0)
++           (mult:SI (match_dup 0) (match_dup 1)))
++     (clobber (reg:CC CC_REGNUM))])]
++  ""
+ )
++(define_peephole2
++  [(set (match_operand:SI 0 "low_register_operand" "")
++        (mult:SI (match_dup 0)
++               (match_operand:SI 1 "low_register_operand" "")))]
++  "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)"
++  [(parallel
++    [(set (match_dup 0)
++           (mult:SI (match_dup 0) (match_dup 1)))
++     (clobber (reg:CC CC_REGNUM))])]
++  ""
++)
++
++(define_insn "*thumb2_mulsi_short"
++  [(set (match_operand:SI 0 "low_register_operand" "=l")
++        (mult:SI (match_operand:SI 1 "low_register_operand" "%0")
++                 (match_operand:SI 2 "low_register_operand" "l")))
++   (clobber (reg:CC CC_REGNUM))]
++  "TARGET_THUMB2 && optimize_size && reload_completed"
++  "mul%!\\t%0, %2, %0"
++  [(set_attr "predicable" "yes")
++   (set_attr "length" "2")
++   (set_attr "insn" "muls")])
++
++(define_insn "*thumb2_mulsi_short_compare0"
++  [(set (reg:CC_NOOV CC_REGNUM)
++        (compare:CC_NOOV
++         (mult:SI (match_operand:SI 1 "register_operand" "%0")
++                (match_operand:SI 2 "register_operand" "l"))
++         (const_int 0)))
++   (set (match_operand:SI 0 "register_operand" "=l")
++      (mult:SI (match_dup 1) (match_dup 2)))]
++  "TARGET_THUMB2 && optimize_size"
++  "muls\\t%0, %2, %0"
++  [(set_attr "length" "2")
++   (set_attr "insn" "muls")])
++
++(define_insn "*thumb2_mulsi_short_compare0_scratch"
++  [(set (reg:CC_NOOV CC_REGNUM)
++        (compare:CC_NOOV
++         (mult:SI (match_operand:SI 1 "register_operand" "%0")
++                (match_operand:SI 2 "register_operand" "l"))
++         (const_int 0)))
++   (clobber (match_scratch:SI 0 "=r"))]
++  "TARGET_THUMB2 && optimize_size"
++  "muls\\t%0, %2, %0"
++  [(set_attr "length" "2")
++   (set_attr "insn" "muls")])
++
+ (define_insn "*thumb2_cbz"
+   [(set (pc) (if_then_else
+             (eq (match_operand:SI 0 "s_register_operand" "l,?r")
+@@ -1185,3 +1231,50 @@
+           (const_int 2)
+           (const_int 8)))]
+ )
++
++;; 16-bit complement
++(define_peephole2
++  [(set (match_operand:SI 0 "low_register_operand" "")
++      (not:SI (match_operand:SI 1 "low_register_operand" "")))]
++  "TARGET_THUMB2
++   && peep2_regno_dead_p(0, CC_REGNUM)"
++  [(parallel
++    [(set (match_dup 0)
++        (not:SI (match_dup 1)))
++     (clobber (reg:CC CC_REGNUM))])]
++  ""
++)
++
++(define_insn "*thumb2_one_cmplsi2_short"
++  [(set (match_operand:SI 0 "low_register_operand" "=l")
++      (not:SI (match_operand:SI 1 "low_register_operand" "l")))
++   (clobber (reg:CC CC_REGNUM))]
++  "TARGET_THUMB2 && reload_completed"
++  "mvn%!\t%0, %1"
++  [(set_attr "predicable" "yes")
++   (set_attr "length" "2")]
++)
++
++;; 16-bit negate
++(define_peephole2
++  [(set (match_operand:SI 0 "low_register_operand" "")
++      (neg:SI (match_operand:SI 1 "low_register_operand" "")))]
++  "TARGET_THUMB2
++   && peep2_regno_dead_p(0, CC_REGNUM)"
++  [(parallel
++    [(set (match_dup 0)
++        (neg:SI (match_dup 1)))
++     (clobber (reg:CC CC_REGNUM))])]
++  ""
++)
++
++(define_insn "*thumb2_negsi2_short"
++  [(set (match_operand:SI 0 "low_register_operand" "=l")
++      (neg:SI (match_operand:SI 1 "low_register_operand" "l")))
++   (clobber (reg:CC CC_REGNUM))]
++  "TARGET_THUMB2 && reload_completed"
++  "neg%!\t%0, %1"
++  [(set_attr "predicable" "yes")
++   (set_attr "length" "2")]
++)
++
+--- a/gcc/config/arm/uclinux-eabi.h
++++ b/gcc/config/arm/uclinux-eabi.h
+@@ -42,7 +42,8 @@
+   while (false)
+ #undef SUBTARGET_EXTRA_LINK_SPEC
+-#define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux_eabi"
++#define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux_eabi -elf2flt" \
++  " --pic-veneer --target2=abs"
+ /* We default to the "aapcs-linux" ABI so that enums are int-sized by
+    default.  */
+@@ -62,4 +63,3 @@
+                   : "=r" (_beg)                                       \
+                   : "0" (_beg), "r" (_end), "r" (_flg), "r" (_scno)); \
+ }
+-
+--- a/gcc/config/arm/uclinux-elf.h
++++ b/gcc/config/arm/uclinux-elf.h
+@@ -83,3 +83,5 @@
+   "%{pthread:-lpthread} \
+    %{shared:-lc} \
+    %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
++
++#define TARGET_DEFAULT_WORD_RELOCATIONS 1
+--- a/gcc/config/arm/unwind-arm.c
++++ b/gcc/config/arm/unwind-arm.c
+@@ -1201,8 +1201,6 @@ __gnu_unwind_pr_common (_Unwind_State st
+                 ucbp->barrier_cache.bitpattern[4] = (_uw) &data[1];
+                 if (data[0] & uint32_highbit)
+-                  phase2_call_unexpected_after_unwind = 1;
+-                else
+                   {
+                     data += rtti_count + 1;
+                     /* Setup for entry to the handler.  */
+@@ -1212,6 +1210,8 @@ __gnu_unwind_pr_common (_Unwind_State st
+                     _Unwind_SetGR (context, 0, (_uw) ucbp);
+                     return _URC_INSTALL_CONTEXT;
+                   }
++                else
++                  phase2_call_unexpected_after_unwind = 1;
+               }
+             if (data[0] & uint32_highbit)
+               data++;
+--- a/gcc/config/arm/unwind-arm.h
++++ b/gcc/config/arm/unwind-arm.h
+@@ -232,11 +232,11 @@ extern "C" {
+       if (!tmp)
+       return 0;
+-#if defined(linux) || defined(__NetBSD__)
++#if (defined(linux) && !defined(__uClinux__)) || defined(__NetBSD__)
+       /* Pc-relative indirect.  */
+       tmp += ptr;
+       tmp = *(_Unwind_Word *) tmp;
+-#elif defined(__symbian__)
++#elif defined(__symbian__) || defined(__uClinux__)
+       /* Absolute pointer.  Nothing more to do.  */
+ #else
+       /* Pc-relative pointer.  */
+--- a/gcc/config/arm/vfp.md
++++ b/gcc/config/arm/vfp.md
+@@ -1,6 +1,6 @@
+-;; ARM VFP coprocessor Machine Description
+-;; Copyright (C) 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
+-;; Written by CodeSourcery, LLC.
++;; ARM VFP instruction patterns
++;; Copyright (C) 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
++;; Written by CodeSourcery.
+ ;;
+ ;; This file is part of GCC.
+ ;;
+@@ -23,45 +23,20 @@
+   [(VFPCC_REGNUM 127)]
+ )
+-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+-;; Pipeline description
+-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+-
+-(define_automaton "vfp11")
+-
+-;; There are 3 pipelines in the VFP11 unit.
+-;;
+-;; - A 8-stage FMAC pipeline (7 execute + writeback) with forward from
+-;;   fourth stage for simple operations.
+-;;
+-;; - A 5-stage DS pipeline (4 execute + writeback) for divide/sqrt insns.
+-;;   These insns also uses first execute stage of FMAC pipeline.
+-;;
+-;; - A 4-stage LS pipeline (execute + 2 memory + writeback) with forward from
+-;;   second memory stage for loads.
+-
+-;; We do not model Write-After-Read hazards.
+-;; We do not do write scheduling with the arm core, so it is only necessary
+-;; to model the first stage of each pipeline
+-;; ??? Need to model LS pipeline properly for load/store multiple?
+-;; We do not model fmstat properly.  This could be done by modeling pipelines
+-;; properly and defining an absence set between a dummy fmstat unit and all
+-;; other vfp units.
+-
+-(define_cpu_unit "fmac" "vfp11")
+-
+-(define_cpu_unit "ds" "vfp11")
+-
+-(define_cpu_unit "vfp_ls" "vfp11")
+-
+-(define_cpu_unit "fmstat" "vfp11")
+-
+-(exclusion_set "fmac,ds" "fmstat")
+-
+ ;; The VFP "type" attributes differ from those used in the FPA model.
+-;; ffarith    Fast floating point insns, e.g. abs, neg, cpy, cmp.
+-;; farith     Most arithmetic insns.
+-;; fmul               Double precision multiply.
++;; fcpys      Single precision cpy.
++;; ffariths   Single precision abs, neg.
++;; ffarithd   Double precision abs, neg, cpy.
++;; fadds      Single precision add/sub.
++;; faddd      Double precision add/sub.
++;; fconsts    Single precision load immediate.
++;; fconstd    Double precision load immediate.
++;; fcmps      Single precision comparison.
++;; fcmpd      Double precision comparison.
++;; fmuls      Single precision multiply.
++;; fmuld      Double precision multiply.
++;; fmacs      Single precision multiply-accumulate.
++;; fmacd      Double precision multiply-accumulate.
+ ;; fdivs      Single precision sqrt or division.
+ ;; fdivd      Double precision sqrt or division.
+ ;; f_flag     fmstat operation
+@@ -71,126 +46,89 @@
+ ;; r_2_f      Transfer arm to vfp reg.
+ ;; f_cvt      Convert floating<->integral
+-(define_insn_reservation "vfp_ffarith" 4
+- (and (eq_attr "generic_vfp" "yes")
+-      (eq_attr "type" "ffarith"))
+- "fmac")
+-
+-(define_insn_reservation "vfp_farith" 8
+- (and (eq_attr "generic_vfp" "yes")
+-      (eq_attr "type" "farith,f_cvt"))
+- "fmac")
+-
+-(define_insn_reservation "vfp_fmul" 9
+- (and (eq_attr "generic_vfp" "yes")
+-      (eq_attr "type" "fmul"))
+- "fmac*2")
+-
+-(define_insn_reservation "vfp_fdivs" 19
+- (and (eq_attr "generic_vfp" "yes")
+-      (eq_attr "type" "fdivs"))
+- "ds*15")
+-
+-(define_insn_reservation "vfp_fdivd" 33
+- (and (eq_attr "generic_vfp" "yes")
+-      (eq_attr "type" "fdivd"))
+- "fmac+ds*29")
+-
+-;; Moves to/from arm regs also use the load/store pipeline.
+-(define_insn_reservation "vfp_fload" 4
+- (and (eq_attr "generic_vfp" "yes")
+-      (eq_attr "type" "f_loads,f_loadd,r_2_f"))
+- "vfp_ls")
+-
+-(define_insn_reservation "vfp_fstore" 4
+- (and (eq_attr "generic_vfp" "yes")
+-      (eq_attr "type" "f_stores,f_stored,f_2_r"))
+- "vfp_ls")
+-
+-(define_insn_reservation "vfp_to_cpsr" 4
+- (and (eq_attr "generic_vfp" "yes")
+-      (eq_attr "type" "f_flag"))
+- "fmstat,vfp_ls*3")
+-
+-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+-;; Insn pattern
+-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+-
+ ;; SImode moves
+ ;; ??? For now do not allow loading constants into vfp regs.  This causes
+ ;; problems because small constants get converted into adds.
+ (define_insn "*arm_movsi_vfp"
+-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r ,m,*t,r,*t,*t, *Uv")
+-      (match_operand:SI 1 "general_operand"      "rI,K,N,mi,r,r,*t,*t,*Uvi,*t"))]
++  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m ,*t,r,*t,*t, *Uv")
++      (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk,r,*t,*t,*Uvi,*t"))]
+   "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
+    && (   s_register_operand (operands[0], SImode)
+        || s_register_operand (operands[1], SImode))"
+   "*
+   switch (which_alternative)
+     {
+-    case 0:
++    case 0: case 1:
+       return \"mov%?\\t%0, %1\";
+-    case 1:
+-      return \"mvn%?\\t%0, #%B1\";
+     case 2:
+-      return \"movw%?\\t%0, %1\";
++      return \"mvn%?\\t%0, #%B1\";
+     case 3:
+-      return \"ldr%?\\t%0, %1\";
++      return \"movw%?\\t%0, %1\";
+     case 4:
+-      return \"str%?\\t%1, %0\";
++      return \"ldr%?\\t%0, %1\";
+     case 5:
+-      return \"fmsr%?\\t%0, %1\\t%@ int\";
++      return \"str%?\\t%1, %0\";
+     case 6:
+-      return \"fmrs%?\\t%0, %1\\t%@ int\";
++      return \"fmsr%?\\t%0, %1\\t%@ int\";
+     case 7:
++      return \"fmrs%?\\t%0, %1\\t%@ int\";
++    case 8:
+       return \"fcpys%?\\t%0, %1\\t%@ int\";
+-    case 8: case 9:
++    case 9: case 10:
+       return output_move_vfp (operands);
+     default:
+       gcc_unreachable ();
+     }
+   "
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "*,*,*,load1,store1,r_2_f,f_2_r,ffarith,f_loads,f_stores")
+-   (set_attr "pool_range"     "*,*,*,4096,*,*,*,*,1020,*")
+-   (set_attr "neg_pool_range" "*,*,*,4084,*,*,*,*,1008,*")]
++   (set_attr "type" "*,*,*,*,load1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores")
++   (set_attr "neon_type" "*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*")
++   (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*")
++   (set_attr "pool_range"     "*,*,*,*,4096,*,*,*,*,1020,*")
++   (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")]
+ )
++;; See thumb2.md:thumb2_movsi_insn for an explanation of the split
++;; high/low register alternatives for loads and stores here.
+ (define_insn "*thumb2_movsi_vfp"
+-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*t,r,*t,*t, *Uv")
+-      (match_operand:SI 1 "general_operand"      "rI,K,N,mi,r,r,*t,*t,*Uvi,*t"))]
++  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,l,*hk,m,*m,*t,r, *t,*t, *Uv")
++      (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,*mi,l,*hk,r,*t,*t,*Uvi,*t"))]
+   "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT
+    && (   s_register_operand (operands[0], SImode)
+        || s_register_operand (operands[1], SImode))"
+   "*
+   switch (which_alternative)
+     {
+-    case 0:
++    case 0: case 1:
+       return \"mov%?\\t%0, %1\";
+-    case 1:
+-      return \"mvn%?\\t%0, #%B1\";
+     case 2:
+-      return \"movw%?\\t%0, %1\";
++      return \"mvn%?\\t%0, #%B1\";
+     case 3:
+-      return \"ldr%?\\t%0, %1\";
++      return \"movw%?\\t%0, %1\";
+     case 4:
+-      return \"str%?\\t%1, %0\";
+     case 5:
+-      return \"fmsr%?\\t%0, %1\\t%@ int\";
++      return \"ldr%?\\t%0, %1\";
+     case 6:
+-      return \"fmrs%?\\t%0, %1\\t%@ int\";
+     case 7:
++      return \"str%?\\t%1, %0\";
++    case 8:
++      return \"fmsr%?\\t%0, %1\\t%@ int\";
++    case 9:
++      return \"fmrs%?\\t%0, %1\\t%@ int\";
++    case 10:
+       return \"fcpys%?\\t%0, %1\\t%@ int\";
+-    case 8: case 9:
++    case 11: case 12:
+       return output_move_vfp (operands);
+     default:
+       gcc_unreachable ();
+     }
+   "
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "*,*,*,load1,store1,r_2_f,f_2_r,ffarith,f_load,f_store")
+-   (set_attr "pool_range"     "*,*,*,4096,*,*,*,*,1020,*")
+-   (set_attr "neg_pool_range" "*,*,*,   0,*,*,*,*,1008,*")]
++   (set_attr "type" "*,*,*,*,load1,load1,store1,store1,r_2_f,f_2_r,fcpys,f_load,f_store")
++   (set_attr "neon_type" "*,*,*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*")
++   (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*,*,*")
++   (set_attr "pool_range"     "*,*,*,*,1020,4096,*,*,*,*,*,1020,*")
++   (set_attr "neg_pool_range" "*,*,*,*,   0,   0,*,*,*,*,*,1008,*")]
+ )
+@@ -222,7 +160,8 @@
+       gcc_unreachable ();
+     }
+   "
+-  [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_loadd,f_stored")
++  [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
++   (set_attr "neon_type" "*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*")
+    (set_attr "length" "8,8,8,4,4,4,4,4")
+    (set_attr "pool_range"     "*,1020,*,*,*,*,1020,*")
+    (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
+@@ -249,12 +188,68 @@
+       abort ();
+     }
+   "
+-  [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_load,f_store")
++  [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarithd,f_load,f_store")
++   (set_attr "neon_type" "*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*")
+    (set_attr "length" "8,8,8,4,4,4,4,4")
+    (set_attr "pool_range"     "*,4096,*,*,*,*,1020,*")
+    (set_attr "neg_pool_range" "*,   0,*,*,*,*,1008,*")]
+ )
++;; HFmode moves
++(define_insn "*movhf_vfp"
++  [(set (match_operand:HF 0 "nonimmediate_operand" "= t,Um,r,m,t,r,t,r,r")
++      (match_operand:HF 1 "general_operand"      " Um, t,m,r,t,r,r,t,F"))]
++  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_NEON_FP16
++   && (   s_register_operand (operands[0], HFmode)
++       || s_register_operand (operands[1], HFmode))"
++  "*
++  switch (which_alternative)
++    {
++    case 0:     /* S register from memory */
++      return \"vld1.16\\t{%z0}, %A1\";
++    case 1:     /* memory from S register */
++      return \"vst1.16\\t{%z1}, %A0\";
++    case 2:     /* ARM register from memory */
++      return \"ldrh\\t%0, %1\\t%@ __fp16\";
++    case 3:     /* memory from ARM register */
++      return \"strh\\t%1, %0\\t%@ __fp16\";
++    case 4:   /* S register from S register */
++      return \"fcpys\\t%0, %1\";
++    case 5:   /* ARM register from ARM register */
++      return \"mov\\t%0, %1\\t%@ __fp16\";
++    case 6:   /* S register from ARM register */
++      return \"fmsr\\t%0, %1\";
++    case 7:   /* ARM register from S register */
++      return \"fmrs\\t%0, %1\";
++    case 8:   /* ARM register from constant */
++      {
++        REAL_VALUE_TYPE r;
++      long bits;
++      rtx ops[4];
++
++        REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
++      bits = real_to_target (NULL, &r, HFmode);
++      ops[0] = operands[0];
++      ops[1] = GEN_INT (bits);
++      ops[2] = GEN_INT (bits & 0xff00);
++      ops[3] = GEN_INT (bits & 0x00ff);
++
++      if (arm_arch_thumb2)
++        output_asm_insn (\"movw\\t%0, %1\", ops);
++      else
++        output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops);
++      return \"\";
++       }
++    default:
++      gcc_unreachable ();
++    }
++  "
++  [(set_attr "conds" "unconditional")
++   (set_attr "type" "*,*,load1,store1,fcpys,*,r_2_f,f_2_r,*")
++   (set_attr "neon_type" "neon_vld1_1_2_regs,neon_vst1_1_2_regs_vst2_2_regs,*,*,*,*,*,*,*")
++   (set_attr "length" "4,4,4,4,4,4,4,4,8")]
++)
++
+ ;; SFmode moves
+ ;; Disparage the w<->r cases because reloading an invalid address is
+@@ -291,7 +286,8 @@
+   "
+   [(set_attr "predicable" "yes")
+    (set_attr "type"
+-     "r_2_f,f_2_r,farith,f_loads,f_stores,load1,store1,ffarith,*")
++     "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,*")
++   (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*")
+    (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*")
+    (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")]
+ )
+@@ -327,7 +323,8 @@
+   "
+   [(set_attr "predicable" "yes")
+    (set_attr "type"
+-     "r_2_f,f_2_r,farith,f_load,f_store,load1,store1,ffarith,*")
++     "r_2_f,f_2_r,fconsts,f_load,f_store,load1,store1,fcpys,*")
++   (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*")
+    (set_attr "pool_range" "*,*,*,1020,*,4092,*,*,*")
+    (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")]
+ )
+@@ -365,7 +362,8 @@
+     }
+   "
+   [(set_attr "type"
+-     "r_2_f,f_2_r,farith,f_loadd,f_stored,load2,store2,ffarith,*")
++     "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*")
++   (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*")
+    (set_attr "length" "4,4,4,8,8,4,4,4,8")
+    (set_attr "pool_range" "*,*,*,1020,*,1020,*,*,*")
+    (set_attr "neg_pool_range" "*,*,*,1008,*,1008,*,*,*")]
+@@ -397,7 +395,8 @@
+     }
+   "
+   [(set_attr "type"
+-     "r_2_f,f_2_r,farith,load2,store2,f_load,f_store,ffarith,*")
++     "r_2_f,f_2_r,fconstd,load2,store2,f_load,f_store,ffarithd,*")
++   (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*")
+    (set_attr "length" "4,4,4,8,8,4,4,4,8")
+    (set_attr "pool_range" "*,*,*,4096,*,1020,*,*,*")
+    (set_attr "neg_pool_range" "*,*,*,0,*,1008,*,*,*")]
+@@ -426,7 +425,8 @@
+    fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
+    [(set_attr "conds" "use")
+     (set_attr "length" "4,4,8,4,4,8,4,4,8")
+-    (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
++    (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
++    (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr,neon_mcr,neon_mcr,neon_mrc,neon_mrc,neon_mrc")]
+ )
+ (define_insn "*thumb2_movsfcc_vfp"
+@@ -449,7 +449,8 @@
+    ite\\t%D3\;fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
+    [(set_attr "conds" "use")
+     (set_attr "length" "6,6,10,6,6,10,6,6,10")
+-    (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
++    (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
++    (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr,neon_mcr,neon_mcr,neon_mrc,neon_mrc,neon_mrc")]
+ )
+ (define_insn "*movdfcc_vfp"
+@@ -472,7 +473,8 @@
+    fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
+    [(set_attr "conds" "use")
+     (set_attr "length" "4,4,8,4,4,8,4,4,8")
+-    (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
++    (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
++    (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mrrc,neon_mrrc,neon_mrrc")]
+ )
+ (define_insn "*thumb2_movdfcc_vfp"
+@@ -495,7 +497,8 @@
+    ite\\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
+    [(set_attr "conds" "use")
+     (set_attr "length" "6,6,10,6,6,10,6,6,10")
+-    (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
++    (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
++    (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mrrc,neon_mrrc,neon_mrrc")]
+ )
+@@ -507,7 +510,7 @@
+   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
+   "fabss%?\\t%0, %1"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "ffarith")]
++   (set_attr "type" "ffariths")]
+ )
+ (define_insn "*absdf2_vfp"
+@@ -516,7 +519,7 @@
+   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
+   "fabsd%?\\t%P0, %P1"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "ffarith")]
++   (set_attr "type" "ffarithd")]
+ )
+ (define_insn "*negsf2_vfp"
+@@ -527,7 +530,7 @@
+    fnegs%?\\t%0, %1
+    eor%?\\t%0, %1, #-2147483648"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "ffarith")]
++   (set_attr "type" "ffariths")]
+ )
+ (define_insn_and_split "*negdf2_vfp"
+@@ -573,7 +576,7 @@
+   "
+   [(set_attr "predicable" "yes")
+    (set_attr "length" "4,4,8")
+-   (set_attr "type" "ffarith")]
++   (set_attr "type" "ffarithd")]
+ )
+@@ -586,7 +589,7 @@
+   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
+   "fadds%?\\t%0, %1, %2"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "farith")]
++   (set_attr "type" "fadds")]
+ )
+ (define_insn "*adddf3_vfp"
+@@ -596,7 +599,7 @@
+   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
+   "faddd%?\\t%P0, %P1, %P2"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "farith")]
++   (set_attr "type" "faddd")]
+ )
+@@ -607,7 +610,7 @@
+   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
+   "fsubs%?\\t%0, %1, %2"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "farith")]
++   (set_attr "type" "fadds")]
+ )
+ (define_insn "*subdf3_vfp"
+@@ -617,7 +620,7 @@
+   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
+   "fsubd%?\\t%P0, %P1, %P2"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "farith")]
++   (set_attr "type" "faddd")]
+ )
+@@ -653,7 +656,7 @@
+   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
+   "fmuls%?\\t%0, %1, %2"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "farith")]
++   (set_attr "type" "fmuls")]
+ )
+ (define_insn "*muldf3_vfp"
+@@ -663,7 +666,7 @@
+   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
+   "fmuld%?\\t%P0, %P1, %P2"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "fmul")]
++   (set_attr "type" "fmuld")]
+ )
+@@ -674,7 +677,7 @@
+   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
+   "fnmuls%?\\t%0, %1, %2"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "farith")]
++   (set_attr "type" "fmuls")]
+ )
+ (define_insn "*muldf3negdf_vfp"
+@@ -684,7 +687,7 @@
+   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
+   "fnmuld%?\\t%P0, %P1, %P2"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "fmul")]
++   (set_attr "type" "fmuld")]
+ )
+@@ -696,10 +699,11 @@
+       (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
+                         (match_operand:SF 3 "s_register_operand" "t"))
+                (match_operand:SF          1 "s_register_operand" "0")))]
+-  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
++  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP
++   && (!arm_tune_marvell_f || optimize_size)"
+   "fmacs%?\\t%0, %2, %3"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "farith")]
++   (set_attr "type" "fmacs")]
+ )
+ (define_insn "*muldf3adddf_vfp"
+@@ -707,10 +711,11 @@
+       (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
+                         (match_operand:DF 3 "s_register_operand" "w"))
+                (match_operand:DF          1 "s_register_operand" "0")))]
+-  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
++  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP
++   && (!arm_tune_marvell_f || optimize_size)"
+   "fmacd%?\\t%P0, %P2, %P3"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "fmul")]
++   (set_attr "type" "fmacd")]
+ )
+ ;; 0 = 1 * 2 - 0
+@@ -719,10 +724,11 @@
+       (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
+                          (match_operand:SF 3 "s_register_operand" "t"))
+                 (match_operand:SF          1 "s_register_operand" "0")))]
+-  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
++  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP
++   && (!arm_tune_marvell_f || optimize_size)"
+   "fmscs%?\\t%0, %2, %3"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "farith")]
++   (set_attr "type" "fmacs")]
+ )
+ (define_insn "*muldf3subdf_vfp"
+@@ -730,10 +736,11 @@
+       (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
+                          (match_operand:DF 3 "s_register_operand" "w"))
+                 (match_operand:DF          1 "s_register_operand" "0")))]
+-  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
++  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP
++   && (!arm_tune_marvell_f || optimize_size)"
+   "fmscd%?\\t%P0, %P2, %P3"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "fmul")]
++   (set_attr "type" "fmacd")]
+ )
+ ;; 0 = -(1 * 2) + 0
+@@ -742,10 +749,11 @@
+       (minus:SF (match_operand:SF          1 "s_register_operand" "0")
+                 (mult:SF (match_operand:SF 2 "s_register_operand" "t")
+                          (match_operand:SF 3 "s_register_operand" "t"))))]
+-  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
++  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP
++   && (!arm_tune_marvell_f || optimize_size)"
+   "fnmacs%?\\t%0, %2, %3"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "farith")]
++   (set_attr "type" "fmacs")]
+ )
+ (define_insn "*fmuldf3negdfadddf_vfp"
+@@ -753,10 +761,11 @@
+       (minus:DF (match_operand:DF          1 "s_register_operand" "0")
+                 (mult:DF (match_operand:DF 2 "s_register_operand" "w")
+                          (match_operand:DF 3 "s_register_operand" "w"))))]
+-  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
++  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP
++   && (!arm_tune_marvell_f || optimize_size)"
+   "fnmacd%?\\t%P0, %P2, %P3"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "fmul")]
++   (set_attr "type" "fmacd")]
+ )
+@@ -767,10 +776,11 @@
+                   (neg:SF (match_operand:SF 2 "s_register_operand" "t"))
+                   (match_operand:SF         3 "s_register_operand" "t"))
+                 (match_operand:SF           1 "s_register_operand" "0")))]
+-  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
++  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP
++   && (!arm_tune_marvell_f || optimize_size)"
+   "fnmscs%?\\t%0, %2, %3"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "farith")]
++   (set_attr "type" "fmacs")]
+ )
+ (define_insn "*muldf3negdfsubdf_vfp"
+@@ -779,10 +789,11 @@
+                   (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
+                   (match_operand:DF         3 "s_register_operand" "w"))
+                 (match_operand:DF           1 "s_register_operand" "0")))]
+-  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
++  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP
++   && (!arm_tune_marvell_f || optimize_size)"
+   "fnmscd%?\\t%P0, %P2, %P3"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "fmul")]
++   (set_attr "type" "fmacd")]
+ )
+@@ -806,6 +817,24 @@
+    (set_attr "type" "f_cvt")]
+ )
++(define_insn "extendhfsf2"
++  [(set (match_operand:SF                0 "s_register_operand" "=t")
++      (float_extend:SF (match_operand:HF 1 "s_register_operand" "t")))]
++  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_NEON_FP16"
++  "vcvtb%?.f32.f16\\t%0, %1"
++  [(set_attr "predicable" "yes")
++   (set_attr "type" "f_cvt")]
++)
++
++(define_insn "truncsfhf2"
++  [(set (match_operand:HF                0 "s_register_operand" "=t")
++      (float_truncate:HF (match_operand:SF 1 "s_register_operand" "t")))]
++  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_NEON_FP16"
++  "vcvtb%?.f16.f32\\t%0, %1"
++  [(set_attr "predicable" "yes")
++   (set_attr "type" "f_cvt")]
++)
++
+ (define_insn "*truncsisf2_vfp"
+   [(set (match_operand:SI               0 "s_register_operand" "=t")
+       (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
+@@ -986,7 +1015,7 @@
+    fcmps%?\\t%0, %1
+    fcmpzs%?\\t%0"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "ffarith")]
++   (set_attr "type" "fcmps")]
+ )
+ (define_insn "*cmpsf_trap_vfp"
+@@ -998,7 +1027,7 @@
+    fcmpes%?\\t%0, %1
+    fcmpezs%?\\t%0"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "ffarith")]
++   (set_attr "type" "fcmpd")]
+ )
+ (define_insn "*cmpdf_vfp"
+@@ -1010,7 +1039,7 @@
+    fcmpd%?\\t%P0, %P1
+    fcmpzd%?\\t%P0"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "ffarith")]
++   (set_attr "type" "fcmpd")]
+ )
+ (define_insn "*cmpdf_trap_vfp"
+@@ -1022,7 +1051,7 @@
+    fcmped%?\\t%P0, %P1
+    fcmpezd%?\\t%P0"
+   [(set_attr "predicable" "yes")
+-   (set_attr "type" "ffarith")]
++   (set_attr "type" "fcmpd")]
+ )
+--- /dev/null
++++ b/gcc/config/arm/vfp11.md
+@@ -0,0 +1,92 @@
++;; ARM VFP11 pipeline description
++;; Copyright (C) 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
++;; Written by CodeSourcery.
++;;
++;; This file is part of GCC.
++
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published
++;; by the Free Software Foundation; either version 3, or (at your
++;; option) any later version.
++
++;; GCC is distributed in the hope that it will be useful, but WITHOUT
++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
++;; License for more details.
++
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING3.  If not see
++;; <http://www.gnu.org/licenses/>.
++
++(define_automaton "vfp11")
++
++;; There are 3 pipelines in the VFP11 unit.
++;;
++;; - A 8-stage FMAC pipeline (7 execute + writeback) with forward from
++;;   fourth stage for simple operations.
++;;
++;; - A 5-stage DS pipeline (4 execute + writeback) for divide/sqrt insns.
++;;   These insns also uses first execute stage of FMAC pipeline.
++;;
++;; - A 4-stage LS pipeline (execute + 2 memory + writeback) with forward from
++;;   second memory stage for loads.
++
++;; We do not model Write-After-Read hazards.
++;; We do not do write scheduling with the arm core, so it is only necessary
++;; to model the first stage of each pipeline
++;; ??? Need to model LS pipeline properly for load/store multiple?
++;; We do not model fmstat properly.  This could be done by modeling pipelines
++;; properly and defining an absence set between a dummy fmstat unit and all
++;; other vfp units.
++
++(define_cpu_unit "fmac" "vfp11")
++
++(define_cpu_unit "ds" "vfp11")
++
++(define_cpu_unit "vfp_ls" "vfp11")
++
++(define_cpu_unit "fmstat" "vfp11")
++
++(exclusion_set "fmac,ds" "fmstat")
++
++(define_insn_reservation "vfp_ffarith" 4
++ (and (eq_attr "generic_vfp" "yes")
++      (eq_attr "type" "fcpys,ffariths,ffarithd,fcmps,fcmpd"))
++ "fmac")
++
++(define_insn_reservation "vfp_farith" 8
++ (and (eq_attr "generic_vfp" "yes")
++      (eq_attr "type" "fadds,faddd,fconsts,fconstd,f_cvt,fmuls,fmacs"))
++ "fmac")
++
++(define_insn_reservation "vfp_fmul" 9
++ (and (eq_attr "generic_vfp" "yes")
++      (eq_attr "type" "fmuld,fmacd"))
++ "fmac*2")
++
++(define_insn_reservation "vfp_fdivs" 19
++ (and (eq_attr "generic_vfp" "yes")
++      (eq_attr "type" "fdivs"))
++ "ds*15")
++
++(define_insn_reservation "vfp_fdivd" 33
++ (and (eq_attr "generic_vfp" "yes")
++      (eq_attr "type" "fdivd"))
++ "fmac+ds*29")
++
++;; Moves to/from arm regs also use the load/store pipeline.
++(define_insn_reservation "vfp_fload" 4
++ (and (eq_attr "generic_vfp" "yes")
++      (eq_attr "type" "f_loads,f_loadd,r_2_f"))
++ "vfp_ls")
++
++(define_insn_reservation "vfp_fstore" 4
++ (and (eq_attr "generic_vfp" "yes")
++      (eq_attr "type" "f_stores,f_stored,f_2_r"))
++ "vfp_ls")
++
++(define_insn_reservation "vfp_to_cpsr" 4
++ (and (eq_attr "generic_vfp" "yes")
++      (eq_attr "type" "f_flag"))
++ "fmstat,vfp_ls*3")
++
+--- a/gcc/config/arm/vxworks.h
++++ b/gcc/config/arm/vxworks.h
+@@ -113,3 +113,6 @@ along with GCC; see the file COPYING3.  
+    cannot allow arbitrary offsets for shared libraries either.  */
+ #undef ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P
+ #define ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 1
++
++#undef TARGET_DEFAULT_WORD_RELOCATIONS
++#define TARGET_DEFAULT_WORD_RELOCATIONS 1
+--- /dev/null
++++ b/gcc/config/arm/wrs-linux.h
+@@ -0,0 +1,76 @@
++/* Wind River GNU/Linux Configuration.
++   Copyright (C) 2006, 2007, 2008
++   Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 3, or (at your option)
++any later version.
++
++GCC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++/* Use the ARM926EJ-S by default.  */
++#undef SUBTARGET_CPU_DEFAULT
++#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm926ejs
++
++/* Add a -tiwmmxt option for convenience in generating multilibs.
++   This option generates big-endian IWMMXT code.  */
++#undef CC1_SPEC
++#define CC1_SPEC "                                                    \
++ %{tarm926ej-s:       -mcpu=arm926ej-s ;                                      \
++   tiwmmxt:     -mcpu=iwmmxt ;                                                \
++   tiwmmxt2:    -mcpu=iwmmxt ;                                                \
++   txscale:     -mcpu=xscale -mbig-endian ;                           \
++   tarm920t:    -mcpu=arm920t ;                                               \
++   tthumb2:     %{!mcpu=*:%{!march=*:-march=armv6t2}} -mthumb ;               \
++   tcortex-a8-be8: -mcpu=cortex-a8 -mbig-endian -mfloat-abi=softfp    \
++                   -mfpu=neon }                                               \
++ %{txscale:%{mfloat-abi=softfp:%eXScale VFP multilib not provided}}   \
++ %{tarm920t:%{mfloat-abi=softfp:%eARM920T VFP multilib not provided}} \
++ %{profile:-p}"
++
++/* Since the ARM926EJ-S is the default processor, we do not need to
++   provide an explicit multilib for that processor.  */
++#undef MULTILIB_DEFAULTS
++#define MULTILIB_DEFAULTS \
++  { "tarm926ej-s" }
++
++/* The GLIBC headers are in /usr/include, relative to the sysroot; the
++   uClibc headers are in /uclibc/usr/include.  */
++#undef SYSROOT_HEADERS_SUFFIX_SPEC
++#define SYSROOT_HEADERS_SUFFIX_SPEC           \
++  "%{muclibc:/uclibc}" 
++
++/* Translate -tiwmmxt appropriately for the assembler.  The -meabi=5
++   option is the relevant part of SUBTARGET_EXTRA_ASM_SPEC in bpabi.h.  */
++#undef SUBTARGET_EXTRA_ASM_SPEC
++#define SUBTARGET_EXTRA_ASM_SPEC \
++  "%{tiwmmxt2:-mcpu=iwmmxt2} %{tiwmmxt:-mcpu=iwmmxt} %{txscale:-mcpu=xscale -EB} %{tcortex-a8-be8:-mcpu=cortex-a8 -EB} -meabi=5" 
++
++/* Translate -tiwmmxt for the linker.  */
++#undef SUBTARGET_EXTRA_LINK_SPEC
++#define SUBTARGET_EXTRA_LINK_SPEC                     \
++  " %{tiwmmxt:-m armelf_linux_eabi ;                  \
++     txscale:-m armelfb_linux_eabi ;                  \
++     tcortex-a8-be8:-m armelfb_linux_eabi %{!r:--be8} ;       \
++     : -m armelf_linux_eabi}"
++
++/* The various C libraries each have their own subdirectory.  */
++#undef SYSROOT_SUFFIX_SPEC
++#define SYSROOT_SUFFIX_SPEC                                   \
++  "%{muclibc:/uclibc}%{tiwmmxt:/tiwmmxt ;                     \
++     tiwmmxt2:/tiwmmxt ;                                      \
++     txscale:/txscale ;                                               \
++     tarm920t:/tarm920t ;                                     \
++     tthumb2:/thumb2 ;                                                \
++     tcortex-a8-be8:/cortex-a8-be8}%{!tthumb2:%{!tcortex-a8-be8:%{mfloat-abi=softfp:/softfp}}}"
++
+--- /dev/null
++++ b/gcc/config/i386/cs-linux.h
+@@ -0,0 +1,41 @@
++/* Sourcery G++ IA32 GNU/Linux Configuration.
++   Copyright (C) 2007
++   Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 3, or (at your option)
++any later version.
++
++GCC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++/* This configuration may be used either with the system glibc (in
++   system32 and system64 subdirectories) or with the included glibc
++   (in the sgxx-glibc subdirectory).  */
++
++#undef SYSROOT_SUFFIX_SPEC
++#define SYSROOT_SUFFIX_SPEC                   \
++  "%{msgxx-glibc:/sgxx-glibc ;                        \
++     m64:/system64 ;                          \
++     mrhel3:/system64 ;                               \
++     mrh73:/system32-old ;                    \
++     :/system32}"
++
++#undef SYSROOT_HEADERS_SUFFIX_SPEC
++#define SYSROOT_HEADERS_SUFFIX_SPEC SYSROOT_SUFFIX_SPEC
++
++/* See mips/wrs-linux.h for details on this use of
++   STARTFILE_PREFIX_SPEC.  */
++#undef STARTFILE_PREFIX_SPEC
++#define STARTFILE_PREFIX_SPEC                         \
++  "%{m64: /usr/local/lib64/ /lib64/ /usr/lib64/}      \
++   %{!m64: /usr/local/lib/ /lib/ /usr/lib/}"
+--- /dev/null
++++ b/gcc/config/i386/cs-linux.opt
+@@ -0,0 +1,11 @@
++; Additional options for Sourcery G++.
++
++mrh73
++Target Undocumented
++
++mrhel3
++Target Undocumented
++
++msgxx-glibc
++Target
++Use included version of GLIBC
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -2700,6 +2700,18 @@ override_options (void)
+       target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
+     }
++  /* If stack probes are required, the space used for large function
++     arguments on the stack must also be probed, so enable
++     -maccumulate-outgoing-args so this happens in the prologue.  */
++  if (TARGET_STACK_PROBE
++      && !(target_flags & MASK_ACCUMULATE_OUTGOING_ARGS))
++    {
++      if (target_flags_explicit & MASK_ACCUMULATE_OUTGOING_ARGS)
++      warning (0, "stack probing requires -maccumulate-outgoing-args "
++               "for correctness");
++      target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
++    }
++
+   /* For sane SSE instruction set generation we need fcomi instruction.
+      It is safe to enable all CMOVE instructions.  */
+   if (TARGET_SSE)
+--- a/gcc/config/i386/i386.h
++++ b/gcc/config/i386/i386.h
+@@ -476,13 +476,23 @@ extern const char *host_detect_local_cpu
+ #define HAVE_LOCAL_CPU_DETECT
+ #endif
++#if TARGET_64BIT_DEFAULT
++#define OPT_ARCH64 "!m32"
++#define OPT_ARCH32 "m32"
++#else
++#define OPT_ARCH64 "m64"
++#define OPT_ARCH32 "!m64"
++#endif
++
+ /* Support for configure-time defaults of some command line options.
+    The order here is important so that -march doesn't squash the
+    tune or cpu values.  */
+ #define OPTION_DEFAULT_SPECS                                     \
+   {"tune", "%{!mtune=*:%{!mcpu=*:%{!march=*:-mtune=%(VALUE)}}}" }, \
+   {"cpu", "%{!mtune=*:%{!mcpu=*:%{!march=*:-mtune=%(VALUE)}}}" },  \
+-  {"arch", "%{!march=*:-march=%(VALUE)}"}
++  {"arch", "%{!march=*:-march=%(VALUE)}"},                       \
++  {"arch32", "%{" OPT_ARCH32 ":%{!march=*:-march=%(VALUE)}}"},           \
++  {"arch64", "%{" OPT_ARCH64 ":%{!march=*:-march=%(VALUE)}}"},
+ /* Specs for the compiler proper */
+--- a/gcc/config/i386/mingw32.h
++++ b/gcc/config/i386/mingw32.h
+@@ -79,7 +79,7 @@ along with GCC; see the file COPYING3.  
+ /* Include in the mingw32 libraries with libgcc */
+ #undef LIBGCC_SPEC
+ #define LIBGCC_SPEC \
+-  "%{mthreads:-lmingwthrd} -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt"
++  "-lgcc %{mthreads:-lmingwthrd} -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt"
+ #undef STARTFILE_SPEC
+ #define STARTFILE_SPEC "%{shared|mdll:dllcrt2%O%s} \
+--- /dev/null
++++ b/gcc/config/i386/t-cs-linux
+@@ -0,0 +1,25 @@
++# Sourcery G++ IA32 GNU/Linux Configuration.
++# Copyright (C) 2007
++# Free Software Foundation, Inc.
++#
++# This file is part of GCC.
++#
++# GCC is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3, or (at your option)
++# any later version.
++# 
++# GCC is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with GCC; see the file COPYING3.  If not see
++# <http://www.gnu.org/licenses/>.
++
++MULTILIB_OPTIONS = m64/m32 msgxx-glibc/mrh73/mrhel3
++MULTILIB_DIRNAMES = 64 32 sgxx-glibc rh73 rhel3
++MULTILIB_OSDIRNAMES = ../lib64 ../lib sgxx-glibc rh73 rhel3
++MULTILIB_EXCEPTIONS = m64/mrh73 m64/mrhel3
++
+--- a/gcc/config/i386/x-mingw32
++++ b/gcc/config/i386/x-mingw32
+@@ -8,6 +8,6 @@ local_includedir=$(libsubdir)/$(unlibsub
+ WERROR_FLAGS += -Wno-format
+ host-mingw32.o : $(srcdir)/config/i386/host-mingw32.c $(CONFIG_H) $(SYSTEM_H) \
+-  coretypes.h hosthooks.h hosthooks-def.h toplev.h diagnostic.h $(HOOKS_H)
++  coretypes.h hosthooks.h hosthooks-def.h toplev.h $(DIAGNOSTIC_H) $(HOOKS_H)
+       $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+               $(srcdir)/config/i386/host-mingw32.c
+--- a/gcc/config/m68k/cf.md
++++ b/gcc/config/m68k/cf.md
+@@ -1,6 +1,6 @@
+-;; ColdFire V2 DFA description.
++;; ColdFire V1, V2, V3 and V4/V4e DFA description.
+ ;; Copyright (C) 2007 Free Software Foundation, Inc.
+-;; Contributed by CodeSourcery Inc.
++;; Contributed by CodeSourcery Inc., www.codesourcery.com
+ ;;
+ ;; This file is part of GCC.
+ ;;
+@@ -19,661 +19,2236 @@
+ ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ ;; Boston, MA 02110-1301, USA.
+-;; ??? To let genattrtab live, implement this attribute in C.
+-(define_attr "type2"
+-  "alu, alu_l, bcc, bra, call, jmp, lea, move, move_l, mul, pea, rts, unlk,
+-   unknown"
+-  (symbol_ref "m68k_sched_attr_type2 (insn)"))
+-
+ ;; Instruction Buffer
+-(define_automaton "cf_v2_ib")
++(define_automaton "cfv123_ib")
+-;; If one of these cpu units is occupied, that means that corresponding
+-;; word in the buffer is empty.
+-(define_cpu_unit "cf_v2_ib_w0, cf_v2_ib_w1, cf_v2_ib_w2, cf_v2_ib_w3, cf_v2_ib_w4, cf_v2_ib_w5" "cf_v2_ib")
+-
+-(final_presence_set "cf_v2_ib_w1, cf_v2_ib_w2, cf_v2_ib_w3, cf_v2_ib_w4, cf_v2_ib_w5" "cf_v2_ib_w0")
+-(final_presence_set "cf_v2_ib_w2, cf_v2_ib_w3, cf_v2_ib_w4, cf_v2_ib_w5" "cf_v2_ib_w1")
+-(final_presence_set "cf_v2_ib_w3, cf_v2_ib_w4, cf_v2_ib_w5" "cf_v2_ib_w2")
+-(final_presence_set "cf_v2_ib_w4, cf_v2_ib_w5" "cf_v2_ib_w3")
+-(final_presence_set "cf_v2_ib_w5" "cf_v2_ib_w4")
+-
+-;; Occupy 1 word.
+-(define_reservation "cf_v2_ib1" "cf_v2_ib_w0|cf_v2_ib_w1|cf_v2_ib_w2|cf_v2_ib_w3|cf_v2_ib_w4|cf_v2_ib_w5")
+-
+-;; Occupy 2 words.
+-(define_reservation "cf_v2_ib2" "(cf_v2_ib_w0+cf_v2_ib_w1)|(cf_v2_ib_w1+cf_v2_ib_w2)|(cf_v2_ib_w2+cf_v2_ib_w3)|(cf_v2_ib_w3+cf_v2_ib_w4)|(cf_v2_ib_w4+cf_v2_ib_w5)")
+-
+-;; Occupy 3 words.
+-(define_reservation "cf_v2_ib3" "(cf_v2_ib_w0+cf_v2_ib_w1+cf_v2_ib_w2)|(cf_v2_ib_w1+cf_v2_ib_w2+cf_v2_ib_w3)|(cf_v2_ib_w2+cf_v2_ib_w3+cf_v2_ib_w4)|(cf_v2_ib_w3+cf_v2_ib_w4+cf_v2_ib_w5)")
+-
+-;; Reservation to subscribe 1 word in the instruction buffer.  If a given
+-;; word in the instruction buffer is subscribed, that means it is empty.
+-;; This reservation is used at the start of each cycle to setup the number
+-;; of prefetched instruction words in the instruction buffer.
+-;; At each cycle, given that memory bus is available (i.e. there is no
+-;; pending memory operation), IFP prefetches two instruction words into IB.
+-(define_insn_reservation "cf_v2_ib" 0
+-  (and (eq_attr "cpu" "cf_v2")
++;; These pseudo units are used to model instruction buffer of ColdFire cores.
++;; Instruction of size N can be issued only when cf_ib_wN is available.
++(define_cpu_unit "cf_ib_w1, cf_ib_w2, cf_ib_w3" "cfv123_ib")
++
++;; Instruction occupies 1 word in the instruction buffer.
++(define_reservation "cf_ib1" "cf_ib_w1")
++;; Instruction occupies 2 words in the instruction buffer.
++(define_reservation "cf_ib2" "cf_ib_w1+cf_ib_w2")
++;; Instruction occupies 3 words in the instruction buffer.
++(define_reservation "cf_ib3" "cf_ib_w1+cf_ib_w2+cf_ib_w3")
++
++;; This reservation is used at the start of each cycle to setup the maximal
++;; length of instruction that can be issued on current cycle.
++;; E.g., when this reservation is applied for the first time, cf_ib_w3
++;; resource is marked busy, thus filtering out all 3-word insns.
++;;
++;; This reservation requires deterministic automaton.
++;;
++;; At each cycle, given that memory bus is available (i.e., there is no
++;; pending memory operation), instruction fetch pipeline (IFP) prefetches
++;; two instruction words into instruction buffer (IB).
++(define_insn_reservation "cf_ib1" 0
++  (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
+        (eq_attr "type" "ib"))
+-  "cf_v2_ib1")
++  "cf_ib_w3|cf_ib_w2|cf_ib_w1")
+ ;; Operand Execution Pipeline
+-(define_automaton "cf_v2_oep")
++(define_automaton "cfv123_oep")
+-(define_cpu_unit "cf_v2_dsoc, cf_v2_agex" "cf_v2_oep")
++(define_cpu_unit "cf_dsoc,cf_agex" "cfv123_oep")
+ ;; A memory unit that is reffered to as 'certain hardware resources' in
+ ;; ColdFire reference manuals.  This unit remains occupied for two cycles
+ ;; after last dsoc cycle of a store - hence there is a 2 cycle delay between
+ ;; two consecutive stores.
+-(define_automaton "cf_v2_chr")
++(define_automaton "cfv123_chr")
+-(define_cpu_unit "cf_v2_chr" "cf_v2_chr")
++(define_cpu_unit "cf_chr" "cfv123_chr")
+ ;; Memory bus
+-(define_automaton "cf_v2_mem")
++(define_automaton "cfv123_mem")
+ ;; When memory bus is subscribed, that implies that instruction buffer won't
+-;; get its portion this cycle.  To model that we query if cf_v2_mem unit is
++;; get its portion this cycle.  To model that we query if cf_mem unit is
+ ;; subscribed and adjust number of prefetched instruction words accordingly.
+ ;; 
+-(define_query_cpu_unit "cf_v2_mem" "cf_v2_mem")
++(define_query_cpu_unit "cf_mem1, cf_mem2" "cfv123_mem")
++
++(define_reservation "cf_mem" "cf_mem1+cf_mem2")
++
++(define_automaton "cf_mac")
++
++(define_cpu_unit "cf_mac1,cf_mac2,cf_mac3,cf_mac4"
++  "cf_mac")
++
++(define_automaton "cfv123_guess")
++
++(define_query_cpu_unit "cfv123_guess" "cfv123_guess")
+ ;; Register to register move.
+ ;; Takes 1 cycle.
+-(define_reservation "cf_v2_move_00"
+-  "cf_v2_dsoc+cf_v2_agex")
++(define_reservation "cfv123_alu_00"
++  "cf_dsoc,cf_agex")
+ ;; Load from a memory location.
+ ;; Takes 3 cycles.
+-(define_reservation "cf_v2_move_10"
+-  "cf_v2_dsoc,cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex")
+-
+-;; Long load from a memory location.
++(define_reservation "cfv12_alu_10"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem,cf_agex")
+ ;; Takes 2 cycles.
+-(define_reservation "cf_v2_move_l_10"
+-  "cf_v2_dsoc+cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex")
++(define_reservation "cfv12_omove_10"
++  "cf_dsoc+cf_agex,cf_dsoc+cf_mem,cf_agex")
++;; Takes 4 cycles.
++(define_reservation "cfv3_alu_10"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex")
++;; Takes 3 cycles.
++(define_reservation "cfv3_omove_10"
++  "cf_dsoc+cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex")
+ ;; Load from an indexed location.
+ ;; Takes 4 cycles.
+-(define_reservation "cf_v2_move_i0"
+-  "cf_v2_dsoc,cf_v2_agex,cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex")
+-
+-;; Long load from an indexed location.
++(define_reservation "cfv12_alu_i0"
++  "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem,cf_agex")
+ ;; Takes 3 cycles.
+-(define_reservation "cf_v2_move_l_i0"
+-  "cf_v2_dsoc+cf_v2_agex,cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex")
++(define_reservation "cfv12_omove_i0"
++  "cf_dsoc+cf_agex,cf_agex,cf_dsoc+cf_mem,cf_agex")
++;; Takes 5 cycles.
++(define_reservation "cfv3_alu_i0"
++  "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex")
++;; Takes 4 cycles.
++(define_reservation "cfv3_omove_i0"
++  "cf_dsoc+cf_agex,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex")
+ ;; Store to a memory location.
+ ;; Takes 1 cycle.
+-(define_reservation "cf_v2_move_01"
+-  "cf_v2_dsoc+cf_v2_agex+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
++(define_reservation "cfv12_alu_01"
++  "cf_dsoc+cf_agex+cf_chr,cf_mem+cf_chr,cf_chr")
++;; Takes 1 cycle.
++(define_reservation "cfv3_alu_01"
++  "cf_dsoc+cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr")
+ ;; Store to an indexed location.
+-;; Takes 2 cycle.
+-(define_reservation "cf_v2_move_0i"
+-  "cf_v2_dsoc+cf_v2_agex,cf_v2_agex+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
++;; Takes 2 cycles.
++(define_reservation "cfv12_alu_0i"
++  "cf_dsoc+cf_agex,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr")
++;; Takes 2 cycles.
++(define_reservation "cfv3_alu_0i"
++  "cf_dsoc+cf_agex,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr")
+ ;; Load from a memory location and store to a memory location.
+ ;; Takes 3 cycles
+-(define_reservation "cf_v2_move_11"
+-  "cf_v2_dsoc,cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
+-
+-;; Long load from a memory location and store to a memory location.
++(define_reservation "cfv12_alu_11"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr")
+ ;; Takes 2 cycles.
+-(define_reservation "cf_v2_move_l_11"
+-  "cf_v2_dsoc+cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
++(define_reservation "cfv12_omove_11"
++  "cf_dsoc+cf_agex,cf_dsoc+cf_mem,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr")
++;; Takes 4 cycles
++(define_reservation "cfv3_alu_11"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr")
++;; Takes 3 cycles.
++(define_reservation "cfv3_omove_11"
++  "cf_dsoc+cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr")
+ ;; Load from an indexed location and store to a memory location.
+ ;; Takes 4 cycles.
+-(define_reservation "cf_v2_move_i1"
+-  "cf_v2_dsoc,cf_v2_agex,cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
+-
+-;; Long load from an indexed location and store to a memory location.
++(define_reservation "cfv12_alu_i1"
++  "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr")
+ ;; Takes 3 cycles.
+-(define_reservation "cf_v2_move_l_i1"
+-  "cf_v2_dsoc+cf_v2_agex,cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
++(define_reservation "cfv12_omove_i1"
++  "cf_dsoc+cf_agex,cf_agex,cf_dsoc+cf_mem,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr")
++;; Takes 5 cycles.
++(define_reservation "cfv3_alu_i1"
++  "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr")
++;; Takes 4 cycles.
++(define_reservation "cfv3_omove_i1"
++  "cf_dsoc+cf_agex,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr")
+ ;; Load from a memory location and store to an indexed location.
+ ;; Takes 4 cycles.
+-(define_reservation "cf_v2_move_1i"
+-  "cf_v2_dsoc,cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem,cf_v2_agex,cf_v2_mem")
+-
+-;; Long load from a memory location and store to an indexed location.
++(define_reservation "cfv12_alu_1i"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem,cf_agex,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr")
+ ;; Takes 3 cycles.
+-(define_reservation "cf_v2_move_l_1i"
+-  "cf_v2_dsoc+cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem,cf_v2_agex,cf_v2_mem")
++(define_reservation "cfv12_omove_1i"
++  "cf_dsoc+cf_agex,cf_dsoc+cf_mem,cf_agex,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr")
++;; Takes 5 cycles.
++(define_reservation "cfv3_alu_1i"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr")
++;; Takes 4 cycles.
++(define_reservation "cfv3_omove_1i"
++  "cf_dsoc+cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr")
+ ;; Lea operation for a memory location.
+ ;; Takes 1 cycle.
+-(define_reservation "cf_v2_lea_10"
+-  "cf_v2_dsoc+cf_v2_agex")
++(define_reservation "cfv123_lea_10"
++  "cf_dsoc,cf_agex")
+ ;; Lea operation for an indexed location.
+ ;; Takes 2 cycles.
+-(define_reservation "cf_v2_lea_i0"
+-  "cf_v2_dsoc+cf_v2_agex,cf_v2_agex")
++(define_reservation "cfv123_lea_i0"
++  "cf_dsoc,cf_agex,cf_agex")
+ ;; Pea operation for a memory location.
+-;; Takes 2 cycle.
+-(define_reservation "cf_v2_pea_11"
+-  "cf_v2_dsoc+cf_v2_agex,cf_v2_agex+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
++;; Takes 2 cycles.
++(define_reservation "cfv12_pea_11"
++  "cf_dsoc,cf_agex,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr")
++;; Takes 2 cycles.
++(define_reservation "cfv3_pea_11"
++  "cf_dsoc,cf_agex,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr")
+ ;; Pea operation for an indexed location.
+ ;; Takes 3 cycles.
+-(define_reservation "cf_v2_pea_i1"
+-  "cf_v2_dsoc+cf_v2_agex,cf_v2_agex,cf_v2_agex+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
+-
+-(define_automaton "cf_v2_emac")
++(define_reservation "cfv12_pea_i1"
++  "cf_dsoc,cf_agex,cf_agex,cf_agex+cf_chr,cf_mem+cf_chr,cf_chr")
++;; Takes 3 cycles.
++(define_reservation "cfv3_pea_i1"
++  "cf_dsoc,cf_agex,cf_agex,cf_agex+cf_chr,cf_mem1+cf_chr,cf_mem2+cf_chr")
+-(define_cpu_unit "cf_v2_emac1,cf_v2_emac2,cf_v2_emac3,cf_v2_emac4"
+-  "cf_v2_emac")
++;; Long multiplication with no mac.
++;; Takes 9-18 cycles.
++(define_reservation "cfv123_mul_l_00"
++  "cf_dsoc,(cf_agex+cf_dsoc)*17,cf_agex")
++
++;; Word multiplication with no mac.
++;; Takes 9 cycles.
++(define_reservation "cfv123_mul_w_00"
++  "cf_dsoc,(cf_agex+cf_dsoc)*8,cf_agex")
++
++;; Long multiplication with no mac.
++;; Takes 11-20 cycles.
++(define_reservation "cfv12_mul_l_10"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem,(cf_agex+cf_dsoc)*17,cf_agex")
++;; Takes 12-21 cycles.
++(define_reservation "cfv3_mul_l_10"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,(cf_agex+cf_dsoc)*17,cf_agex")
++
++;; Word multiplication with no mac.
++;; Takes 11 cycles.
++(define_reservation "cfv12_mul_w_10"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem,(cf_agex+cf_dsoc)*8,cf_agex")
++;; Takes 12 cycles.
++(define_reservation "cfv3_mul_w_10"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,(cf_agex+cf_dsoc)*8,cf_agex")
++
++;; Word multiplication with no mac.
++;; Takes 12 cycles.
++(define_reservation "cfv12_mul_w_i0"
++  "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem,(cf_agex+cf_dsoc)*8,cf_agex")
++;; Takes 13 cycles.
++(define_reservation "cfv3_mul_w_i0"
++  "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,(cf_agex+cf_dsoc)*8,cf_agex")
++
++;; Long multiplication with mac.
++;; Takes 5 cycles.
++(define_reservation "cfv123_mac_l_00"
++  "cf_dsoc,cf_agex,cf_mac1,cf_mac2,cf_mac3,cf_mac4")
+-;; Mul operation with register operands.
+-;; Takes 4 cycles.
+-(define_reservation "cf_v2_mul_00"
+-  "cf_v2_dsoc,cf_v2_agex+cf_v2_emac1,cf_v2_emac2,cf_v2_emac3,cf_v2_emac4")
++;; Word multiplication with mac.
++;; Takes 3 cycles.
++(define_reservation "cfv123_mac_w_00"
++  "cf_dsoc,cf_agex,cf_mac1,cf_mac2")
+-;; Mul operation with implicit load from a memory location.
++;; Long multiplication with mac.
++;; Takes 7 cycles.
++(define_reservation "cfv12_mac_l_10"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem,cf_agex,cf_mac1,cf_mac2,cf_mac3,cf_mac4")
++;; Takes 8 cycles.
++(define_reservation "cfv3_mac_l_10"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex,cf_mac1,cf_mac2,cf_mac3,cf_mac4")
++
++;; Word multiplication with mac.
++;; Takes 5 cycles.
++(define_reservation "cfv12_mac_w_10"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem,cf_agex,cf_mac1,cf_mac2")
+ ;; Takes 6 cycles.
+-(define_reservation "cf_v2_mul_10"
+-  "cf_v2_dsoc,cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex+cf_v2_emac1,cf_v2_emac2,cf_v2_emac3,cf_v2_emac4")
++(define_reservation "cfv3_mac_w_10"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex,cf_mac1,cf_mac2")
+-;; Mul operation with implicit load from an indexed location.
++;; Word multiplication with mac.
++;; Takes 6 cycles.
++(define_reservation "cfv12_mac_w_i0"
++  "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem,cf_agex,cf_mac1,cf_mac2")
+ ;; Takes 7 cycles.
+-(define_reservation "cf_v2_mul_i0"
+-  "cf_v2_dsoc,cf_v2_agex,cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex+cf_v2_emac1,cf_v2_emac2,cf_v2_emac3,cf_v2_emac4")
+-
+-;; Instruction reservations.
+-
+-;; Below reservations are simple derivation from the above reservations.
+-;; Each reservation from the above expands into 3 reservations below - one
+-;; for each instruction size.
+-;; A number in the end of reservation's name is the size of the instruction.
+-
+-(define_insn_reservation "cf_v2_move_00_1" 1
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu,alu_l,move,move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
+-       (eq_attr "op_mem" "00"))
+-  "cf_v2_ib1+cf_v2_move_00")
+-
+-(define_insn_reservation "cf_v2_move_00_2" 1
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu,alu_l,move,move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "00"))
+-  "cf_v2_ib2+cf_v2_move_00")
+-
+-(define_insn_reservation "cf_v2_move_00_3" 1
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu,alu_l,move,move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "00"))
+-  "cf_v2_ib3+cf_v2_move_00")
+-
+-(define_insn_reservation "cf_v2_move_10_1" 4
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
+-       (eq_attr "op_mem" "10"))
+-  "cf_v2_ib1+cf_v2_move_10")
+-
+-(define_insn_reservation "cf_v2_move_10_2" 4
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "10"))
+-  "cf_v2_ib2+cf_v2_move_10")
+-
+-(define_insn_reservation "cf_v2_move_10_3" 4
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "10"))
+-  "cf_v2_ib3+cf_v2_move_10")
+-
+-(define_insn_reservation "cf_v2_move_l_10_1" 3
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
+-       (eq_attr "op_mem" "10"))
+-  "cf_v2_ib1+cf_v2_move_l_10")
+-
+-(define_insn_reservation "cf_v2_move_l_10_2" 3
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "10"))
+-  "cf_v2_ib2+cf_v2_move_l_10")
+-
+-(define_insn_reservation "cf_v2_move_l_10_3" 3
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "10"))
+-  "cf_v2_ib3+cf_v2_move_l_10")
+-
+-(define_insn_reservation "cf_v2_move_i0_2" 5
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "i0"))
+-  "cf_v2_ib2+cf_v2_move_i0")
+-
+-(define_insn_reservation "cf_v2_move_i0_3" 5
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "i0"))
+-  "cf_v2_ib3+cf_v2_move_i0")
+-
+-(define_insn_reservation "cf_v2_move_l_i0_2" 4
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "i0"))
+-  "cf_v2_ib2+cf_v2_move_l_i0")
+-
+-(define_insn_reservation "cf_v2_move_l_i0_3" 4
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "i0"))
+-  "cf_v2_ib3+cf_v2_move_l_i0")
+-
+-(define_insn_reservation "cf_v2_move_01_1" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move,move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
+-       (eq_attr "op_mem" "01"))
+-  "cf_v2_ib1+cf_v2_move_01")
+-
+-(define_insn_reservation "cf_v2_move_01_2" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move,move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "01"))
+-  "cf_v2_ib2+cf_v2_move_01")
+-
+-(define_insn_reservation "cf_v2_move_01_3" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move,move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "01"))
+-  "cf_v2_ib3+cf_v2_move_01")
++(define_reservation "cfv3_mac_w_i0"
++  "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex,cf_mac1,cf_mac2")
+-(define_insn_reservation "cf_v2_move_0i_2" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move,move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "0i"))
+-  "cf_v2_ib2+cf_v2_move_0i")
+-
+-(define_insn_reservation "cf_v2_move_0i_3" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move,move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "0i"))
+-  "cf_v2_ib3+cf_v2_move_0i")
+-
+-(define_insn_reservation "cf_v2_move_11_1" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
+-       (eq_attr "op_mem" "11"))
+-  "cf_v2_ib1+cf_v2_move_11")
+-
+-(define_insn_reservation "cf_v2_move_11_2" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "11"))
+-  "cf_v2_ib2+cf_v2_move_11")
+-
+-(define_insn_reservation "cf_v2_move_11_3" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "11"))
+-  "cf_v2_ib3+cf_v2_move_11")
+-
+-(define_insn_reservation "cf_v2_move_l_11_1" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
+-       (eq_attr "op_mem" "11"))
+-  "cf_v2_ib1+cf_v2_move_l_11")
+-
+-(define_insn_reservation "cf_v2_move_l_11_2" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "11"))
+-  "cf_v2_ib2+cf_v2_move_l_11")
+-
+-(define_insn_reservation "cf_v2_move_l_11_3" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "11"))
+-  "cf_v2_ib3+cf_v2_move_l_11")
+-
+-(define_insn_reservation "cf_v2_move_i1_2" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "i1"))
+-  "cf_v2_ib2+cf_v2_move_i1")
+-
+-(define_insn_reservation "cf_v2_move_i1_3" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "i1"))
+-  "cf_v2_ib3+cf_v2_move_i1")
+-
+-(define_insn_reservation "cf_v2_move_l_i1_2" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "i1"))
+-  "cf_v2_ib2+cf_v2_move_l_i1")
+-
+-(define_insn_reservation "cf_v2_move_l_i1_3" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "i1"))
+-  "cf_v2_ib3+cf_v2_move_l_i1")
++;; Multiplication with emac.
++;; Takes 4 cycles.
++(define_reservation "cfv123_emac_00"
++  "cf_dsoc,cf_agex+cf_mac1,cf_mac2,cf_mac3,cf_mac4")
+-(define_insn_reservation "cf_v2_move_1i_2" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "1i"))
+-  "cf_v2_ib2+cf_v2_move_1i")
++;; Multiplication with emac.
++;; Takes 6 cycles.
++(define_reservation "cfv12_emac_10"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem,cf_agex+cf_mac1,cf_mac2,cf_mac3,cf_mac4")
++;; Takes 7 cycles.
++(define_reservation "cfv3_emac_10"
++  "cf_dsoc,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex+cf_mac1,cf_mac2,cf_mac3,cf_mac4")
+-(define_insn_reservation "cf_v2_move_1i_3" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "alu_l,move"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "1i"))
+-  "cf_v2_ib3+cf_v2_move_1i")
++;; Word multiplication with emac.
++;; Takes 7 cycles.
++(define_reservation "cfv12_emac_w_i0"
++  "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem,cf_agex+cf_mac1,cf_mac2,cf_mac3,cf_mac4")
++;; Takes 8 cycles.
++(define_reservation "cfv3_emac_w_i0"
++  "cf_dsoc,cf_agex,cf_agex,cf_dsoc+cf_mem1,cf_dsoc+cf_mem2,cf_agex+cf_mac1,cf_mac2,cf_mac3,cf_mac4")
+-(define_insn_reservation "cf_v2_move_l_1i_2" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "1i"))
+-  "cf_v2_ib2+cf_v2_move_l_1i")
++;; Return instruction.
++;; ??? As return reads target address from stack, use a mem-read reservation
++;; ??? for it.
++;; ??? It's not clear what the core does during these 5 cycles.
++;; ??? Luckily, we don't care that much about an insn that won't be moved.
++;; Takes 5 cycles.
++(define_reservation "cfv12_rts" "cfv12_alu_10")
++;; Takes 8 cycles.
++(define_reservation "cfv3_rts" "cfv3_alu_10")
+-(define_insn_reservation "cf_v2_move_l_1i_3" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "move_l"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "1i"))
+-  "cf_v2_ib3+cf_v2_move_l_1i")
++;; Call instruction.
++;; ??? It's not clear what reservation is best to use for calls.
++;; ??? For now we use mem-write + return reservations to reflect the fact of
++;; ??? pushing and poping return address to and from the stack.
++;; Takes 3 cycles.
++(define_reservation "cfv12_call" "cfv12_alu_01,cfv12_rts")
++;; Takes 1/5 cycles.
++(define_reservation "cfv3_call" "cfv3_alu_01,cfv3_rts")
+-(define_insn_reservation "cf_v2_lea_10_1" 1
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "lea"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
+-       (eq_attr "op_mem" "10"))
+-  "cf_v2_ib1+cf_v2_lea_10")
++;; Conditional branch instruction.
++;; ??? Branch reservations are unclear to me so far.  Luckily, we don't care
++;; ??? that much about branches.
++;; Takes 2 cycles.
++(define_reservation "cfv12_bcc" "cfv123_alu_00")
++;; Takes 1 cycles.
++(define_reservation "cfv3_bcc" "cfv123_alu_00")
+-(define_insn_reservation "cf_v2_lea_10_2" 1
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "lea"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "10"))
+-  "cf_v2_ib2+cf_v2_lea_10")
++;; Unconditional branch instruciton.
++;; Takes 2 cycles.
++(define_reservation "cfv12_bra" "cfv12_alu_01")
++;; Takes 1 cycles.
++(define_reservation "cfv3_bra" "cfv3_alu_01")
+-(define_insn_reservation "cf_v2_lea_10_3" 1
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "lea"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "10"))
+-  "cf_v2_ib3+cf_v2_lea_10")
++;; Computed jump instruction.
++;; Takes 3 cycles.
++(define_reservation "cfv12_jmp"
++  "(cf_dsoc+cf_agex)*3")
++;; Takes 5 cycles.
++(define_reservation "cfv3_jmp"
++  "(cf_dsoc+cf_agex)*5")
+-(define_insn_reservation "cf_v2_lea_i0_2" 2
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "lea"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "i0"))
+-  "cf_v2_ib2+cf_v2_lea_i0")
++;; Instruction reservations.
+-(define_insn_reservation "cf_v2_lea_i0_3" 2
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "lea"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "i0"))
+-  "cf_v2_ib3+cf_v2_lea_i0")
++;; Below reservations are simple derivation from the above reservations.
++;; Each reservation from the above expands into 3 reservations below - one
++;; for each instruction size.
++;; A number in the end of reservation's name is the size of the instruction.
+-(define_insn_reservation "cf_v2_pea_11_1" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "pea"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
++(define_insn_reservation "cfv123_alu_00_1" 1
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "00"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv123_alu_00")
++
++(define_insn_reservation "cfv123_alu_00_2" 1
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "00"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv123_alu_00")
++
++(define_insn_reservation "cfv123_alu_00_3" 1
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "00"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv123_alu_00")
++
++(define_insn_reservation "cfv1_alu_10_1" 3
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_alu_10")
++
++(define_insn_reservation "cfv1_alu_10_2" 3
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_alu_10")
++
++(define_insn_reservation "cfv1_alu_10_3" 3
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_alu_10")
++
++(define_insn_reservation "cfv1_omove_10_1" 2
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_omove_10")
++
++(define_insn_reservation "cfv1_omove_10_2" 2
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_omove_10")
++
++(define_insn_reservation "cfv1_omove_10_3" 2
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_omove_10")
++
++(define_insn_reservation "cfv2_alu_10_1" 3
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_alu_10")
++
++(define_insn_reservation "cfv2_alu_10_2" 3
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_alu_10")
++
++(define_insn_reservation "cfv2_alu_10_3" 3
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_alu_10")
++
++(define_insn_reservation "cfv2_omove_10_1" 2
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_omove_10")
++
++(define_insn_reservation "cfv2_omove_10_2" 2
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_omove_10")
++
++(define_insn_reservation "cfv2_omove_10_3" 2
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_omove_10")
++
++(define_insn_reservation "cfv3_alu_10_1" 4
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_alu_10")
++
++(define_insn_reservation "cfv3_alu_10_2" 4
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv3_alu_10")
++
++(define_insn_reservation "cfv3_alu_10_3" 4
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_alu_10")
++
++(define_insn_reservation "cfv3_omove_10_1" 3
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_omove_10")
++
++(define_insn_reservation "cfv3_omove_10_2" 3
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv3_omove_10")
++
++(define_insn_reservation "cfv3_omove_10_3" 3
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "10"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_omove_10")
++
++(define_insn_reservation "cfv1_alu_i0_2" 4
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift"))
++          (eq_attr "op_mem" "i0"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_alu_i0")
++
++(define_insn_reservation "cfv1_alu_i0_3" 4
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift"))
++          (eq_attr "op_mem" "i0"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_alu_i0")
++
++(define_insn_reservation "cfv1_omove_i0_2" 3
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "i0"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_omove_i0")
++
++(define_insn_reservation "cfv1_omove_i0_3" 3
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "i0"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_omove_i0")
++
++(define_insn_reservation "cfv2_alu_i0_2" 4
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "i0"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_alu_i0")
++
++(define_insn_reservation "cfv2_alu_i0_3" 4
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "i0"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_alu_i0")
++
++(define_insn_reservation "cfv2_omove_i0_2" 3
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "i0"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_omove_i0")
++
++(define_insn_reservation "cfv2_omove_i0_3" 3
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "i0"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_omove_i0")
++
++(define_insn_reservation "cfv3_alu_i0_2" 5
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "i0"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv3_alu_i0")
++
++(define_insn_reservation "cfv3_alu_i0_3" 5
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "i0"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_alu_i0")
++
++(define_insn_reservation "cfv3_omove_i0_2" 4
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "i0"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv3_omove_i0")
++
++(define_insn_reservation "cfv3_omove_i0_3" 4
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "i0"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_omove_i0")
++
++(define_insn_reservation "cfv12_alu_01_1" 1
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "01"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_alu_01")
++
++(define_insn_reservation "cfv12_alu_01_2" 1
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "01"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_alu_01")
++
++(define_insn_reservation "cfv12_alu_01_3" 1
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "01"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_alu_01")
++
++(define_insn_reservation "cfv3_alu_01_1" 1
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "01"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_alu_01")
++
++(define_insn_reservation "cfv3_alu_01_2" 1
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "01"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv3_alu_01")
++
++(define_insn_reservation "cfv3_alu_01_3" 1
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "01"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_alu_01")
++
++(define_insn_reservation "cfv12_alu_0i_2" 2
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "0i"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_alu_0i")
++
++(define_insn_reservation "cfv12_alu_0i_3" 2
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "0i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_alu_0i")
++
++(define_insn_reservation "cfv3_alu_0i_2" 2
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "0i"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv3_alu_0i")
++
++(define_insn_reservation "cfv3_alu_0i_3" 2
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "0i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_alu_0i")
++
++(define_insn_reservation "cfv1_alu_11_1" 1
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_alu_11")
++
++(define_insn_reservation "cfv1_alu_11_2" 1
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_alu_11")
++
++(define_insn_reservation "cfv1_alu_11_3" 1
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_alu_11")
++
++(define_insn_reservation "cfv1_omove_11_1" 1
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_omove_11")
++
++(define_insn_reservation "cfv1_omove_11_2" 1
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_omove_11")
++
++(define_insn_reservation "cfv1_omove_11_3" 1
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_omove_11")
++
++(define_insn_reservation "cfv2_alu_11_1" 1
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_alu_11")
++
++(define_insn_reservation "cfv2_alu_11_2" 1
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_alu_11")
++
++(define_insn_reservation "cfv2_alu_11_3" 1
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_alu_11")
++
++(define_insn_reservation "cfv2_omove_11_1" 1
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_omove_11")
++
++(define_insn_reservation "cfv2_omove_11_2" 1
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_omove_11")
++
++(define_insn_reservation "cfv2_omove_11_3" 1
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_omove_11")
++
++(define_insn_reservation "cfv3_alu_11_1" 1
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_alu_11")
++
++(define_insn_reservation "cfv3_alu_11_2" 1
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "size" "2"))
+        (eq_attr "op_mem" "11"))
+-  "cf_v2_ib1+cf_v2_pea_11")
++  "cf_ib2+cfv3_alu_11")
+-(define_insn_reservation "cf_v2_pea_11_2" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "pea"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
++(define_insn_reservation "cfv3_alu_11_3" 1
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_alu_11")
++
++(define_insn_reservation "cfv3_omove_11_1" 1
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_omove_11")
++
++(define_insn_reservation "cfv3_omove_11_2" 1
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "size" "2"))
+        (eq_attr "op_mem" "11"))
+-  "cf_v2_ib2+cf_v2_pea_11")
++  "cf_ib2+cfv3_omove_11")
+-(define_insn_reservation "cf_v2_pea_11_3" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "pea"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "11"))
+-  "cf_v2_ib3+cf_v2_pea_11")
++(define_insn_reservation "cfv3_omove_11_3" 1
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_omove_11")
++
++(define_insn_reservation "cfv1_alu_i1_2" 2
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_alu_i1")
++
++(define_insn_reservation "cfv1_alu_i1_3" 2
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_alu_i1")
++
++(define_insn_reservation "cfv1_omove_i1_2" 2
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_omove_i1")
++
++(define_insn_reservation "cfv1_omove_i1_3" 2
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_omove_i1")
++
++(define_insn_reservation "cfv2_alu_i1_2" 2
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_alu_i1")
++
++(define_insn_reservation "cfv2_alu_i1_3" 2
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_alu_i1")
++
++(define_insn_reservation "cfv2_omove_i1_2" 2
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_omove_i1")
++
++(define_insn_reservation "cfv2_omove_i1_3" 2
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_omove_i1")
++
++(define_insn_reservation "cfv3_alu_i1_2" 2
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv3_alu_i1")
++
++(define_insn_reservation "cfv3_alu_i1_3" 2
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_alu_i1")
++
++(define_insn_reservation "cfv3_omove_i1_2" 2
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv3_omove_i1")
++
++(define_insn_reservation "cfv3_omove_i1_3" 2
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_omove_i1")
++
++(define_insn_reservation "cfv1_alu_1i_2" 2
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift"))
++          (eq_attr "op_mem" "1i"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_alu_1i")
++
++(define_insn_reservation "cfv1_alu_1i_3" 2
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift"))
++          (eq_attr "op_mem" "1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_alu_1i")
++
++(define_insn_reservation "cfv1_omove_1i_2" 2
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "1i"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_omove_1i")
++
++(define_insn_reservation "cfv1_omove_1i_3" 2
++  (and (and (and (eq_attr "cpu" "cfv1")
++               (eq_attr "type" "
++clr,clr_l,mov3q_l,move,moveq_l,tst,
++move_l,tst_l"))
++          (eq_attr "op_mem" "1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_omove_1i")
++
++(define_insn_reservation "cfv2_alu_1i_2" 2
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "1i"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_alu_1i")
++
++(define_insn_reservation "cfv2_alu_1i_3" 2
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_alu_1i")
++
++(define_insn_reservation "cfv2_omove_1i_2" 2
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "1i"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_omove_1i")
++
++(define_insn_reservation "cfv2_omove_1i_3" 2
++  (and (and (and (eq_attr "cpu" "cfv2")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_omove_1i")
++
++(define_insn_reservation "cfv3_alu_1i_2" 2
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "1i"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv3_alu_1i")
++
++(define_insn_reservation "cfv3_alu_1i_3" 2
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++alu_l,aluq_l,bitr,bitrw,cmp,cmp_l,alux_l,ext,neg_l,scc,shift,
++clr,clr_l,mov3q_l,move,moveq_l,tst"))
++          (eq_attr "op_mem" "1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_alu_1i")
++
++(define_insn_reservation "cfv3_omove_1i_2" 2
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "1i"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv3_omove_1i")
++
++(define_insn_reservation "cfv3_omove_1i_3" 2
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "
++move_l,tst_l"))
++          (eq_attr "op_mem" "1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_omove_1i")
++
++(define_insn_reservation "cfv123_lea_10_1" 1
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++               (eq_attr "type" "lea"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv123_lea_10")
++
++(define_insn_reservation "cfv123_lea_10_2" 1
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++               (eq_attr "type" "lea"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv123_lea_10")
++
++(define_insn_reservation "cfv123_lea_10_3" 1
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++               (eq_attr "type" "lea"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv123_lea_10")
++
++(define_insn_reservation "cfv123_lea_i0_2" 2
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++               (eq_attr "type" "lea"))
++          (eq_attr "op_mem" "i0,i1"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv123_lea_i0")
++
++(define_insn_reservation "cfv123_lea_i0_3" 2
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++               (eq_attr "type" "lea"))
++          (eq_attr "op_mem" "i0,i1"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv123_lea_i0")
++
++(define_insn_reservation "cfv12_pea_11_1" 1
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++               (eq_attr "type" "pea"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_pea_11")
++
++(define_insn_reservation "cfv12_pea_11_2" 1
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++               (eq_attr "type" "pea"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_pea_11")
++
++(define_insn_reservation "cfv12_pea_11_3" 1
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++               (eq_attr "type" "pea"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_pea_11")
++
++(define_insn_reservation "cfv3_pea_11_1" 1
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "pea"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_pea_11")
++
++(define_insn_reservation "cfv3_pea_11_2" 1
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "pea"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv3_pea_11")
++
++(define_insn_reservation "cfv3_pea_11_3" 1
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "pea"))
++          (eq_attr "op_mem" "11"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_pea_11")
++
++(define_insn_reservation "cfv12_pea_i1_2" 2
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++               (eq_attr "type" "pea"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_pea_i1")
++
++(define_insn_reservation "cfv12_pea_i1_3" 2
++  (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++               (eq_attr "type" "pea"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_pea_i1")
++
++(define_insn_reservation "cfv3_pea_i1_2" 2
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "pea"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv3_pea_i1")
++
++(define_insn_reservation "cfv3_pea_i1_3" 2
++  (and (and (and (eq_attr "cpu" "cfv3")
++               (eq_attr "type" "pea"))
++          (eq_attr "op_mem" "i1"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_pea_i1")
++
++(define_insn_reservation "cfv123_mul_l_00_1" 18
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "00,01,0i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv123_mul_l_00")
++
++(define_insn_reservation "cfv123_mul_l_00_2" 18
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "00,01,0i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv123_mul_l_00")
++
++(define_insn_reservation "cfv123_mul_l_00_3" 18
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "00,01,0i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv123_mul_l_00")
++
++(define_insn_reservation "cfv123_mul_w_00_1" 9
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "00,01,0i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv123_mul_w_00")
++
++(define_insn_reservation "cfv123_mul_w_00_2" 9
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "00,01,0i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv123_mul_w_00")
++
++(define_insn_reservation "cfv123_mul_w_00_3" 9
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "00,01,0i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv123_mul_w_00")
++
++(define_insn_reservation "cfv12_mul_l_10_1" 20
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_mul_l_10")
++
++(define_insn_reservation "cfv12_mul_l_10_2" 20
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_mul_l_10")
++
++(define_insn_reservation "cfv12_mul_l_10_3" 20
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_mul_l_10")
++
++(define_insn_reservation "cfv3_mul_l_10_1" 21
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_mul_l_10")
++
++(define_insn_reservation "cfv3_mul_l_10_2" 21
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv3_mul_l_10")
++
++(define_insn_reservation "cfv3_mul_l_10_3" 21
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_mul_l_10")
++
++(define_insn_reservation "cfv12_mul_w_10_1" 11
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_mul_w_10")
++
++(define_insn_reservation "cfv12_mul_w_10_2" 11
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_mul_w_10")
++
++(define_insn_reservation "cfv12_mul_w_10_3" 11
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_mul_w_10")
++
++(define_insn_reservation "cfv3_mul_w_10_1" 12
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_mul_w_10")
++
++(define_insn_reservation "cfv3_mul_w_10_2" 12
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv3_mul_w_10")
++
++(define_insn_reservation "cfv3_mul_w_10_3" 12
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_mul_w_10")
++
++(define_insn_reservation "cfv12_mul_w_i0_2" 12
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "i0,i1"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_mul_w_i0")
++
++(define_insn_reservation "cfv12_mul_w_i0_3" 12
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "i0,i1"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_mul_w_i0")
++
++(define_insn_reservation "cfv3_mul_w_i0_2" 13
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "i0,i1"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv3_mul_w_i0")
++
++(define_insn_reservation "cfv3_mul_w_i0_3" 13
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "no"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "i0,i1"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_mul_w_i0")
++
++(define_insn_reservation "cfv123_mac_l_00_1" 5
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "00,01,0i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv123_mac_l_00")
++
++(define_insn_reservation "cfv123_mac_l_00_2" 5
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "00,01,0i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv123_mac_l_00")
++
++(define_insn_reservation "cfv123_mac_l_00_3" 5
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "00,01,0i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv123_mac_l_00")
++
++(define_insn_reservation "cfv123_mac_w_00_1" 3
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "00,01,0i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv123_mac_w_00")
++
++(define_insn_reservation "cfv123_mac_w_00_2" 3
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "00,01,0i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv123_mac_w_00")
++
++(define_insn_reservation "cfv123_mac_w_00_3" 3
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "00,01,0i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv123_mac_w_00")
++
++(define_insn_reservation "cfv12_mac_l_10_1" 7
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_mac_l_10")
++
++(define_insn_reservation "cfv12_mac_l_10_2" 7
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_mac_l_10")
++
++(define_insn_reservation "cfv12_mac_l_10_3" 7
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_mac_l_10")
++
++(define_insn_reservation "cfv3_mac_l_10_1" 8
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_mac_l_10")
++
++(define_insn_reservation "cfv3_mac_l_10_2" 8
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv3_mac_l_10")
++
++(define_insn_reservation "cfv3_mac_l_10_3" 8
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_mac_l_10")
++
++(define_insn_reservation "cfv12_mac_w_10_1" 5
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_mac_w_10")
++
++(define_insn_reservation "cfv12_mac_w_10_2" 5
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_mac_w_10")
++
++(define_insn_reservation "cfv12_mac_w_10_3" 5
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_mac_w_10")
++
++(define_insn_reservation "cfv3_mac_w_10_1" 6
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_mac_w_10")
++
++(define_insn_reservation "cfv3_mac_w_10_2" 6
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv3_mac_w_10")
++
++(define_insn_reservation "cfv3_mac_w_10_3" 6
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_mac_w_10")
++
++(define_insn_reservation "cfv12_mac_w_i0_2" 6
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "i0,i1"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_mac_w_i0")
++
++(define_insn_reservation "cfv12_mac_w_i0_3" 6
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "i0,i1"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_mac_w_i0")
++
++(define_insn_reservation "cfv3_mac_w_i0_2" 7
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "i0,i1"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv3_mac_w_i0")
++
++(define_insn_reservation "cfv3_mac_w_i0_3" 7
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_mac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "i0,i1"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_mac_w_i0")
++
++(define_insn_reservation "cfv123_emac_00_1" 4
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_l,mul_w"))
++          (eq_attr "op_mem" "00,01,0i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv123_emac_00")
++
++(define_insn_reservation "cfv123_emac_00_2" 4
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_l,mul_w"))
++          (eq_attr "op_mem" "00,01,0i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv123_emac_00")
++
++(define_insn_reservation "cfv123_emac_00_3" 4
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_l,mul_w"))
++          (eq_attr "op_mem" "00,01,0i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv123_emac_00")
++
++(define_insn_reservation "cfv12_emac_l_10_1" 6
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_emac_10")
++
++(define_insn_reservation "cfv12_emac_l_10_2" 6
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_emac_10")
++
++(define_insn_reservation "cfv12_emac_l_10_3" 6
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_emac_10")
++
++(define_insn_reservation "cfv3_emac_l_10_1" 7
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_emac_10")
++
++(define_insn_reservation "cfv3_emac_l_10_2" 7
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv3_emac_10")
++
++(define_insn_reservation "cfv3_emac_l_10_3" 7
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_l"))
++          (eq_attr "op_mem" "10,i0,i1,11,1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_emac_10")
++
++(define_insn_reservation "cfv12_emac_w_10_1" 6
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_emac_10")
++
++(define_insn_reservation "cfv12_emac_w_10_2" 6
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_emac_10")
++
++(define_insn_reservation "cfv12_emac_w_10_3" 6
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_emac_10")
++
++(define_insn_reservation "cfv3_emac_w_10_1" 7
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_emac_10")
++
++(define_insn_reservation "cfv3_emac_w_10_2" 7
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv3_emac_10")
++
++(define_insn_reservation "cfv3_emac_w_10_3" 7
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "10,11,1i"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_emac_10")
++
++(define_insn_reservation "cfv12_emac_w_i0_2" 7
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "i0,i1"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv12_emac_w_i0")
++
++(define_insn_reservation "cfv12_emac_w_i0_3" 7
++  (and (and (and (and (eq_attr "cpu" "cfv1,cfv2")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "i0,i1"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_emac_w_i0")
++
++(define_insn_reservation "cfv3_emac_w_i0_2" 8
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "i0,i1"))
++       (eq_attr "size" "1,2"))
++  "cf_ib2+cfv3_emac_w_i0")
++
++(define_insn_reservation "cfv3_emac_w_i0_3" 8
++  (and (and (and (and (eq_attr "cpu" "cfv3")
++                    (eq_attr "mac" "cf_emac"))
++               (eq_attr "type" "mul_w"))
++          (eq_attr "op_mem" "i0,i1"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_emac_w_i0")
++
++(define_insn_reservation "cfv12_rts" 5
++  (and (eq_attr "cpu" "cfv1,cfv2")
++       (eq_attr "type" "rts"))
++  "cf_ib1+cfv12_rts")
++
++(define_insn_reservation "cfv3_rts" 8
++  (and (eq_attr "cpu" "cfv3")
++       (eq_attr "type" "rts"))
++  "cf_ib1+cfv3_rts")
++
++(define_insn_reservation "cfv12_call_1" 3
++  (and (and (eq_attr "cpu" "cfv1,cfv2")
++          (eq_attr "type" "bsr,jsr"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_call")
++
++(define_insn_reservation "cfv12_call_2" 3
++  (and (and (eq_attr "cpu" "cfv1,cfv2")
++          (eq_attr "type" "bsr,jsr"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_call")
++
++(define_insn_reservation "cfv12_call_3" 3
++  (and (and (eq_attr "cpu" "cfv1,cfv2")
++          (eq_attr "type" "bsr,jsr"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_call")
++
++(define_insn_reservation "cfv3_call_1" 1
++  (and (and (eq_attr "cpu" "cfv3")
++          (eq_attr "type" "bsr,jsr"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_call")
++
++(define_insn_reservation "cfv3_call_2" 1
++  (and (and (eq_attr "cpu" "cfv3")
++          (eq_attr "type" "bsr,jsr"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv3_call")
++
++(define_insn_reservation "cfv3_call_3" 1
++  (and (and (eq_attr "cpu" "cfv3")
++          (eq_attr "type" "bsr,jsr"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_call")
++
++(define_insn_reservation "cfv12_bcc_1" 2
++  (and (and (eq_attr "cpu" "cfv1,cfv2")
++          (eq_attr "type" "bcc"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_bcc")
++
++(define_insn_reservation "cfv12_bcc_2" 2
++  (and (and (eq_attr "cpu" "cfv1,cfv2")
++          (eq_attr "type" "bcc"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_bcc")
++
++(define_insn_reservation "cfv12_bcc_3" 2
++  (and (and (eq_attr "cpu" "cfv1,cfv2")
++          (eq_attr "type" "bcc"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_bcc")
++
++(define_insn_reservation "cfv3_bcc_1" 1
++  (and (and (eq_attr "cpu" "cfv3")
++          (eq_attr "type" "bcc"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_bcc")
++
++(define_insn_reservation "cfv3_bcc_2" 1
++  (and (and (eq_attr "cpu" "cfv3")
++          (eq_attr "type" "bcc"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv3_bcc")
++
++(define_insn_reservation "cfv3_bcc_3" 1
++  (and (and (eq_attr "cpu" "cfv3")
++          (eq_attr "type" "bcc"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_bcc")
++
++(define_insn_reservation "cfv12_bra_1" 2
++  (and (and (eq_attr "cpu" "cfv1,cfv2")
++          (eq_attr "type" "bra"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_bra")
++
++(define_insn_reservation "cfv12_bra_2" 2
++  (and (and (eq_attr "cpu" "cfv1,cfv2")
++          (eq_attr "type" "bra"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_bra")
++
++(define_insn_reservation "cfv12_bra_3" 2
++  (and (and (eq_attr "cpu" "cfv1,cfv2")
++          (eq_attr "type" "bra"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_bra")
++
++(define_insn_reservation "cfv3_bra_1" 1
++  (and (and (eq_attr "cpu" "cfv3")
++          (eq_attr "type" "bra"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_bra")
++
++(define_insn_reservation "cfv3_bra_2" 1
++  (and (and (eq_attr "cpu" "cfv3")
++          (eq_attr "type" "bra"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv3_bra")
++
++(define_insn_reservation "cfv3_bra_3" 1
++  (and (and (eq_attr "cpu" "cfv3")
++          (eq_attr "type" "bra"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_bra")
++
++(define_insn_reservation "cfv12_jmp_1" 3
++  (and (and (eq_attr "cpu" "cfv1,cfv2")
++          (eq_attr "type" "jmp"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv12_jmp")
++
++(define_insn_reservation "cfv12_jmp_2" 3
++  (and (and (eq_attr "cpu" "cfv1,cfv2")
++          (eq_attr "type" "jmp"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv12_jmp")
++
++(define_insn_reservation "cfv12_jmp_3" 3
++  (and (and (eq_attr "cpu" "cfv1,cfv2")
++          (eq_attr "type" "jmp"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv12_jmp")
++
++(define_insn_reservation "cfv3_jmp_1" 5
++  (and (and (eq_attr "cpu" "cfv3")
++          (eq_attr "type" "jmp"))
++       (eq_attr "size" "1"))
++  "cf_ib1+cfv3_jmp")
++
++(define_insn_reservation "cfv3_jmp_2" 5
++  (and (and (eq_attr "cpu" "cfv3")
++          (eq_attr "type" "jmp"))
++       (eq_attr "size" "2"))
++  "cf_ib2+cfv3_jmp")
++
++(define_insn_reservation "cfv3_jmp_3" 5
++  (and (and (eq_attr "cpu" "cfv3")
++          (eq_attr "type" "jmp"))
++       (eq_attr "size" "3"))
++  "cf_ib3+cfv3_jmp")
++
++(define_insn_reservation "cfv12_unlk" 2
++  (and (eq_attr "cpu" "cfv1,cfv2")
++       (eq_attr "type" "unlk"))
++  "cf_ib1+cfv12_alu_10")
++
++(define_insn_reservation "cfv3_unlk" 3
++  (and (eq_attr "cpu" "cfv3")
++       (eq_attr "type" "unlk"))
++  "cf_ib1+cfv3_alu_10")
++
++;; Dummy reservation for instructions that are not handled.
++(define_insn_reservation "cfv123_guess" 3
++  (and (eq_attr "cpu" "cfv1,cfv2,cfv3")
++       (eq_attr "type" "falu,fbcc,fcmp,fdiv,fmove,fmul,fneg,fsqrt,ftst,
++                        div_w,div_l,link,mvsz,nop,trap,unknown"))
++  "cf_ib3+cfv123_guess+cf_dsoc+cf_agex+cf_mem")
++
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++
++;; Below is pipeline description of ColdFire V4 core.
++;; It is substantially different from the description of V1, V2 or V3 cores,
++;; primarily due to no need to model the instruction buffer.
++;;
++;; V4 pipeline model uses a completely separate set of cpu units.
+-(define_insn_reservation "cf_v2_pea_i1_2" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "pea"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-       (eq_attr "op_mem" "i1"))
+-  "cf_v2_ib2+cf_v2_pea_i1")
++;; Operand Execution Pipeline.
++(define_automaton "cfv4_oep")
+-(define_insn_reservation "cf_v2_pea_i1_3" 0
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "pea"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-       (eq_attr "op_mem" "i1"))
+-  "cf_v2_ib3+cf_v2_pea_i1")
++(define_cpu_unit "cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_da"
++  "cfv4_oep")
+-(define_insn_reservation "cf_v2_mul_00_1" 4
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "mul"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
++;; This automaton is used to support CFv4 dual-issue.
++(define_automaton "cfv4_ds")
++
++;; V4 has 3 cases of dual-issue.
++;; After issuing a cfv4_pOEPx instruction, it'll be possible to issue
++;; a cfv4_sOEPx instruction on the same cycle (see final_presence_sets below).
++(define_cpu_unit "cfv4_pOEP1,cfv4_sOEP1,
++                  cfv4_pOEP2,cfv4_sOEP2,
++                  cfv4_pOEP3,cfv4_sOEP3" "cfv4_ds")
++
++(final_presence_set "cfv4_sOEP1" "cfv4_pOEP1")
++(final_presence_set "cfv4_sOEP2" "cfv4_pOEP2")
++(final_presence_set "cfv4_sOEP3" "cfv4_pOEP3")
++
++;; Reservation for instructions that don't allow dual-issue.
++(define_reservation "cfv4_ds" "cfv4_pOEP1+cfv4_sOEP1+
++                               cfv4_pOEP2+cfv4_sOEP2+
++                               cfv4_pOEP3+cfv4_sOEP3")
++
++;; Memory access resource.
++(define_automaton "cfv4_mem")
++
++(define_cpu_unit "cfv4_mem" "cfv4_mem")
++
++;; EMAC.
++(define_automaton "cfv4_emac")
++
++(define_cpu_unit "cfv4_emac" "cfv4_emac")
++
++;; FPU.
++(define_automaton "cfv4_fp")
++
++(define_cpu_unit "cfv4_fp" "cfv4_fp")
++
++;; Automaton for unknown instruction.
++(define_automaton "cfv4_guess")
++
++(define_query_cpu_unit "cfv4_guess" "cfv4_guess")
++
++;; This bypass allows 1st case of dual-issue.
++(define_bypass 0 "cfv4_00_oag_pOEP1,cfv4_10_pOEP1,cfv4_i0_pOEP1"
++  "cfv4_00_oag,cfv4_00_oag_pOEP3_sOEP12,cfv4_00_oag_pOEP1,
++   cfv4_00_oag_moveql,cfv4_00_ex_sOEP13")
++
++;; The following bypasses decrease the latency of producers if it modifies
++;; a target register in the EX stage and the consumer also uses
++;; that register in the EX stage.
++(define_bypass 1 "cfv4_00_ex" "cfv4_00_ex,cfv4_00_ex_sOEP13")
++(define_bypass 1 "cfv4_00_ex" "cfv4_10,cfv4_10_pOEP1,cfv4_i0,cfv4_i0_pOEP1"
++  "!m68k_sched_address_bypass_p")
++
++;; Indexed loads with scale factors 2 and 4 require an update of the index
++;; register in the register file.  Considering that the index register is
++;; only needed at the second cycle of address generation, we get
++;; a latency of 4.
++;; Producers for indexed loads with scale factor 1 should have
++;; a latency of 3.  Since we're only allowed one bypass, we handle it
++;; in the adjust_cost hook.
++(define_bypass 4
++  "cfv4_00_oag,cfv4_00_oag_pOEP3_sOEP12,cfv4_00_oag_lea,cfv4_00_oag_pOEP1,
++   cfv4_00_oag_moveql"
++  "cfv4_i0,cfv4_i0_pOEP1"
++  "m68k_sched_indexed_address_bypass_p")
++
++;; First part of cfv4_00.
++;; If issued in pairs with cfv4_movel_?0, the cost should be increased.
++;; ??? Is it possible that combined cfv4_movel_00 and cfv4_oag_00 instructions
++;; have longer latency than the two instructions emitted sequentially?
++;; Due to register renaming, the result of the sequence would be available
++;; after 3 cycles, instead of 4 for combined instruction?
++(define_insn_reservation "cfv4_00_oag" 1
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "alu_l,aluq_l,clr_l,cmp_l,mov3q_l,neg_l"))
+        (eq_attr "op_mem" "00"))
+-  "cf_v2_ib1+cf_v2_mul_00")
++  "cfv4_sOEP1|cfv4_sOEP3|(cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex)")
+-(define_insn_reservation "cf_v2_mul_00_2" 4
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "mul"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
++(define_insn_reservation "cfv4_00_oag_pOEP3_sOEP12" 1
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "move_l,mov3q_l,clr_l"))
++       (and (eq_attr "op_mem" "00")
++          (and (eq_attr "opx_type" "Rn")
++               (eq_attr "opy_type" "none,imm_q,imm_w,imm_l"))))
++  "cfv4_sOEP1|cfv4_sOEP2|(cfv4_pOEP3,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex)")
++
++(define_insn_reservation "cfv4_00_oag_lea" 1
++  (and (eq_attr "cpu" "cfv4")
++       (eq_attr "type" "lea"))
++  "cfv4_pOEP3,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex")
++
++(define_insn_reservation "cfv4_00_oag_pOEP1" 1
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "move_l,mov3q_l,clr_l"))
++       (and (eq_attr "op_mem" "00")
++          (ior (eq_attr "opx_type" "!Rn")
++               (eq_attr "opy_type" "!none,imm_q,imm_w,imm_l"))))
++  "cfv4_sOEP1|(cfv4_pOEP1,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex)")
++
++(define_insn_reservation "cfv4_00_oag_moveql" 1
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "moveq_l"))
+        (eq_attr "op_mem" "00"))
+-  "cf_v2_ib2+cf_v2_mul_00")
++  "cfv4_sOEP1|cfv4_sOEP2|cfv4_sOEP3|(cfv4_pOEP3,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex)")
+-(define_insn_reservation "cf_v2_mul_00_3" 4
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "mul"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
++;; Second part of cfv4_00.
++;; Latency is either 1 or 4 depending on which stage the consumer
++;; will need the data.
++
++(define_insn_reservation "cfv4_00_ex" 4
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "bitr,bitrw,clr,cmp,move,mvsz,scc,tst"))
+        (eq_attr "op_mem" "00"))
+-  "cf_v2_ib3+cf_v2_mul_00")
++  "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex")
+-(define_insn_reservation "cf_v2_mul_10_1" 6
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "mul"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
+-       (eq_attr "op_mem" "10"))
+-  "cf_v2_ib1+cf_v2_mul_10")
++(define_insn_reservation "cfv4_00_ex_sOEP13" 4
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "alux_l,ext,shift,tst_l"))
++       (eq_attr "op_mem" "00"))
++  "cfv4_sOEP1|cfv4_sOEP3|(cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex)")
+-(define_insn_reservation "cf_v2_mul_10_2" 6
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "mul"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
++;; Several types mentioned in this reservation (e.g., ext and shift) don't
++;; support implicit load.  But we handle them anyway due to first scheduling
++;; pass, which handles non-strict rtl.
++;;
++;; Latency is either 1 or 4 depending in which stage the consumer
++;; will need the data.
++(define_insn_reservation "cfv4_10" 4
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "alu_l,aluq_l,alux_l,bitr,bitrw,
++                             clr,clr_l,cmp,cmp_l,ext,
++                             mov3q_l,move,moveq_l,mvsz,neg_l,
++                             shift,tst,tst_l"))
+        (eq_attr "op_mem" "10"))
+-  "cf_v2_ib2+cf_v2_mul_10")
++  "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex")
+-(define_insn_reservation "cf_v2_mul_10_3" 6
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "mul"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
++;; Specialization of cfv4_10.
++;; move.l has OC2-to-DS forwarding path, that saves one cycle of latency.
++(define_insn_reservation "cfv4_10_pOEP1" 3
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "move_l"))
+        (eq_attr "op_mem" "10"))
+-  "cf_v2_ib3+cf_v2_mul_10")
++  "cfv4_pOEP1,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex")
+-(define_insn_reservation "cf_v2_mul_i0_2" 7
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "mul"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
++;; Same here.  But +1 to latency due to longer OAG.
++(define_insn_reservation "cfv4_i0" 5
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "alu_l,aluq_l,alux_l,bitr,bitrw,
++                             clr,clr_l,cmp,cmp_l,ext,
++                             mov3q_l,move,moveq_l,mvsz,neg_l,
++                             shift,tst,tst_l"))
+        (eq_attr "op_mem" "i0"))
+-  "cf_v2_ib2+cf_v2_mul_i0")
++  "cfv4_ds,cfv4_oag,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex")
+-(define_insn_reservation "cf_v2_mul_i0_3" 7
+-  (and (and (and (eq_attr "cpu" "cf_v2")
+-               (eq_attr "type2" "mul"))
+-          (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
++;; ??? Does indexed load trigger dual-issue?
++;; ??? Does OC2-to-DS forwarding path saves a cycle?
++(define_insn_reservation "cfv4_i0_pOEP1" 4
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "move_l"))
+        (eq_attr "op_mem" "i0"))
+-  "cf_v2_ib3+cf_v2_mul_i0")
++  "cfv4_ds,cfv4_oag,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex")
+-;; ??? As return reads target address from stack, use a mem-read reservation
+-;; for it.
+-(define_reservation "cf_v2_rts" "cf_v2_move_10")
+-
+-;; ??? It's not clear what the core does during these 5 cycles.
+-;; Luckily, we don't care that much about an insn that won't be moved.
+-(define_insn_reservation "cf_v2_rts_1" 5
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "type2" "rts"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
+-  "cf_v2_ib1+cf_v2_rts")
++;; This reservation is for moves and clr.  Arithmetic instructions
++;; don't write to memory unless they also read from it.
++;; But, before reload we can have all sorts of things.
++;; With cfv4_pOEP2 allow dual-issue for type 2 cases.
++(define_insn_reservation "cfv4_01" 1
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "alu_l,aluq_l,alux_l,bitr,bitrw,
++                             clr,clr_l,cmp,cmp_l,ext,
++                             mov3q_l,move,move_l,moveq_l,mvsz,neg_l,
++                             shift"))
++       (eq_attr "op_mem" "01"))
++  "cfv4_pOEP2,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_da,cfv4_mem")
+-;; Call instructions reservations.
++;; ??? Does indexed store trigger dual-issue?
++(define_insn_reservation "cfv4_0i" 2
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "alu_l,aluq_l,alux_l,bitr,bitrw,
++                             clr,clr_l,cmp,cmp_l,ext,
++                             mov3q_l,move,move_l,moveq_l,mvsz,neg_l,
++                             shift"))
++       (eq_attr "op_mem" "0i"))
++  "cfv4_pOEP2,cfv4_oag,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_da,cfv4_mem")
+-;; ??? It's not clear what reservation is best to use for calls.
+-;; For now we use mem-write + return reservations to reflect the fact of
+-;; pushing and poping return address to and from the stack.
++(define_insn_reservation "cfv4_11" 1
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "alu_l,aluq_l,alux_l,bitr,bitrw,
++                             clr,clr_l,cmp,cmp_l,ext,
++                             mov3q_l,move,move_l,moveq_l,mvsz,neg_l,
++                             shift"))
++       (eq_attr "op_mem" "11"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_da,cfv4_mem")
+-(define_insn_reservation "cf_v2_call_1" 3
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "type2" "call"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
+-  "cf_v2_ib1+cf_v2_move_10,cf_v2_rts")
+-
+-(define_insn_reservation "cf_v2_call_2" 3
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "type2" "call"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-  "cf_v2_ib2+cf_v2_move_10,cf_v2_rts")
+-
+-(define_insn_reservation "cf_v2_call_3" 3
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "type2" "call"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-  "cf_v2_ib3+cf_v2_move_10,cf_v2_rts")
++;; Latency is 2 due to long OAG stage.
++(define_insn_reservation "cfv4_i1" 2
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "alu_l,aluq_l,alux_l,bitr,bitrw,
++                             clr,clr_l,cmp,cmp_l,ext,
++                             mov3q_l,move,move_l,moveq_l,mvsz,neg_l,
++                             shift"))
++       (eq_attr "op_mem" "i1"))
++  "cfv4_ds,cfv4_oag,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_da,cfv4_mem")
+-;; Branch reservations.
++;; This one is the same as cfv4_i1.
++;; ??? Should it be different?
++(define_insn_reservation "cfv4_1i" 2
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "alu_l,aluq_l,alux_l,bitr,bitrw,
++                             clr,clr_l,cmp,cmp_l,ext,
++                             mov3q_l,move,move_l,moveq_l,mvsz,neg_l,
++                             shift"))
++       (eq_attr "op_mem" "1i"))
++  "cfv4_ds,cfv4_oag,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_da,cfv4_mem")
+-;; ??? Branch reservations are unclear to me so far.  Luckily, we don't care
+-;; ??? that much about branches.
+-(define_reservation "cf_v2_bcc" "cf_v2_move_00")
++;; ??? Does pea indeed support case 2 of dual-issue?
++(define_insn_reservation "cfv4_11_pea" 1
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "pea"))
++       (eq_attr "op_mem" "11,00,01,0i,10"))
++  "cfv4_pOEP2,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_da,cfv4_mem")
++
++;; ??? Does pea indeed support case 2 of dual-issue?
++;; ??? Does indexed store trigger dual-issue?
++(define_insn_reservation "cfv4_i1_pea" 1
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "pea"))
++       (eq_attr "op_mem" "i1,1i"))
++  "cfv4_pOEP2,cfv4_oag,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_da,cfv4_mem")
++
++(define_insn_reservation "cfv4_link" 2
++  (and (eq_attr "cpu" "cfv4")
++       (eq_attr "type" "link"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_ex,cfv4_da,cfv4_mem")
++
++(define_insn_reservation "cfv4_unlink" 2
++  (and (eq_attr "cpu" "cfv4")
++       (eq_attr "type" "unlk"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex")
++
++(define_insn_reservation "cfv4_divw_00" 20
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "div_w"))
++       (eq_attr "op_mem" "00,01,0i"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex*15")
++
++(define_insn_reservation "cfv4_divw_10" 20
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "div_w"))
++       (eq_attr "op_mem" "10,11,1i"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex*15")
++
++(define_insn_reservation "cfv4_divw_i0" 21
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "div_w"))
++       (eq_attr "op_mem" "i0,i1"))
++  "cfv4_ds,cfv4_oag,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex*15")
++
++(define_insn_reservation "cfv4_divl_00" 35
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "div_l"))
++       (eq_attr "op_mem" "00,01,0i"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex*30")
++
++(define_insn_reservation "cfv4_divl_10" 35
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "div_l"))
++       (eq_attr "op_mem" "10,11,1i,i0,i1"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex*30")
++
++(define_insn_reservation "cfv4_emac_mul_00" 7
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "mul_w,mul_l"))
++       (eq_attr "op_mem" "00,01,0i"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_emac")
++
++(define_insn_reservation "cfv4_emac_mul_10" 7
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "mul_w,mul_l"))
++       (eq_attr "op_mem" "10,11,1i"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_emac")
++
++(define_insn_reservation "cfv4_emac_mul_i0" 8
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "mul_w,mul_l"))
++       (eq_attr "op_mem" "i0,i1"))
++  "cfv4_ds,cfv4_oag,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_emac")
++
++(define_insn_reservation "cfv4_falu_00" 7
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "falu,fcmp,fmul"))
++       (eq_attr "op_mem" "00,01,0i"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_fp")
++
++(define_insn_reservation "cfv4_falu_10" 7
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "falu,fcmp,fmul"))
++       (eq_attr "op_mem" "10,i0,11,1i,i1"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_fp")
++
++(define_insn_reservation "cfv4_fneg_00" 4
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "fmove,fneg,ftst"))
++       (eq_attr "op_mem" "00"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_fp")
+-(define_insn_reservation "cf_v2_bcc_1" 2
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "type2" "bcc"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
+-  "cf_v2_ib1+cf_v2_bcc")
+-
+-(define_insn_reservation "cf_v2_bcc_2" 2
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "type2" "bcc"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-  "cf_v2_ib2+cf_v2_bcc")
+-
+-(define_insn_reservation "cf_v2_bcc_3" 2
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "type2" "bcc"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-  "cf_v2_ib3+cf_v2_bcc")
+-
+-(define_reservation "cf_v2_bra" "cf_v2_move_01")
+-
+-(define_insn_reservation "cf_v2_bra_1" 2
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "type2" "bra"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
+-  "cf_v2_ib1+cf_v2_bra")
+-
+-(define_insn_reservation "cf_v2_bra_2" 2
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "type2" "bra"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-  "cf_v2_ib2+cf_v2_bra")
+-
+-(define_insn_reservation "cf_v2_bra_3" 2
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "type2" "bra"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-  "cf_v2_ib3+cf_v2_bra")
+-
+-;; Computed jump.
+-;; Takes 3 cycles.
+-(define_reservation "cf_v2_jmp"
+-  "cf_v2_dsoc,cf_v2_agex,cf_v2_dsoc,cf_v2_agex")
+-
+-(define_insn_reservation "cf_v2_jmp_1" 3
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "type2" "jmp"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
+-  "cf_v2_ib1+cf_v2_jmp")
+-
+-(define_insn_reservation "cf_v2_jmp_2" 3
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "type2" "jmp"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-  "cf_v2_ib2+cf_v2_jmp")
+-
+-(define_insn_reservation "cf_v2_jmp_3" 3
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "type2" "jmp"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-  "cf_v2_ib3+cf_v2_jmp")
+-
+-;; Misc reservations.
+-
+-(define_insn_reservation "cf_v2_unlk_1" 2
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "type2" "unlk"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
+-  "cf_v2_ib1+cf_v2_move_l_10")
+-
+-;; This automaton is used to gather statistics on insns that need reservations.
+-(define_automaton "cf_v2_guess")
+-
+-(define_query_cpu_unit "cf_v2_guess" "cf_v2_guess")
+-
+-;; Dummy reservation for instructions that are not handled yet.
+-
+-(define_insn_reservation "cf_v2_guess_1" 1
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "guess" "yes"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
+-  "cf_v2_ib1+cf_v2_guess+cf_v2_dsoc+cf_v2_agex")
+-
+-(define_insn_reservation "cf_v2_guess_2" 1
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "guess" "yes"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
+-  "cf_v2_ib2+cf_v2_guess+cf_v2_dsoc+cf_v2_agex")
+-
+-(define_insn_reservation "cf_v2_guess_3" 1
+-  (and (and (eq_attr "cpu" "cf_v2")
+-          (eq_attr "guess" "yes"))
+-       (eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
+-  "cf_v2_ib3+cf_v2_guess+cf_v2_dsoc+cf_v2_agex")
++(define_insn_reservation "cfv4_fmove_fneg_10" 4
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "fmove,fneg,ftst"))
++       (eq_attr "op_mem" "10,i0,11,1i,i1"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_fp")
++
++(define_insn_reservation "cfv4_fmove_01" 1
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "fmove,fneg,ftst"))
++       (eq_attr "op_mem" "01,0i"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_fp,cfv4_da,cfv4_mem")
++
++(define_insn_reservation "cfv4_fdiv_00" 23
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "fdiv"))
++       (eq_attr "op_mem" "00,01,0i"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_fp*17")
++
++(define_insn_reservation "cfv4_fdiv_10" 23
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "fdiv"))
++       (eq_attr "op_mem" "10,i0,11,1i,i1"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_fp*17")
++
++(define_insn_reservation "cfv4_fsqrt_00" 56
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "fsqrt"))
++       (eq_attr "op_mem" "00,01,0i"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_fp*50")
++
++(define_insn_reservation "cfv4_fsqrt_10" 56
++  (and (and (eq_attr "cpu" "cfv4")
++          (eq_attr "type" "fsqrt"))
++       (eq_attr "op_mem" "10,i0,11,1i,i1"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_fp*50")
++
++(define_insn_reservation "cfv4_bcc" 0
++  (and (eq_attr "cpu" "cfv4")
++       (eq_attr "type" "bcc"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex")
++
++(define_insn_reservation "cfv4_fbcc" 2
++  (and (eq_attr "cpu" "cfv4")
++       (eq_attr "type" "fbcc"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex,cfv4_fp")
++
++;; ??? Why is bra said to write to memory: 1(0/1) ?
++(define_insn_reservation "cfv4_bra_bsr" 1
++  (and (eq_attr "cpu" "cfv4")
++       (eq_attr "type" "bra,bsr"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex")
++
++(define_insn_reservation "cfv4_jmp_jsr" 5
++  (and (eq_attr "cpu" "cfv4")
++       (eq_attr "type" "jmp,jsr"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1,cfv4_oc2,cfv4_ex")
++
++(define_insn_reservation "cfv4_rts" 2
++  (and (eq_attr "cpu" "cfv4")
++       (eq_attr "type" "rts"))
++  "cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex")
++
++(define_insn_reservation "cfv4_nop" 1
++  (and (eq_attr "cpu" "cfv4")
++       (eq_attr "type" "nop"))
++  "cfv4_ds+cfv4_oag+cfv4_oc1+cfv4_mem+cfv4_oc2+cfv4_ex")
++
++(define_insn_reservation "cfv4_guess" 10
++  (and (eq_attr "cpu" "cfv4")
++       (eq_attr "type" "trap,unknown"))
++  "cfv4_guess+cfv4_ds,cfv4_oag,cfv4_oc1+cfv4_mem,cfv4_oc2,cfv4_ex,cfv4_emac+cfv4_fp")
++
++(define_insn_reservation "ignore" 0
++  (eq_attr "type" "ignore")
++  "nothing")
+--- a/gcc/config/m68k/constraints.md
++++ b/gcc/config/m68k/constraints.md
+@@ -124,6 +124,11 @@
+   (and (match_code "const_int")
+        (match_test "ival < -0x8000 || ival > 0x7FFF")))
++(define_constraint "Cu"
++  "16-bit offset for wrapped symbols"
++  (and (match_code "const")
++       (match_test "m68k_unwrap_symbol (op, false) != op")))
++
+ (define_constraint "CQ"
+   "Integers valid for mvq."
+   (and (match_code "const_int")
+--- a/gcc/config/m68k/lb1sf68.asm
++++ b/gcc/config/m68k/lb1sf68.asm
+@@ -129,10 +129,48 @@ Boston, MA 02110-1301, USA.  */
+ #else /* __PIC__ */
+-      /* Common for -mid-shared-libary and -msep-data */
++# if defined (__uClinux__)
++
++      /* Versions for uClinux */
++
++#  if defined(__ID_SHARED_LIBRARY__)
++
++      /* -mid-shared-library versions  */
++
++      .macro PICLEA sym, reg
++      movel   a5@(_current_shared_library_a5_offset_), \reg
++      movel   \sym@GOT(\reg), \reg
++      .endm
++
++      .macro PICPEA sym, areg
++      movel   a5@(_current_shared_library_a5_offset_), \areg
++      movel   \sym@GOT(\areg), sp@-
++      .endm
+       .macro PICCALL addr
+-#if defined (__mcoldfire__) && !defined (__mcfisab__)
++      PICLEA  \addr,a0
++      jsr     a0@
++      .endm
++
++      .macro PICJUMP addr
++      PICLEA  \addr,a0
++      jmp     a0@
++      .endm
++
++#  else /* !__ID_SHARED_LIBRARY__ */
++
++      /* Versions for -msep-data */
++
++      .macro PICLEA sym, reg
++      movel   \sym@GOT(a5), \reg
++      .endm
++
++      .macro PICPEA sym, areg
++      movel   \sym@GOT(a5), sp@-
++      .endm
++
++      .macro PICCALL addr
++#if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__)
+       lea     \addr-.-8,a0
+       jsr     pc@(a0)
+ #else
+@@ -141,6 +179,9 @@ Boston, MA 02110-1301, USA.  */
+       .endm
+       .macro PICJUMP addr
++      /* ISA C has no bra.l instruction, and since this assembly file
++         gets assembled into multiple object files, we avoid the
++         bra instruction entirely.  */
+ #if defined (__mcoldfire__) && !defined (__mcfisab__)
+       lea     \addr-.-8,a0
+       jmp     pc@(a0)
+@@ -149,33 +190,46 @@ Boston, MA 02110-1301, USA.  */
+ #endif
+       .endm
+-# if defined(__ID_SHARED_LIBRARY__)
++#  endif
+-      /* -mid-shared-library versions  */
++# else /* !__uClinux__ */
++
++      /* Versions for Linux */
+       .macro PICLEA sym, reg
+-      movel   a5@(_current_shared_library_a5_offset_), \reg
++      movel   #_GLOBAL_OFFSET_TABLE_@GOTPC, \reg
++      lea     (-6, pc, \reg), \reg
+       movel   \sym@GOT(\reg), \reg
+       .endm
+       .macro PICPEA sym, areg
+-      movel   a5@(_current_shared_library_a5_offset_), \areg
++      movel   #_GLOBAL_OFFSET_TABLE_@GOTPC, \areg
++      lea     (-6, pc, \areg), \areg
+       movel   \sym@GOT(\areg), sp@-
+       .endm
+-# else /* !__ID_SHARED_LIBRARY__ */
+-
+-      /* Versions for -msep-data */
+-
+-      .macro PICLEA sym, reg
+-      movel   \sym@GOT(a5), \reg
++      .macro PICCALL addr
++#if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__)
++      lea     \addr-.-8,a0
++      jsr     pc@(a0)
++#else
++      bsr     \addr
++#endif
+       .endm
+-      .macro PICPEA sym, areg
+-      movel   \sym@GOT(a5), sp@-
++      .macro PICJUMP addr
++      /* ISA C has no bra.l instruction, and since this assembly file
++         gets assembled into multiple object files, we avoid the
++         bra instruction entirely.  */
++#if defined (__mcoldfire__) && !defined (__mcfisab__)
++      lea     \addr-.-8,a0
++      jmp     pc@(a0)
++#else
++      bra     \addr
++#endif
+       .endm
+-# endif /* !__ID_SHARED_LIBRARY__ */
++# endif
+ #endif /* __PIC__ */
+@@ -622,6 +676,7 @@ ROUND_TO_MINUS    = 3 | round result tow
+       .globl SYM (__negdf2)
+       .globl SYM (__cmpdf2)
+       .globl SYM (__cmpdf2_internal)
++      .hidden SYM (__cmpdf2_internal)
+       .text
+       .even
+@@ -2384,7 +2439,7 @@ SYM (__cmpdf2):
+       movl    a6@(16),sp@-
+       movl    a6@(12),sp@-
+       movl    a6@(8),sp@-
+-      bsr     SYM (__cmpdf2_internal)
++      PICCALL SYM (__cmpdf2_internal)
+       unlk    a6
+       rts
+@@ -2536,6 +2591,7 @@ ROUND_TO_MINUS    = 3 | round result tow
+       .globl SYM (__negsf2)
+       .globl SYM (__cmpsf2)
+       .globl SYM (__cmpsf2_internal)
++      .hidden SYM (__cmpsf2_internal)
+ | These are common routines to return and signal exceptions.  
+@@ -3790,7 +3846,7 @@ SYM (__cmpsf2):
+       pea     1
+       movl    a6@(12),sp@-
+       movl    a6@(8),sp@-
+-      bsr (__cmpsf2_internal)
++      PICCALL SYM (__cmpsf2_internal)
+       unlk    a6
+       rts
+@@ -4063,3 +4119,8 @@ SYM (__lesf2):
+       unlk    a6
+       rts
+ #endif /* L_lesf2 */
++
++#if defined (__ELF__) && defined (__linux__)
++      /* Make stack non-executable for ELF linux targets.  */
++      .section        .note.GNU-stack,"",@progbits
++#endif
+--- a/gcc/config/m68k/m68k-devices.def
++++ b/gcc/config/m68k/m68k-devices.def
+@@ -63,13 +63,17 @@
+    There is a bit of duplication between devices in the same family,
+    but this approach makes scripting easier.  We keep each entry on
+-   a single line for the same reason.  */
++   a single line for the same reason.
++
++   As the compiler does not (currently) generate MAC or EMAC commands,
++   we do not need separate multilibs for cores that only differ in
++   their MAC functionality.  */
+ /* 680x0 series processors.  */
+ M68K_DEVICE ("68000", m68000,   "68000", "68000", 68000,    isa_00,    0)
+ M68K_DEVICE ("68010", m68010,   "68010", "68000", 68010,    isa_10,    0)
+-M68K_DEVICE ("68020", m68020,   "68020", "68020", 68020,    isa_20,    FL_MMU)
+-M68K_DEVICE ("68030", m68030,   "68030", "68020", 68030,    isa_20,    FL_MMU)
++M68K_DEVICE ("68020", m68020,   "68020", "68020", 68020,    isa_20,    FL_MMU | FL_UCLINUX)
++M68K_DEVICE ("68030", m68030,   "68030", "68020", 68030,    isa_20,    FL_MMU | FL_UCLINUX)
+ M68K_DEVICE ("68040", m68040,   "68040", "68040", 68040,    isa_40,    FL_MMU)
+ M68K_DEVICE ("68060", m68060,   "68060", "68060", 68060,    isa_40,    FL_MMU)
+ M68K_DEVICE ("68302", m68302,   "68302", "68000", 68000,    isa_00,    FL_MMU)
+@@ -77,7 +81,13 @@ M68K_DEVICE ("68332", m68332,   "68332",
+ M68K_DEVICE ("cpu32", cpu32,    "cpu32", "cpu32", cpu32,    isa_cpu32, FL_MMU)
+ /* ColdFire CFV1 processor.  */
+-M68K_DEVICE ("51qe",  mcf51qe,  "51qe",  "51qe",  cfv1,     isa_c,     FL_CF_USP)
++/* For historical reasons, the 51 multilib is named 51qe.  */
++M68K_DEVICE ("51",    mcf51,    "51",    "51qe",  cfv1,     isa_c,     FL_CF_USP)
++M68K_DEVICE ("51ac",  mcf51ac,  "51",    "51qe",  cfv1,     isa_c,     FL_CF_USP)
++M68K_DEVICE ("51cn",  mcf51cn,  "51",    "51qe",  cfv1,     isa_c,     FL_CF_USP)
++M68K_DEVICE ("51em",  mcf51em,  "51",    "51qe",  cfv1,     isa_c,     FL_CF_USP | FL_CF_MAC)
++M68K_DEVICE ("51jm",  mcf51jm,  "51",    "51qe",  cfv1,     isa_c,     FL_CF_USP)
++M68K_DEVICE ("51qe",  mcf51qe,  "51",    "51qe",  cfv1,     isa_c,     FL_CF_USP)
+ /* ColdFire CFV2 processors.  */
+ M68K_DEVICE ("5202",  mcf5202,  "5206",  "5206",  cfv2,     isa_a,     0)
+@@ -86,31 +96,39 @@ M68K_DEVICE ("5206",  mcf5206,  "5206", 
+ M68K_DEVICE ("5206e", mcf5206e, "5206e", "5206e", cfv2,     isa_a,     FL_CF_HWDIV | FL_CF_MAC)
+ M68K_DEVICE ("5207",  mcf5207,  "5208",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("5208",  mcf5208,  "5208",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+-M68K_DEVICE ("5210a", mcf5210a, "5211a", "5213",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+-M68K_DEVICE ("5211a", mcf5211a, "5211a", "5213",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+-M68K_DEVICE ("5211",  mcf5211,  "5213",  "5213",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+-M68K_DEVICE ("5212",  mcf5212,  "5213",  "5213",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+-M68K_DEVICE ("5213",  mcf5213,  "5213",  "5213",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
++M68K_DEVICE ("5210a", mcf5210a, "5211a", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
++M68K_DEVICE ("5211a", mcf5211a, "5211a", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
++M68K_DEVICE ("5211",  mcf5211,  "5213",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
++M68K_DEVICE ("5212",  mcf5212,  "5213",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
++M68K_DEVICE ("5213",  mcf5213,  "5213",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+ M68K_DEVICE ("5214",  mcf5214,  "5216",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("5216",  mcf5216,  "5216",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+-M68K_DEVICE ("52221", mcf52221, "52223", "5213",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+-M68K_DEVICE ("52223", mcf52223, "52223", "5213",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
++M68K_DEVICE ("52221", mcf52221, "52223", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
++M68K_DEVICE ("52223", mcf52223, "52223", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+ M68K_DEVICE ("52230", mcf52230, "52235", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("52231", mcf52231, "52235", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("52232", mcf52232, "52235", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("52233", mcf52233, "52235", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("52234", mcf52234, "52235", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("52235", mcf52235, "52235", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+-M68K_DEVICE ("5224",  mcf5224,  "5225",  "5213",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+-M68K_DEVICE ("5225",  mcf5225,  "5225",  "5213",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
++M68K_DEVICE ("5224",  mcf5224,  "5225",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
++M68K_DEVICE ("5225",  mcf5225,  "5225",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
++M68K_DEVICE ("52252", mcf52252, "52259", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("52254", mcf52254, "52259", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("52255", mcf52255, "52259", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("52256", mcf52256, "52259", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("52258", mcf52258, "52259", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("52259", mcf52259, "52259", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("52274", mcf52274, "52277", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("52277", mcf52277, "52277", "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("5232",  mcf5232,  "5235",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("5233",  mcf5233,  "5235",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("5234",  mcf5234,  "5235",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("5235",  mcf5235,  "5235",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("523x",  mcf523x,  "5235",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+-M68K_DEVICE ("5249",  mcf5249,  "5249",  "5249",  cfv2,     isa_a,     FL_CF_HWDIV | FL_CF_EMAC)
+-M68K_DEVICE ("5250",  mcf5250,  "5250",  "5249",  cfv2,     isa_a,     FL_CF_HWDIV | FL_CF_EMAC)
+-M68K_DEVICE ("5253",  mcf5253,  "5253",  "5249",  cfv2,     isa_a,     FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("5249",  mcf5249,  "5249",  "5206e", cfv2,     isa_a,     FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("5250",  mcf5250,  "5250",  "5206e", cfv2,     isa_a,     FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("5253",  mcf5253,  "5253",  "5206e", cfv2,     isa_a,     FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("5270",  mcf5270,  "5271",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("5271",  mcf5271,  "5271",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV)
+ M68K_DEVICE ("5272",  mcf5272,  "5272",  "5206e", cfv2,     isa_a,     FL_CF_HWDIV | FL_CF_MAC)
+@@ -122,6 +140,13 @@ M68K_DEVICE ("5282",  mcf5282,  "5282", 
+ M68K_DEVICE ("528x",  mcf528x,  "5282",  "5208",  cfv2,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ /* CFV3 processors.  */
++M68K_DEVICE ("53011", mcf53011, "53017", "5329",  cfv3,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("53012", mcf53012, "53017", "5329",  cfv3,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("53013", mcf53013, "53017", "5329",  cfv3,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("53014", mcf53014, "53017", "5329",  cfv3,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("53015", mcf53015, "53017", "5329",  cfv3,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("53016", mcf53016, "53017", "5329",  cfv3,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
++M68K_DEVICE ("53017", mcf53017, "53017", "5329",  cfv3,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("5307",  mcf5307,  "5307",  "5307",  cfv3,     isa_a,     FL_CF_HWDIV | FL_CF_MAC)
+ M68K_DEVICE ("5327",  mcf5327,  "5329",  "5329",  cfv3,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+ M68K_DEVICE ("5328",  mcf5328,  "5329",  "5329",  cfv3,     isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
+@@ -133,12 +158,12 @@ M68K_DEVICE ("537x",  mcf537x,  "5373", 
+ /* CFV4/CFV4e processors.  */
+ M68K_DEVICE ("5407",  mcf5407,  "5407",  "5407",  cfv4,     isa_b,     FL_CF_MAC)
+-M68K_DEVICE ("54450", mcf54450, "54455", "54455", cfv4,     isa_c,     FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
+-M68K_DEVICE ("54451", mcf54451, "54455", "54455", cfv4,     isa_c,     FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
+-M68K_DEVICE ("54452", mcf54452, "54455", "54455", cfv4,     isa_c,     FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
+-M68K_DEVICE ("54453", mcf54453, "54455", "54455", cfv4,     isa_c,     FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
+-M68K_DEVICE ("54454", mcf54454, "54455", "54455", cfv4,     isa_c,     FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
+-M68K_DEVICE ("54455", mcf54455, "54455", "54455", cfv4,     isa_c,     FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
++M68K_DEVICE ("54450", mcf54450, "54455", "54455", cfv4,     isa_c,     FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
++M68K_DEVICE ("54451", mcf54451, "54455", "54455", cfv4,     isa_c,     FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
++M68K_DEVICE ("54452", mcf54452, "54455", "54455", cfv4,     isa_c,     FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
++M68K_DEVICE ("54453", mcf54453, "54455", "54455", cfv4,     isa_c,     FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
++M68K_DEVICE ("54454", mcf54454, "54455", "54455", cfv4,     isa_c,     FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
++M68K_DEVICE ("54455", mcf54455, "54455", "54455", cfv4,     isa_c,     FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
+ M68K_DEVICE ("5470",  mcf5470,  "5475",  "5475",  cfv4e,    isa_b,     FL_CF_USP | FL_CF_EMAC | FL_CF_FPU | FL_MMU)
+ M68K_DEVICE ("5471",  mcf5471,  "5475",  "5475",  cfv4e,    isa_b,     FL_CF_USP | FL_CF_EMAC | FL_CF_FPU | FL_MMU)
+ M68K_DEVICE ("5472",  mcf5472,  "5475",  "5475",  cfv4e,    isa_b,     FL_CF_USP | FL_CF_EMAC | FL_CF_FPU | FL_MMU)
+--- a/gcc/config/m68k/m68k-protos.h
++++ b/gcc/config/m68k/m68k-protos.h
+@@ -50,14 +50,19 @@ extern bool strict_low_part_peephole_ok 
+ extern int standard_68881_constant_p (rtx);
+ extern void print_operand_address (FILE *, rtx);
+ extern void print_operand (FILE *, rtx, int);
++extern bool m68k_output_addr_const_extra (FILE *, rtx);
+ extern void notice_update_cc (rtx, rtx);
+ extern bool m68k_legitimate_base_reg_p (rtx, bool);
+-extern bool m68k_legitimate_index_reg_p (rtx, bool);
++extern bool m68k_legitimate_index_reg_p (enum machine_mode, rtx, bool);
+ extern bool m68k_illegitimate_symbolic_constant_p (rtx);
+ extern bool m68k_legitimate_address_p (enum machine_mode, rtx, bool);
+ extern bool m68k_matches_q_p (rtx);
+ extern bool m68k_matches_u_p (rtx);
+ extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
++extern rtx m68k_legitimize_tls_address (rtx);
++extern bool m68k_tls_referenced_p (rtx);
++extern bool m68k_tls_mentioned_p (rtx);
++extern rtx m68k_legitimize_address (rtx, rtx, enum machine_mode);
+ extern int valid_dbcc_comparison_p_2 (rtx, enum machine_mode);
+ extern rtx m68k_libcall_value (enum machine_mode);
+ extern rtx m68k_function_value (const_tree, const_tree);
+@@ -65,15 +70,19 @@ extern int emit_move_sequence (rtx *, en
+ extern bool m68k_movem_pattern_p (rtx, rtx, HOST_WIDE_INT, bool);
+ extern const char *m68k_output_movem (rtx *, rtx, HOST_WIDE_INT, bool);
++/* Functions from m68k.c used in constraints.md.  */
++extern rtx m68k_unwrap_symbol (rtx, bool);
++
++/* Functions from m68k.c used in genattrtab.  */
+ #ifdef HAVE_ATTR_cpu
+ extern enum attr_cpu m68k_sched_cpu;
++extern enum attr_mac m68k_sched_mac;
+ extern enum attr_opx_type m68k_sched_attr_opx_type (rtx, int);
+ extern enum attr_opy_type m68k_sched_attr_opy_type (rtx, int);
+-extern int m68k_sched_attr_size (rtx);
++extern enum attr_size m68k_sched_attr_size (rtx);
+ extern enum attr_op_mem m68k_sched_attr_op_mem (rtx);
+ extern enum attr_type m68k_sched_branch_type (rtx);
+-extern enum attr_type2 m68k_sched_attr_type2 (rtx);
+ #endif /* HAVE_ATTR_cpu */
+ #endif /* RTX_CODE */
+--- a/gcc/config/m68k/m68k.c
++++ b/gcc/config/m68k/m68k.c
+@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  
+ /* ??? Need to add a dependency between m68k.o and sched-int.h.  */
+ #include "sched-int.h"
+ #include "insn-codes.h"
++#include "ggc.h"
+ enum reg_class regno_reg_class[] =
+ {
+@@ -122,12 +123,14 @@ struct m68k_address {
+ };
+ static int m68k_sched_adjust_cost (rtx, rtx, rtx, int);
++static int m68k_sched_issue_rate (void);
+ static int m68k_sched_variable_issue (FILE *, int, rtx, int);
+ static void m68k_sched_md_init_global (FILE *, int, int);
+ static void m68k_sched_md_finish_global (FILE *, int);
+ static void m68k_sched_md_init (FILE *, int, int);
+ static void m68k_sched_dfa_pre_advance_cycle (void);
+ static void m68k_sched_dfa_post_advance_cycle (void);
++static int m68k_sched_first_cycle_multipass_dfa_lookahead (void);
+ static bool m68k_handle_option (size_t, const char *, int);
+ static rtx find_addr_reg (rtx);
+@@ -146,8 +149,9 @@ static bool m68k_save_reg (unsigned int 
+ static bool m68k_ok_for_sibcall_p (tree, tree);
+ static bool m68k_rtx_costs (rtx, int, int, int *);
+ #if M68K_HONOR_TARGET_STRICT_ALIGNMENT
+-static bool m68k_return_in_memory (tree, tree);
++static bool m68k_return_in_memory (const_tree, const_tree);
+ #endif
++static void m68k_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
\f
+ /* Specify the identification number of the library being built */
+@@ -199,6 +203,9 @@ int m68k_last_compare_had_fp_operands;
+ #undef TARGET_SCHED_ADJUST_COST
+ #define TARGET_SCHED_ADJUST_COST m68k_sched_adjust_cost
++#undef TARGET_SCHED_ISSUE_RATE
++#define TARGET_SCHED_ISSUE_RATE m68k_sched_issue_rate
++
+ #undef TARGET_SCHED_VARIABLE_ISSUE
+ #define TARGET_SCHED_VARIABLE_ISSUE m68k_sched_variable_issue
+@@ -217,6 +224,10 @@ int m68k_last_compare_had_fp_operands;
+ #undef TARGET_SCHED_DFA_POST_ADVANCE_CYCLE
+ #define TARGET_SCHED_DFA_POST_ADVANCE_CYCLE m68k_sched_dfa_post_advance_cycle
++#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
++#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD      \
++  m68k_sched_first_cycle_multipass_dfa_lookahead
++
+ #undef TARGET_HANDLE_OPTION
+ #define TARGET_HANDLE_OPTION m68k_handle_option
+@@ -243,6 +254,14 @@ int m68k_last_compare_had_fp_operands;
+ #define TARGET_RETURN_IN_MEMORY m68k_return_in_memory
+ #endif
++#ifdef HAVE_AS_TLS
++#undef TARGET_HAVE_TLS
++#define TARGET_HAVE_TLS (true)
++
++#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
++#define TARGET_ASM_OUTPUT_DWARF_DTPREL m68k_output_dwarf_dtprel
++#endif
++
+ static const struct attribute_spec m68k_attribute_table[] =
+ {
+   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
+@@ -382,6 +401,9 @@ enum fpu_type m68k_fpu;
+ /* The set of FL_* flags that apply to the target processor.  */
+ unsigned int m68k_cpu_flags;
++/* The set of FL_* flags that apply to the processor to be tuned for.  */
++unsigned int m68k_tune_flags;
++
+ /* Asm templates for calling or jumping to an arbitrary symbolic address,
+    or NULL if such calls or jumps are not supported.  The address is held
+    in operand 0.  */
+@@ -562,13 +584,23 @@ override_options (void)
+   /* Set the directly-usable versions of the -mcpu and -mtune settings.  */
+   m68k_cpu = entry->device;
+   if (m68k_tune_entry)
+-    m68k_tune = m68k_tune_entry->microarch;
++    {
++      m68k_tune = m68k_tune_entry->microarch;
++      m68k_tune_flags = m68k_tune_entry->flags;
++    }
+ #ifdef M68K_DEFAULT_TUNE
+   else if (!m68k_cpu_entry && !m68k_arch_entry)
+-    m68k_tune = M68K_DEFAULT_TUNE;
++    {
++      enum target_device dev;
++      dev = all_microarchs[M68K_DEFAULT_TUNE].device;
++      m68k_tune_flags = all_devices[dev]->flags;
++    }
+ #endif
+   else
+-    m68k_tune = entry->microarch;
++    {
++      m68k_tune = entry->microarch;
++      m68k_tune_flags = entry->flags;
++    }
+   /* Set the type of FPU.  */
+   m68k_fpu = (!TARGET_HARD_FLOAT ? FPUTYPE_NONE
+@@ -666,8 +698,14 @@ override_options (void)
+   SUBTARGET_OVERRIDE_OPTIONS;
+   /* Setup scheduling options.  */
+-  if (TUNE_CFV2)
+-    m68k_sched_cpu = CPU_CF_V2;
++  if (TUNE_CFV1)
++    m68k_sched_cpu = CPU_CFV1;
++  else if (TUNE_CFV2)
++    m68k_sched_cpu = CPU_CFV2;
++  else if (TUNE_CFV3)
++    m68k_sched_cpu = CPU_CFV3;
++  else if (TUNE_CFV4)
++    m68k_sched_cpu = CPU_CFV4;
+   else
+     {
+       m68k_sched_cpu = CPU_UNKNOWN;
+@@ -675,6 +713,16 @@ override_options (void)
+       flag_schedule_insns_after_reload = 0;
+       flag_modulo_sched = 0;
+     }
++
++  if (m68k_sched_cpu != CPU_UNKNOWN)
++    {
++      if ((m68k_cpu_flags & (FL_CF_EMAC | FL_CF_EMAC_B)) != 0)
++      m68k_sched_mac = MAC_CF_EMAC;
++      else if ((m68k_cpu_flags & FL_CF_MAC) != 0)
++      m68k_sched_mac = MAC_CF_MAC;
++      else
++      m68k_sched_mac = MAC_NO;
++    }
+ }
+ /* Generate a macro of the form __mPREFIX_cpu_NAME, where PREFIX is the
+@@ -1023,6 +1071,11 @@ m68k_expand_prologue (void)
+                                   stack_pointer_rtx,
+                                   GEN_INT (-fsize_with_regs))));
+       }
++
++      /* If the frame pointer is needed, emit a special barrier that
++       will prevent the scheduler from moving stores to the frame
++       before the stack adjustment.  */
++      emit_insn (gen_stack_tie (stack_pointer_rtx, frame_pointer_rtx));
+     }
+   else if (fsize_with_regs != 0)
+     m68k_set_frame_related
+@@ -1103,8 +1156,7 @@ m68k_expand_prologue (void)
+                           current_frame.reg_mask, true, true));
+     }
+-  if (flag_pic
+-      && !TARGET_SEP_DATA
++  if (!TARGET_SEP_DATA
+       && current_function_uses_pic_offset_table)
+     insn = emit_insn (gen_load_got (pic_offset_table_rtx));
+ }
+@@ -1666,15 +1718,16 @@ m68k_legitimate_base_reg_p (rtx x, bool 
+    whether we need strict checking.  */
+ bool
+-m68k_legitimate_index_reg_p (rtx x, bool strict_p)
++m68k_legitimate_index_reg_p (enum machine_mode mode, rtx x, bool strict_p)
+ {
+   if (!strict_p && GET_CODE (x) == SUBREG)
+     x = SUBREG_REG (x);
+   return (REG_P (x)
+         && (strict_p
+-            ? REGNO_OK_FOR_INDEX_P (REGNO (x))
+-            : REGNO_OK_FOR_INDEX_NONSTRICT_P (REGNO (x))));
++            ? REGNO_MODE_OK_FOR_INDEX_P (REGNO (x), mode)
++            : (MODE_OK_FOR_INDEX_P (mode)
++               && REGNO_OK_FOR_INDEX_NONSTRICT_P (REGNO (x)))));
+ }
+ /* Return true if X is a legitimate index expression for a (d8,An,Xn) or
+@@ -1682,7 +1735,8 @@ m68k_legitimate_index_reg_p (rtx x, bool
+    ADDRESS if so.  STRICT_P says whether we need strict checking.  */
+ static bool
+-m68k_decompose_index (rtx x, bool strict_p, struct m68k_address *address)
++m68k_decompose_index (enum machine_mode mode, rtx x, bool strict_p,
++                    struct m68k_address *address)
+ {
+   int scale;
+@@ -1706,7 +1760,7 @@ m68k_decompose_index (rtx x, bool strict
+       && GET_MODE (XEXP (x, 0)) == HImode)
+     x = XEXP (x, 0);
+-  if (m68k_legitimate_index_reg_p (x, strict_p))
++  if (m68k_legitimate_index_reg_p (mode, x, strict_p))
+     {
+       address->scale = scale;
+       address->index = x;
+@@ -1730,7 +1784,7 @@ m68k_illegitimate_symbolic_constant_p (r
+         && !offset_within_block_p (base, INTVAL (offset)))
+       return true;
+     }
+-  return false;
++  return m68k_tls_referenced_p (x);
+ }
+ /* Return true if X is a legitimate constant address that can reach
+@@ -1758,7 +1812,7 @@ m68k_legitimate_constant_address_p (rtx 
+       return false;
+     }
+-  return true;
++  return !m68k_tls_referenced_p (x);
+ }
+ /* Return true if X is a LABEL_REF for a jump table.  Assume that unplaced
+@@ -1778,6 +1832,40 @@ m68k_jump_table_ref_p (rtx x)
+   return x && JUMP_TABLE_DATA_P (x);
+ }
++/* Unwrap symbol from UNSPEC_RELOC16 and, if unwrap_reloc32_p,
++   UNSPEC_RELOC32 wrappers.  */
++
++rtx
++m68k_unwrap_symbol (rtx orig, bool unwrap_reloc32_p)
++{
++  if (GET_CODE (orig) == CONST)
++    {
++      rtx x;
++
++      x = XEXP (orig, 0);
++
++      if (GET_CODE (x) == UNSPEC)
++      {
++        switch (XINT (x, 1))
++          {
++          case UNSPEC_RELOC16:
++            orig = XVECEXP (x, 0, 0);
++            break;
++
++          case UNSPEC_RELOC32:
++            if (unwrap_reloc32_p)
++              orig = XVECEXP (x, 0, 0);
++            break;
++
++          default:
++            break;
++          }
++      }
++    }
++
++  return orig;
++}
++
+ /* Return true if X is a legitimate address for values of mode MODE.
+    STRICT_P says whether strict checking is needed.  If the address
+    is valid, describe its components in *ADDRESS.  */
+@@ -1825,15 +1913,23 @@ m68k_decompose_address (enum machine_mod
+   /* Check for GOT loads.  These are (bd,An,Xn) addresses if
+      TARGET_68020 && flag_pic == 2, otherwise they are (d16,An)
+      addresses.  */
+-  if (flag_pic
++  if (pic_offset_table_rtx != NULL_RTX
+       && GET_CODE (x) == PLUS
+-      && XEXP (x, 0) == pic_offset_table_rtx
+-      && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
+-        || GET_CODE (XEXP (x, 1)) == LABEL_REF))
++      && XEXP (x, 0) == pic_offset_table_rtx)
+     {
+-      address->base = XEXP (x, 0);
+-      address->offset = XEXP (x, 1);
+-      return true;
++      rtx sym;
++
++      /* As we are processing a PLUS, do not unwrap RELOC32
++       symbols here; they are invalid in this context.  */
++      sym = m68k_unwrap_symbol (XEXP (x, 1), false);
++
++      if (GET_CODE (sym) == SYMBOL_REF
++        || GET_CODE (sym) == LABEL_REF)
++      {
++        address->base = XEXP (x, 0);
++        address->offset = XEXP (x, 1);
++        return true;
++      }
+     }
+   /* The ColdFire FPU only accepts addressing modes 2-5.  */
+@@ -1858,7 +1954,7 @@ m68k_decompose_address (enum machine_mod
+      accesses to unplaced labels in other cases.  */
+   if (GET_CODE (x) == PLUS
+       && m68k_jump_table_ref_p (XEXP (x, 1))
+-      && m68k_decompose_index (XEXP (x, 0), strict_p, address))
++      && m68k_decompose_index (mode, XEXP (x, 0), strict_p, address))
+     {
+       address->offset = XEXP (x, 1);
+       return true;
+@@ -1890,7 +1986,7 @@ m68k_decompose_address (enum machine_mod
+        worse code.  */
+       if (address->offset
+         && symbolic_operand (address->offset, VOIDmode)
+-        && m68k_decompose_index (x, strict_p, address))
++        && m68k_decompose_index (mode, x, strict_p, address))
+       return true;
+     }
+   else
+@@ -1909,14 +2005,14 @@ m68k_decompose_address (enum machine_mod
+   if (GET_CODE (x) == PLUS)
+     {
+       if (m68k_legitimate_base_reg_p (XEXP (x, 0), strict_p)
+-        && m68k_decompose_index (XEXP (x, 1), strict_p, address))
++        && m68k_decompose_index (mode, XEXP (x, 1), strict_p, address))
+       {
+         address->base = XEXP (x, 0);
+         return true;
+       }
+       if (m68k_legitimate_base_reg_p (XEXP (x, 1), strict_p)
+-        && m68k_decompose_index (XEXP (x, 0), strict_p, address))
++        && m68k_decompose_index (mode, XEXP (x, 0), strict_p, address))
+       {
+         address->base = XEXP (x, 1);
+         return true;
+@@ -1978,6 +2074,115 @@ m68k_matches_u_p (rtx x)
+         && !address.index);
+ }
++/* Return GOT pointer.  */
++
++static rtx
++m68k_get_gp (void)
++{
++  if (pic_offset_table_rtx == NULL_RTX)
++    pic_offset_table_rtx = gen_rtx_REG (Pmode, PIC_REG);
++
++  current_function_uses_pic_offset_table = 1;
++
++  return pic_offset_table_rtx;
++}
++
++/* M68K relocations, used to distinguish GOT and TLS relocations in UNSPEC
++   wrappers.  */
++enum m68k_reloc { RELOC_GOT, RELOC_TLSGD, RELOC_TLSLDM, RELOC_TLSLDO,
++                RELOC_TLSIE, RELOC_TLSLE };
++
++#define TLS_RELOC_P(RELOC) ((RELOC) != RELOC_GOT)
++
++/* Wrap symbol X into unspec representing relocation RELOC.
++   If USE_X_P, use 32-bit relocations, otherwise use 16-bit relocs.
++   BASE_REG - register that should be added to the result.
++   TEMP_REG - if non-null, temporary register.  */
++
++static rtx
++m68k_wrap_symbol (rtx x, enum m68k_reloc reloc, rtx base_reg, rtx temp_reg)
++{
++  bool use_x_p;
++
++  use_x_p = (base_reg == pic_offset_table_rtx) ? TARGET_XGOT : TARGET_XTLS;
++
++  if (TARGET_COLDFIRE && use_x_p)
++    /* When compiling with -mx{got, tls} switch the code will look like this:
++
++       move.l <X>@<RELOC>,<TEMP_REG>
++       add.l <BASE_REG>,<TEMP_REG>  */
++    {
++      /* Wrap X in UNSPEC_??? to tip m68k_output_addr_const_extra
++       to put @RELOC after reference.  */
++      x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, x, GEN_INT (reloc)),
++                        UNSPEC_RELOC32);
++      x = gen_rtx_CONST (Pmode, x);
++
++      if (temp_reg == NULL)
++      {
++        gcc_assert (can_create_pseudo_p ());
++        temp_reg = gen_reg_rtx (Pmode);
++      }
++
++      emit_move_insn (temp_reg, x);
++      emit_insn (gen_addsi3 (temp_reg, temp_reg, base_reg));
++      x = temp_reg;
++    }
++  else
++    {
++      /* ??? It would be simplier to wrap 16-bit GOT relocs into UNSPEC too,
++       historically, we don't do this, but I'm not aware of any downside
++       of such a change.  */
++      if (reloc != RELOC_GOT)
++      /* Wrap X into (const (unspec (X))).  */
++      {
++        x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, x, GEN_INT (reloc)),
++                            UNSPEC_RELOC16);
++        x = gen_rtx_CONST (Pmode, x);
++      }
++
++      x = gen_rtx_PLUS (Pmode, base_reg, x);
++    }
++
++  return x;
++}
++
++/* Move X to a register and add REG_EQUAL note pointing to ORIG.
++   If REG is non-null, use it; generate new pseudo otherwise.  */
++
++static rtx
++m68k_move_to_reg (rtx x, rtx orig, rtx reg)
++{
++  rtx insn;
++
++  if (reg == NULL_RTX)
++    {
++      gcc_assert (can_create_pseudo_p ());
++      reg = gen_reg_rtx (Pmode);
++    }
++
++  insn = emit_move_insn (reg, x);
++  /* Put a REG_EQUAL note on this insn, so that it can be optimized
++     by loop.  */
++  set_unique_reg_note (insn, REG_EQUAL, orig);
++
++  return reg;
++}
++
++/* Does the same as m68k_wrap_symbol, but returns a memory reference to
++   GOT slot.  */
++
++static rtx
++m68k_wrap_symbol_into_got_ref (rtx x, enum m68k_reloc reloc, rtx temp_reg)
++{
++  x = m68k_wrap_symbol (x, reloc, m68k_get_gp (), temp_reg);
++
++  x = gen_rtx_MEM (Pmode, x);
++  MEM_READONLY_P (x) = 1;
++
++  return x;
++}
++
+ /* Legitimize PIC addresses.  If the address is already
+    position-independent, we return ORIG.  Newly generated
+    position-independent addresses go to REG.  If we need more
+@@ -2029,13 +2234,8 @@ legitimize_pic_address (rtx orig, enum m
+     {
+       gcc_assert (reg);
+-      pic_ref = gen_rtx_MEM (Pmode,
+-                           gen_rtx_PLUS (Pmode,
+-                                         pic_offset_table_rtx, orig));
+-      current_function_uses_pic_offset_table = 1;
+-      MEM_READONLY_P (pic_ref) = 1;
+-      emit_move_insn (reg, pic_ref);
+-      return reg;
++      pic_ref = m68k_wrap_symbol_into_got_ref (orig, RELOC_GOT, reg);
++      pic_ref = m68k_move_to_reg (pic_ref, orig, reg);
+     }
+   else if (GET_CODE (orig) == CONST)
+     {
+@@ -2046,6 +2246,10 @@ legitimize_pic_address (rtx orig, enum m
+         && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
+       return orig;
++      /* Handle the case where we have: const (UNSPEC_RELOC??).  */
++      if (m68k_unwrap_symbol (orig, true) != orig)
++      return orig;
++
+       gcc_assert (reg);
+       /* legitimize both operands of the PLUS */
+@@ -2056,13 +2260,372 @@ legitimize_pic_address (rtx orig, enum m
+                                    base == reg ? 0 : reg);
+       if (GET_CODE (orig) == CONST_INT)
+-      return plus_constant (base, INTVAL (orig));
+-      pic_ref = gen_rtx_PLUS (Pmode, base, orig);
+-      /* Likewise, should we set special REG_NOTEs here?  */
++      pic_ref = plus_constant (base, INTVAL (orig));
++      else
++      pic_ref = gen_rtx_PLUS (Pmode, base, orig);
+     }
++
+   return pic_ref;
+ }
++/* The __tls_get_addr symbol.  */
++static GTY(()) rtx m68k_tls_get_addr;
++
++/* Return SYMBOL_REF for __tls_get_addr.  */
++
++static rtx
++m68k_get_tls_get_addr (void)
++{
++  if (m68k_tls_get_addr == NULL_RTX)
++    m68k_tls_get_addr = init_one_libfunc ("__tls_get_addr");
++
++  return m68k_tls_get_addr;
++}
++
++/* Return libcall result in A0 instead of usual D0.  */
++static bool m68k_libcall_value_in_a0_p = false;
++
++/* Emit instruction sequence that calls __tls_get_addr.  X is
++   the TLS symbol we are referencing and RELOC is the symbol type to use
++   (either TLSGD or TLSLDM).  EQV is the REG_EQUAL note for the sequence
++   emitted.  A pseudo register with result of __tls_get_addr call is
++   returned.  */
++
++static rtx
++m68k_call_tls_get_addr (rtx x, rtx eqv, enum m68k_reloc reloc)
++{
++  rtx a0;
++  rtx insns;
++  rtx dest;
++
++  /* Emit the call sequence.  */
++  start_sequence ();
++
++  /* FIXME: Unfortunately, emit_library_call_value does not
++     consider (plus (%a5) (const (unspec))) to be a good enough
++     operand for push, so it forces it into a register.  The bad
++     thing about this is that combiner, due to copy propagation and other
++     optimizations, sometimes can not later fix this.  As a consequence,
++     additional register may be allocated resulting in a spill.
++     For reference, see args processing loops in
++     calls.c:emit_library_call_value_1.
++     For testcase, see gcc.target/m68k/tls-{gd, ld}.c  */
++  x = m68k_wrap_symbol (x, reloc, m68k_get_gp (), NULL_RTX);
++
++  /* __tls_get_addr() is not a libcall, but emitting a libcall_value
++     is the simpliest way of generating a call.  The difference between
++     __tls_get_addr() and libcall is that the result is returned in D0
++     instead of A0.  To workaround this, we use m68k_libcall_value_in_a0_p
++     which temporarily switches returning the result to A0.  */ 
++
++  m68k_libcall_value_in_a0_p = true;
++  a0 = emit_library_call_value (m68k_get_tls_get_addr (), NULL_RTX, LCT_PURE,
++                              Pmode, 1, x, Pmode);
++  m68k_libcall_value_in_a0_p = false;
++  
++  insns = get_insns ();
++  end_sequence ();
++
++  gcc_assert (can_create_pseudo_p ());
++  dest = gen_reg_rtx (Pmode);
++  emit_libcall_block (insns, dest, a0, eqv);
++
++  return dest;
++}
++
++/* The __tls_get_addr symbol.  */
++static GTY(()) rtx m68k_read_tp;
++
++/* Return SYMBOL_REF for __m68k_read_tp.  */
++
++static rtx
++m68k_get_m68k_read_tp (void)
++{
++  if (m68k_read_tp == NULL_RTX)
++    m68k_read_tp = init_one_libfunc ("__m68k_read_tp");
++
++  return m68k_read_tp;
++}
++
++/* Emit instruction sequence that calls __m68k_read_tp.
++   A pseudo register with result of __m68k_read_tp call is returned.  */
++
++static rtx 
++m68k_call_m68k_read_tp (void)
++{
++  rtx a0;
++  rtx eqv;
++  rtx insns;
++  rtx dest;
++
++  start_sequence ();
++
++  /* __m68k_read_tp() is not a libcall, but emitting a libcall_value
++     is the simpliest way of generating a call.  The difference between
++     __m68k_read_tp() and libcall is that the result is returned in D0
++     instead of A0.  To workaround this, we use m68k_libcall_value_in_a0_p
++     which temporarily switches returning the result to A0.  */ 
++
++  /* Emit the call sequence.  */
++  m68k_libcall_value_in_a0_p = true;
++  a0 = emit_library_call_value (m68k_get_m68k_read_tp (), NULL_RTX, LCT_PURE,
++                              Pmode, 0);
++  m68k_libcall_value_in_a0_p = false;
++  insns = get_insns ();
++  end_sequence ();
++
++  /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
++     share the m68k_read_tp result with other IE/LE model accesses.  */
++  eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const1_rtx), UNSPEC_RELOC32);
++
++  gcc_assert (can_create_pseudo_p ());
++  dest = gen_reg_rtx (Pmode);
++  emit_libcall_block (insns, dest, a0, eqv);
++
++  return dest;
++}
++
++/* Return a legitimized address for accessing TLS SYMBOL_REF X.
++   For explanations on instructions sequences see TLS/NPTL ABI for m68k and
++   ColdFire.  */
++
++rtx
++m68k_legitimize_tls_address (rtx orig)
++{
++  switch (SYMBOL_REF_TLS_MODEL (orig))
++    {
++    case TLS_MODEL_GLOBAL_DYNAMIC:
++      orig = m68k_call_tls_get_addr (orig, orig, RELOC_TLSGD);
++      break;
++
++    case TLS_MODEL_LOCAL_DYNAMIC:
++      {
++      rtx eqv;
++      rtx a0;
++      rtx x;
++ 
++      /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
++         share the LDM result with other LD model accesses.  */
++      eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
++                            UNSPEC_RELOC32);
++
++      a0 = m68k_call_tls_get_addr (orig, eqv, RELOC_TLSLDM);
++
++      x = m68k_wrap_symbol (orig, RELOC_TLSLDO, a0, NULL_RTX);
++
++      if (can_create_pseudo_p ())
++        x = m68k_move_to_reg (x, orig, NULL_RTX);
++
++      orig = x;
++      break;
++      }
++
++    case TLS_MODEL_INITIAL_EXEC:
++      {
++      rtx a0;
++      rtx x;
++
++      a0 = m68k_call_m68k_read_tp ();
++
++      x = m68k_wrap_symbol_into_got_ref (orig, RELOC_TLSIE, NULL_RTX);
++      x = gen_rtx_PLUS (Pmode, x, a0);
++
++      if (can_create_pseudo_p ())
++        x = m68k_move_to_reg (x, orig, NULL_RTX);
++
++      orig = x;
++      break;
++      }
++
++    case TLS_MODEL_LOCAL_EXEC:
++      {
++      rtx a0;
++      rtx x;
++
++      a0 = m68k_call_m68k_read_tp ();
++
++      x = m68k_wrap_symbol (orig, RELOC_TLSLE, a0, NULL_RTX);
++
++      if (can_create_pseudo_p ())
++        x = m68k_move_to_reg (x, orig, NULL_RTX);
++
++      orig = x;
++      break;
++      }
++
++    default:
++      gcc_unreachable ();
++    }
++
++  return orig;
++}
++
++/* Return true if X is a TLS symbol.  */
++
++static bool
++m68k_tls_symbol_p (rtx x)
++{
++  if (!TARGET_HAVE_TLS)
++    return false;
++
++  if (GET_CODE (x) != SYMBOL_REF)
++    return false;
++
++  return SYMBOL_REF_TLS_MODEL (x) != 0;
++}
++
++/* Helper for m68k_tls_referenced_p.  */
++
++static int
++m68k_tls_referenced_p_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
++{
++  if (GET_CODE (*x) == SYMBOL_REF)
++    return SYMBOL_REF_TLS_MODEL (*x) != 0;
++
++  /* Don't recurse into UNSPEC_TLS looking for TLS symbols; these are
++     TLS offsets, not real symbol references.  */
++  if (GET_CODE (*x) == UNSPEC
++      && (XINT (*x, 1) == UNSPEC_RELOC16 || XINT (*x, 1) == UNSPEC_RELOC32)
++      && TLS_RELOC_P (INTVAL (XVECEXP (*x, 0, 1))))
++    return -1;
++
++  return 0;
++}
++
++/* Return true if X contains any TLS symbol references.  */
++
++bool
++m68k_tls_referenced_p (rtx x)
++{
++  if (!TARGET_HAVE_TLS)
++    return false;
++
++  return for_each_rtx (&x, m68k_tls_referenced_p_1, NULL);
++}
++
++/* Return true if X is legitimate TLS symbol reference.  */
++
++bool
++m68k_tls_mentioned_p (rtx x)
++{
++  switch (GET_CODE (x))
++    {
++    case CONST:
++      return m68k_tls_mentioned_p (XEXP (x, 0));
++
++    case UNSPEC:
++      if ((XINT (x, 1) == UNSPEC_RELOC16 || XINT (x, 1) == UNSPEC_RELOC32)
++        && TLS_RELOC_P (INTVAL (XVECEXP (x, 0, 1))))
++      return 1;
++
++    default:
++      return 0;
++    }
++}
++
++/* Legitimize X.  */
++
++rtx
++m68k_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
++{
++  if (m68k_tls_symbol_p (x))
++    return m68k_legitimize_tls_address (x);
++
++  if (GET_CODE (x) == PLUS)
++    {
++      bool ch;
++      bool copied;
++
++      ch = (x != oldx);
++      copied = 0;
++
++      /* For the 68000, we handle X+REG by loading X into a register R and
++       using R+REG.  R will go in an address reg and indexing will be used.
++       However, if REG is a broken-out memory address or multiplication,
++       nothing needs to be done because REG can certainly go in an address
++       reg.  */
++#define COPY_ONCE(Y) if (!copied) { Y = copy_rtx (Y); copied = ch = true; }
++
++      if (GET_CODE (XEXP (x, 0)) == MULT) 
++      {
++        COPY_ONCE (x);
++        XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
++      }                                       
++
++      if (GET_CODE (XEXP (x, 1)) == MULT)
++      {
++        COPY_ONCE (x);
++        XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
++      }
++
++      if (ch
++        && GET_CODE (XEXP (x, 1)) == REG
++        && GET_CODE (XEXP (x, 0)) == REG)
++      {
++        if (TARGET_COLDFIRE_FPU
++            && GET_MODE_CLASS (mode) == MODE_FLOAT)
++          {
++            COPY_ONCE (x);
++            x = force_operand (x, 0);
++          }
++
++        return x;
++      }
++
++      if (ch && m68k_legitimate_address_p (mode, x, REG_STRICT_P))
++      return x;
++
++      if (GET_CODE (XEXP (x, 0)) == REG
++        || (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND
++            && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
++            && GET_MODE (XEXP (XEXP (x, 0), 0)) == HImode))
++      {
++        rtx temp;
++        rtx val;
++
++        temp = gen_reg_rtx (Pmode);
++        val = force_operand (XEXP (x, 1), 0);
++
++        emit_move_insn (temp, val);
++        COPY_ONCE (x);
++        XEXP (x, 1) = temp;
++
++        if (TARGET_COLDFIRE_FPU
++            && GET_MODE_CLASS (mode) == MODE_FLOAT
++            && GET_CODE (XEXP (x, 0)) == REG)
++          x = force_operand (x, 0);
++
++        return x;
++      }
++      else if (GET_CODE (XEXP (x, 1)) == REG
++             || (GET_CODE (XEXP (x, 1)) == SIGN_EXTEND
++                 && GET_CODE (XEXP (XEXP (x, 1), 0)) == REG
++                 && GET_MODE (XEXP (XEXP (x, 1), 0)) == HImode))
++      {
++        rtx temp;
++        rtx val;
++
++        temp = gen_reg_rtx (Pmode);
++        val = force_operand (XEXP (x, 0), 0);
++
++        emit_move_insn (temp, val);
++        COPY_ONCE (x);
++        XEXP (x, 0) = temp;
++
++        if (TARGET_COLDFIRE_FPU
++            && GET_MODE_CLASS (mode) == MODE_FLOAT
++            && GET_CODE (XEXP (x, 1)) == REG)
++          x = force_operand (x, 0);
++
++        return x;
++      }
++
++#undef COPY_ONCE
++    }
++
++  return NULL_RTX;
++}
++
\f
+ #define USE_MOVQ(i)   ((unsigned) ((i) + 128) <= 255)
+@@ -2175,13 +2738,18 @@ m68k_rtx_costs (rtx x, int code, int out
+ #define MULL_COST                             \
+   (TUNE_68060 ? 2                             \
+    : TUNE_68040 ? 5                           \
+-   : TUNE_CFV2 ? 10                           \
++   : (TUNE_CFV2 && TUNE_EMAC) ? 3             \
++   : (TUNE_CFV2 && TUNE_MAC) ? 4              \
++   : TUNE_CFV2 ? 8                            \
+    : TARGET_COLDFIRE ? 3 : 13)
+ #define MULW_COST                             \
+   (TUNE_68060 ? 2                             \
+    : TUNE_68040 ? 3                           \
+-   : TUNE_68000_10 || TUNE_CFV2 ? 5           \
++   : TUNE_68000_10 ? 5                                \
++   : (TUNE_CFV2 && TUNE_EMAC) ? 3             \
++   : (TUNE_CFV2 && TUNE_MAC) ? 2              \
++   : TUNE_CFV2 ? 8                            \
+    : TARGET_COLDFIRE ? 2 : 8)
+ #define DIVW_COST                             \
+@@ -3531,9 +4099,7 @@ notice_update_cc (rtx exp, rtx insn)
+       case ROTATE: case ROTATERT:
+       /* These instructions always clear the overflow bit, and set
+          the carry to the bit shifted out.  */
+-      /* ??? We don't currently have a way to signal carry not valid,
+-         nor do we check for it in the branch insns.  */
+-      CC_STATUS_INIT;
++      cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
+       break;
+       case PLUS: case MINUS: case MULT:
+@@ -3839,7 +4405,75 @@ print_operand (FILE *file, rtx op, int l
+     }
+ }
+-\f
++/* Return string for TLS relocation RELOC.  */
++
++static const char *
++m68k_get_reloc_decoration (enum m68k_reloc reloc)
++{
++  switch (reloc)
++    {
++    case RELOC_GOT:
++      return "@GOT";
++
++    case RELOC_TLSGD:
++      return "@TLSGD";
++
++    case RELOC_TLSLDM:
++      return "@TLSLDM";
++
++    case RELOC_TLSLDO:
++      return "@TLSLDO";
++
++    case RELOC_TLSIE:
++      return "@TLSIE";
++
++    case RELOC_TLSLE:
++      return "@TLSLE";
++
++    default:
++      gcc_unreachable ();
++    }
++}
++
++/* m68k implementation of OUTPUT_ADDR_CONST_EXTRA.  */
++
++bool
++m68k_output_addr_const_extra (FILE *file, rtx x)
++{
++  if (GET_CODE (x) == UNSPEC)
++    {
++      switch (XINT (x, 1))
++      {
++        /* ??? It would be cleaner to wrap normal GOT references into
++           UNSPEC_GOT too, then we won't have to handle them separately
++           in print_operand_address.  I'm not aware of any downside of
++           such clean up.  */
++      case UNSPEC_RELOC16:
++      case UNSPEC_RELOC32:
++        output_addr_const (file, XVECEXP (x, 0, 0));
++        fputs (m68k_get_reloc_decoration (INTVAL (XVECEXP (x, 0, 1))), file);
++        return true;
++
++      default:
++        break;
++      }
++    }
++
++  return false;
++}
++
++/* M68K implementation of TARGET_ASM_OUTPUT_DWARF_DTPREL.  */
++
++static void
++m68k_output_dwarf_dtprel (FILE *file, int size, rtx x)
++{
++  gcc_assert (size == 4);
++  fputs ("\t.long\t", file);
++  output_addr_const (file, x);
++  fputs ("@TLSLDO+0x8000", file);
++}
++
++\f
+ /* A C compound statement to output to stdio stream STREAM the
+    assembler syntax for an instruction operand that is a memory
+    reference whose address is ADDR.  ADDR is an RTL expression.
+@@ -3928,7 +4562,9 @@ print_operand_address (FILE *file, rtx a
+             if (address.offset)
+               {
+                 output_addr_const (file, address.offset);
+-                if (flag_pic && address.base == pic_offset_table_rtx)
++                if (flag_pic && address.base == pic_offset_table_rtx
++                    && (m68k_unwrap_symbol (address.offset, false)
++                        == address.offset))
+                   {
+                     fprintf (file, "@GOT");
+                     if (flag_pic == 1 && TARGET_68020)
+@@ -4486,7 +5122,8 @@ m68k_libcall_value (enum machine_mode mo
+   default:
+     break;
+   }
+-  return gen_rtx_REG (mode, D0_REG);
++
++  return gen_rtx_REG (mode, m68k_libcall_value_in_a0_p ? A0_REG : D0_REG);
+ }
+ rtx
+@@ -4533,7 +5170,7 @@ m68k_function_value (const_tree valtype,
+ /* Worker function for TARGET_RETURN_IN_MEMORY.  */
+ #if M68K_HONOR_TARGET_STRICT_ALIGNMENT
+ static bool
+-m68k_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
++m68k_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
+ {
+   enum machine_mode mode = TYPE_MODE (type);
+@@ -4555,14 +5192,20 @@ m68k_return_in_memory (tree type, tree f
+ /* CPU to schedule the program for.  */
+ enum attr_cpu m68k_sched_cpu;
++/* MAC to schedule the program for.  */
++enum attr_mac m68k_sched_mac;
++
+ /* Operand type.  */
+ enum attr_op_type
+   {
+     /* No operand.  */
+     OP_TYPE_NONE,
+-    /* Register.  */
+-    OP_TYPE_REG,
++    /* Integer register.  */
++    OP_TYPE_RN,
++
++    /* FP register.  */
++    OP_TYPE_FPN,
+     /* Implicit mem reference (e.g. stack).  */
+     OP_TYPE_MEM1,
+@@ -4589,19 +5232,19 @@ enum attr_op_type
+     OP_TYPE_IMM_L
+   };
+-/* True if current insn doesn't have complete pipeline description.  */
+-static bool sched_guess_p;
+-
+ /* Return type of memory ADDR_RTX refers to.  */
+ static enum attr_op_type
+ sched_address_type (enum machine_mode mode, rtx addr_rtx)
+ {
+   struct m68k_address address;
++  if (symbolic_operand (addr_rtx, VOIDmode))
++    return OP_TYPE_MEM7;
++
+   if (!m68k_decompose_address (mode, addr_rtx,
+                              reload_completed, &address))
+     {
+-      gcc_assert (sched_guess_p);
++      gcc_assert (!reload_completed);
+       /* Reload will likely fix the address to be in the register.  */
+       return OP_TYPE_MEM234;
+     }
+@@ -4622,12 +5265,42 @@ sched_address_type (enum machine_mode mo
+   return OP_TYPE_MEM7;
+ }
+-/* Return type of the operand OP.
+-   If ADDRESS_P is true, return type of memory location OP refers to.  */
++/* Return X or Y (depending on OPX_P) operand of INSN.  */
++static rtx
++sched_get_operand (rtx insn, bool opx_p)
++{
++  int i;
++
++  if (recog_memoized (insn) < 0)
++    gcc_unreachable ();
++
++  extract_constrain_insn_cached (insn);
++
++  if (opx_p)
++    i = get_attr_opx (insn);
++  else
++    i = get_attr_opy (insn);
++
++  if (i >= recog_data.n_operands)
++    return NULL;
++
++  return recog_data.operand[i];
++}
++
++/* Return type of INSN's operand X (if OPX_P) or operand Y (if !OPX_P).
++   If ADDRESS_P is true, return type of memory location operand refers to.  */
+ static enum attr_op_type
+-sched_operand_type (rtx op, bool address_p)
++sched_attr_op_type (rtx insn, bool opx_p, bool address_p)
+ {
+-  gcc_assert (op != NULL_RTX);
++  rtx op;
++
++  op = sched_get_operand (insn, opx_p);
++
++  if (op == NULL)
++    {
++      gcc_assert (!reload_completed);
++      return OP_TYPE_RN;
++    }
+   if (address_p)
+     return sched_address_type (QImode, op);
+@@ -4636,13 +5309,49 @@ sched_operand_type (rtx op, bool address
+     return sched_address_type (GET_MODE (op), XEXP (op, 0));
+   if (register_operand (op, VOIDmode))
+-    return OP_TYPE_REG;
++    {
++      if ((!reload_completed && FLOAT_MODE_P (GET_MODE (op)))
++        || (reload_completed && FP_REG_P (op)))
++      return OP_TYPE_FPN;
++
++      return OP_TYPE_RN;
++    }
+   if (GET_CODE (op) == CONST_INT)
+     {
+-      /* ??? Below condition should probably check if the operation is
+-       signed or unsigned.  */
+-      if (IN_RANGE (INTVAL (op), -0x8000, 0x7fff))
++      int ival;
++
++      ival = INTVAL (op);
++
++      /* Check for quick constants.  */
++      switch (get_attr_type (insn))
++      {
++      case TYPE_ALUQ_L:
++        if (IN_RANGE (ival, 1, 8) || IN_RANGE (ival, -8, -1))
++          return OP_TYPE_IMM_Q;
++
++        gcc_assert (!reload_completed);
++        break;
++
++      case TYPE_MOVEQ_L:
++        if (USE_MOVQ (ival))
++          return OP_TYPE_IMM_Q;
++
++        gcc_assert (!reload_completed);
++        break;
++
++      case TYPE_MOV3Q_L:
++        if (valid_mov3q_const (ival))
++          return OP_TYPE_IMM_Q;
++
++        gcc_assert (!reload_completed);
++        break;
++
++      default:
++        break;
++      }
++
++      if (IN_RANGE (ival, -0x8000, 0x7fff))
+       return OP_TYPE_IMM_W;
+       return OP_TYPE_IMM_L;
+@@ -4664,7 +5373,8 @@ sched_operand_type (rtx op, bool address
+       }
+     }
+-  if (symbolic_operand (op, VOIDmode)
++  if (GET_CODE (op) == CONST
++      || symbolic_operand (op, VOIDmode)
+       || LABEL_P (op))
+     {
+       switch (GET_MODE (op))
+@@ -4679,41 +5389,20 @@ sched_operand_type (rtx op, bool address
+         return OP_TYPE_IMM_L;
+       default:
+-        if (GET_CODE (op) == SYMBOL_REF)
+-          /* ??? Just a guess.  Probably we can guess better using length
+-             attribute of the instructions.  */
++        if (symbolic_operand (m68k_unwrap_symbol (op, false), VOIDmode))
++          /* Just a guess.  */
+           return OP_TYPE_IMM_W;
+         return OP_TYPE_IMM_L;
+       }
+     }
+-  gcc_assert (sched_guess_p);
+-
+-  return OP_TYPE_REG;
+-}
+-
+-/* Return type of INSN's operand X (if OPX_P) or operand Y (if !OPX_P).
+-   If ADDRESS_P is true, return type of memory location operand refers to.  */
+-static enum attr_op_type
+-sched_attr_op_type (rtx insn, bool opx_p, bool address_p)
+-{
+-  int i;
+-
+-  extract_constrain_insn_cached (insn);
+-
+-  if (opx_p)
+-    i = get_attr_opx (insn);
+-  else
+-    i = get_attr_opy (insn);
++  gcc_assert (!reload_completed);
+-  if (i >= recog_data.n_operands)
+-    {
+-      gcc_assert (sched_guess_p);
+-      return OP_TYPE_REG;
+-    }
++  if (FLOAT_MODE_P (GET_MODE (op)))
++    return OP_TYPE_FPN;
+-  return sched_operand_type (recog_data.operand[i], address_p);
++  return OP_TYPE_RN;
+ }
+ /* Implement opx_type attribute.
+@@ -4722,12 +5411,13 @@ sched_attr_op_type (rtx insn, bool opx_p
+ enum attr_opx_type
+ m68k_sched_attr_opx_type (rtx insn, int address_p)
+ {
+-  sched_guess_p = (get_attr_guess (insn) == GUESS_YES);
+-
+   switch (sched_attr_op_type (insn, true, address_p != 0))
+     {
+-    case OP_TYPE_REG:
+-      return OPX_TYPE_REG;
++    case OP_TYPE_RN:
++      return OPX_TYPE_RN;
++
++    case OP_TYPE_FPN:
++      return OPX_TYPE_FPN;
+     case OP_TYPE_MEM1:
+       return OPX_TYPE_MEM1;
+@@ -4765,12 +5455,13 @@ m68k_sched_attr_opx_type (rtx insn, int 
+ enum attr_opy_type
+ m68k_sched_attr_opy_type (rtx insn, int address_p)
+ {
+-  sched_guess_p = (get_attr_guess (insn) == GUESS_YES);
+-
+   switch (sched_attr_op_type (insn, false, address_p != 0))
+     {
+-    case OP_TYPE_REG:
+-      return OPY_TYPE_REG;
++    case OP_TYPE_RN:
++      return OPY_TYPE_RN;
++
++    case OP_TYPE_FPN:
++      return OPY_TYPE_FPN;
+     case OP_TYPE_MEM1:
+       return OPY_TYPE_MEM1;
+@@ -4802,17 +5493,21 @@ m68k_sched_attr_opy_type (rtx insn, int 
+     }
+ }
+-/* Return the size of INSN.  */
+-int
+-m68k_sched_attr_size (rtx insn)
++/* Return size of INSN as int.  */
++static int
++sched_get_attr_size_int (rtx insn)
+ {
+   int size;
+-  sched_guess_p = (get_attr_guess (insn) == GUESS_YES);
+-
+-  switch (get_attr_type1 (insn))
++  switch (get_attr_type (insn))
+     {
+-    case TYPE1_MUL_L:
++    case TYPE_IGNORE:
++      /* There should be no references to m68k_sched_attr_size for 'ignore'
++       instructions.  */
++      gcc_unreachable ();
++      return 0;
++
++    case TYPE_MUL_L:
+       size = 2;
+       break;
+@@ -4824,7 +5519,8 @@ m68k_sched_attr_size (rtx insn)
+   switch (get_attr_opx_type (insn))
+     {
+     case OPX_TYPE_NONE:
+-    case OPX_TYPE_REG:
++    case OPX_TYPE_RN:
++    case OPX_TYPE_FPN:
+     case OPX_TYPE_MEM1:
+     case OPX_TYPE_MEM234:
+     case OPY_TYPE_IMM_Q:
+@@ -4849,7 +5545,8 @@ m68k_sched_attr_size (rtx insn)
+   switch (get_attr_opy_type (insn))
+     {
+     case OPY_TYPE_NONE:
+-    case OPY_TYPE_REG:
++    case OPY_TYPE_RN:
++    case OPY_TYPE_FPN:
+     case OPY_TYPE_MEM1:
+     case OPY_TYPE_MEM234:
+     case OPY_TYPE_IMM_Q:
+@@ -4873,7 +5570,7 @@ m68k_sched_attr_size (rtx insn)
+   if (size > 3)
+     {
+-      gcc_assert (sched_guess_p);
++      gcc_assert (!reload_completed);
+       size = 3;
+     }
+@@ -4881,22 +5578,100 @@ m68k_sched_attr_size (rtx insn)
+   return size;
+ }
++/* Return size of INSN as attribute enum value.  */
++enum attr_size
++m68k_sched_attr_size (rtx insn)
++{
++  switch (sched_get_attr_size_int (insn))
++    {
++    case 1:
++      return SIZE_1;
++
++    case 2:
++      return SIZE_2;
++
++    case 3:
++      return SIZE_3;
++
++    default:
++      gcc_unreachable ();
++      return 0;
++    }
++}
++
++/* Return operand X or Y (depending on OPX_P) of INSN,
++   if it is a MEM, or NULL overwise.  */
++static enum attr_op_type
++sched_get_opxy_mem_type (rtx insn, bool opx_p)
++{
++  if (opx_p)
++    {
++      switch (get_attr_opx_type (insn))
++      {
++      case OPX_TYPE_NONE:
++      case OPX_TYPE_RN:
++      case OPX_TYPE_FPN:
++      case OPX_TYPE_IMM_Q:
++      case OPX_TYPE_IMM_W:
++      case OPX_TYPE_IMM_L:
++        return OP_TYPE_RN;
++
++      case OPX_TYPE_MEM1:
++      case OPX_TYPE_MEM234:
++      case OPX_TYPE_MEM5:
++      case OPX_TYPE_MEM7:
++        return OP_TYPE_MEM1;
++
++      case OPX_TYPE_MEM6:
++        return OP_TYPE_MEM6;
++
++      default:
++        gcc_unreachable ();
++        return 0;
++      }
++    }
++  else
++    {
++      switch (get_attr_opy_type (insn))
++      {
++      case OPY_TYPE_NONE:
++      case OPY_TYPE_RN:
++      case OPY_TYPE_FPN:
++      case OPY_TYPE_IMM_Q:
++      case OPY_TYPE_IMM_W:
++      case OPY_TYPE_IMM_L:
++        return OP_TYPE_RN;
++
++      case OPY_TYPE_MEM1:
++      case OPY_TYPE_MEM234:
++      case OPY_TYPE_MEM5:
++      case OPY_TYPE_MEM7:
++        return OP_TYPE_MEM1;
++
++      case OPY_TYPE_MEM6:
++        return OP_TYPE_MEM6;
++
++      default:
++        gcc_unreachable ();
++        return 0;
++      }
++    }
++}
++
+ /* Implement op_mem attribute.  */
+ enum attr_op_mem
+ m68k_sched_attr_op_mem (rtx insn)
+ {
+-  enum attr_opy_mem opy;
+-  enum attr_opx_mem opx;
++  enum attr_op_type opx;
++  enum attr_op_type opy;
+-  sched_guess_p = (get_attr_guess (insn) == GUESS_YES);
++  opx = sched_get_opxy_mem_type (insn, true);
++  opy = sched_get_opxy_mem_type (insn, false);
+-  opy = get_attr_opy_mem (insn);
+-  opx = get_attr_opx_mem (insn);
+-
+-  if (opy == OPY_MEM_R && opx == OPX_MEM_R)
++  if (opy == OP_TYPE_RN && opx == OP_TYPE_RN)
+     return OP_MEM_00;
+-  if (opy == OPY_MEM_R && opx == OPX_MEM_M)
++  if (opy == OP_TYPE_RN && opx == OP_TYPE_MEM1)
+     {
+       switch (get_attr_opx_access (insn))
+       {
+@@ -4910,12 +5685,12 @@ m68k_sched_attr_op_mem (rtx insn)
+         return OP_MEM_11;
+       default:
+-        gcc_assert (sched_guess_p);
+-        return OP_MEM_UNKNOWN;
++        gcc_unreachable ();
++        return 0;
+       }
+     }
+-  if (opy == OPY_MEM_R && opx == OPX_MEM_I)
++  if (opy == OP_TYPE_RN && opx == OP_TYPE_MEM6)
+     {
+       switch (get_attr_opx_access (insn))
+       {
+@@ -4929,15 +5704,15 @@ m68k_sched_attr_op_mem (rtx insn)
+         return OP_MEM_I1;
+       default:
+-        gcc_assert (sched_guess_p);
+-        return OP_MEM_UNKNOWN;
++        gcc_unreachable ();
++        return 0;
+       }
+     }
+-  if (opy == OPY_MEM_M && opx == OPX_MEM_R)
++  if (opy == OP_TYPE_MEM1 && opx == OP_TYPE_RN)
+     return OP_MEM_10;
+-  if (opy == OPY_MEM_M && opx == OPX_MEM_M)
++  if (opy == OP_TYPE_MEM1 && opx == OP_TYPE_MEM1)
+     {
+       switch (get_attr_opx_access (insn))
+       {
+@@ -4945,12 +5720,12 @@ m68k_sched_attr_op_mem (rtx insn)
+         return OP_MEM_11;
+       default:
+-        gcc_assert (sched_guess_p);
+-        return OP_MEM_UNKNOWN;
++        gcc_assert (!reload_completed);
++        return OP_MEM_11;
+       }
+     }
+-  if (opy == OPY_MEM_M && opx == OPX_MEM_I)
++  if (opy == OP_TYPE_MEM1 && opx == OP_TYPE_MEM6)
+     {
+       switch (get_attr_opx_access (insn))
+       {
+@@ -4958,16 +5733,15 @@ m68k_sched_attr_op_mem (rtx insn)
+         return OP_MEM_1I;
+       default:
+-        gcc_assert (sched_guess_p);
+-        return OP_MEM_UNKNOWN;
++        gcc_assert (!reload_completed);
++        return OP_MEM_1I;
+       }
+     }
+-  if (opy == OPY_MEM_I && opx == OPX_MEM_R)
++  if (opy == OP_TYPE_MEM6 && opx == OP_TYPE_RN)
+     return OP_MEM_I0;
+-
+-  if (opy == OPY_MEM_I && opx == OPX_MEM_M)
++  if (opy == OP_TYPE_MEM6 && opx == OP_TYPE_MEM1)
+     {
+       switch (get_attr_opx_access (insn))
+       {
+@@ -4975,13 +5749,14 @@ m68k_sched_attr_op_mem (rtx insn)
+         return OP_MEM_I1;
+       default:
+-        gcc_assert (sched_guess_p);
+-        return OP_MEM_UNKNOWN;
++        gcc_assert (!reload_completed);
++        return OP_MEM_I1;
+       }
+     }
+-  gcc_assert (sched_guess_p);
+-  return OP_MEM_UNKNOWN;
++  gcc_assert (opy == OP_TYPE_MEM6 && opx == OP_TYPE_MEM6);
++  gcc_assert (!reload_completed);
++  return OP_MEM_I1;
+ }
+ /* Jump instructions types.  Indexed by INSN_UID.
+@@ -5004,66 +5779,21 @@ m68k_sched_branch_type (rtx insn)
+   return type;
+ }
+-/* Implement type2 attribute.  */
+-enum attr_type2
+-m68k_sched_attr_type2 (rtx insn)
++/* Data for ColdFire V4 index bypass.
++   Producer modifies register that is used as index in consumer with
++   specified scale.  */
++static struct
+ {
+-  switch (get_attr_type1 (insn))
+-    {
+-    case TYPE1_ALU_REG1:
+-    case TYPE1_ALU_REGX:
+-      return TYPE2_ALU;
+-
+-    case TYPE1_ALU_L:
+-    case TYPE1_ALUQ_L:
+-    case TYPE1_CMP_L:
+-      return TYPE2_ALU_L;
+-
+-    case TYPE1_BCC:
+-      return TYPE2_BCC;
+-
+-    case TYPE1_BRA:
+-      return TYPE2_BRA;
+-
+-    case TYPE1_BSR:
+-    case TYPE1_JSR:
+-      return TYPE2_CALL;
+-
+-    case TYPE1_JMP:
+-      return TYPE2_JMP;
+-
+-    case TYPE1_LEA:
+-      return TYPE2_LEA;
+-
+-    case TYPE1_CLR:
+-    case TYPE1_MOV3Q_L:
+-    case TYPE1_MOVE:
+-    case TYPE1_MOVEQ_L:
+-    case TYPE1_TST:
+-      return TYPE2_MOVE;
+-
+-    case TYPE1_MOVE_L:
+-    case TYPE1_TST_L:
+-      return TYPE2_MOVE_L;
++  /* Producer instruction.  */
++  rtx pro;
+-    case TYPE1_MUL_W:
+-    case TYPE1_MUL_L:
+-      return TYPE2_MUL;
++  /* Consumer instruction.  */
++  rtx con;
+-    case TYPE1_PEA:
+-      return TYPE2_PEA;
+-
+-    case TYPE1_RTS:
+-      return TYPE2_RTS;
+-
+-    case TYPE1_UNLK:
+-      return TYPE2_UNLK;
+-
+-    default:
+-      gcc_assert (get_attr_guess (insn) == GUESS_YES);
+-      return TYPE2_UNKNOWN;
+-    }
+-}
++  /* Scale of indexed memory access within consumer.
++     Or zero if bypass should not be effective at the moment.  */
++  int scale;
++} sched_cfv4_bypass_data;
+ /* An empty state that is used in m68k_sched_adjust_cost.  */
+ static state_t sched_adjust_cost_state;
+@@ -5080,13 +5810,33 @@ m68k_sched_adjust_cost (rtx insn, rtx li
+       || recog_memoized (insn) < 0)
+     return cost;
++  if (sched_cfv4_bypass_data.scale == 1)
++    /* Handle ColdFire V4 bypass for indexed address with 1x scale.  */
++    {
++      /* haifa-sched.c: insn_cost () calls bypass_p () just before
++       targetm.sched.adjust_cost ().  Hence, we can be relatively sure
++       that the data in sched_cfv4_bypass_data is up to date.  */
++      gcc_assert (sched_cfv4_bypass_data.pro == def_insn
++                && sched_cfv4_bypass_data.con == insn);
++
++      if (cost < 3)
++      cost = 3;
++
++      sched_cfv4_bypass_data.pro = NULL;
++      sched_cfv4_bypass_data.con = NULL;
++      sched_cfv4_bypass_data.scale = 0;
++    }
++  else
++    gcc_assert (sched_cfv4_bypass_data.pro == NULL
++              && sched_cfv4_bypass_data.con == NULL
++              && sched_cfv4_bypass_data.scale == 0);
++
+   /* Don't try to issue INSN earlier than DFA permits.
+      This is especially useful for instructions that write to memory,
+      as their true dependence (default) latency is better to be set to 0
+      to workaround alias analysis limitations.
+      This is, in fact, a machine independent tweak, so, probably,
+      it should be moved to haifa-sched.c: insn_cost ().  */
+-
+   delay = min_insn_conflict_delay (sched_adjust_cost_state, def_insn, insn);
+   if (delay > cost)
+     cost = delay;
+@@ -5094,237 +5844,147 @@ m68k_sched_adjust_cost (rtx insn, rtx li
+   return cost;
+ }
+-/* Size of the instruction buffer in words.  */
+-static int sched_ib_size;
+-
+-/* Number of filled words in the instruction buffer.  */
+-static int sched_ib_filled;
+-
+-/* An insn that reserves (marks empty) one word in the instruction buffer.  */
+-static rtx sched_ib_insn;
+-
+-/* ID of memory unit.  */
+-static int sched_mem_unit_code;
+-
+-/* Implementation of the targetm.sched.variable_issue () hook.
+-   It is called after INSN was issued.  It returns the number of insns
+-   that can possibly get scheduled on the current cycle.
+-   It is used here to determine the effect of INSN on the instruction
+-   buffer.  */
++/* Return maximal number of insns that can be scheduled on a single cycle.  */
+ static int
+-m68k_sched_variable_issue (FILE *sched_dump ATTRIBUTE_UNUSED,
+-                         int sched_verbose ATTRIBUTE_UNUSED,
+-                         rtx insn, int can_issue_more)
+-{
+-  int insn_size;
+-
+-  if (recog_memoized (insn) >= 0)
+-    {
+-      insn_size = get_attr_size (insn);
+-
+-      gcc_assert (insn_size <= sched_ib_filled);
+-
+-      --can_issue_more;
+-    }
+-  else if (GET_CODE (PATTERN (insn)) == ASM_INPUT
+-         || asm_noperands (PATTERN (insn)) >= 0)
+-    insn_size = sched_ib_filled;
+-  else
+-    insn_size = 0;
+-
+-  sched_ib_filled -= insn_size;
+-
+-  return can_issue_more;
+-}
+-
+-/* Statistics gatherer.  */
+-
+-typedef enum
+-  {
+-    /* Something needs to be done for this insn.  */
+-    SCHED_DUMP_TODO,
+-
+-    /* Support for this insn is complete.  */
+-    SCHED_DUMP_DONE,
+-
+-    /* This insn didn't require much effort to support it.  */
+-    SCHED_DUMP_NOTHING
+-  } sched_dump_class_def;
+-
+-/* Pointer to functions that classifies insns into 3 above classes.  */
+-typedef sched_dump_class_def (*sched_dump_class_func_t) (rtx);
+-
+-/* Return statistical type of INSN regarding splits.  */
+-static sched_dump_class_def
+-sched_dump_split_class (rtx insn)
++m68k_sched_issue_rate (void)
+ {
+-  int i;
+-
+-  i = recog_memoized (insn);
+-  gcc_assert (i >= 0);
+-
+-  switch (get_attr_split (insn))
++  switch (m68k_sched_cpu)
+     {
+-    case SPLIT_TODO:
+-      return SCHED_DUMP_TODO;
+-
+-    case SPLIT_DONE:
+-      return SCHED_DUMP_DONE;
++    case CPU_CFV1:
++    case CPU_CFV2:
++    case CPU_CFV3:
++      return 1;
+-    case SPLIT_NOTHING:
+-      return SCHED_DUMP_NOTHING;
++    case CPU_CFV4:
++      return 2;
+     default:
+       gcc_unreachable ();
++      return 0;
+     }
+ }
+-/* ID of the guess unit.  */
+-static int sched_dump_dfa_guess_unit_code;
++/* Maximal length of instruction for current CPU.
++   E.g. it is 3 for any ColdFire core.  */
++static int max_insn_size;
+-/* DFA state for use in sched_dump_dfa_class ().  */
+-static state_t sched_dump_dfa_state;
+-
+-/* Return statistical type of INSN regarding DFA reservations.  */
+-static sched_dump_class_def
+-sched_dump_dfa_class (rtx insn)
++/* Data to model instruction buffer of CPU.  */
++struct _sched_ib
+ {
+-  int i;
++  /* True if instruction buffer model is modeled for current CPU.  */
++  bool enabled_p;
+-  i = recog_memoized (insn);
+-  gcc_assert (i >= 0 && insn_has_dfa_reservation_p (insn));
++  /* Size of the instruction buffer in words.  */
++  int size;
+-  if (sched_dump_split_class (insn) == SCHED_DUMP_TODO)
+-    /* Insn is not yet ready for reservations.  */
+-    return SCHED_DUMP_NOTHING;
++  /* Number of filled words in the instruction buffer.  */
++  int filled;
+-  state_reset (sched_dump_dfa_state);
++  /* Additional information about instruction buffer for CPUs that have
++     a buffer of instruction records, rather then a plain buffer
++     of instruction words.  */
++  struct _sched_ib_records
++  {
++    /* Size of buffer in records.  */
++    int n_insns;
+-  if (state_transition (sched_dump_dfa_state, insn) >= 0)
+-    gcc_unreachable ();
++    /* Array to hold data on adjustements made to the size of the buffer.  */
++    int *adjust;
+-  if (cpu_unit_reservation_p (sched_dump_dfa_state,
+-                            sched_dump_dfa_guess_unit_code))
+-    return SCHED_DUMP_TODO;
++    /* Index of the above array.  */
++    int adjust_index;
++  } records;
+-  return SCHED_DUMP_DONE;
+-}
+-
+-/* Dump statistics on current function into file DUMP_FILENAME and prefix
+-   each entry with PREFIX.
+-   Instructions are classified with DUMP_CLASS.  */
+-static void
+-m68k_sched_dump (sched_dump_class_func_t dump_class,
+-               const char *prefix, FILE *dump)
+-{
+-  sbitmap present;
+-  int *todos;
+-  int *dones;
+-  int *nothings;
++  /* An insn that reserves (marks empty) one word in the instruction buffer.  */
+   rtx insn;
++};
+-  gcc_assert (dump != NULL);
++static struct _sched_ib sched_ib;
+-  present = sbitmap_alloc (CODE_FOR_nothing);
+-  sbitmap_zero (present);
++/* ID of memory unit.  */
++static int sched_mem_unit_code;
+-  todos = xcalloc (CODE_FOR_nothing, sizeof (*todos));
+-  dones = xcalloc (CODE_FOR_nothing, sizeof (*dones));
+-  nothings = xcalloc (CODE_FOR_nothing, sizeof (*nothings));
++/* Implementation of the targetm.sched.variable_issue () hook.
++   It is called after INSN was issued.  It returns the number of insns
++   that can possibly get scheduled on the current cycle.
++   It is used here to determine the effect of INSN on the instruction
++   buffer.  */
++static int
++m68k_sched_variable_issue (FILE *sched_dump ATTRIBUTE_UNUSED,
++                         int sched_verbose ATTRIBUTE_UNUSED,
++                         rtx insn, int can_issue_more)
++{
++  int insn_size;
+-  /* Gather statistics.  */
+-  for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
++  if (recog_memoized (insn) >= 0 && get_attr_type (insn) != TYPE_IGNORE)
+     {
+-      if (INSN_P (insn) && recog_memoized (insn) >= 0)
++      switch (m68k_sched_cpu)
+       {
+-        enum insn_code code;
++      case CPU_CFV1:
++      case CPU_CFV2:
++        insn_size = sched_get_attr_size_int (insn);
++        break;
++
++      case CPU_CFV3:
++        insn_size = sched_get_attr_size_int (insn);
++        
++        /* ColdFire V3 and V4 cores have instruction buffers that can
++           accumulate up to 8 instructions regardless of instructions'
++           sizes.  So we should take care not to "prefetch" 24 one-word
++           or 12 two-words instructions.
++           To model this behavior we temporarily decrease size of the
++           buffer by (max_insn_size - insn_size) for next 7 instructions.  */
++        {
++          int adjust;
+-        code = INSN_CODE (insn);
+-        gcc_assert (code < CODE_FOR_nothing);
++          adjust = max_insn_size - insn_size;
++          sched_ib.size -= adjust;
+-        SET_BIT (present, code);
++          if (sched_ib.filled > sched_ib.size)
++            sched_ib.filled = sched_ib.size;
+-        switch (dump_class (insn))
+-          {
+-          case SCHED_DUMP_TODO:
+-            ++todos[code];
+-            break;
++          sched_ib.records.adjust[sched_ib.records.adjust_index] = adjust;
++        }
+-          case SCHED_DUMP_DONE:
+-            ++dones[code];
+-            break;
++        ++sched_ib.records.adjust_index;
++        if (sched_ib.records.adjust_index == sched_ib.records.n_insns)
++          sched_ib.records.adjust_index = 0;
++
++        /* Undo adjustement we did 7 instructions ago.  */
++        sched_ib.size
++          += sched_ib.records.adjust[sched_ib.records.adjust_index];
++
++        break;
++
++      case CPU_CFV4:
++        gcc_assert (!sched_ib.enabled_p);
++        insn_size = 0;
++        break;
+-          case SCHED_DUMP_NOTHING:
+-            ++nothings[code];
+-            break;
+-          }
++      default:
++        gcc_unreachable ();
+       }
+-    }
+-
+-  /* Print statisctics.  */
+-  {
+-    unsigned int i;
+-    sbitmap_iterator si;
+-    int total_todo;
+-    int total_done;
+-    int total_nothing;
+-
+-    total_todo = 0;
+-    total_done = 0;
+-    total_nothing = 0;
+-
+-    EXECUTE_IF_SET_IN_SBITMAP (present, 0, i, si)
+-      {
+-      int todo;
+-      int done;
+-      int nothing;
+-      enum insn_code code;
+-
+-      code = (enum insn_code) i;
+-
+-      todo = todos[code];
+-      done = dones[code];
+-      nothing = nothings[code];
+-
+-      total_todo += todo;
+-      total_done += done;
+-      total_nothing += nothing;
+-      if (todo != 0)
+-        {
+-          fprintf (dump,
+-                   "%s: %3d: %d / %d / %d ;",
+-                   prefix, code, todo, done, nothing);
+-
+-          {
+-            const char *name;
+-
+-            name = get_insn_name (code);
+-
+-            if (name != NULL)
+-              fprintf (dump, " {%s}\n", name);
+-            else
+-              fprintf (dump, " {unknown}\n");
+-          }
+-        }
+-      }
+-
+-    gcc_assert (CODE_FOR_nothing < 999);
++      gcc_assert (insn_size <= sched_ib.filled);
++      --can_issue_more;
++    }
++  else if (GET_CODE (PATTERN (insn)) == ASM_INPUT
++         || asm_noperands (PATTERN (insn)) >= 0)
++    insn_size = sched_ib.filled;
++  else
++    insn_size = 0;
+-    fprintf (dump,
+-           "%s: 999: %d / %d / %d ; {total}\n",
+-           prefix, total_todo, total_done, total_nothing);
+-  }
++  sched_ib.filled -= insn_size;
+-  free (nothings);
+-  nothings = NULL;
+-  free (dones);
+-  dones = NULL;
+-  free (todos);
+-  todos = NULL;
++  return can_issue_more;
++}
+-  sbitmap_free (present);
+-  present = NULL;
++/* Return how many instructions should scheduler lookahead to choose the
++   best one.  */
++static int
++m68k_sched_first_cycle_multipass_dfa_lookahead (void)
++{
++  return m68k_sched_issue_rate () - 1;
+ }
+ /* Implementation of targetm.sched.md_init_global () hook.
+@@ -5350,40 +6010,69 @@ m68k_sched_md_init_global (FILE *sched_d
+       }
+   }
+-  if (reload_completed && sched_verbose >= 8)
+-    /* Dump statistics.  */
+-    {
+-      m68k_sched_dump (sched_dump_split_class, "m68k_sched_split",
+-                     sched_dump);
++#ifdef ENABLE_CHECKING
++  /* Check that all instructions have DFA reservations and
++     that all instructions can be issued from a clean state.  */
++  {
++    rtx insn;
++    state_t state;
+-      sched_dump_dfa_guess_unit_code = get_cpu_unit_code ("cf_v2_guess");
+-      sched_dump_dfa_state = alloca (state_size ());
++    state = alloca (state_size ());
+-      m68k_sched_dump (sched_dump_dfa_class, "m68k_sched_dfa",
+-                     sched_dump);
++    for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
++      {
++      if (INSN_P (insn) && recog_memoized (insn) >= 0)
++        {
++          gcc_assert (insn_has_dfa_reservation_p (insn));
+-      sched_dump_dfa_state = NULL;
+-      sched_dump_dfa_guess_unit_code = 0;
+-    }
++          state_reset (state);
++          if (state_transition (state, insn) >= 0)
++            gcc_unreachable ();
++        }
++      }
++  }
++#endif
+   /* Setup target cpu.  */
++
++  /* ColdFire V4 has a set of features to keep its instruction buffer full
++     (e.g., a separate memory bus for instructions) and, hence, we do not model
++     buffer for this CPU.  */
++  sched_ib.enabled_p = (m68k_sched_cpu != CPU_CFV4);
++
+   switch (m68k_sched_cpu)
+     {
+-    case CPU_CF_V2:
+-      sched_ib_size = 6;
+-      sched_mem_unit_code = get_cpu_unit_code ("cf_v2_mem");
++    case CPU_CFV4:
++      sched_ib.filled = 0;
++
++      /* FALLTHRU */
++
++    case CPU_CFV1:
++    case CPU_CFV2:
++      max_insn_size = 3;
++      sched_ib.records.n_insns = 0;
++      sched_ib.records.adjust = NULL;
++      break;
++
++    case CPU_CFV3:
++      max_insn_size = 3;
++      sched_ib.records.n_insns = 8;
++      sched_ib.records.adjust = xmalloc (sched_ib.records.n_insns
++                                       * sizeof (*sched_ib.records.adjust));
+       break;
+     default:
+       gcc_unreachable ();
+     }
++  sched_mem_unit_code = get_cpu_unit_code ("cf_mem1");
++
+   sched_adjust_cost_state = xmalloc (state_size ());
+   state_reset (sched_adjust_cost_state);
+   start_sequence ();
+   emit_insn (gen_ib ());
+-  sched_ib_insn = get_insns ();
++  sched_ib.insn = get_insns ();
+   end_sequence ();
+ }
+@@ -5392,13 +6081,17 @@ static void
+ m68k_sched_md_finish_global (FILE *dump ATTRIBUTE_UNUSED,
+                            int verbose ATTRIBUTE_UNUSED)
+ {
+-  sched_ib_insn = NULL;
++  sched_ib.insn = NULL;
+   free (sched_adjust_cost_state);
+   sched_adjust_cost_state = NULL;
+   sched_mem_unit_code = 0;
+-  sched_ib_size = 0;
++
++  free (sched_ib.records.adjust);
++  sched_ib.records.adjust = NULL;
++  sched_ib.records.n_insns = 0;
++  max_insn_size = 0;
+   free (sched_branch_type);
+   sched_branch_type = NULL;
+@@ -5412,9 +6105,34 @@ m68k_sched_md_init (FILE *sched_dump ATT
+                   int sched_verbose ATTRIBUTE_UNUSED,
+                   int n_insns ATTRIBUTE_UNUSED)
+ {
+-  /* haifa-sched.c: schedule_block () calls advance_cycle () just before
+-     the first cycle.  Workaround that.  */
+-  sched_ib_filled = -2;
++  switch (m68k_sched_cpu)
++    {
++    case CPU_CFV1:
++    case CPU_CFV2:
++      sched_ib.size = 6;
++      break;
++
++    case CPU_CFV3:
++      sched_ib.size = sched_ib.records.n_insns * max_insn_size;
++
++      memset (sched_ib.records.adjust, 0,
++            sched_ib.records.n_insns * sizeof (*sched_ib.records.adjust));
++      sched_ib.records.adjust_index = 0;
++      break;
++
++    case CPU_CFV4:
++      gcc_assert (!sched_ib.enabled_p);
++      sched_ib.size = 0;
++      break;
++
++    default:
++      gcc_unreachable ();
++    }
++
++  if (sched_ib.enabled_p)
++    /* haifa-sched.c: schedule_block () calls advance_cycle () just before
++       the first cycle.  Workaround that.  */
++    sched_ib.filled = -2;
+ }
+ /* Implementation of targetm.sched.dfa_pre_advance_cycle () hook.
+@@ -5423,12 +6141,15 @@ m68k_sched_md_init (FILE *sched_dump ATT
+ static void
+ m68k_sched_dfa_pre_advance_cycle (void)
+ {
++  if (!sched_ib.enabled_p)
++    return;
++
+   if (!cpu_unit_reservation_p (curr_state, sched_mem_unit_code))
+     {
+-      sched_ib_filled += 2;
++      sched_ib.filled += 2;
+-      if (sched_ib_filled > sched_ib_size)
+-      sched_ib_filled = sched_ib_size;
++      if (sched_ib.filled > sched_ib.size)
++      sched_ib.filled = sched_ib.size;
+     }
+ }
+@@ -5441,13 +6162,180 @@ static void
+ m68k_sched_dfa_post_advance_cycle (void)
+ {
+   int i;
+-  int n;
++
++  if (!sched_ib.enabled_p)
++    return;
+   /* Setup number of prefetched instruction words in the instruction
+      buffer.  */
+-  for (i = sched_ib_filled, n = sched_ib_size; i < n; ++i)
++  i = max_insn_size - sched_ib.filled;
++
++  while (--i >= 0)
+     {
+-      if (state_transition (curr_state, sched_ib_insn) >= 0)
++      if (state_transition (curr_state, sched_ib.insn) >= 0)
+       gcc_unreachable ();
+     }
+ }
++
++/* Return X or Y (depending on OPX_P) operand of INSN,
++   if it is an integer register, or NULL overwise.  */
++static rtx
++sched_get_reg_operand (rtx insn, bool opx_p)
++{
++  rtx op = NULL;
++
++  if (opx_p)
++    {
++      if (get_attr_opx_type (insn) == OPX_TYPE_RN)
++      {
++        op = sched_get_operand (insn, true);
++        gcc_assert (op != NULL);
++
++        if (!reload_completed && !REG_P (op))
++          return NULL;
++      }
++    }
++  else
++    {
++      if (get_attr_opy_type (insn) == OPY_TYPE_RN)
++      {
++        op = sched_get_operand (insn, false);
++        gcc_assert (op != NULL);
++
++        if (!reload_completed && !REG_P (op))
++          return NULL;
++      }
++    }
++
++  return op;
++}
++
++/* Return true, if X or Y (depending on OPX_P) operand of INSN
++   is a MEM.  */
++static bool
++sched_mem_operand_p (rtx insn, bool opx_p)
++{
++  switch (sched_get_opxy_mem_type (insn, opx_p))
++    {
++    case OP_TYPE_MEM1:
++    case OP_TYPE_MEM6:
++      return true;
++
++    default:
++      return false;
++    }
++}
++
++/* Return X or Y (depending on OPX_P) operand of INSN,
++   if it is a MEM, or NULL overwise.  */
++static rtx
++sched_get_mem_operand (rtx insn, bool must_read_p, bool must_write_p)
++{
++  bool opx_p;
++  bool opy_p;
++
++  opx_p = false;
++  opy_p = false;
++
++  if (must_read_p)
++    {
++      opx_p = true;
++      opy_p = true;
++    }
++
++  if (must_write_p)
++    {
++      opx_p = true;
++      opy_p = false;
++    }
++
++  if (opy_p && sched_mem_operand_p (insn, false))
++    return sched_get_operand (insn, false);
++
++  if (opx_p && sched_mem_operand_p (insn, true))
++    return sched_get_operand (insn, true);
++
++  gcc_unreachable ();
++  return NULL;
++}
++
++/* Return non-zero if PRO modifies register used as part of
++   address in CON.  */
++int
++m68k_sched_address_bypass_p (rtx pro, rtx con)
++{
++  rtx pro_x;
++  rtx con_mem_read;
++
++  pro_x = sched_get_reg_operand (pro, true);
++  if (pro_x == NULL)
++    return 0;
++
++  con_mem_read = sched_get_mem_operand (con, true, false);
++  gcc_assert (con_mem_read != NULL);
++
++  if (reg_mentioned_p (pro_x, con_mem_read))
++    return 1;
++
++  return 0;
++}
++
++/* Helper function for m68k_sched_indexed_address_bypass_p.
++   if PRO modifies register used as index in CON,
++   return scale of indexed memory access in CON.  Return zero overwise.  */
++static int
++sched_get_indexed_address_scale (rtx pro, rtx con)
++{
++  rtx reg;
++  rtx mem;
++  struct m68k_address address;
++
++  reg = sched_get_reg_operand (pro, true);
++  if (reg == NULL)
++    return 0;
++
++  mem = sched_get_mem_operand (con, true, false);
++  gcc_assert (mem != NULL && MEM_P (mem));
++
++  if (!m68k_decompose_address (GET_MODE (mem), XEXP (mem, 0), reload_completed,
++                             &address))
++    gcc_unreachable ();
++
++  if (REGNO (reg) == REGNO (address.index))
++    {
++      gcc_assert (address.scale != 0);
++      return address.scale;
++    }
++
++  return 0;
++}
++
++/* Return non-zero if PRO modifies register used
++   as index with scale 2 or 4 in CON.  */
++int
++m68k_sched_indexed_address_bypass_p (rtx pro, rtx con)
++{
++  gcc_assert (sched_cfv4_bypass_data.pro == NULL
++            && sched_cfv4_bypass_data.con == NULL
++            && sched_cfv4_bypass_data.scale == 0);
++
++  switch (sched_get_indexed_address_scale (pro, con))
++    {
++    case 1:
++      /* We can't have a variable latency bypass, so
++       remember to adjust the insn cost in adjust_cost hook.  */
++      sched_cfv4_bypass_data.pro = pro;
++      sched_cfv4_bypass_data.con = con;
++      sched_cfv4_bypass_data.scale = 1;
++      return 0;
++
++    case 2:
++    case 4:
++      return 1;
++
++    default:
++      return 0;
++    }
++}
++
++#include "gt-m68k.h"
+--- a/gcc/config/m68k/m68k.h
++++ b/gcc/config/m68k/m68k.h
+@@ -232,6 +232,7 @@ along with GCC; see the file COPYING3.  
+ #define FL_ISA_C     (1 << 16)
+ #define FL_FIDOA     (1 << 17)
+ #define FL_MMU             0   /* Used by multilib machinery.  */
++#define FL_UCLINUX   0   /* Used by multilib machinery.  */
+ #define TARGET_68010          ((m68k_cpu_flags & FL_ISA_68010) != 0)
+ #define TARGET_68020          ((m68k_cpu_flags & FL_ISA_68020) != 0)
+@@ -266,6 +267,11 @@ along with GCC; see the file COPYING3.  
+ #define TUNE_CPU32    (m68k_tune == ucpu32)
+ #define TUNE_CFV1       (m68k_tune == ucfv1)
+ #define TUNE_CFV2     (m68k_tune == ucfv2)
++#define TUNE_CFV3       (m68k_tune == ucfv3)
++#define TUNE_CFV4       (m68k_tune == ucfv4 || m68k_tune == ucfv4e)
++
++#define TUNE_MAC      ((m68k_tune_flags & FL_CF_MAC) != 0)
++#define TUNE_EMAC     ((m68k_tune_flags & FL_CF_EMAC) != 0)
+ #define OVERRIDE_OPTIONS   override_options()
+@@ -496,7 +502,8 @@ enum reg_class {
+ extern enum reg_class regno_reg_class[];
+ #define REGNO_REG_CLASS(REGNO) (regno_reg_class[(REGNO)])
+-#define INDEX_REG_CLASS GENERAL_REGS
++#define MODE_INDEX_REG_CLASS(MODE) \
++  (MODE_OK_FOR_INDEX_P (MODE) ? GENERAL_REGS : NO_REGS)
+ #define BASE_REG_CLASS ADDR_REGS
+ #define PREFERRED_RELOAD_CLASS(X,CLASS) \
+@@ -665,6 +672,10 @@ __transfer_from_trampoline ()                                     \
+ #define HAVE_POST_INCREMENT 1
+ #define HAVE_PRE_DECREMENT 1
++/* Return true if addresses of mode MODE can have an index register.  */
++#define MODE_OK_FOR_INDEX_P(MODE) \
++  (!TARGET_COLDFIRE_FPU || GET_MODE_CLASS (MODE) != MODE_FLOAT)
++
+ /* Macros to check register numbers against specific register classes.  */
+ /* True for data registers, D0 through D7.  */
+@@ -679,9 +690,10 @@ __transfer_from_trampoline ()                                     \
+ /* True for floating point registers, FP0 through FP7.  */
+ #define FP_REGNO_P(REGNO)     IN_RANGE (REGNO, 16, 23)
+-#define REGNO_OK_FOR_INDEX_P(REGNO)                   \
+-  (INT_REGNO_P (REGNO)                                        \
+-   || INT_REGNO_P (reg_renumber[REGNO]))
++#define REGNO_MODE_OK_FOR_INDEX_P(REGNO, MODE)                \
++  (MODE_OK_FOR_INDEX_P (MODE)                         \
++   && (INT_REGNO_P (REGNO)                            \
++       || INT_REGNO_P (reg_renumber[REGNO])))
+ #define REGNO_OK_FOR_BASE_P(REGNO)                    \
+   (ADDRESS_REGNO_P (REGNO)                            \
+@@ -741,13 +753,14 @@ __transfer_from_trampoline ()                                    \
+ #define LEGITIMATE_PIC_OPERAND_P(X)                           \
+   (!symbolic_operand (X, VOIDmode)                            \
+-   || (TARGET_PCREL && REG_STRICT_P))
++   || (TARGET_PCREL && REG_STRICT_P)                          \
++   || m68k_tls_mentioned_p (X))
+ #define REG_OK_FOR_BASE_P(X) \
+   m68k_legitimate_base_reg_p (X, REG_STRICT_P)
+-#define REG_OK_FOR_INDEX_P(X) \
+-  m68k_legitimate_index_reg_p (X, REG_STRICT_P)
++#define REG_MODE_OK_FOR_INDEX_P(X, MODE)      \
++  m68k_legitimate_index_reg_p (MODE, X, REG_STRICT_P)
+ #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                               \
+   do                                                                  \
+@@ -760,52 +773,19 @@ __transfer_from_trampoline ()                                    \
+ /* This address is OK as it stands.  */
+ #define PIC_CASE_VECTOR_ADDRESS(index) index
\f
+-/* For the 68000, we handle X+REG by loading X into a register R and
+-   using R+REG.  R will go in an address reg and indexing will be used.
+-   However, if REG is a broken-out memory address or multiplication,
+-   nothing needs to be done because REG can certainly go in an address reg.  */
+-#define COPY_ONCE(Y) if (!copied) { Y = copy_rtx (Y); copied = ch = 1; }
+-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)   \
+-{ register int ch = (X) != (OLDX);                                    \
+-  if (GET_CODE (X) == PLUS)                                           \
+-    { int copied = 0;                                                 \
+-      if (GET_CODE (XEXP (X, 0)) == MULT)                             \
+-      { COPY_ONCE (X); XEXP (X, 0) = force_operand (XEXP (X, 0), 0);} \
+-      if (GET_CODE (XEXP (X, 1)) == MULT)                             \
+-      { COPY_ONCE (X); XEXP (X, 1) = force_operand (XEXP (X, 1), 0);} \
+-      if (ch && GET_CODE (XEXP (X, 1)) == REG                         \
+-        && GET_CODE (XEXP (X, 0)) == REG)                             \
+-      { if (TARGET_COLDFIRE_FPU                                       \
+-            && GET_MODE_CLASS (MODE) == MODE_FLOAT)                   \
+-          { COPY_ONCE (X); X = force_operand (X, 0);}                 \
+-        goto WIN; }                                                   \
+-      if (ch) { GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN); }            \
+-      if (GET_CODE (XEXP (X, 0)) == REG                                       \
+-             || (GET_CODE (XEXP (X, 0)) == SIGN_EXTEND                \
+-                 && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG           \
+-                 && GET_MODE (XEXP (XEXP (X, 0), 0)) == HImode))      \
+-      { register rtx temp = gen_reg_rtx (Pmode);                      \
+-        register rtx val = force_operand (XEXP (X, 1), 0);            \
+-        emit_move_insn (temp, val);                                   \
+-        COPY_ONCE (X);                                                \
+-        XEXP (X, 1) = temp;                                           \
+-        if (TARGET_COLDFIRE_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT \
+-            && GET_CODE (XEXP (X, 0)) == REG)                         \
+-          X = force_operand (X, 0);                                   \
+-        goto WIN; }                                                   \
+-      else if (GET_CODE (XEXP (X, 1)) == REG                          \
+-             || (GET_CODE (XEXP (X, 1)) == SIGN_EXTEND                \
+-                 && GET_CODE (XEXP (XEXP (X, 1), 0)) == REG           \
+-                 && GET_MODE (XEXP (XEXP (X, 1), 0)) == HImode))      \
+-      { register rtx temp = gen_reg_rtx (Pmode);                      \
+-        register rtx val = force_operand (XEXP (X, 0), 0);            \
+-        emit_move_insn (temp, val);                                   \
+-        COPY_ONCE (X);                                                \
+-        XEXP (X, 0) = temp;                                           \
+-        if (TARGET_COLDFIRE_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT \
+-            && GET_CODE (XEXP (X, 1)) == REG)                         \
+-          X = force_operand (X, 0);                                   \
+-        goto WIN; }}}
++#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)                \
++do {                                                  \
++  rtx __x;                                            \
++                                                      \
++  __x = m68k_legitimize_address (X, OLDX, MODE);      \
++  if (__x != NULL_RTX)                                        \
++    {                                                 \
++      X = __x;                                                \
++                                                      \
++      if (memory_address_p (MODE, X))                 \
++      goto WIN;                                       \
++    }                                                 \
++} while (0)
+ /* On the 68000, only predecrement and postincrement address depend thus
+    (the amount of decrement or increment being the length of the operand).
+@@ -845,6 +825,14 @@ __transfer_from_trampoline ()                                     \
+    some or all of the saved cc's so they won't be used.  */
+ #define NOTICE_UPDATE_CC(EXP,INSN) notice_update_cc (EXP, INSN)
++/* The shift instructions always clear the overflow bit.  */
++#define CC_OVERFLOW_UNUSABLE 01000
++
++/* The shift instructions use the carry bit in a way not compatible with
++   conditional branches.  conditions.h uses CC_NO_OVERFLOW for this purpose.
++   Rename it to something more understandable.  */
++#define CC_NO_CARRY CC_NO_OVERFLOW
++
+ #define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV)  \
+ do { if (cc_prev_status.flags & CC_IN_68881)                  \
+     return FLOAT;                                             \
+@@ -1077,6 +1065,12 @@ do { if (cc_prev_status.flags & CC_IN_68
+ #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
++#define OUTPUT_ADDR_CONST_EXTRA(FILE, X, FAIL)                \
++do {                                                  \
++  if (! m68k_output_addr_const_extra (FILE, (X)))     \
++    goto FAIL;                                                \
++} while (0);
++
+ /* Values used in the MICROARCH argument to M68K_DEVICE.  */
+ enum uarch_type
+ {
+@@ -1129,6 +1123,7 @@ extern enum target_device m68k_cpu;
+ extern enum uarch_type m68k_tune;
+ extern enum fpu_type m68k_fpu;
+ extern unsigned int m68k_cpu_flags;
++extern unsigned int m68k_tune_flags;
+ extern const char *m68k_symbolic_call;
+ extern const char *m68k_symbolic_jump;
+@@ -1148,4 +1143,7 @@ extern M68K_CONST_METHOD m68k_const_meth
+ extern void m68k_emit_move_double (rtx [2]);
++extern int m68k_sched_address_bypass_p (rtx, rtx);
++extern int m68k_sched_indexed_address_bypass_p (rtx, rtx);
++
+ #define CPU_UNITS_QUERY 1
+--- a/gcc/config/m68k/m68k.md
++++ b/gcc/config/m68k/m68k.md
+@@ -115,6 +115,9 @@
+    (UNSPEC_COS 2)
+    (UNSPEC_GOT 3)
+    (UNSPEC_IB 4)
++   (UNSPEC_TIE 5)
++   (UNSPEC_RELOC16 6)
++   (UNSPEC_RELOC32 7)
+   ])
+ ;; UNSPEC_VOLATILE usage:
+@@ -144,197 +147,104 @@
+ ;; ::::::::::::::::::::
+ ;; Processor type.
+-(define_attr "cpu" "cf_v2, unknown" (const (symbol_ref "m68k_sched_cpu")))
++(define_attr "cpu" "cfv1, cfv2, cfv3, cfv4, unknown"
++  (const (symbol_ref "m68k_sched_cpu")))
+-;; Instruction type.
+-;; Basically, an asm pattern.
+-(define_attr "type"
+-  "add_l, addq_l, asr_l, bcc, bclr, bra, bset, bsr,
+-   clr_b, clr_w, clr_l, cmp_l,
+-   ext_w, extb_l, ext_l,
+-   fadd, fcmp, fdiv, ff1, fintrz, fmove, fmul, fsqrt, fsub, ftst, jmp, jsr,
+-   ib,
+-   lea, lsr_l,
+-   move_b, move_w, move_l, moveq_l, mov3q_l, mvs_b, mvs_w, mvz_b, mvz_w,
+-   muls_w, muls_l, mulu_w, mulu_l,
+-   neg_l, nop, not_l,
+-   pea, rts,
+-   scc, sub_l, subq_l,
+-   trap, tst_b, tst_l, tst_w,
+-   unlk, unknown"
+-  (const_string "unknown"))
++;; MAC type.
++(define_attr "mac" "no, cf_mac, cf_emac"
++  (const (symbol_ref "m68k_sched_mac")))
+ ;; Instruction type for use in scheduling description.
+ ;; _l and _w suffixes indicate size of the operands of instruction.
+ ;; alu - usual arithmetic or logic instruction.
+-;; alu_reg1 - arithmetic or logic instruction with one operand that is
+-;;            a register.
+-;; alu_regx - arithmetic or logic instruction which has a register for its
+-;;            X operand.
+ ;; aluq - arithmetic or logic instruction which has a quick immediate (the one
+ ;;        that is encoded in the instruction word) for its Y operand.
+-;; <all other values> - corresponding asm instructions.
+-(define_attr "type1"
+-  "alu_l, alu_reg1, alu_regx, aluq_l, bcc, bra, bsr, clr, cmp_l, jmp, jsr, lea,
+-   mov3q_l, move, move_l, moveq_l, mul_l, mul_w, pea, rts, tst, tst_l, unlk,
++;; alux - Arithmetic instruction that uses carry bit (e.g., addx and subx).
++;; bcc - conditional branch.
++;; bitr - bit operation that only updates flags.
++;; bitrw - bit operation that updates flags and output operand.
++;; bra, bsr, clr, cmp, div, ext - corresponding instruction.
++;; falu, fbcc, fcmp, fdiv, fmove, fmul, fneg, fsqrt, ftst - corresponding
++;;                                                          instruction.
++;; ib - fake instruction to subscribe slots in ColdFire V1,V2,V3 instruction
++;;      buffer.
++;; ignore - fake instruction.
++;; jmp, jsr, lea, link, mov3q, move, moveq, mul - corresponding instruction.
++;; mvsz - mvs or mvz instruction.
++;; neg, nop, pea, rts, scc - corresponding instruction.
++;; shift - arithmetic or logical shift instruction.
++;; trap, tst, unlk - corresponding instruction.
++(define_attr "type"
++  "alu_l,aluq_l,alux_l,bcc,bitr,bitrw,bra,bsr,clr,clr_l,cmp,cmp_l,
++   div_w,div_l,ext,
++   falu,fbcc,fcmp,fdiv,fmove,fmul,fneg,fsqrt,ftst,
++   ib,ignore,
++   jmp,jsr,lea,link,mov3q_l,move,move_l,moveq_l,mul_w,mul_l,mvsz,neg_l,nop,
++   pea,rts,scc,shift,
++   trap,tst,tst_l,unlk,
+    unknown"
+-  (cond [(eq_attr "type" "add_l,sub_l") (const_string "alu_l")
+-       (eq_attr "type" "ext_w,extb_l,ext_l,neg_l,not_l")
+-       (const_string "alu_reg1")
+-       (eq_attr "type" "asr_l,lsr_l") (const_string "alu_regx")
+-       (eq_attr "type" "addq_l,subq_l") (const_string "aluq_l")
+-       (eq_attr "type" "bcc") (const_string "bcc")
+-       (eq_attr "type" "bra") (const_string "bra")
+-       (eq_attr "type" "bsr") (const_string "bsr")
+-       (eq_attr "type" "clr_b,clr_l,clr_w") (const_string "clr")
+-       (eq_attr "type" "cmp_l") (const_string "cmp_l")
+-       (eq_attr "type" "jmp") (const_string "jmp")
+-       (eq_attr "type" "jsr") (const_string "jsr")
+-       (eq_attr "type" "lea") (const_string "lea")
+-       (eq_attr "type" "mov3q_l") (const_string "mov3q_l")
+-       (eq_attr "type" "move_b,move_w") (const_string "move")
+-       (eq_attr "type" "move_l") (const_string "move_l")
+-       (eq_attr "type" "moveq_l") (const_string "moveq_l")
+-       (eq_attr "type" "muls_l,mulu_l") (const_string "mul_l")
+-       (eq_attr "type" "muls_w,mulu_w") (const_string "mul_w")
+-       (eq_attr "type" "pea") (const_string "pea")
+-       (eq_attr "type" "rts") (const_string "rts")
+-       (eq_attr "type" "tst_b,tst_w") (const_string "tst")
+-       (eq_attr "type" "tst_l") (const_string "tst_l")
+-       (eq_attr "type" "unlk") (const_string "unlk")]
+-      (const_string "unknown")))
++  (const_string "unknown"))
+ ;; Index of the X or Y operand in recog_data.operand[].
+ ;; Should be used only within opx_type and opy_type.
+ (define_attr "opx" "" (const_int 0))
+ (define_attr "opy" "" (const_int 1))
+-;; Type of the X operand.
+-;; See m68k.c: enum attr_op_type.
+-(define_attr "opx_type"
+-  "none, reg, mem1, mem234, mem5, mem6, mem7, imm_q, imm_w, imm_l"
+-  (cond [(eq_attr "type1" "rts,unlk") (const_string "none")
+-       (eq_attr "type1" "alu_reg1,alu_regx,lea,moveq_l,mul_l,mul_w")
+-       (const_string "reg")
+-       (eq_attr "type1" "pea") (const_string "mem1")
+-       (eq_attr "type1" "bcc") (const_string "imm_q")
+-       (eq_attr "type1" "bra,bsr") (const_string "imm_w")
+-       (eq_attr "type1" "jmp,jsr")
+-       (symbol_ref "m68k_sched_attr_opx_type (insn, 1)")]
+-      (symbol_ref "m68k_sched_attr_opx_type (insn, 0)")))
+-
+ ;; Type of the Y operand.
+ ;; See m68k.c: enum attr_op_type.
+ (define_attr "opy_type"
+-  "none, reg, mem1, mem234, mem5, mem6, mem7, imm_q, imm_w, imm_l"
+-  (cond [(eq_attr "type1" "alu_reg1,bcc,bra,bsr,clr,jmp,jsr,rts,tst,tst_l,
+-                           unlk") (const_string "none")
+-       (eq_attr "type1" "mov3q_l,moveq_l,aluq_l") (const_string "imm_q")
+-       (eq_attr "type1" "lea,pea")
++  "none,Rn,FPn,mem1,mem234,mem5,mem6,mem7,imm_q,imm_w,imm_l"
++  (cond [(eq_attr "type" "ext,fbcc,ftst,neg_l,bcc,bra,bsr,clr,clr_l,ib,ignore,
++                          jmp,jsr,nop,rts,scc,trap,tst,tst_l,
++                          unlk,unknown") (const_string "none")
++       (eq_attr "type" "lea,pea")
+        (symbol_ref "m68k_sched_attr_opy_type (insn, 1)")]
+       (symbol_ref "m68k_sched_attr_opy_type (insn, 0)")))
+-;; Instruction size in words.
+-(define_attr "size" ""
+-  (cond [(eq_attr "type1" "alu_reg1,moveq_l,rts,unlk") (const_int 1)]
+-      (symbol_ref "m68k_sched_attr_size (insn)")))
++;; Type of the X operand.
++;; See m68k.c: enum attr_op_type.
++(define_attr "opx_type"
++  "none,Rn,FPn,mem1,mem234,mem5,mem6,mem7,imm_q,imm_w,imm_l"
++  (cond [(eq_attr "type" "ib,ignore,nop,rts,trap,unlk,
++                          unknown") (const_string "none")
++       (eq_attr "type" "pea") (const_string "mem1")
++       (eq_attr "type" "jmp,jsr")
++       (symbol_ref "m68k_sched_attr_opx_type (insn, 1)")]
++      (symbol_ref "m68k_sched_attr_opx_type (insn, 0)")))
+ ;; Access to the X operand: none, read, write, read/write, unknown.
+ ;; Access to the Y operand is either none (if opy_type is none)
+ ;; or read otherwise.
+-(define_attr "opx_access" "none, r, w, rw, unknown"
+-  (cond [(eq_attr "type1" "rts,unlk") (const_string "none")
+-       (eq_attr "type1" "bcc,bra,bsr,cmp_l,jmp,jsr,tst,tst_l")
+-       (const_string "r")
+-       (eq_attr "type1" "clr,lea,mov3q_l,move,move_l,moveq_l,pea")
+-       (const_string "w")
+-       (eq_attr "type1" "alu_l,alu_reg1,alu_regx,aluq_l")
+-       (const_string "rw")]
+-      (const_string "unknown")))
+-
+-;; Memory relation of operands:
+-;; r - register or immediate operand
+-;; m - non-indexed memory location
+-;; i - indexed memory location
+-
+-(define_attr "opx_mem" "r, m, i, unknown"
+-  (cond [(eq_attr "opx_type" "none,reg,imm_q,imm_w,imm_l") (const_string "r")
+-       (eq_attr "opx_type" "mem1,mem234,mem5,mem7") (const_string "m")
+-       (eq_attr "opx_type" "mem6") (const_string "i")]
+-      (const_string "unknown")))
+-
+-(define_attr "opy_mem" "r, m, i, unknown"
+-  (cond [(eq_attr "opy_type" "none,reg,imm_q,imm_w,imm_l") (const_string "r")
+-       (eq_attr "opy_type" "mem1,mem234,mem5,mem7") (const_string "m")
+-       (eq_attr "opy_type" "mem6") (const_string "i")]
+-      (const_string "unknown")))
++(define_attr "opx_access" "none, r, w, rw"
++  (cond [(eq_attr "type" "ib,ignore,nop,rts,trap,unlk,
++                          unknown") (const_string "none")
++       (eq_attr "type" "bcc,bra,bsr,bitr,cmp,cmp_l,fbcc,fcmp,ftst,
++                          jmp,jsr,tst,tst_l") (const_string "r")
++       (eq_attr "type" "clr,clr_l,fneg,fmove,lea,
++                          mov3q_l,move,move_l,moveq_l,mvsz,
++                          pea,scc") (const_string "w")
++       (eq_attr "type" "alu_l,aluq_l,alux_l,bitrw,div_w,div_l,ext,
++                          falu,fdiv,fmul,fsqrt,link,mul_w,mul_l,
++                          neg_l,shift") (const_string "rw")]
++      ;; Should never be used.
++      (symbol_ref "(gcc_unreachable (), OPX_ACCESS_NONE)")))
+ ;; Memory accesses of the insn.
+ ;; 00 - no memory references
+ ;; 10 - memory is read
+-;; i10 - indexed memory is read
++;; i0 - indexed memory is read
+ ;; 01 - memory is written
+-;; 0i1 - indexed memory is written
++;; 0i - indexed memory is written
+ ;; 11 - memory is read, memory is written
+-;; i11 - indexed memory is read, memory is written
+-;; 1i1 - memory is read, indexed memory is written
+-;;
+-;; unknown - should now occur on normal insn.
+-;; ??? This attribute is implemented in C to spare genattrtab from
+-;; ??? optimizing it.
+-(define_attr "op_mem" "00, 10, i0, 01, 0i, 11, i1, 1i, unknown"
+-;  (cond [(and (eq_attr "opy_mem" "r") (eq_attr "opx_mem" "r"))
+-;      (const_string "00")
+-;
+-;      (and (eq_attr "opy_mem" "r") (eq_attr "opx_mem" "m"))
+-;      (cond [(eq_attr "opx_access" "r") (const_string "10")
+-;             (eq_attr "opx_access" "w") (const_string "01")
+-;             (eq_attr "opx_access" "rw") (const_string "11")]
+-;            (const_string "unknown"))
+-;
+-;      (and (eq_attr "opy_mem" "r") (eq_attr "opx_mem" "i"))
+-;      (cond [(eq_attr "opx_access" "r") (const_string "i0")
+-;             (eq_attr "opx_access" "w") (const_string "0i")
+-;             (eq_attr "opx_access" "rw") (const_string "i1")]
+-;            (const_string "unknown"))
+-;
+-;      (and (eq_attr "opy_mem" "m") (eq_attr "opx_mem" "r"))
+-;      (const_string "10")
+-;
+-;      (and (eq_attr "opy_mem" "m") (eq_attr "opx_mem" "m"))
+-;      (cond [(eq_attr "opx_access" "w") (const_string "11")]
+-;            (const_string "unknown"))
+-;
+-;      (and (eq_attr "opy_mem" "m") (eq_attr "opx_mem" "i"))
+-;      (cond [(eq_attr "opx_access" "w") (const_string "1i")]
+-;            (const_string "unknown"))
+-;
+-;      (and (eq_attr "opy_mem" "i") (eq_attr "opx_mem" "r"))
+-;      (const_string "i0")
+-;
+-;      (and (eq_attr "opy_mem" "i") (eq_attr "opx_mem" "m"))
+-;      (cond [(eq_attr "opx_access" "w") (const_string "i1")]
+-;            (const_string "unknown"))]
+-;     (const_string "unknown"))
++;; i1 - indexed memory is read, memory is written
++;; 1i - memory is read, indexed memory is written
++(define_attr "op_mem" "00, 10, i0, 01, 0i, 11, i1, 1i"
+   (symbol_ref "m68k_sched_attr_op_mem (insn)"))
+-;; Attribute to support partial automata description.
+-;; This attribute has value 'yes' for instructions that are not
+-;; fully handled yet.
+-(define_attr "guess" "yes, no"
+-  (cond [(ior (eq (symbol_ref "reload_completed") (const_int 0))
+-            (eq_attr "type1" "unknown"))
+-       (const_string "yes")]
+-      (const_string "no")))
+-
+-;; Attribute to support statistics gathering.
+-;; Todo means that insn lacks something to get pipeline description.
+-;; Done means that insn was transformed to suit pipeline description.
+-;; Nothing means that insn was originally good enough for scheduling. 
+-(define_attr "split" "todo, done, nothing"
+-  (if_then_else (eq_attr "type" "unknown")
+-              (const_string "todo")
+-              (const_string "nothing")))
++;; Instruction size in words.
++(define_attr "size" "1,2,3"
++  (symbol_ref "m68k_sched_attr_size (insn)"))
++
\f
+ ;; Mode macros for floating point operations.
+ ;; Valid floating point modes
+@@ -364,8 +274,7 @@
+   m68k_emit_move_double (operands);
+   DONE;
+ }
+-  [(set_attr "type" "fmove,*")
+-   (set_attr "split" "done,*")])
++  [(set_attr "type" "fmove,*")])
+ (define_insn_and_split "pushdi"
+   [(set (match_operand:DI 0 "push_operand" "=m")
+@@ -445,7 +354,7 @@
+   "@
+    tst%.l %0
+    cmp%.w #0,%0"
+-  [(set_attr "type" "tst_l,*")])
++  [(set_attr "type" "tst_l,cmp")])
+ ;; This can't use an address register, because comparisons
+ ;; with address registers as second operand always test the whole word.
+@@ -460,7 +369,7 @@
+       (match_operand:HI 0 "nonimmediate_operand" "dm"))]
+   ""
+   "tst%.w %0"
+-  [(set_attr "type" "tst_w")])
++  [(set_attr "type" "tst")])
+ (define_expand "tstqi"
+   [(set (cc0)
+@@ -473,7 +382,7 @@
+       (match_operand:QI 0 "nonimmediate_operand" "dm"))]
+   ""
+   "tst%.b %0"
+-  [(set_attr "type" "tst_b")])
++  [(set_attr "type" "tst")])
+ (define_expand "tst<mode>"
+   [(set (cc0)
+@@ -492,11 +401,12 @@
+   if (FP_REG_P (operands[0]))
+     return "ftst%.x %0";
+   return "ftst%.<FP:prec> %0";
+-})
++}
++  [(set_attr "type" "ftst")])
+ (define_insn "tst<mode>_cf"
+   [(set (cc0)
+-      (match_operand:FP 0 "general_operand" "f<FP:dreg><Q>U"))]
++      (match_operand:FP 0 "general_operand" "f<FP:dreg>m"))]
+   "TARGET_COLDFIRE_FPU"
+ {
+   cc_status.flags = CC_IN_68881;
+@@ -514,15 +424,15 @@
+     [(set (cc0)
+         (compare (match_operand:DI 0 "nonimmediate_operand" "")
+                  (match_operand:DI 1 "general_operand" "")))
+-     (clobber (match_dup 2))])]
++     (clobber (match_scratch:DI 2 ""))])]
+   ""
+-  "m68k_last_compare_had_fp_operands = 0; operands[2] = gen_reg_rtx (DImode);")
++  "m68k_last_compare_had_fp_operands = 0;")
+ (define_insn ""
+   [(set (cc0)
+       (compare (match_operand:DI 1 "nonimmediate_operand" "0,d")
+                (match_operand:DI 2 "general_operand" "d,0")))
+-   (clobber (match_operand:DI 0 "register_operand" "=d,d"))]
++   (clobber (match_scratch:DI 0 "=d,d"))]
+   ""
+ {
+   if (rtx_equal_p (operands[0], operands[1]))
+@@ -600,7 +510,7 @@
+   if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1]))
+       || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
+     {
+-      cc_status.flags |= CC_REVERSED;
++      cc_status.flags |= CC_REVERSED; /*|*/
+       return "cmp%.w %d0,%d1";
+     }
+   return "cmp%.w %d1,%d0";
+@@ -652,8 +562,8 @@
+ (define_insn "*cmp<mode>_cf"
+   [(set (cc0)
+-      (compare (match_operand:FP 0 "fp_src_operand" "f,f,<FP:dreg><Q>U")
+-               (match_operand:FP 1 "fp_src_operand" "f,<FP:dreg><Q>U,f")))]
++      (compare (match_operand:FP 0 "fp_src_operand" "f,f,<FP:dreg>m")
++               (match_operand:FP 1 "fp_src_operand" "f,<FP:dreg>m,f")))]
+   "TARGET_COLDFIRE_FPU
+    && (register_operand (operands[0], <MODE>mode)
+        || register_operand (operands[1], <MODE>mode))"
+@@ -792,8 +702,7 @@
+    clr%.l %0
+    mov3q%.l %1,%-
+    pea %a1"
+-  [(set_attr "type" "clr_l,mov3q_l,pea")
+-   (set_attr "split" "done")])
++  [(set_attr "type" "clr_l,mov3q_l,pea")])
+ ;This is never used.
+ ;(define_insn "swapsi"
+@@ -813,9 +722,8 @@
+    moveq #0,%0
+    sub%.l %0,%0
+    clr%.l %0"
+-  [(set_attr "type" "moveq_l,sub_l,clr_l")
+-   (set_attr "opy_type" "imm_q,reg,*")
+-   (set_attr "split" "done")])
++  [(set_attr "type" "moveq_l,alu_l,clr_l")
++   (set_attr "opy" "*,0,*")])
+ ;; Special case of fullword move when source is zero for 68040_60.
+ ;; On the '040, 'subl an,an' takes 2 clocks while lea takes only 1
+@@ -834,9 +742,7 @@
+       return "";
+     }
+ }
+-  [(set_attr "type" "lea,clr_l")
+-   (set_attr "opy_type" "imm_w,*")
+-   (set_attr "split" "done")])
++  [(set_attr "type" "lea,clr_l")])
+ ;; Special case of fullword move when source is zero.
+ (define_insn "*movsi_const0"
+@@ -846,9 +752,8 @@
+   "@
+    sub%.l %0,%0
+    clr%.l %0"
+-  [(set_attr "type" "sub_l,clr_l")
+-   (set_attr "opy_type" "reg,*")
+-   (set_attr "split" "done")])
++  [(set_attr "type" "alu_l,clr_l")
++   (set_attr "opy" "0,*")])
+ ;; General case of fullword move.
+ ;;
+@@ -866,7 +771,41 @@
+ {
+   rtx tmp, base, offset;
+-  if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
++  /* Recognize the case where operand[1] is a reference to thread-local
++     data and load its address to a register.  */
++  if (!TARGET_PCREL && m68k_tls_referenced_p (operands[1]))
++    {
++      rtx tmp = operands[1];
++      rtx addend = NULL;
++
++      if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
++        {
++          addend = XEXP (XEXP (tmp, 0), 1);
++          tmp = XEXP (XEXP (tmp, 0), 0);
++        }
++
++      gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
++      gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
++
++      tmp = m68k_legitimize_tls_address (tmp);
++
++      if (addend)
++        {
++        if (!REG_P (tmp))
++          {
++            rtx reg;
++
++            reg = gen_reg_rtx (Pmode);
++            emit_move_insn (reg, tmp);
++            tmp = reg;
++          }
++
++          tmp = gen_rtx_PLUS (SImode, tmp, addend);
++      }
++
++      operands[1] = tmp;
++    }
++  else if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
+     {
+       /* The source is an address which requires PIC relocation.
+          Call legitimize_pic_address with the source, mode, and a relocation
+@@ -973,11 +912,7 @@
+       return "";
+     }
+ }
+-  [(set_attr "type" "mov3q_l, moveq_l,*, mvz_w, mvs_w, move_l, move_w, pea, lea, move_l, move_l, move_l")
+-   (set (attr "split")
+-      (if_then_else (eq_attr "alternative" "2")
+-                    (const_string "*")
+-                    (const_string "done")))])
++  [(set_attr "type" "mov3q_l,moveq_l,*,mvsz,mvsz,move_l,move,pea,lea,move_l,move_l,move_l")])
+ ;; Special case of fullword move, where we need to get a non-GOT PIC
+ ;; reference into an address register.
+@@ -1066,8 +1001,7 @@
+    clr%.b %0
+    move%.b %1,%0
+    move%.b %1,%0"
+-  [(set_attr "type" "clr_b,clr_b,move_b,move_b")
+-   (set_attr "split" "done")])
++  [(set_attr "type" "clr,clr,move,move")])
+ (define_expand "pushqi1"
+   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -2)))
+@@ -1162,10 +1096,8 @@
+ ;; SFmode MEMs are restricted to modes 2-4 if TARGET_COLDFIRE_FPU.
+ ;; The move instructions can handle all combinations.
+ (define_insn "movsf_cf_hard"
+-  [(set (match_operand:SF 0 "nonimmediate_operand" "=r<Q>U, f,    f,mr,f,r<Q>,f
+-,m")
+-        (match_operand:SF 1 "general_operand"      " f,     r<Q>U,f,rm,F,F,   m
+-,f"))]
++  [(set (match_operand:SF 0 "nonimmediate_operand" "=rm,f, f,rm,f,r<Q>,f,m")
++        (match_operand:SF 1 "general_operand"      " f, rm,f,rm,F,F,   m,f"))]
+   "TARGET_COLDFIRE_FPU"
+ {
+   if (which_alternative == 4 || which_alternative == 5) {
+@@ -1307,8 +1239,8 @@
+ })
+ (define_insn "movdf_cf_hard"
+-  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,    <Q>U,r,f,r,r,m,f")
+-        (match_operand:DF 1 "general_operand"      " f<Q>U,f,   f,r,r,m,r,E"))]
++  [(set (match_operand:DF 0 "nonimmediate_operand" "=f, m,r,f,r,r,m,f")
++        (match_operand:DF 1 "general_operand"      " fm,f,f,r,r,m,r,E"))]
+   "TARGET_COLDFIRE_FPU"
+ {
+   rtx xoperands[3];
+@@ -1688,7 +1620,7 @@
+       (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))]
+   "ISA_HAS_MVS_MVZ"
+   "mvz%.w %1,%0"
+-  [(set_attr "type" "mvz_w")])
++  [(set_attr "type" "mvsz")])
+ (define_insn "zero_extendhisi2"
+   [(set (match_operand:SI 0 "register_operand" "=d")
+@@ -1713,7 +1645,7 @@
+       (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))]
+   "ISA_HAS_MVS_MVZ"
+   "mvz%.b %1,%0"
+-  [(set_attr "type" "mvz_b")])
++  [(set_attr "type" "mvsz")])
+ (define_insn "zero_extendqisi2"
+   [(set (match_operand:SI 0 "register_operand" "=d")
+@@ -1794,28 +1726,73 @@
+     return "move%.w %1,%2\;ext%.l %2\;smi %0\;ext%.w %0\;ext%.l %0";
+ })
+-(define_insn "extendsidi2"
+-  [(set (match_operand:DI 0 "register_operand" "=d")
+-      (sign_extend:DI (match_operand:SI 1 "nonimmediate_src_operand" "rm")))]
+-  ""
++(define_expand "extendsidi2"
++  [(parallel
++    [(set (match_operand:DI 0 "nonimmediate_operand")
++        (sign_extend:DI (match_operand:SI 1 "nonimmediate_src_operand")))
++     (clobber (match_scratch:SI 2 ""))
++     (clobber (match_scratch:SI 3 ""))])])
++
++(define_insn "*extendsidi2_m68k"
++  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,<,o")
++      (sign_extend:DI
++       (match_operand:SI 1 "nonimmediate_src_operand" "rm,rm,rm")))
++   (clobber (match_scratch:SI 2 "=X,d,d"))
++   (clobber (match_scratch:SI 3 "=X,X,X"))]
++  "!TARGET_COLDFIRE"
+ {
+   CC_STATUS_INIT;
++
++  if (which_alternative == 0)
++    /* Handle alternative 0.  */
++    {
++      if (TARGET_68020 || TARGET_COLDFIRE)
++        return "move%.l %1,%R0\;smi %0\;extb%.l %0";
++      else
++        return "move%.l %1,%R0\;smi %0\;ext%.w %0\;ext%.l %0";
++    }
++
++  /* Handle alternatives 1 and 2.  We don't need to adjust address by 4
++     in alternative 1 because autodecrement will do that for us.  */
++  operands[3] = adjust_address (operands[0], SImode,
++                              which_alternative == 1 ? 0 : 4);
++  operands[0] = adjust_address (operands[0], SImode, 0);
++
+   if (TARGET_68020 || TARGET_COLDFIRE)
+-    return "move%.l %1,%R0\;smi %0\;extb%.l %0";
++    return "move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0";
+   else
+-    return "move%.l %1,%R0\;smi %0\;ext%.w %0\;ext%.l %0";
++    return "move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0";
+ })
+-(define_insn "*extendsidi2_mem"
+-  [(set (match_operand:DI 0 "memory_operand" "=o,<")
+-      (sign_extend:DI (match_operand:SI 1 "nonimmediate_src_operand" "rm,rm")))
+-   (clobber (match_scratch:SI 2 "=d,d"))]
+-   ""
++;; This is a copy of extendsidi2_m68k except for that we can't
++;; fully handle the last alternative on ColdFire.
++;; FIXME: when 'enabled' attribute is available (in GCC 4.4) merge the
++;; two define_insns.
++(define_insn "*extendsidi2_cf"
++  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,<,o")
++      (sign_extend:DI
++       (match_operand:SI 1 "nonimmediate_src_operand" "rm,rm,r<Q>")))
++   (clobber (match_scratch:SI 2 "=X,d,d"))
++   (clobber (match_scratch:SI 3 "=X,X,X"))]
++   "TARGET_COLDFIRE"
+ {
+   CC_STATUS_INIT;
++
++  if (which_alternative == 0)
++    /* Handle alternative 0.  */
++    {
++      if (TARGET_68020 || TARGET_COLDFIRE)
++        return "move%.l %1,%R0\;smi %0\;extb%.l %0";
++      else
++        return "move%.l %1,%R0\;smi %0\;ext%.w %0\;ext%.l %0";
++    }
++
++  /* Handle alternatives 1 and 2.  We don't need to adjust address by 4
++     in alternative 1 because autodecrement will do that for us.  */
+   operands[3] = adjust_address (operands[0], SImode,
+-                              which_alternative == 0 ? 4 : 0);
++                              which_alternative == 1 ? 0 : 4);
+   operands[0] = adjust_address (operands[0], SImode, 0);
++
+   if (TARGET_68020 || TARGET_COLDFIRE)
+     return "move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0";
+   else
+@@ -1866,7 +1843,7 @@
+        (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))]
+   "ISA_HAS_MVS_MVZ"
+   "mvs%.w %1,%0"
+-  [(set_attr "type" "mvs_w")])
++  [(set_attr "type" "mvsz")])
+ (define_insn "*68k_extendhisi2"
+   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,a")
+@@ -1876,14 +1853,14 @@
+   "@
+    ext%.l %0
+    move%.w %1,%0"
+-  [(set_attr "type" "ext_l,move_w")])
++  [(set_attr "type" "ext,move")])
+ (define_insn "extendqihi2"
+   [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
+       (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))]
+   ""
+   "ext%.w %0"
+-  [(set_attr "type" "ext_w")])
++  [(set_attr "type" "ext")])
+ (define_expand "extendqisi2"
+   [(set (match_operand:SI 0 "nonimmediate_operand" "")
+@@ -1896,14 +1873,14 @@
+       (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rms")))]
+   "ISA_HAS_MVS_MVZ"
+   "mvs%.b %1,%0"
+-  [(set_attr "type" "mvs_b")])
++  [(set_attr "type" "mvsz")])
+ (define_insn "*68k_extendqisi2"
+   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
+       (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))]
+   "TARGET_68020 || (TARGET_COLDFIRE && !ISA_HAS_MVS_MVZ)"
+   "extb%.l %0"
+-  [(set_attr "type" "extb_l")])
++  [(set_attr "type" "ext")])
\f
+ ;; Conversions between float and double.
+@@ -1946,7 +1923,7 @@
+ (define_insn "extendsfdf2_cf"
+   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f")
+       (float_extend:DF
+-       (match_operand:SF 1 "general_operand" "f,<Q>U")))]
++       (match_operand:SF 1 "general_operand" "f,m")))]
+   "TARGET_COLDFIRE_FPU"
+ {
+   if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
+@@ -1986,9 +1963,9 @@
+ })
+ (define_insn "truncdfsf2_cf"
+-  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,d<Q>U")
++  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,dm")
+       (float_truncate:SF
+-        (match_operand:DF 1 "general_operand" "<Q>U,f")))]
++        (match_operand:DF 1 "general_operand" "m,f")))]
+   "TARGET_COLDFIRE_FPU"
+   "@
+   fsmove%.d %1,%0
+@@ -2021,7 +1998,8 @@
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+       (float:FP (match_operand:SI 1 "general_operand" "dmi")))]
+   "TARGET_68881"
+-  "f<FP:round>move%.l %1,%0")
++  "f<FP:round>move%.l %1,%0"
++  [(set_attr "type" "fmove")])
+ (define_insn "floatsi<mode>2_cf"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+@@ -2128,18 +2106,19 @@
+   if (FP_REG_P (operands[1]))
+     return "fintrz%.x %f1,%0";
+   return "fintrz%.<FP:prec> %f1,%0";
+-})
++}
++  [(set_attr "type" "falu")])
+ (define_insn "ftrunc<mode>2_cf"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+-        (fix:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U")))]
++        (fix:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m")))]
+   "TARGET_COLDFIRE_FPU"
+ {
+   if (FP_REG_P (operands[1]))
+     return "fintrz%.d %f1,%0";
+   return "fintrz%.<FP:prec> %f1,%0";
+ }
+-  [(set_attr "type" "fintrz")])
++  [(set_attr "type" "falu")])
+ ;; Convert a float whose value is an integer
+ ;; to an actual integer.  Second stage of converting float to integer type.
+@@ -2153,7 +2132,8 @@
+   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
+       (fix:QI (match_operand:FP 1 "general_operand" "f")))]
+   "TARGET_68881"
+-  "fmove%.b %1,%0")
++  "fmove%.b %1,%0"
++  [(set_attr "type" "fmove")])
+ (define_insn "fix<mode>qi2_cf"
+   [(set (match_operand:QI 0 "nonimmediate_operand" "=d<Q>U")
+@@ -2172,7 +2152,8 @@
+   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
+       (fix:HI (match_operand:FP 1 "general_operand" "f")))]
+   "TARGET_68881"
+-  "fmove%.w %1,%0")
++  "fmove%.w %1,%0"
++  [(set_attr "type" "fmove")])
+ (define_insn "fix<mode>hi2_cf"
+   [(set (match_operand:HI 0 "nonimmediate_operand" "=d<Q>U")
+@@ -2191,7 +2172,8 @@
+   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
+       (fix:SI (match_operand:FP 1 "general_operand" "f")))]
+   "TARGET_68881"
+-  "fmove%.l %1,%0")
++  "fmove%.l %1,%0"
++  [(set_attr "type" "fmove")])
+ (define_insn "fix<mode>si2_cf"
+   [(set (match_operand:SI 0 "nonimmediate_operand" "=d<Q>U")
+@@ -2297,7 +2279,7 @@
+     operands[1] = adjust_address (operands[1], SImode, 4);
+   return "add%.l %1,%0";
+ }
+-  [(set_attr "type" "add_l")])
++  [(set_attr "type" "alu_l")])
+ (define_insn "adddi3"
+   [(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,d,d,d")
+@@ -2376,12 +2358,44 @@
+     }
+ })
+-(define_insn "addsi_lshrsi_31"
++(define_expand "addsi_lshrsi_31"
++  [(set (match_operand:SI 0 "nonimmediate_operand")
++      (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand")
++                            (const_int 31))
++               (match_dup 1)))])
++
++(define_insn "*addsi_lshrsi_31_m68k"
+   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
+-    (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "rm")
+-            (const_int 31))
+-        (match_dup 1)))]
+-  ""
++      (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "rm")
++                            (const_int 31))
++               (match_dup 1)))]
++  "!TARGET_COLDFIRE"
++{
++  operands[2] = operands[0];
++  operands[3] = gen_label_rtx();
++  if (GET_CODE (operands[0]) == MEM)
++    {
++      if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
++        operands[0] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0));
++      else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
++        operands[2] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0));
++    }
++  output_asm_insn ("move%.l %1,%0", operands);
++  output_asm_insn ("jpl %l3", operands);
++  output_asm_insn ("addq%.l #1,%2", operands);
++  (*targetm.asm_out.internal_label) (asm_out_file, "L",
++                              CODE_LABEL_NUMBER (operands[3]));
++  return "";
++})
++
++;; FIXME: When 'enabled' attribute is available (in GCC 4.4) merge
++;; this with previous pattern.
++(define_insn "*addsi_lshrsi_31_cf"
++  [(set (match_operand:SI 0 "nonimmediate_operand" "=dm,d<Q>")
++      (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "r<Q>,rm")
++                            (const_int 31))
++               (match_dup 1)))]
++  "TARGET_COLDFIRE"
+ {
+   operands[2] = operands[0];
+   operands[3] = gen_label_rtx();
+@@ -2421,9 +2435,9 @@
+   "* return output_addsi3 (operands);")
+ (define_insn_and_split "*addsi3_5200"
+-  [(set (match_operand:SI 0 "nonimmediate_operand"         "=mr,mr,m,r,  ?a,?a,?a,?a")
+-      (plus:SI (match_operand:SI 1 "general_operand"     "%0, 0, 0,0,   a, a, r, a")
+-               (match_operand:SI 2 "general_src_operand" " I, L, d,mrKi,Cj,r, a, J")))]
++  [(set (match_operand:SI 0 "nonimmediate_operand"         "=mr,mr,a,  m,r,  ?a, ?a,?a,?a")
++      (plus:SI (match_operand:SI 1 "general_operand"     "%0, 0, 0,  0,0,   a,  a, r, a")
++               (match_operand:SI 2 "general_src_operand" " I, L, JCu,d,mrKi,Cj, r, a, JCu")))]
+   "TARGET_COLDFIRE"
+ {
+   switch (which_alternative)
+@@ -2435,21 +2449,22 @@
+       operands[2] = GEN_INT (- INTVAL (operands[2]));
+       return "subq%.l %2,%0";
+-    case 2:
+     case 3:
++    case 4:
+       return "add%.l %2,%0";
+-    case 4:
++    case 5:
+       /* move%.l %2,%0\n\tadd%.l %1,%0 */
+       return "#";
+-    case 5:
++    case 6:
+       return MOTOROLA ? "lea (%1,%2.l),%0" : "lea %1@(0,%2:l),%0";
+-    case 6:
++    case 7:
+       return MOTOROLA ? "lea (%2,%1.l),%0" : "lea %2@(0,%1:l),%0";
+-    case 7:
++    case 2:
++    case 8:
+       return MOTOROLA ? "lea (%c2,%1),%0" : "lea %1@(%c2),%0";
+     default:
+@@ -2457,17 +2472,16 @@
+       return "";
+     }
+ }
+-  "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 4) && !operands_match_p (operands[0], operands[1])"
++  "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 5) && !operands_match_p (operands[0], operands[1])"
+   [(set (match_dup 0)
+       (match_dup 2))
+    (set (match_dup 0)
+       (plus:SI (match_dup 0)
+                (match_dup 1)))]
+   ""
+-  [(set_attr "type" "addq_l,subq_l,add_l,add_l,*,lea,lea,lea")
+-   (set_attr "opy" "2,2,2,2,*,*,*,*")
+-   (set_attr "opy_type" "*,*,*,*,*,mem6,mem6,mem5")
+-   (set_attr "split" "done,done,done,done,*,done,done,done")])
++  [(set_attr "type"     "aluq_l,aluq_l,lea, alu_l,alu_l,*,lea, lea, lea")
++   (set_attr "opy"      "2,     2,     *,   2,    2,    *,*,   *,   *")
++   (set_attr "opy_type" "*,     *,     mem5,*,    *,    *,mem6,mem6,mem5")])
+ (define_insn ""
+   [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
+@@ -2711,21 +2725,27 @@
+       (plus:FP (float:FP (match_operand:SI 2 "general_operand" "dmi"))
+                (match_operand:FP 1 "general_operand" "0")))]
+   "TARGET_68881"
+-  "f<FP:round>add%.l %2,%0")
++  "f<FP:round>add%.l %2,%0"
++  [(set_attr "type" "falu")
++   (set_attr "opy" "2")])
+ (define_insn "add<mode>3_floathi_68881"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+       (plus:FP (float:FP (match_operand:HI 2 "general_operand" "dmn"))
+                (match_operand:FP 1 "general_operand" "0")))]
+   "TARGET_68881"
+-  "f<FP:round>add%.w %2,%0")
++  "f<FP:round>add%.w %2,%0"
++  [(set_attr "type" "falu")
++   (set_attr "opy" "2")])
+ (define_insn "add<mode>3_floatqi_68881"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+       (plus:FP (float:FP (match_operand:QI 2 "general_operand" "dmn"))
+                (match_operand:FP 1 "general_operand" "0")))]
+   "TARGET_68881"
+-  "f<FP:round>add%.b %2,%0")
++  "f<FP:round>add%.b %2,%0"
++  [(set_attr "type" "falu")
++   (set_attr "opy" "2")])
+ (define_insn "add<mode>3_68881"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+@@ -2736,19 +2756,22 @@
+   if (FP_REG_P (operands[2]))
+     return "f<FP:round>add%.x %2,%0";
+   return "f<FP:round>add%.<FP:prec> %f2,%0";
+-})
++}
++  [(set_attr "type" "falu")
++   (set_attr "opy" "2")])
+ (define_insn "add<mode>3_cf"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+       (plus:FP (match_operand:FP 1 "general_operand" "%0")
+-               (match_operand:FP 2 "general_operand" "f<FP:dreg><Q>U")))]
++               (match_operand:FP 2 "general_operand" "f<FP:dreg>m")))]
+   "TARGET_COLDFIRE_FPU"
+ {
+   if (FP_REG_P (operands[2]))
+     return "f<FP:prec>add%.d %2,%0";
+   return "f<FP:prec>add%.<FP:prec> %2,%0";
+ }
+-  [(set_attr "type" "fadd")])
++  [(set_attr "type" "falu")
++   (set_attr "opy" "2")])
\f
+ ;; subtract instructions
+@@ -2783,7 +2806,7 @@
+     operands[1] = adjust_address (operands[1], SImode, 4);
+   return "sub%.l %1,%0";
+ }
+-  [(set_attr "type" "sub_l")])
++  [(set_attr "type" "alu_l")])
+ (define_insn "subdi3"
+   [(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,d,d,d")
+@@ -2874,7 +2897,7 @@
+    sub%.l %2,%0
+    sub%.l %2,%0
+    sub%.l %2,%0"
+-  [(set_attr "type" "subq_l,sub_l,sub_l,sub_l")
++  [(set_attr "type" "aluq_l,alu_l,alu_l,alu_l")
+    (set_attr "opy" "2")])
+ (define_insn ""
+@@ -2925,21 +2948,27 @@
+       (minus:FP (match_operand:FP 1 "general_operand" "0")
+                 (float:FP (match_operand:SI 2 "general_operand" "dmi"))))]
+   "TARGET_68881"
+-  "f<FP:round>sub%.l %2,%0")
++  "f<FP:round>sub%.l %2,%0"
++  [(set_attr "type" "falu")
++   (set_attr "opy" "2")])
+ (define_insn "sub<mode>3_floathi_68881"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+       (minus:FP (match_operand:FP 1 "general_operand" "0")
+                 (float:FP (match_operand:HI 2 "general_operand" "dmn"))))]
+   "TARGET_68881"
+-  "f<FP:round>sub%.w %2,%0")
++  "f<FP:round>sub%.w %2,%0"
++  [(set_attr "type" "falu")
++   (set_attr "opy" "2")])
+ (define_insn "sub<mode>3_floatqi_68881"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+       (minus:FP (match_operand:FP 1 "general_operand" "0")
+                 (float:FP (match_operand:QI 2 "general_operand" "dmn"))))]
+   "TARGET_68881"
+-  "f<FP:round>sub%.b %2,%0")
++  "f<FP:round>sub%.b %2,%0"
++  [(set_attr "type" "falu")
++   (set_attr "opy" "2")])
+ (define_insn "sub<mode>3_68881"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+@@ -2950,19 +2979,22 @@
+   if (FP_REG_P (operands[2]))
+     return "f<FP:round>sub%.x %2,%0";
+   return "f<FP:round>sub%.<FP:prec> %f2,%0";
+-})
++}
++  [(set_attr "type" "falu")
++   (set_attr "opy" "2")])
+ (define_insn "sub<mode>3_cf"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+         (minus:FP (match_operand:FP 1 "general_operand" "0")
+-                  (match_operand:FP 2 "general_operand" "f<FP:dreg><Q>U")))]
++                  (match_operand:FP 2 "general_operand" "f<FP:dreg>m")))]
+   "TARGET_COLDFIRE_FPU"
+ {
+   if (FP_REG_P (operands[2]))
+     return "f<FP:prec>sub%.d %2,%0";
+   return "f<FP:prec>sub%.<FP:prec> %2,%0";
+ }
+-  [(set_attr "type" "fsub")])
++  [(set_attr "type" "falu")
++   (set_attr "opy" "2")])
\f
+ ;; multiply instructions
+@@ -2974,7 +3006,7 @@
+ {
+   return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
+ }
+-  [(set_attr "type" "muls_w")
++  [(set_attr "type" "mul_w")
+    (set_attr "opy" "2")])
+ (define_insn "mulhisi3"
+@@ -2987,7 +3019,7 @@
+ {
+   return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
+ }
+-  [(set_attr "type" "muls_w")
++  [(set_attr "type" "mul_w")
+    (set_attr "opy" "2")])
+ (define_insn "*mulhisisi3_s"
+@@ -2999,7 +3031,7 @@
+ {
+   return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
+ }
+-  [(set_attr "type" "muls_w")
++  [(set_attr "type" "mul_w")
+    (set_attr "opy" "2")])
+ (define_expand "mulsi3"
+@@ -3016,7 +3048,7 @@
+   "TARGET_68020"
+   "muls%.l %2,%0"
+-  [(set_attr "type" "muls_l")
++  [(set_attr "type" "mul_l")
+    (set_attr "opy" "2")])
+ (define_insn "*mulsi3_cf"
+@@ -3025,7 +3057,7 @@
+                (match_operand:SI 2 "general_operand" "d<Q>")))]
+   "TARGET_COLDFIRE"
+   "muls%.l %2,%0"
+-  [(set_attr "type" "muls_l")
++  [(set_attr "type" "mul_l")
+    (set_attr "opy" "2")])
+ (define_insn "umulhisi3"
+@@ -3038,7 +3070,7 @@
+ {
+   return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0";
+ }
+-  [(set_attr "type" "mulu_w")
++  [(set_attr "type" "mul_w")
+    (set_attr "opy" "2")])
+ (define_insn "*mulhisisi3_z"
+@@ -3050,7 +3082,7 @@
+ {
+   return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0";
+ }
+-  [(set_attr "type" "mulu_w")
++  [(set_attr "type" "mul_w")
+    (set_attr "opy" "2")])
+ ;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the
+@@ -3235,7 +3267,9 @@
+   return TARGET_68040
+        ? "f<FP:round>mul%.l %2,%0"
+        : "f<FP:round_mul>mul%.l %2,%0";
+-})
++}
++  [(set_attr "type" "fmul")
++   (set_attr "opy" "2")])
+ (define_insn "mul<mode>3_floathi_68881"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+@@ -3246,7 +3280,9 @@
+   return TARGET_68040
+        ? "f<FP:round>mul%.w %2,%0"
+        : "f<FP:round_mul>mul%.w %2,%0";
+-})
++}
++  [(set_attr "type" "fmul")
++   (set_attr "opy" "2")])
+ (define_insn "mul<mode>3_floatqi_68881"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+@@ -3257,7 +3293,9 @@
+   return TARGET_68040
+        ? "f<FP:round>mul%.b %2,%0"
+        : "f<FP:round_mul>mul%.b %2,%0";
+-})
++}
++  [(set_attr "type" "fmul")
++   (set_attr "opy" "2")])
+ (define_insn "muldf_68881"
+   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
+@@ -3304,14 +3342,15 @@
+ (define_insn "fmul<mode>3_cf"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+       (mult:FP (match_operand:FP 1 "general_operand" "%0")
+-               (match_operand:FP 2 "general_operand" "f<Q>U<FP:dreg>")))]
++               (match_operand:FP 2 "general_operand" "fm<FP:dreg>")))]
+   "TARGET_COLDFIRE_FPU"
+ {
+   if (FP_REG_P (operands[2]))
+     return "f<FP:prec>mul%.d %2,%0";
+   return "f<FP:prec>mul%.<FP:prec> %2,%0";
+ }
+-  [(set_attr "type" "fmul")])
++  [(set_attr "type" "fmul")
++   (set_attr "opy" "2")])
\f
+ ;; divide instructions
+@@ -3373,14 +3412,15 @@
+ (define_insn "div<mode>3_cf"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+       (div:FP (match_operand:FP 1 "general_operand" "0")
+-              (match_operand:FP 2 "general_operand" "f<Q>U<FP:dreg>")))]
++              (match_operand:FP 2 "general_operand" "fm<FP:dreg>")))]
+   "TARGET_COLDFIRE_FPU"
+ {
+   if (FP_REG_P (operands[2]))
+     return "f<FP:prec>div%.d %2,%0";
+   return "f<FP:prec>div%.<FP:prec> %2,%0";
+ }
+-  [(set_attr "type" "fdiv")])
++  [(set_attr "type" "fdiv")
++   (set_attr "opy" "2")])
\f
+ ;; Remainder instructions.
+@@ -3408,7 +3448,9 @@
+     return "rems%.l %2,%3:%0";
+   else
+     return "rems%.l %2,%3:%0\;divs%.l %2,%0";
+-})
++}
++  [(set_attr "type" "div_l")
++   (set_attr "opy" "2")])
+ (define_insn ""
+   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
+@@ -3448,7 +3490,9 @@
+     return "remu%.l %2,%3:%0";
+   else
+     return "remu%.l %2,%3:%0\;divu%.l %2,%0";
+-})
++}
++  [(set_attr "type" "div_l")
++   (set_attr "opy" "2")])
+ (define_insn ""
+   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
+@@ -4216,7 +4260,7 @@
+ (define_insn "neg<mode>2_cf"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d")
+-      (neg:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U,0")))]
++      (neg:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m,0")))]
+   "TARGET_COLDFIRE_FPU"
+ {
+   if (DATA_REG_P (operands[0]))
+@@ -4250,13 +4294,14 @@
+ (define_insn "sqrt<mode>2_cf"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
+-      (sqrt:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U")))]
++      (sqrt:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m")))]
+   "TARGET_COLDFIRE_FPU"
+ {
+   if (FP_REG_P (operands[1]))
+     return "f<FP:prec>sqrt%.d %1,%0";
+   return "f<FP:prec>sqrt%.<FP:prec> %1,%0";
+-})
++}
++  [(set_attr "type" "fsqrt")])
+ ;; Absolute value instructions
+ ;; If using software floating point, just zero the sign bit.
+@@ -4368,7 +4413,7 @@
+ (define_insn "abs<mode>2_cf"
+   [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d")
+-      (abs:FP (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U,0")))]
++      (abs:FP (match_operand:FP 1 "general_operand" "f<FP:dreg>m,0")))]
+   "TARGET_COLDFIRE_FPU"
+ {
+   if (DATA_REG_P (operands[0]))
+@@ -4379,7 +4424,8 @@
+   if (FP_REG_P (operands[1]))
+     return "f<FP:prec>abs%.d %1,%0";
+   return "f<FP:prec>abs%.<FP:prec> %1,%0";
+-})
++}
++  [(set_attr "type" "bitrw,fneg")])
\f
+ ;; bit indexing instructions
+@@ -4389,7 +4435,7 @@
+       (clz:SI (match_operand:SI 1 "register_operand" "0")))]
+   "ISA_HAS_FF1"
+   "ff1 %0"
+-  [(set_attr "type" "ff1")])
++  [(set_attr "type" "ext")])
\f
+ ;; one complement instructions
+@@ -4433,7 +4479,7 @@
+       (not:SI (match_operand:SI 1 "general_operand" "0")))]
+   "TARGET_COLDFIRE"
+   "not%.l %0"
+-  [(set_attr "type" "not_l")])
++  [(set_attr "type" "neg_l")])
+ (define_insn "one_cmplhi2"
+   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
+@@ -4785,7 +4831,7 @@
+     operands[1] = adjust_address (operands[1], HImode, 2);
+   return "move%.w %1,%0";
+ }
+-  [(set_attr "type" "move_w")])
++  [(set_attr "type" "move")])
+ (define_insn "subregsi1ashrdi_const32"
+   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
+@@ -4965,7 +5011,7 @@
+                    (match_operand:SI 2 "general_operand" "dI")))]
+   ""
+   "asr%.l %2,%0"
+-  [(set_attr "type" "asr_l")
++  [(set_attr "type" "shift")
+    (set_attr "opy" "2")])
+ (define_insn "ashrhi3"
+@@ -5261,7 +5307,7 @@
+                    (match_operand:SI 2 "general_operand" "dI")))]
+   ""
+   "lsr%.l %2,%0"
+-  [(set_attr "type" "lsr_l")
++  [(set_attr "type" "shift")
+    (set_attr "opy" "2")])
+ (define_insn "lshrhi3"
+@@ -5420,7 +5466,7 @@
+   CC_STATUS_INIT;
+   return "bset %1,%0";
+ }
+-  [(set_attr "type" "bset")])
++  [(set_attr "type" "bitrw")])
+ ;; set bit, bit number is (sign/zero)_extended from HImode/QImode
+ (define_insn "*bsetmemqi_ext"
+@@ -5434,7 +5480,7 @@
+   CC_STATUS_INIT;
+   return "bset %1,%0";
+ }
+-  [(set_attr "type" "bset")])
++  [(set_attr "type" "bitrw")])
+ ;; clear bit, bit number is int
+ (define_insn "bclrmemqi"
+@@ -5448,7 +5494,7 @@
+   CC_STATUS_INIT;
+   return "bclr %1,%0";
+ }
+-  [(set_attr "type" "bclr")])
++  [(set_attr "type" "bitrw")])
+ ;; clear bit, bit number is (sign/zero)_extended from HImode/QImode
+ (define_insn "*bclrmemqi_ext"
+@@ -5463,7 +5509,7 @@
+   CC_STATUS_INIT;
+   return "bclr %1,%0";
+ }
+-  [(set_attr "type" "bclr")])
++  [(set_attr "type" "bitrw")])
+ ;; Special cases of bit-field insns which we should
+ ;; recognize in preference to the general case.
+@@ -6413,8 +6459,7 @@
+ {
+   OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0");
+ }
+-  [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))
+-   (set_attr "split" "done")])
++  [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))])
+ (define_insn "bne"
+   [(set (pc)
+@@ -6426,8 +6471,7 @@
+ {
+   OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0");
+ }
+-  [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))
+-   (set_attr "split" "done")])
++  [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))])
+ (define_insn "bgt"
+   [(set (pc)
+@@ -6437,10 +6481,15 @@
+                     (pc)))]
+   ""
+ {
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
+   OUTPUT_JUMP ("jgt %l0", "fjgt %l0", 0);
+ }
+-  [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))
+-   (set_attr "split" "done")])
++  [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))])
+ (define_insn "bgtu"
+   [(set (pc)
+@@ -6449,7 +6498,15 @@
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+   ""
+-  "jhi %l0"
++{
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
++  return "jhi %l0";
++}
+   [(set_attr "type" "bcc")])
+ (define_insn "blt"
+@@ -6460,10 +6517,15 @@
+                     (pc)))]
+   ""
+ {
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
+   OUTPUT_JUMP ("jlt %l0", "fjlt %l0", "jmi %l0");
+ }
+-  [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))
+-   (set_attr "split" "done")])
++  [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))])
+ (define_insn "bltu"
+   [(set (pc)
+@@ -6472,7 +6534,15 @@
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+   ""
+-  "jcs %l0"
++{
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
++  return "jcs %l0";
++}
+   [(set_attr "type" "bcc")])
+ (define_insn "bge"
+@@ -6483,6 +6553,12 @@
+                     (pc)))]
+   ""
+ {
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
+   OUTPUT_JUMP ("jge %l0", "fjge %l0", "jpl %l0");
+ })
+@@ -6493,7 +6569,15 @@
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+   ""
+-  "jcc %l0"
++{
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
++  return "jcc %l0";
++}
+   [(set_attr "type" "bcc")])
+ (define_insn "ble"
+@@ -6504,6 +6588,12 @@
+                     (pc)))]
+   ""
+ {
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
+   OUTPUT_JUMP ("jle %l0", "fjle %l0", 0);
+ }
+   [(set_attr "type" "bcc")])
+@@ -6515,7 +6605,15 @@
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+   ""
+-  "jls %l0"
++{
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
++  return "jls %l0";
++}
+   [(set_attr "type" "bcc")])
+ (define_insn "bordered"
+@@ -6527,7 +6625,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjor %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
+ (define_insn "bunordered"
+   [(set (pc)
+@@ -6538,7 +6637,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjun %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
+ (define_insn "buneq"
+   [(set (pc)
+@@ -6549,7 +6649,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjueq %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
+ (define_insn "bunge"
+   [(set (pc)
+@@ -6560,7 +6661,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjuge %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
+ (define_insn "bungt"
+   [(set (pc)
+@@ -6571,7 +6673,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjugt %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
+ (define_insn "bunle"
+   [(set (pc)
+@@ -6582,7 +6685,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjule %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
+ (define_insn "bunlt"
+   [(set (pc)
+@@ -6593,7 +6697,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjult %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
+ (define_insn "bltgt"
+   [(set (pc)
+@@ -6604,7 +6709,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjogl %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
\f
+ ;; Negated conditional jump instructions.
+@@ -6640,6 +6746,12 @@
+                     (label_ref (match_operand 0 "" ""))))]
+   ""
+ {
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
+   OUTPUT_JUMP ("jle %l0", "fjngt %l0", 0);
+ }
+   [(set_attr "type" "bcc")])
+@@ -6651,7 +6763,15 @@
+                     (pc)
+                     (label_ref (match_operand 0 "" ""))))]
+   ""
+-  "jls %l0"
++{
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
++  return "jls %l0";
++}
+   [(set_attr "type" "bcc")])
+ (define_insn "*blt_rev"
+@@ -6662,6 +6782,12 @@
+                     (label_ref (match_operand 0 "" ""))))]
+   ""
+ {
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
+   OUTPUT_JUMP ("jge %l0", "fjnlt %l0", "jpl %l0");
+ }
+   [(set_attr "type" "bcc")])
+@@ -6673,7 +6799,15 @@
+                     (pc)
+                     (label_ref (match_operand 0 "" ""))))]
+   ""
+-  "jcc %l0"
++{
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
++  return "jcc %l0";
++}
+   [(set_attr "type" "bcc")])
+ (define_insn "*bge_rev"
+@@ -6684,6 +6818,12 @@
+                     (label_ref (match_operand 0 "" ""))))]
+   ""
+ {
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
+   OUTPUT_JUMP ("jlt %l0", "fjnge %l0", "jmi %l0");
+ }
+   [(set_attr "type" "bcc")])
+@@ -6695,7 +6835,15 @@
+                     (pc)
+                     (label_ref (match_operand 0 "" ""))))]
+   ""
+-  "jcs %l0"
++{
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
++  return "jcs %l0";
++}
+   [(set_attr "type" "bcc")])
+ (define_insn "*ble_rev"
+@@ -6706,6 +6854,12 @@
+                     (label_ref (match_operand 0 "" ""))))]
+   ""
+ {
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
+   OUTPUT_JUMP ("jgt %l0", "fjnle %l0", 0);
+ }
+   [(set_attr "type" "bcc")])
+@@ -6717,7 +6871,15 @@
+                     (pc)
+                     (label_ref (match_operand 0 "" ""))))]
+   ""
+-  "jhi %l0"
++{
++  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
++    {
++      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
++      return 0;
++    }
++
++  return "jhi %l0";
++}
+   [(set_attr "type" "bcc")])
+ (define_insn "*bordered_rev"
+@@ -6729,7 +6891,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjun %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
+ (define_insn "*bunordered_rev"
+   [(set (pc)
+@@ -6740,7 +6903,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjor %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
+ (define_insn "*buneq_rev"
+   [(set (pc)
+@@ -6751,7 +6915,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjogl %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
+ (define_insn "*bunge_rev"
+   [(set (pc)
+@@ -6762,7 +6927,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjolt %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
+ (define_insn "*bungt_rev"
+   [(set (pc)
+@@ -6773,7 +6939,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjole %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
+ (define_insn "*bunle_rev"
+   [(set (pc)
+@@ -6784,7 +6951,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjogt %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
+ (define_insn "*bunlt_rev"
+   [(set (pc)
+@@ -6795,7 +6963,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjoge %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
+ (define_insn "*bltgt_rev"
+   [(set (pc)
+@@ -6806,7 +6975,8 @@
+ {
+   gcc_assert (cc_prev_status.flags & CC_IN_68881);
+   return "fjueq %l0";
+-})
++}
++  [(set_attr "type" "fbcc")])
\f
+ ;; Unconditional and other jump instructions
+ (define_insn "jump"
+@@ -6835,7 +7005,7 @@
+ {
+   return MOTOROLA ? "jmp (%0)" : "jmp %0@";
+ }
+-  [(set_attr "type" "bra")])
++  [(set_attr "type" "jmp")])
+ ;; Jump to variable address from dispatch table of relative addresses.
+ (define_insn ""
+@@ -7013,7 +7183,8 @@
+   "!SIBLING_CALL_P (insn)"
+ {
+   return output_call (operands[0]);
+-})
++}
++  [(set_attr "type" "jsr")])
+ ;; Call subroutine, returning value in operand 0
+ ;; (which must be a hard register).
+@@ -7035,7 +7206,6 @@
+   "!SIBLING_CALL_P (insn)"
+   "jsr %a1"
+   [(set_attr "type" "jsr")
+-   (set_attr "split" "done")
+    (set_attr "opx" "1")])
+ (define_insn "*symbolic_call_value_jsr"
+@@ -7049,7 +7219,6 @@
+   return m68k_symbolic_call;
+ }
+   [(set_attr "type" "jsr")
+-   (set_attr "split" "done")
+    (set_attr "opx" "1")])
+ (define_insn "*symbolic_call_value_bsr"
+@@ -7065,7 +7234,6 @@
+   return m68k_symbolic_call;
+ }
+   [(set_attr "type" "bsr")
+-   (set_attr "split" "done")
+    (set_attr "opx" "1")])
+ ;; Call subroutine returning any type.
+@@ -7231,7 +7399,8 @@
+     return "link.w %0,%1";
+   else
+     return "link.l %0,%1";
+-})
++}
++  [(set_attr "type" "link")])
+ (define_expand "unlink"
+   [(parallel
+@@ -7721,6 +7890,17 @@
+   }
+ })
++;; These are to prevent the scheduler from moving stores to the frame
++;; before the stack adjustment.
++(define_insn "stack_tie"
++  [(set (mem:BLK (scratch))
++      (unspec:BLK [(match_operand:SI 0 "register_operand" "r")
++                   (match_operand:SI 1 "register_operand" "r")]
++                  UNSPEC_TIE))]
++  ""
++  ""
++  [(set_attr "type" "ignore")])
++
+ ;; Instruction that subscribes one word in ColdFire instruction buffer.
+ ;; This instruction is used within scheduler only and should not appear
+ ;; in the instruction stream.
+--- a/gcc/config/m68k/m68k.opt
++++ b/gcc/config/m68k/m68k.opt
+@@ -178,3 +178,11 @@ Do not use unaligned memory references
+ mtune=
+ Target RejectNegative Joined
+ Tune for the specified target CPU or architecture
++
++mxgot
++Target Report Mask(XGOT)
++Support more than 8192 GOT entries on ColdFire
++
++mxtls
++Target Report Mask(XTLS)
++Support TLS segment larger than 64K
+--- a/gcc/config/m68k/predicates.md
++++ b/gcc/config/m68k/predicates.md
+@@ -130,7 +130,9 @@
+   (match_code "sign_extend,zero_extend"))
+ ;; Returns true if OP is either a symbol reference or a sum of a
+-;; symbol reference and a constant.
++;; symbol reference and a constant.  This predicate is for "raw"
++;; symbol references not yet processed by legitimize*_address,
++;; hence we do not handle UNSPEC_{XGOT, TLS, XTLS} here.
+ (define_predicate "symbolic_operand"
+   (match_code "symbol_ref,label_ref,const")
+--- a/gcc/config/m68k/t-cf
++++ b/gcc/config/m68k/t-cf
+@@ -2,3 +2,6 @@
+ M68K_MLIB_CPU += && (CPU ~ "^mcf")
+ M68K_ARCH := cf
++# Do not stamp the multilibs with a MAC type, as we never use those
++# instructions in compiler-generated code.
++MULTILIB_EXTRA_OPTS += Wa,-mno-mac
+--- /dev/null
++++ b/gcc/config/m68k/t-linux
+@@ -0,0 +1,11 @@
++EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
++
++# Only include multilibs for CPUs with an MMU.
++M68K_MLIB_CPU += && match(FLAGS, "FL_MMU")
++
++# This rule uses MULTILIB_MATCHES to generate a definition of
++# SYSROOT_SUFFIX_SPEC.
++sysroot-suffix.h: $(srcdir)/config/m68k/print-sysroot-suffix.sh
++      $(SHELL) $(srcdir)/config/m68k/print-sysroot-suffix.sh \
++        "$(SYSTEM_HEADER_DIR)/../.." "$(MULTILIB_MATCHES)" \
++        "$(MULTILIB_OPTIONS)" > $@
+--- a/gcc/config/m68k/t-uclinux
++++ b/gcc/config/m68k/t-uclinux
+@@ -1,8 +1,8 @@
+ # crti and crtn are provided by uClibc.
+ EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o
+-# Only include multilibs for the 68020 and for CPUs without an MMU.
+-M68K_MLIB_CPU += && (MLIB == "68020" || !match(FLAGS, "FL_MMU"))
++# Include multilibs for CPUs without an MMU or with FL_UCLINUX
++M68K_MLIB_CPU += && (!match(FLAGS, "FL_MMU") || match(FLAGS, "FL_UCLINUX"))
+ # Add multilibs for execute-in-place and shared-library code.
+ M68K_MLIB_OPTIONS += msep-data/mid-shared-library
+--- a/gcc/config/mips/74k.md
++++ b/gcc/config/mips/74k.md
+@@ -118,8 +118,7 @@
+ ;; stores
+ (define_insn_reservation "r74k_int_store" 1
+   (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
+-       (and (eq_attr "type" "store")
+-            (eq_attr "mode" "!unknown")))
++       (eq_attr "type" "store"))
+   "r74k_agen")
+@@ -145,33 +144,123 @@
+ ;; load->load base:  4 cycles
+ ;; load->store base: 4 cycles
+ (define_bypass 4 "r74k_int_load" "r74k_int_load")
+-(define_bypass 4 "r74k_int_load" "r74k_int_store" "!store_data_bypass_p")
++(define_bypass 4 "r74k_int_load" "r74k_int_store" "!mips_store_data_bypass_p")
+ ;; logical/move/slt/signext->next use :  1 cycles (Default)
+ ;; logical/move/slt/signext->load base:  2 cycles
+ ;; logical/move/slt/signext->store base: 2 cycles
+ (define_bypass 2 "r74k_int_logical" "r74k_int_load")
+-(define_bypass 2 "r74k_int_logical" "r74k_int_store" "!store_data_bypass_p")
++(define_bypass 2 "r74k_int_logical" "r74k_int_store"
++  "!mips_store_data_bypass_p")
+ ;; arith->next use :  2 cycles (Default)
+ ;; arith->load base:  3 cycles
+ ;; arith->store base: 3 cycles
+ (define_bypass 3 "r74k_int_arith" "r74k_int_load")
+-(define_bypass 3 "r74k_int_arith" "r74k_int_store" "!store_data_bypass_p")
++(define_bypass 3 "r74k_int_arith" "r74k_int_store" "!mips_store_data_bypass_p")
+ ;; cmove->next use :  4 cycles (Default)
+ ;; cmove->load base:  5 cycles
+ ;; cmove->store base: 5 cycles
+ (define_bypass 5 "r74k_int_cmove"  "r74k_int_load")
+-(define_bypass 5 "r74k_int_cmove"  "r74k_int_store" "!store_data_bypass_p")
++(define_bypass 5 "r74k_int_cmove"  "r74k_int_store"
++  "!mips_store_data_bypass_p")
+ ;; mult/madd/msub->int_mfhilo  : 4 cycles (default)
+ ;; mult->madd/msub             : 1 cycles
+ ;; madd/msub->madd/msub        : 1 cycles
+-(define_bypass 1 "r74k_int_mult,r74k_int_mul3" "r74k_int_madd"
+-  "mips_linked_madd_p")
+-(define_bypass 1 "r74k_int_madd" "r74k_int_madd"
+-  "mips_linked_madd_p")
++(define_bypass 1 "r74k_int_mult" "r74k_int_madd")
++(define_bypass 1 "r74k_int_madd" "r74k_int_madd")
++
++(define_bypass 1 "r74k_int_mul3" "r74k_int_madd"
++  "mips_mult_madd_chain_bypass_p")
++
++
++;; --------------------------------------------------------------
++;; DSP instructins
++;; --------------------------------------------------------------
++
++;; Non-saturating insn have the same latency as normal ALU operations,
++(define_insn_reservation "r74k_dsp_alu" 2
++  (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
++       (eq_attr "type" "dspalu"))
++  "r74k_alu")
++
++;; Saturating insn takes an extra cycle.
++(define_insn_reservation "r74k_dsp_alu_sat" 3
++  (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
++       (eq_attr "type" "dspalusat"))
++  "r74k_alu")
++
++;; dpaq_s, dpau, dpsq_s, dpsu, maq_s, mulsaq
++;; - delivers result to hi/lo in 6 cycle (bypass at M4)
++(define_insn_reservation "r74k_dsp_mac" 6
++  (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
++       (eq_attr "type" "dspmac"))
++  "r74k_alu+r74k_mul")
++
++;; dpaq_sa, dpsq_sa, maq_sa
++;; - delivers result to hi/lo in 7 cycle (bypass at WB)
++(define_insn_reservation "r74k_dsp_mac_sat" 7
++  (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
++       (eq_attr "type" "dspmacsat"))
++  "r74k_alu+r74k_mul")
++
++;; extp, extpdp, extpdpv, extpv, extr, extrv
++;; - same latency as "mul"
++(define_insn_reservation "r74k_dsp_acc_ext" 7
++  (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
++       (eq_attr "type" "accext"))
++  "r74k_alu+r74k_mul")
++
++;; mthlip, shilo, shilov
++;; - same latency as "mul"
++(define_insn_reservation "r74k_dsp_acc_mod" 7
++  (and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
++       (eq_attr "type" "accmod"))
++  "r74k_alu+r74k_mul")
++
++;; dspalu   ->load/store base
++;; dspalusat->load/store base
++;; - we should never see these in real life.
++
++;; dsp_mac->dsp_mac     : 1 cycles (repeat rate of 1)
++;; dsp_mac->dsp_mac_sat : 1 cycles (repeat rate of 1)
++(define_bypass 1 "r74k_dsp_mac" "r74k_dsp_mac")
++(define_bypass 1 "r74k_dsp_mac" "r74k_dsp_mac_sat")
++
++;; dsp_mac_sat->dsp_mac_sat : 2 cycles (repeat rate of 2)
++;; dsp_mac_sat->dsp_mac     : 2 cycles (repeat rate of 2)
++(define_bypass 2 "r74k_dsp_mac_sat" "r74k_dsp_mac_sat")
++(define_bypass 2 "r74k_dsp_mac_sat" "r74k_dsp_mac")
++
++(define_bypass 1 "r74k_int_mult" "r74k_dsp_mac")
++(define_bypass 1 "r74k_int_mult" "r74k_dsp_mac_sat")
++
++;; Before reload, all multiplier is registered as imul3 (which has a long
++;;  latency).  We temporary jig the latency such that the macc groups
++;;  are scheduled closely together during the first scheduler pass.
++(define_bypass 1 "r74k_int_mul3" "r74k_dsp_mac"
++  "mips_mult_madd_chain_bypass_p")
++(define_bypass 1 "r74k_int_mul3" "r74k_dsp_mac_sat"
++  "mips_mult_madd_chain_bypass_p")
++
++;; Assuming the following is true (bypass at M4)
++;;  AP AF AM MB M1 M2 M3 M4 WB GR GC
++;;              AP AF AM MB M1 M2 M3 M4 WB GR GC
++;; dsp_mac->dsp_acc_ext : 4 cycles
++;; dsp_mac->dsp_acc_mod : 4 cycles
++(define_bypass 4 "r74k_dsp_mac" "r74k_dsp_acc_ext")
++(define_bypass 4 "r74k_dsp_mac" "r74k_dsp_acc_mod")
++
++;; Assuming the following is true (bypass at WB)
++;;  AP AF AM MB M1 M2 M3 M4 WB GR GC
++;;                 AP AF AM MB M1 M2 M3 M4 WB GR GC
++;; dsp_mac_sat->dsp_acc_ext : 5 cycles
++;; dsp_mac_sat->dsp_acc_mod : 5 cycles
++(define_bypass 5 "r74k_dsp_mac_sat" "r74k_dsp_acc_ext")
++(define_bypass 5 "r74k_dsp_mac_sat" "r74k_dsp_acc_mod")
++
+ ;; --------------------------------------------------------------
+ ;; Floating Point Instructions
+--- /dev/null
++++ b/gcc/config/mips/crtfastmath.c
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (C) 2008 Free Software Foundation, Inc.
++ *
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 3, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with GCC; see the file COPYING3.  If not see
++ * <http://www.gnu.org/licenses/>.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */
++
++#ifdef __mips_hard_float
++
++/* flush denormalized numbers to zero */
++#define _FPU_FLUSH_TZ   0x1000000
++
++/* rounding control */
++#define _FPU_RC_NEAREST 0x0     /* RECOMMENDED */
++#define _FPU_RC_ZERO    0x1
++#define _FPU_RC_UP      0x2
++#define _FPU_RC_DOWN    0x3
++
++/* enable interrupts for IEEE exceptions */
++#define _FPU_IEEE     0x00000F80
++
++/* Macros for accessing the hardware control word.  */
++#define _FPU_GETCW(cw) __asm__ ("cfc1 %0,$31" : "=r" (cw))
++#define _FPU_SETCW(cw) __asm__ ("ctc1 %0,$31" : : "r" (cw))
++
++static void __attribute__((constructor))
++set_fast_math (void)
++{
++  unsigned int fcr;
++
++  /* fastmath: flush to zero, round to nearest, ieee exceptions disabled */
++  fcr = _FPU_FLUSH_TZ | _FPU_RC_NEAREST;
++
++  _FPU_SETCW(fcr);
++}
++
++#endif /* __mips_hard_float */
+--- /dev/null
++++ b/gcc/config/mips/cs-sgxx-linux.h
+@@ -0,0 +1,40 @@
++/* MIPS SourceryG++ GNU/Linux Configuration.
++   Copyright (C) 2008
++   Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 3, or (at your option)
++any later version.
++
++GCC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++/* We do not need to provide an explicit big-endian multilib.  */
++#undef MULTILIB_DEFAULTS
++#define MULTILIB_DEFAULTS \
++  { "EB" }
++
++/* The various C libraries each have their own subdirectory.  */
++#undef SYSROOT_SUFFIX_SPEC
++#define SYSROOT_SUFFIX_SPEC                   \
++"%{muclibc:/uclibc}\
++%{mips2|mips3|mips4|march=mips2|march=mips3|march=mips4|march=r6000|\
++march=r4000|march=vr4100|march=vr4111|march=vr4120|march=vr4130|\
++march=vr4300|march=r4400|march=r4600|march=orion|march=r4650|march=r8000|\
++march=vr5000|march=vr5400|march=vr5500|march=rm7000|\
++march=rm9000:/mips2;\
++mips32|march=mips32|march=4kc|march=4km|march=4kp|march=4ks:/mips32}\
++%{msoft-float:/soft-float}%{mel|EL:/el}"
++
++#undef SYSROOT_HEADERS_SUFFIX_SPEC
++#define SYSROOT_HEADERS_SUFFIX_SPEC \
++  "%{muclibc:/uclibc}"
+--- /dev/null
++++ b/gcc/config/mips/cs-sgxxlite-linux.h
+@@ -0,0 +1,33 @@
++/* MIPS SourceryG++ GNU/Linux Configuration.
++   Copyright (C) 2008
++   Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 3, or (at your option)
++any later version.
++
++GCC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++/* We do not need to provide an explicit big-endian multilib.  */
++#undef MULTILIB_DEFAULTS
++#define MULTILIB_DEFAULTS \
++  { "EB" }
++
++/* The various C libraries each have their own subdirectory.  */
++#undef SYSROOT_SUFFIX_SPEC
++#define SYSROOT_SUFFIX_SPEC \
++"%{muclibc:/uclibc}%{msoft-float:/soft-float}%{mel|EL:/el}"
++
++#undef SYSROOT_HEADERS_SUFFIX_SPEC
++#define SYSROOT_HEADERS_SUFFIX_SPEC \
++  "%{muclibc:/uclibc}"
+--- a/gcc/config/mips/elfoabi.h
++++ b/gcc/config/mips/elfoabi.h
+@@ -19,7 +19,7 @@ You should have received a copy of the G
+ along with GCC; see the file COPYING3.  If not see
+ <http://www.gnu.org/licenses/>.  */
+-#define DRIVER_SELF_SPECS                                             \
++#define SUBTARGET_SELF_SPECS                                          \
+   /* Make sure a -mips option is present.  This helps us to pick      \
+      the right multilib, and also makes the later specs easier                \
+      to write.  */                                                    \
+--- a/gcc/config/mips/iris6.h
++++ b/gcc/config/mips/iris6.h
+@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3.  
+ /* Force the default ABI onto the command line in order to make the specs
+    easier to write.  Default to the mips2 ISA for the O32 ABI.  */
+-#define DRIVER_SELF_SPECS \
++#define SUBTARGET_SELF_SPECS \
+   "%{!mabi=*: -mabi=n32}", \
+   "%{mabi=32: %{!mips*: %{!march*: -mips2}}}"
+--- a/gcc/config/mips/linux.h
++++ b/gcc/config/mips/linux.h
+@@ -37,10 +37,6 @@ along with GCC; see the file COPYING3.  
+ #undef MD_EXEC_PREFIX
+ #undef MD_STARTFILE_PREFIX
+-/* If we don't set MASK_ABICALLS, we can't default to PIC.  */
+-#undef TARGET_DEFAULT
+-#define TARGET_DEFAULT MASK_ABICALLS
+-
+ #define TARGET_OS_CPP_BUILTINS()                              \
+   do {                                                                \
+     LINUX_TARGET_OS_CPP_BUILTINS();                           \
+@@ -79,7 +75,8 @@ along with GCC; see the file COPYING3.  
+         %{static:-static}}}"
+ #undef SUBTARGET_ASM_SPEC
+-#define SUBTARGET_ASM_SPEC "%{mabi=64: -64} %{!mno-abicalls:-KPIC}"
++#define SUBTARGET_ASM_SPEC \
++ "%{mabi=64: -64} %{mabicalls:%{fpic|fPIC|fpie|fPIE:-KPIC;:-mnon-pic-abicalls}}"
+ /* The MIPS assembler has different syntax for .set. We set it to
+    .dummy to trap any errors.  */
+@@ -145,7 +142,15 @@ along with GCC; see the file COPYING3.  
+ /* Default to -mno-shared for non-PIC.  */
+ #define NO_SHARED_SPECS \
+   "%{mshared|mno-shared|fpic|fPIC|fpie|fPIE:;:-mno-shared}"
+-#define DRIVER_SELF_SPECS NO_SHARED_SPECS
++#undef SUBTARGET_SELF_SPECS
++#define SUBTARGET_SELF_SPECS NO_SHARED_SPECS
+ #else
+ #define NO_SHARED_SPECS
+ #endif
++
++/* Similar to standard Linux, but adding -ffast-math support.  */
++#undef  ENDFILE_SPEC
++#define ENDFILE_SPEC \
++  "%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
++   %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
++
+--- a/gcc/config/mips/linux64.h
++++ b/gcc/config/mips/linux64.h
+@@ -20,15 +20,15 @@ along with GCC; see the file COPYING3.  
+ /* Force the default endianness and ABI flags onto the command line
+    in order to make the other specs easier to write.  */
+-#undef DRIVER_SELF_SPECS
+-#define DRIVER_SELF_SPECS \
++#undef SUBTARGET_SELF_SPECS
++#define SUBTARGET_SELF_SPECS \
+ NO_SHARED_SPECS \
+ " %{!EB:%{!EL:%(endian_spec)}}" \
+ " %{!mabi=*: -mabi=n32}"
+ #undef SUBTARGET_ASM_SPEC
+ #define SUBTARGET_ASM_SPEC "\
+-%{!fno-PIC:%{!fno-pic:-KPIC}} \
++%{mabicalls:%{fpic|fPIC|fpie|fPIE:-KPIC;:-mnon-pic-abicalls}} \
+ %{fno-PIC:-non_shared} %{fno-pic:-non_shared}"
+ #undef LIB_SPEC
+@@ -72,3 +72,9 @@ NO_SHARED_SPECS \
+    ieee_quad_format is the default, but let's put this here to make
+    sure nobody thinks we just forgot to set it to something else.  */
+ #define MIPS_TFMODE_FORMAT mips_quad_format
++
++/* Similar to standard Linux, but adding -ffast-math support.  */
++#undef  ENDFILE_SPEC
++#define ENDFILE_SPEC \
++  "%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
++   %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
+--- a/gcc/config/mips/mips-dsp.md
++++ b/gcc/config/mips/mips-dsp.md
+@@ -42,9 +42,9 @@
+                    (match_operand:DSPV 2 "register_operand" "d")))
+      (set (reg:CCDSP CCDSP_OU_REGNUM)
+         (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDQ))])]
+-  ""
++  "ISA_HAS_DSP"
+   "add<DSPV:dspfmt1>.<DSPV:dspfmt2>\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_add<DSP:dspfmt1>_s_<DSP:dspfmt2>"
+@@ -55,9 +55,9 @@
+                     UNSPEC_ADDQ_S))
+      (set (reg:CCDSP CCDSP_OU_REGNUM)
+         (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDQ_S))])]
+-  ""
++  "ISA_HAS_DSP"
+   "add<DSP:dspfmt1>_s.<DSP:dspfmt2>\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalusat")
+    (set_attr "mode"   "SI")])
+ ;; SUBQ*
+@@ -70,7 +70,7 @@
+         (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_SUBQ))])]
+   "ISA_HAS_DSP"
+   "sub<DSPV:dspfmt1>.<DSPV:dspfmt2>\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_sub<DSP:dspfmt1>_s_<DSP:dspfmt2>"
+@@ -83,7 +83,7 @@
+         (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_SUBQ_S))])]
+   "ISA_HAS_DSP"
+   "sub<DSP:dspfmt1>_s.<DSP:dspfmt2>\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalusat")
+    (set_attr "mode"   "SI")])
+ ;; ADDSC
+@@ -97,7 +97,7 @@
+         (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDSC))])]
+   "ISA_HAS_DSP"
+   "addsc\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; ADDWC
+@@ -112,7 +112,7 @@
+         (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDWC))])]
+   "ISA_HAS_DSP"
+   "addwc\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; MODSUB
+@@ -123,7 +123,7 @@
+                  UNSPEC_MODSUB))]
+   "ISA_HAS_DSP"
+   "modsub\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; RADDU*
+@@ -133,7 +133,7 @@
+                  UNSPEC_RADDU_W_QB))]
+   "ISA_HAS_DSP"
+   "raddu.w.qb\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; ABSQ*
+@@ -146,7 +146,7 @@
+         (unspec:CCDSP [(match_dup 1)] UNSPEC_ABSQ_S))])]
+   "ISA_HAS_DSP"
+   "absq_s.<DSPQ:dspfmt2>\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalusat")
+    (set_attr "mode"   "SI")])
+ ;; PRECRQ*
+@@ -157,7 +157,7 @@
+                    UNSPEC_PRECRQ_QB_PH))]
+   "ISA_HAS_DSP"
+   "precrq.qb.ph\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_precrq_ph_w"
+@@ -167,7 +167,7 @@
+                    UNSPEC_PRECRQ_PH_W))]
+   "ISA_HAS_DSP"
+   "precrq.ph.w\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_precrq_rs_ph_w"
+@@ -181,7 +181,7 @@
+                       UNSPEC_PRECRQ_RS_PH_W))])]
+   "ISA_HAS_DSP"
+   "precrq_rs.ph.w\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; PRECRQU*
+@@ -196,7 +196,7 @@
+                       UNSPEC_PRECRQU_S_QB_PH))])]
+   "ISA_HAS_DSP"
+   "precrqu_s.qb.ph\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalusat")
+    (set_attr "mode"   "SI")])
+ ;; PRECEQ*
+@@ -206,7 +206,7 @@
+                  UNSPEC_PRECEQ_W_PHL))]
+   "ISA_HAS_DSP"
+   "preceq.w.phl\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_preceq_w_phr"
+@@ -215,7 +215,7 @@
+                  UNSPEC_PRECEQ_W_PHR))]
+   "ISA_HAS_DSP"
+   "preceq.w.phr\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; PRECEQU*
+@@ -225,7 +225,7 @@
+                    UNSPEC_PRECEQU_PH_QBL))]
+   "ISA_HAS_DSP"
+   "precequ.ph.qbl\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_precequ_ph_qbr"
+@@ -234,7 +234,7 @@
+                    UNSPEC_PRECEQU_PH_QBR))]
+   "ISA_HAS_DSP"
+   "precequ.ph.qbr\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_precequ_ph_qbla"
+@@ -243,7 +243,7 @@
+                    UNSPEC_PRECEQU_PH_QBLA))]
+   "ISA_HAS_DSP"
+   "precequ.ph.qbla\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_precequ_ph_qbra"
+@@ -252,7 +252,7 @@
+                    UNSPEC_PRECEQU_PH_QBRA))]
+   "ISA_HAS_DSP"
+   "precequ.ph.qbra\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; PRECEU*
+@@ -262,7 +262,7 @@
+                    UNSPEC_PRECEU_PH_QBL))]
+   "ISA_HAS_DSP"
+   "preceu.ph.qbl\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_preceu_ph_qbr"
+@@ -271,7 +271,7 @@
+                    UNSPEC_PRECEU_PH_QBR))]
+   "ISA_HAS_DSP"
+   "preceu.ph.qbr\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_preceu_ph_qbla"
+@@ -280,7 +280,7 @@
+                    UNSPEC_PRECEU_PH_QBLA))]
+   "ISA_HAS_DSP"
+   "preceu.ph.qbla\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_preceu_ph_qbra"
+@@ -289,7 +289,7 @@
+                    UNSPEC_PRECEU_PH_QBRA))]
+   "ISA_HAS_DSP"
+   "preceu.ph.qbra\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; Table 2-2. MIPS DSP ASE Instructions: Shift
+@@ -313,7 +313,7 @@
+     }
+   return "shllv.<DSPV:dspfmt2>\t%0,%1,%2";
+ }
+-  [(set_attr "type"   "shift")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_shll_s_<DSPQ:dspfmt2>"
+@@ -335,7 +335,7 @@
+     }
+   return "shllv_s.<DSPQ:dspfmt2>\t%0,%1,%2";
+ }
+-  [(set_attr "type"   "shift")
++  [(set_attr "type"   "dspalusat")
+    (set_attr "mode"   "SI")])
+ ;; SHRL*
+@@ -354,7 +354,7 @@
+     }
+   return "shrlv.qb\t%0,%1,%2";
+ }
+-  [(set_attr "type"   "shift")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; SHRA*
+@@ -373,7 +373,7 @@
+     }
+   return "shrav.ph\t%0,%1,%2";
+ }
+-  [(set_attr "type"   "shift")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_shra_r_<DSPQ:dspfmt2>"
+@@ -392,7 +392,7 @@
+     }
+   return "shrav_r.<DSPQ:dspfmt2>\t%0,%1,%2";
+ }
+-  [(set_attr "type"   "shift")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; Table 2-3. MIPS DSP ASE Instructions: Multiply
+@@ -478,7 +478,7 @@
+                  UNSPEC_DPAU_H_QBL))]
+   "ISA_HAS_DSP && !TARGET_64BIT"
+   "dpau.h.qbl\t%q0,%2,%3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_dpau_h_qbr"
+@@ -489,7 +489,7 @@
+                  UNSPEC_DPAU_H_QBR))]
+   "ISA_HAS_DSP && !TARGET_64BIT"
+   "dpau.h.qbr\t%q0,%2,%3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ ;; DPSU*
+@@ -501,7 +501,7 @@
+                  UNSPEC_DPSU_H_QBL))]
+   "ISA_HAS_DSP && !TARGET_64BIT"
+   "dpsu.h.qbl\t%q0,%2,%3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_dpsu_h_qbr"
+@@ -512,7 +512,7 @@
+                  UNSPEC_DPSU_H_QBR))]
+   "ISA_HAS_DSP && !TARGET_64BIT"
+   "dpsu.h.qbr\t%q0,%2,%3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ ;; DPAQ*
+@@ -528,7 +528,7 @@
+                       UNSPEC_DPAQ_S_W_PH))])]
+   "ISA_HAS_DSP && !TARGET_64BIT"
+   "dpaq_s.w.ph\t%q0,%2,%3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ ;; DPSQ*
+@@ -544,7 +544,7 @@
+                       UNSPEC_DPSQ_S_W_PH))])]
+   "ISA_HAS_DSP && !TARGET_64BIT"
+   "dpsq_s.w.ph\t%q0,%2,%3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ ;; MULSAQ*
+@@ -560,7 +560,7 @@
+                       UNSPEC_MULSAQ_S_W_PH))])]
+   "ISA_HAS_DSP && !TARGET_64BIT"
+   "mulsaq_s.w.ph\t%q0,%2,%3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ ;; DPAQ*
+@@ -576,7 +576,7 @@
+                       UNSPEC_DPAQ_SA_L_W))])]
+   "ISA_HAS_DSP && !TARGET_64BIT"
+   "dpaq_sa.l.w\t%q0,%2,%3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmacsat")
+    (set_attr "mode"   "SI")])
+ ;; DPSQ*
+@@ -592,7 +592,7 @@
+                       UNSPEC_DPSQ_SA_L_W))])]
+   "ISA_HAS_DSP && !TARGET_64BIT"
+   "dpsq_sa.l.w\t%q0,%2,%3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmacsat")
+    (set_attr "mode"   "SI")])
+ ;; MAQ*
+@@ -608,7 +608,7 @@
+                       UNSPEC_MAQ_S_W_PHL))])]
+   "ISA_HAS_DSP && !TARGET_64BIT"
+   "maq_s.w.phl\t%q0,%2,%3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_maq_s_w_phr"
+@@ -623,7 +623,7 @@
+                       UNSPEC_MAQ_S_W_PHR))])]
+   "ISA_HAS_DSP && !TARGET_64BIT"
+   "maq_s.w.phr\t%q0,%2,%3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ ;; MAQ_SA*
+@@ -639,7 +639,7 @@
+                       UNSPEC_MAQ_SA_W_PHL))])]
+   "ISA_HAS_DSP && !TARGET_64BIT"
+   "maq_sa.w.phl\t%q0,%2,%3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmacsat")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_maq_sa_w_phr"
+@@ -654,7 +654,7 @@
+                       UNSPEC_MAQ_SA_W_PHR))])]
+   "ISA_HAS_DSP && !TARGET_64BIT"
+   "maq_sa.w.phr\t%q0,%2,%3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmacsat")
+    (set_attr "mode"   "SI")])
+ ;; Table 2-4. MIPS DSP ASE Instructions: General Bit/Manipulation
+@@ -665,7 +665,7 @@
+                  UNSPEC_BITREV))]
+   "ISA_HAS_DSP"
+   "bitrev\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; INSV
+@@ -678,7 +678,7 @@
+                  UNSPEC_INSV))]
+   "ISA_HAS_DSP"
+   "insv\t%0,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; REPL*
+@@ -696,7 +696,7 @@
+     }
+   return "replv.qb\t%0,%1";
+ }
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_repl_ph"
+@@ -707,7 +707,7 @@
+   "@
+    repl.ph\t%0,%1
+    replv.ph\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; Table 2-5. MIPS DSP ASE Instructions: Compare-Pick
+@@ -720,7 +720,7 @@
+                     UNSPEC_CMP_EQ))]
+   "ISA_HAS_DSP"
+   "cmp<DSPV:dspfmt1_1>.eq.<DSPV:dspfmt2>\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_cmp<DSPV:dspfmt1_1>_lt_<DSPV:dspfmt2>"
+@@ -731,7 +731,7 @@
+                     UNSPEC_CMP_LT))]
+   "ISA_HAS_DSP"
+   "cmp<DSPV:dspfmt1_1>.lt.<DSPV:dspfmt2>\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_cmp<DSPV:dspfmt1_1>_le_<DSPV:dspfmt2>"
+@@ -742,7 +742,7 @@
+                     UNSPEC_CMP_LE))]
+   "ISA_HAS_DSP"
+   "cmp<DSPV:dspfmt1_1>.le.<DSPV:dspfmt2>\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_cmpgu_eq_qb"
+@@ -752,7 +752,7 @@
+                  UNSPEC_CMPGU_EQ_QB))]
+   "ISA_HAS_DSP"
+   "cmpgu.eq.qb\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_cmpgu_lt_qb"
+@@ -762,7 +762,7 @@
+                  UNSPEC_CMPGU_LT_QB))]
+   "ISA_HAS_DSP"
+   "cmpgu.lt.qb\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_cmpgu_le_qb"
+@@ -772,7 +772,7 @@
+                  UNSPEC_CMPGU_LE_QB))]
+   "ISA_HAS_DSP"
+   "cmpgu.le.qb\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; PICK*
+@@ -784,7 +784,7 @@
+                    UNSPEC_PICK))]
+   "ISA_HAS_DSP"
+   "pick.<DSPV:dspfmt2>\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; PACKRL*
+@@ -795,7 +795,7 @@
+                    UNSPEC_PACKRL_PH))]
+   "ISA_HAS_DSP"
+   "packrl.ph\t%0,%1,%2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; Table 2-6. MIPS DSP ASE Instructions: Accumulator and DSPControl Access
+@@ -818,7 +818,7 @@
+     }
+   return "extrv.w\t%0,%q1,%2";
+ }
+-  [(set_attr "type"   "mfhilo")
++  [(set_attr "type"   "accext")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_extr_r_w"
+@@ -839,7 +839,7 @@
+     }
+   return "extrv_r.w\t%0,%q1,%2";
+ }
+-  [(set_attr "type"   "mfhilo")
++  [(set_attr "type"   "accext")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_extr_rs_w"
+@@ -860,7 +860,7 @@
+     }
+   return "extrv_rs.w\t%0,%q1,%2";
+ }
+-  [(set_attr "type"   "mfhilo")
++  [(set_attr "type"   "accext")
+    (set_attr "mode"   "SI")])
+ ;; EXTR*_S.H
+@@ -882,7 +882,7 @@
+     }
+   return "extrv_s.h\t%0,%q1,%2";
+ }
+-  [(set_attr "type"   "mfhilo")
++  [(set_attr "type"   "accext")
+    (set_attr "mode"   "SI")])
+ ;; EXTP*
+@@ -905,7 +905,7 @@
+     }
+   return "extpv\t%0,%q1,%2";
+ }
+-  [(set_attr "type"   "mfhilo")
++  [(set_attr "type"   "accext")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_extpdp"
+@@ -930,7 +930,7 @@
+     }
+   return "extpdpv\t%0,%q1,%2";
+ }
+-  [(set_attr "type"   "mfhilo")
++  [(set_attr "type"   "accext")
+    (set_attr "mode"   "SI")])
+ ;; SHILO*
+@@ -949,7 +949,7 @@
+     }
+   return "shilov\t%q0,%2";
+ }
+-  [(set_attr "type"   "mfhilo")
++  [(set_attr "type"   "accmod")
+    (set_attr "mode"   "SI")])
+ ;; MTHLIP*
+@@ -965,7 +965,7 @@
+                        (reg:CCDSP CCDSP_PO_REGNUM)] UNSPEC_MTHLIP))])]
+   "ISA_HAS_DSP && !TARGET_64BIT"
+   "mthlip\t%2,%q0"
+-  [(set_attr "type"   "mfhilo")
++  [(set_attr "type"   "accmod")
+    (set_attr "mode"   "SI")])
+ ;; WRDSP
+@@ -987,7 +987,7 @@
+         (unspec:CCDSP [(match_dup 0) (match_dup 1)] UNSPEC_WRDSP))])]
+   "ISA_HAS_DSP"
+   "wrdsp\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; RDDSP
+@@ -1003,7 +1003,7 @@
+                  UNSPEC_RDDSP))]
+   "ISA_HAS_DSP"
+   "rddsp\t%0,%1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ ;; Table 2-7. MIPS DSP ASE Instructions: Indexed-Load
+--- a/gcc/config/mips/mips-dspr2.md
++++ b/gcc/config/mips/mips-dspr2.md
+@@ -9,7 +9,7 @@
+         (unspec:CCDSP [(match_dup 1)] UNSPEC_ABSQ_S_QB))])]
+   "ISA_HAS_DSPR2"
+   "absq_s.qb\t%0,%z1"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalusat")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_addu_ph"
+@@ -21,7 +21,7 @@
+         (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDU_PH))])]
+   "ISA_HAS_DSPR2"
+   "addu.ph\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_addu_s_ph"
+@@ -34,7 +34,7 @@
+         (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDU_S_PH))])]
+   "ISA_HAS_DSPR2"
+   "addu_s.ph\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalusat")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_adduh_qb"
+@@ -44,7 +44,7 @@
+                    UNSPEC_ADDUH_QB))]
+   "ISA_HAS_DSPR2"
+   "adduh.qb\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_adduh_r_qb"
+@@ -54,7 +54,7 @@
+                    UNSPEC_ADDUH_R_QB))]
+   "ISA_HAS_DSPR2"
+   "adduh_r.qb\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalusat")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_append"
+@@ -69,7 +69,7 @@
+     operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
+   return "append\t%0,%z2,%3";
+ }
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_balign"
+@@ -84,7 +84,7 @@
+     operands[2] = GEN_INT (INTVAL (operands[2]) & 3);
+   return "balign\t%0,%z2,%3";
+ }
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_cmpgdu_eq_qb"
+@@ -99,7 +99,7 @@
+                       UNSPEC_CMPGDU_EQ_QB))])]
+   "ISA_HAS_DSPR2"
+   "cmpgdu.eq.qb\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_cmpgdu_lt_qb"
+@@ -114,7 +114,7 @@
+                       UNSPEC_CMPGDU_LT_QB))])]
+   "ISA_HAS_DSPR2"
+   "cmpgdu.lt.qb\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_cmpgdu_le_qb"
+@@ -129,7 +129,7 @@
+                       UNSPEC_CMPGDU_LE_QB))])]
+   "ISA_HAS_DSPR2"
+   "cmpgdu.le.qb\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_dpa_w_ph"
+@@ -140,7 +140,7 @@
+                  UNSPEC_DPA_W_PH))]
+   "ISA_HAS_DSPR2 && !TARGET_64BIT"
+   "dpa.w.ph\t%q0,%z2,%z3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_dps_w_ph"
+@@ -151,7 +151,7 @@
+                  UNSPEC_DPS_W_PH))]
+   "ISA_HAS_DSPR2 && !TARGET_64BIT"
+   "dps.w.ph\t%q0,%z2,%z3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ (define_expand "mips_madd<u>"
+@@ -247,7 +247,7 @@
+                  UNSPEC_MULSA_W_PH))]
+   "ISA_HAS_DSPR2 && !TARGET_64BIT"
+   "mulsa.w.ph\t%q0,%z2,%z3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_mult"
+@@ -277,7 +277,7 @@
+                    UNSPEC_PRECR_QB_PH))]
+   "ISA_HAS_DSPR2"
+   "precr.qb.ph\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_precr_sra_ph_w"
+@@ -292,7 +292,7 @@
+     operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
+   return "precr_sra.ph.w\t%0,%z2,%3";
+ }
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_precr_sra_r_ph_w"
+@@ -307,7 +307,7 @@
+     operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
+   return "precr_sra_r.ph.w\t%0,%z2,%3";
+ }
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_prepend"
+@@ -322,7 +322,7 @@
+     operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
+   return "prepend\t%0,%z2,%3";
+ }
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_shra_qb"
+@@ -340,7 +340,7 @@
+     }
+   return "shrav.qb\t%0,%z1,%2";
+ }
+-  [(set_attr "type"   "shift")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+@@ -359,7 +359,7 @@
+     }
+   return "shrav_r.qb\t%0,%z1,%2";
+ }
+-  [(set_attr "type"   "shift")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_shrl_ph"
+@@ -377,7 +377,7 @@
+     }
+   return "shrlv.ph\t%0,%z1,%2";
+ }
+-  [(set_attr "type"   "shift")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_subu_ph"
+@@ -390,7 +390,7 @@
+         (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_SUBU_PH))])]
+   "ISA_HAS_DSPR2"
+   "subu.ph\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_subu_s_ph"
+@@ -403,7 +403,7 @@
+         (unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_SUBU_S_PH))])]
+   "ISA_HAS_DSPR2"
+   "subu_s.ph\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalusat")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_subuh_qb"
+@@ -413,7 +413,7 @@
+                    UNSPEC_SUBUH_QB))]
+   "ISA_HAS_DSPR2"
+   "subuh.qb\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_subuh_r_qb"
+@@ -423,7 +423,7 @@
+                    UNSPEC_SUBUH_R_QB))]
+   "ISA_HAS_DSPR2"
+   "subuh_r.qb\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_addqh_ph"
+@@ -433,7 +433,7 @@
+                    UNSPEC_ADDQH_PH))]
+   "ISA_HAS_DSPR2"
+   "addqh.ph\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_addqh_r_ph"
+@@ -443,7 +443,7 @@
+                    UNSPEC_ADDQH_R_PH))]
+   "ISA_HAS_DSPR2"
+   "addqh_r.ph\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_addqh_w"
+@@ -453,7 +453,7 @@
+                  UNSPEC_ADDQH_W))]
+   "ISA_HAS_DSPR2"
+   "addqh.w\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_addqh_r_w"
+@@ -463,7 +463,7 @@
+                  UNSPEC_ADDQH_R_W))]
+   "ISA_HAS_DSPR2"
+   "addqh_r.w\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_subqh_ph"
+@@ -473,7 +473,7 @@
+                    UNSPEC_SUBQH_PH))]
+   "ISA_HAS_DSPR2"
+   "subqh.ph\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_subqh_r_ph"
+@@ -483,7 +483,7 @@
+                    UNSPEC_SUBQH_R_PH))]
+   "ISA_HAS_DSPR2"
+   "subqh_r.ph\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_subqh_w"
+@@ -493,7 +493,7 @@
+                  UNSPEC_SUBQH_W))]
+   "ISA_HAS_DSPR2"
+   "subqh.w\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_subqh_r_w"
+@@ -503,7 +503,7 @@
+                  UNSPEC_SUBQH_R_W))]
+   "ISA_HAS_DSPR2"
+   "subqh_r.w\t%0,%z1,%z2"
+-  [(set_attr "type"   "arith")
++  [(set_attr "type"   "dspalu")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_dpax_w_ph"
+@@ -514,7 +514,7 @@
+                  UNSPEC_DPAX_W_PH))]
+   "ISA_HAS_DSPR2 && !TARGET_64BIT"
+   "dpax.w.ph\t%q0,%z2,%z3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_dpsx_w_ph"
+@@ -525,7 +525,7 @@
+                  UNSPEC_DPSX_W_PH))]
+   "ISA_HAS_DSPR2 && !TARGET_64BIT"
+   "dpsx.w.ph\t%q0,%z2,%z3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_dpaqx_s_w_ph"
+@@ -540,7 +540,7 @@
+                       UNSPEC_DPAQX_S_W_PH))])]
+   "ISA_HAS_DSPR2 && !TARGET_64BIT"
+   "dpaqx_s.w.ph\t%q0,%z2,%z3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_dpaqx_sa_w_ph"
+@@ -555,7 +555,7 @@
+                       UNSPEC_DPAQX_SA_W_PH))])]
+   "ISA_HAS_DSPR2 && !TARGET_64BIT"
+   "dpaqx_sa.w.ph\t%q0,%z2,%z3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmacsat")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_dpsqx_s_w_ph"
+@@ -570,7 +570,7 @@
+                       UNSPEC_DPSQX_S_W_PH))])]
+   "ISA_HAS_DSPR2 && !TARGET_64BIT"
+   "dpsqx_s.w.ph\t%q0,%z2,%z3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmac")
+    (set_attr "mode"   "SI")])
+ (define_insn "mips_dpsqx_sa_w_ph"
+@@ -585,5 +585,43 @@
+                       UNSPEC_DPSQX_SA_W_PH))])]
+   "ISA_HAS_DSPR2 && !TARGET_64BIT"
+   "dpsqx_sa.w.ph\t%q0,%z2,%z3"
+-  [(set_attr "type"   "imadd")
++  [(set_attr "type"   "dspmacsat")
++   (set_attr "mode"   "SI")])
++
++;; Convert  mtlo $ac[1-3],$0  =>  mult $ac[1-3],$0,$0
++;;          mthi $ac[1-3],$0
++(define_peephole2
++  [(set (match_operand:SI 0 "register_operand" "")
++      (const_int 0))
++   (set (match_operand:SI 1 "register_operand" "")
++      (const_int 0))]
++  "ISA_HAS_DSPR2
++   && !TARGET_MIPS16
++   && !TARGET_64BIT
++   && (((true_regnum (operands[0]) == AC1LO_REGNUM
++                   && true_regnum (operands[1]) == AC1HI_REGNUM)
++      || (true_regnum (operands[0]) == AC1HI_REGNUM
++                      && true_regnum (operands[1]) == AC1LO_REGNUM))
++       || ((true_regnum (operands[0]) == AC2LO_REGNUM
++                      && true_regnum (operands[1]) == AC2HI_REGNUM)
++         || (true_regnum (operands[0]) == AC2HI_REGNUM
++                      && true_regnum (operands[1]) == AC2LO_REGNUM))
++       || ((true_regnum (operands[0]) == AC3LO_REGNUM
++                   && true_regnum (operands[1]) == AC3HI_REGNUM)
++         || (true_regnum (operands[0]) == AC3HI_REGNUM
++                         && true_regnum (operands[1]) == AC3LO_REGNUM)))"
++  [(parallel [(set (match_dup 0) (const_int 0))
++            (set (match_dup 1) (const_int 0))])]
++)
++
++(define_insn "*mips_acc_init"
++  [(parallel [(set (match_operand:SI 0 "register_operand" "=a")
++            (const_int 0))
++            (set (match_operand:SI 1 "register_operand" "=a")
++            (const_int 0))])]
++  "ISA_HAS_DSPR2
++   && !TARGET_MIPS16
++   && !TARGET_64BIT"
++  "mult\t%q0,$0,$0\t\t# Clear ACC HI/LO"
++  [(set_attr "type"   "imul")
+    (set_attr "mode"   "SI")])
+--- a/gcc/config/mips/mips-protos.h
++++ b/gcc/config/mips/mips-protos.h
+@@ -177,6 +177,8 @@ extern rtx mips_emit_move (rtx, rtx);
+ extern bool mips_split_symbol (rtx, rtx, enum machine_mode, rtx *);
+ extern rtx mips_unspec_address (rtx, enum mips_symbol_type);
+ extern bool mips_legitimize_address (rtx *, enum machine_mode);
++extern int mask_low_and_shift_len (enum machine_mode, unsigned HOST_WIDE_INT,
++                                 unsigned HOST_WIDE_INT);
+ extern void mips_move_integer (rtx, rtx, unsigned HOST_WIDE_INT);
+ extern bool mips_legitimize_move (enum machine_mode, rtx, rtx);
+@@ -239,6 +241,8 @@ extern void mips_print_operand_address (
+ extern void mips_output_external (FILE *, tree, const char *);
+ extern void mips_output_filename (FILE *, const char *);
+ extern void mips_output_ascii (FILE *, const char *, size_t);
++extern void octeon_output_shared_variable (FILE *, tree, const char *,
++                                         unsigned HOST_WIDE_INT, int);
+ extern void mips_output_aligned_decl_common (FILE *, tree, const char *,
+                                            unsigned HOST_WIDE_INT,
+                                            unsigned int);
+@@ -283,14 +287,18 @@ extern unsigned int mips_hard_regno_nreg
+ extern bool mips_linked_madd_p (rtx, rtx);
+ extern bool mips_store_data_bypass_p (rtx, rtx);
+ extern rtx mips_prefetch_cookie (rtx, rtx);
++extern int mips_mult_madd_chain_bypass_p (rtx, rtx);
++extern int mips_dspalu_bypass_p (rtx, rtx);
+ extern void irix_asm_output_align (FILE *, unsigned);
+ extern const char *current_section_name (void);
+ extern unsigned int current_section_flags (void);
+ extern bool mips_use_ins_ext_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
++extern void mips_adjust_register_ext_operands (rtx *);
+ extern const char *mips16e_output_save_restore (rtx, HOST_WIDE_INT);
+ extern bool mips16e_save_restore_pattern_p (rtx, HOST_WIDE_INT,
+                                           struct mips16e_save_restore_info *);
++extern void mips_expand_vector_init (rtx, rtx);
+ #endif /* ! GCC_MIPS_PROTOS_H */
+--- a/gcc/config/mips/mips.c
++++ b/gcc/config/mips/mips.c
+@@ -232,6 +232,8 @@ static const char *const mips_fp_conditi
+   MIPS_FP_CONDITIONS (STRINGIFY)
+ };
++static rtx mips_gnu_local_gp (void);
++
+ /* Information about a function's frame layout.  */
+ struct mips_frame_info GTY(()) {
+   /* The size of the frame in bytes.  */
+@@ -455,6 +457,10 @@ static int mips_base_align_functions; /*
+ /* The -mcode-readable setting.  */
+ enum mips_code_readable_setting mips_code_readable = CODE_READABLE_YES;
++/* If size of stack frame exceeds this value, compiler will emit
++   warning message.  */
++static HOST_WIDE_INT mips_warn_framesize = -1;
++
+ /* Index [M][R] is true if register R is allowed to hold a value of mode M.  */
+ bool mips_hard_regno_mode_ok[(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
+@@ -497,7 +503,7 @@ const enum reg_class mips_regno_to_class
+   MD0_REG,    MD1_REG,        NO_REGS,        ST_REGS,
+   ST_REGS,    ST_REGS,        ST_REGS,        ST_REGS,
+   ST_REGS,    ST_REGS,        ST_REGS,        NO_REGS,
+-  NO_REGS,    ALL_REGS,       ALL_REGS,       NO_REGS,
++  NO_REGS,    FRAME_REGS,     FRAME_REGS,     NO_REGS,
+   COP0_REGS,  COP0_REGS,      COP0_REGS,      COP0_REGS,
+   COP0_REGS,  COP0_REGS,      COP0_REGS,      COP0_REGS,
+   COP0_REGS,  COP0_REGS,      COP0_REGS,      COP0_REGS,
+@@ -527,9 +533,16 @@ const enum reg_class mips_regno_to_class
+   ALL_REGS,   ALL_REGS,       ALL_REGS,       ALL_REGS
+ };
++#ifdef CVMX_SHARED_BSS_FLAGS
++static tree octeon_handle_cvmx_shared_attribute (tree *, tree, tree, int, bool *);
++#endif
++
+ /* The value of TARGET_ATTRIBUTE_TABLE.  */
+ const struct attribute_spec mips_attribute_table[] = {
+   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
++#ifdef CVMX_SHARED_BSS_FLAGS
++  { "cvmx_shared", 0, 0, true, false, false, octeon_handle_cvmx_shared_attribute },
++#endif
+   { "long_call",   0, 0, false, true,  true,  NULL },
+   { "far",               0, 0, false, true,  true,  NULL },
+   { "near",        0, 0, false, true,  true,  NULL },
+@@ -642,6 +655,9 @@ static const struct mips_cpu_info mips_c
+   { "sb1", PROCESSOR_SB1, 64, PTF_AVOID_BRANCHLIKELY },
+   { "sb1a", PROCESSOR_SB1A, 64, PTF_AVOID_BRANCHLIKELY },
+   { "sr71000", PROCESSOR_SR71000, 64, PTF_AVOID_BRANCHLIKELY },
++  { "xlr", PROCESSOR_XLR, 64, 0 },
++  { "octeon", PROCESSOR_OCTEON, 64, 0 },
++  { "ice9", PROCESSOR_5KF, 64 }, /* May diverge from 5kf in future. */
+ };
+ /* Default costs.  If these are used for a processor we should look
+@@ -1006,6 +1022,26 @@ static const struct mips_rtx_cost_data m
+   { /* SR71000 */
+     DEFAULT_COSTS
+   },
++  { /* OCTEON */
++    SOFT_FP_COSTS,
++    /* Increase the latency values (5, 72) by 10% because MULT and
++       DIV are no fully pipelined.  */
++    COSTS_N_INSNS (6),            /* int_mult_si */
++    COSTS_N_INSNS (6),            /* int_mult_di */
++    COSTS_N_INSNS (80),           /* int_div_si */
++    COSTS_N_INSNS (80),           /* int_div_di */
++                   1,           /* branch_cost */
++                     4            /* memory_latency */
++  },
++  { /* XLR */
++    SOFT_FP_COSTS,
++    COSTS_N_INSNS (8),            /* int_mult_si */
++    COSTS_N_INSNS (8),            /* int_mult_di */
++    COSTS_N_INSNS (72),           /* int_div_si */
++    COSTS_N_INSNS (72),           /* int_div_di */
++                   1,           /* branch_cost */
++                   4            /* memory_latency */
++  }
+ };
\f
+ /* This hash table keeps track of implicit "mips16" and "nomips16" attributes
+@@ -1213,7 +1249,29 @@ mips_split_plus (rtx x, rtx *base_ptr, H
+ static unsigned int mips_build_integer (struct mips_integer_op *,
+                                       unsigned HOST_WIDE_INT);
+-/* A subroutine of mips_build_integer, with the same interface.
++/* See whether:
++
++      (and:MODE (ashift:MODE X SHIFT) MASK)
++
++   would have the effect of masking the low N bits of X and then shifting
++   the result left SHIFT bits.  Return N if so, otherwise return -1.  */
++
++int
++mask_low_and_shift_len (enum machine_mode mode,
++                      unsigned HOST_WIDE_INT shift,
++                      unsigned HOST_WIDE_INT mask)
++{
++  if (shift >= GET_MODE_BITSIZE (mode))
++    return -1;
++
++  /* Undo the CONST_INT sign-extension canonicalisation.  */
++  mask &= GET_MODE_MASK (mode);
++
++  /* We don't care about the low SHIFT bits of MASK.  */
++  return exact_log2 ((mask >> shift) + 1);
++}
++
++/* Subroutine of mips_build_integer (with the same interface).
+    Assume that the final action in the sequence should be a left shift.  */
+ static unsigned int
+@@ -1390,7 +1448,7 @@ mips_classify_symbol (const_rtx x, enum 
+       if (TARGET_MIPS16_SHORT_JUMP_TABLES)
+       return SYMBOL_PC_RELATIVE;
+-      if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS)
++      if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS && flag_pic)
+       return SYMBOL_GOT_PAGE_OFST;
+       return SYMBOL_ABSOLUTE;
+@@ -1413,14 +1471,16 @@ mips_classify_symbol (const_rtx x, enum 
+       return SYMBOL_GP_RELATIVE;
+     }
+-  /* Do not use small-data accesses for weak symbols; they may end up
+-     being zero.  */
+-  if (TARGET_GPOPT && SYMBOL_REF_SMALL_P (x) && !SYMBOL_REF_WEAK (x))
++  /* Use a small-data access if appropriate; but do not use small-data
++     accesses for weak symbols; they may end up being zero.  */
++  if (TARGET_GPOPT
++      && SYMBOL_REF_SMALL_P (x)
++      && !SYMBOL_REF_WEAK (x))
+     return SYMBOL_GP_RELATIVE;
+-  /* Don't use GOT accesses for locally-binding symbols when -mno-shared
+-     is in effect.  */
+-  if (TARGET_ABICALLS
++  /* Don't use GOT accesses when compiling for the non-PIC ABI,
++     or for locally-binding symbols when -mno-shared is in effect.  */
++  if (TARGET_ABICALLS && flag_pic
+       && !(TARGET_ABSOLUTE_ABICALLS && mips_symbol_binds_local_p (x)))
+     {
+       /* There are three cases to consider:
+@@ -1800,6 +1860,24 @@ mips_valid_base_register_p (rtx x, enum 
+         && mips_regno_mode_ok_for_base_p (REGNO (x), mode, strict_p));
+ }
++/* Return true if, for every base register BASE_REG, (plus BASE_REG X)
++   can address a value of mode MODE.  */
++
++static bool
++mips_valid_offset_p (rtx x, enum machine_mode mode)
++{
++  /* Check that X is a signed 16-bit number.  */
++  if (!const_arith_operand (x, Pmode))
++    return false;
++
++  /* We may need to split multiword moves, so make sure that every word
++     is accessible.  */
++  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
++      && !SMALL_OPERAND (INTVAL (x) + GET_MODE_SIZE (mode) - UNITS_PER_WORD))
++    return false;
++
++  return true;
++}
+ /* Return true if X is a valid address for machine mode MODE.  If it is,
+    fill in INFO appropriately.  STRICT_P is true if REG_OK_STRICT is in
+    effect.  */
+@@ -2175,7 +2253,9 @@ gen_load_const_gp (rtx reg)
+ /* Return a pseudo register that contains the value of $gp throughout
+    the current function.  Such registers are needed by MIPS16 functions,
+-   for which $gp itself is not a valid base register or addition operand.  */
++   for which $gp itself is not a valid base register or addition operand.
++   Also hold the GP in a non-PIC abicalls function which refers to TLS
++   data - such functions do not require $28 or even a hard register.  */
+ static rtx
+ mips16_gp_pseudo_reg (void)
+@@ -2191,7 +2271,11 @@ mips16_gp_pseudo_reg (void)
+     {
+       rtx insn, scan, after;
+-      insn = gen_load_const_gp (cfun->machine->mips16_gp_pseudo_rtx);
++      if (TARGET_NONPIC_ABICALLS)
++      insn = gen_loadgp_nonpic (cfun->machine->mips16_gp_pseudo_rtx,
++                                mips_gnu_local_gp ());
++      else
++      insn = gen_load_const_gp (cfun->machine->mips16_gp_pseudo_rtx);
+       push_topmost_sequence ();
+       /* We need to emit the initialization after the FUNCTION_BEG
+@@ -2333,6 +2417,19 @@ mips_add_offset (rtx temp, rtx reg, HOST
+   return plus_constant (reg, offset);
+ }
\f
++/* Return the RTX to use for explicit GOT accesses.  Uses a pseudo if
++   possible.  */
++
++static rtx
++mips_got_base (void)
++{
++  gcc_assert (can_create_pseudo_p ());
++  if (TARGET_NONPIC_ABICALLS)
++    return mips16_gp_pseudo_reg ();
++  else
++    return pic_offset_table_rtx;
++}
++
+ /* The __tls_get_attr symbol.  */
+ static GTY(()) rtx mips_tls_symbol;
+@@ -2356,7 +2453,7 @@ mips_call_tls_get_addr (rtx sym, enum mi
+   start_sequence ();
+   emit_insn (gen_rtx_SET (Pmode, a0,
+-                        gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, loc)));
++                        gen_rtx_LO_SUM (Pmode, mips_got_base (), loc)));
+   insn = mips_expand_call (v0, mips_tls_symbol, const0_rtx, const0_rtx, false);
+   CONST_OR_PURE_CALL_P (insn) = 1;
+   use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0);
+@@ -2435,9 +2532,9 @@ mips_legitimize_tls_address (rtx loc)
+       tmp1 = gen_reg_rtx (Pmode);
+       tmp2 = mips_unspec_address (loc, SYMBOL_GOTTPREL);
+       if (Pmode == DImode)
+-      emit_insn (gen_load_gotdi (tmp1, pic_offset_table_rtx, tmp2));
++      emit_insn (gen_load_gotdi (tmp1, mips_got_base (), tmp2));
+       else
+-      emit_insn (gen_load_gotsi (tmp1, pic_offset_table_rtx, tmp2));
++      emit_insn (gen_load_gotsi (tmp1, mips_got_base (), tmp2));
+       dest = gen_reg_rtx (Pmode);
+       emit_insn (gen_add3_insn (dest, tmp1, tp));
+       break;
+@@ -2464,7 +2561,7 @@ bool
+ mips_legitimize_address (rtx *xloc, enum machine_mode mode)
+ {
+   rtx base;
+-  HOST_WIDE_INT offset;
++  HOST_WIDE_INT intval, high, offset;
+   if (mips_tls_symbol_p (*xloc))
+     {
+@@ -2485,6 +2582,32 @@ mips_legitimize_address (rtx *xloc, enum
+       *xloc = mips_add_offset (NULL, base, offset);
+       return true;
+     }
++
++ /* Handle references to constant addresses by loading the high part
++    into a register and using an offset for the low part.  */
++ if (GET_CODE (base) == CONST_INT)
++   {
++     intval = INTVAL (base);
++     high = trunc_int_for_mode (CONST_HIGH_PART (intval), Pmode);
++     offset = CONST_LOW_PART (intval);
++     /* Ignore cases in which a positive address would be accessed by a
++       negative offset from a negative address.  The required wraparound
++       does not occur for 32-bit addresses on 64-bit targets, and it is
++       very unlikely that such an access would occur in real code anyway.
++
++       If the low offset is not legitimate for MODE, prefer to load
++       the constant normally, instead of using mips_force_address on
++       the legitimized address.  The latter option would cause us to
++       use (D)ADDIU unconditionally, but LUI/ORI is more efficient
++       than LUI/ADDIU on some targets.  */
++     if ((intval < 0 || high > 0)
++        && mips_valid_offset_p (GEN_INT (offset), mode))
++      {
++        base = mips_force_temporary (NULL, GEN_INT (high));
++        *xloc = plus_constant (base, offset);
++        return true;
++      }
++   }
+   return false;
+ }
+@@ -3360,6 +3483,27 @@ mips_rtx_costs (rtx x, int code, int out
+       return false;
+     case ZERO_EXTEND:
++      /* Check for BADDU patterns; see mips.md.  */
++      if (ISA_HAS_BADDU)
++      {
++        rtx op0 = XEXP (x, 0);
++        if ((GET_CODE (op0) == TRUNCATE || GET_CODE (op0) == SUBREG)
++            && GET_MODE (op0) == QImode
++            && GET_CODE (XEXP (op0, 0)) == PLUS)
++          {
++            rtx op1 = XEXP (XEXP (op0, 0), 0);
++            rtx op2 = XEXP (XEXP (op0, 0), 1);
++            if (GET_CODE (op1) == SUBREG
++                && GET_CODE (XEXP (op1, 0)) == TRUNCATE)
++              op1 = XEXP (XEXP (op1, 0), 0);
++            if (GET_CODE (op2) == SUBREG
++                && GET_CODE (XEXP (op2, 0)) == TRUNCATE)
++              op2 = XEXP (XEXP (op2, 0), 0);
++            *total =
++              COSTS_N_INSNS (1) + rtx_cost (op1, 0) + rtx_cost (op2, 0);
++            return true;
++          }
++      }
+       *total = mips_zero_extend_cost (mode, XEXP (x, 0));
+       return false;
+@@ -3869,6 +4013,30 @@ mips_emit_compare (enum rtx_code *code, 
+     }
+ }
\f
++/* If it is possible and profitable to use SEQ or SNE to compare a
++   register with OP, return the instruction's second source operand,
++   otherwise return null.  MODE is the mode of OP.  */
++
++static rtx
++mips_get_seq_sne_operand (enum machine_mode mode, rtx op)
++{
++  if (!ISA_HAS_SEQ_SNE)
++    return NULL;
++
++  if (reg_imm10_operand (op, mode))
++    return op;
++
++  /* If OP is in the range of either ADDIU or XORI, we could either
++     use those instructions and boolify the result, or move OP into a
++     register and use SEQ or SNE.  Prefer the former, because it is
++     better than the latter when a 0/1 result is not needed.  */
++  if (uns_arith_operand (op, mode)
++      || arith_operand (op, mode))
++    return NULL;
++
++  return force_reg (mode, op);
++}
++
+ /* Try comparing cmp_operands[0] and cmp_operands[1] using rtl code CODE.
+    Store the result in TARGET and return true if successful.
+@@ -3883,8 +4051,15 @@ mips_expand_scc (enum rtx_code code, rtx
+   target = gen_lowpart (GET_MODE (cmp_operands[0]), target);
+   if (code == EQ || code == NE)
+     {
+-      rtx zie = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]);
+-      mips_emit_binary (code, target, zie, const0_rtx);
++      rtx scc_operand = mips_get_seq_sne_operand (GET_MODE (cmp_operands[0]),
++                                                  cmp_operands[1]);
++      if (scc_operand)
++        mips_emit_binary (code, target, cmp_operands[0], scc_operand);
++      else
++        {
++          rtx zie = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]);
++          mips_emit_binary (code, target, zie, const0_rtx);
++      }
+     }
+   else
+     mips_emit_int_order_test (code, 0, target,
+@@ -5954,6 +6129,15 @@ mips_expand_ext_as_unaligned_load (rtx d
+   if (!mips_get_unaligned_mem (&src, width, bitpos, &left, &right))
+     return false;
++  if (ISA_HAS_UL_US)
++    {
++      if (GET_MODE (dest) == DImode)
++        emit_insn (gen_mov_uld (dest, src, left));
++      else
++        emit_insn (gen_mov_ulw (dest, src, left));
++      return true;
++    }
++
+   temp = gen_reg_rtx (GET_MODE (dest));
+   if (GET_MODE (dest) == DImode)
+     {
+@@ -5988,6 +6172,16 @@ mips_expand_ins_as_unaligned_store (rtx 
+   mode = mode_for_size (width, MODE_INT, 0);
+   src = gen_lowpart (mode, src);
++
++  if (ISA_HAS_UL_US)
++    {
++      if (GET_MODE (src) == DImode)
++        emit_insn (gen_mov_usd (dest, src, left));
++      else
++        emit_insn (gen_mov_usw (dest, src, left));
++      return true;
++    }
++
+   if (mode == DImode)
+     {
+       emit_insn (gen_mov_sdl (dest, src, left));
+@@ -6398,6 +6592,27 @@ mips_print_float_branch_condition (FILE 
+     }
+ }
++/* Likewise bit branches.  */
++
++static void
++mips_print_bit_branch_condition (FILE *file, enum rtx_code code, int letter)
++{
++  switch (code)
++    {
++    case EQ:
++      fputs ("bit0", file);
++      break;
++
++    case NE:
++      fputs ("bit1", file);
++      break;
++
++    default:
++      output_operand_lossage ("'%%%c' is not a valid operand prefix", letter);
++      break;
++    }
++}
++
+ /* Implement the PRINT_OPERAND macro.  The MIPS-specific operand codes are:
+    'X'        Print CONST_INT OP in hexadecimal format.
+@@ -6419,8 +6634,11 @@ mips_print_float_branch_condition (FILE 
+    'D'        Print the second part of a double-word register or memory operand.
+    'L'        Print the low-order register in a double-word register operand.
+    'M'        Print high-order register in a double-word register operand.
+-   'z'        Print $0 if OP is zero, otherwise print OP normally.  */
+-
++   'z'        Print $0 if OP is zero, otherwise print OP normally. 
++   'E'  substract 1 from the const_int value.
++   'G'  print part of opcode for a branch-bit condition.
++   'H'  print part of opcode for a branch-bit condition, inverted.  */
++   
+ void
+ mips_print_operand (FILE *file, rtx op, int letter)
+ {
+@@ -6518,6 +6736,23 @@ mips_print_operand (FILE *file, rtx op, 
+       output_operand_lossage ("invalid use of '%%%c'", letter);
+       break;
++    case 'E':
++      {
++      if (code != CONST_INT)
++        output_operand_lossage ("'%%E' misused");
++      fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op) - 1);
++      }
++      break;
++
++    case 'G':
++      mips_print_bit_branch_condition (file, code, letter);
++      break;
++
++    case 'H':
++      mips_print_bit_branch_condition (file, reverse_condition (code),
++                                       letter);
++      break;
++
+     default:
+       switch (code)
+       {
+@@ -6627,7 +6862,7 @@ mips_select_rtx_section (enum machine_mo
+ static section *
+ mips_function_rodata_section (tree decl)
+ {
+-  if (!TARGET_ABICALLS || TARGET_GPWORD)
++  if (!TARGET_ABICALLS || !flag_pic || TARGET_GPWORD)
+     return default_function_rodata_section (decl);
+   if (decl && DECL_SECTION_NAME (decl))
+@@ -6667,6 +6902,12 @@ mips_in_small_data_p (const_tree decl)
+   if (TARGET_ABICALLS || TARGET_VXWORKS_RTP)
+     return false;
++#ifdef CVMX_SHARED_BSS_FLAGS
++  if (TARGET_OCTEON && TREE_CODE (decl) == VAR_DECL
++      && lookup_attribute ("cvmx_shared", DECL_ATTRIBUTES (decl)))
++    return false;
++#endif
++
+   if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0)
+     {
+       const char *name;
+@@ -6845,6 +7086,26 @@ mips_output_filename (FILE *stream, cons
+     }
+ }
++/* Initialize vector TARGET to VALS.  */
++
++void
++mips_expand_vector_init (rtx target, rtx vals)
++{
++  enum machine_mode mode = GET_MODE (target);
++  enum machine_mode inner = GET_MODE_INNER (mode);
++  unsigned int i, n_elts = GET_MODE_NUNITS (mode);
++  rtx mem;
++
++  gcc_assert (VECTOR_MODE_P (mode));
++
++  mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
++  for (i = 0; i < n_elts; i++)
++    emit_move_insn (adjust_address_nv (mem, inner, i * GET_MODE_SIZE (inner)),
++                    XVECEXP (vals, 0, i));
++
++  emit_move_insn (target, mem);
++}
++
+ /* Implement TARGET_ASM_OUTPUT_DWARF_DTPREL.  */
+ static void ATTRIBUTE_UNUSED
+@@ -6893,6 +7154,37 @@ mips_dwarf_register_span (rtx reg)
+   return NULL_RTX;
+ }
++/* DSP ALU can bypass data with no delays for the following pairs. */
++enum insn_code dspalu_bypass_table[][2] =
++{
++  {CODE_FOR_mips_addsc, CODE_FOR_mips_addwc},
++  {CODE_FOR_mips_cmpu_eq_qb, CODE_FOR_mips_pick_qb},
++  {CODE_FOR_mips_cmpu_lt_qb, CODE_FOR_mips_pick_qb},
++  {CODE_FOR_mips_cmpu_le_qb, CODE_FOR_mips_pick_qb},
++  {CODE_FOR_mips_cmp_eq_ph, CODE_FOR_mips_pick_ph},
++  {CODE_FOR_mips_cmp_lt_ph, CODE_FOR_mips_pick_ph},
++  {CODE_FOR_mips_cmp_le_ph, CODE_FOR_mips_pick_ph},
++  {CODE_FOR_mips_wrdsp, CODE_FOR_mips_insv}
++};
++
++int
++mips_dspalu_bypass_p (rtx out_insn, rtx in_insn)
++{
++  int i;
++  int num_bypass = (sizeof (dspalu_bypass_table)
++                  / (2 * sizeof (enum insn_code)));
++  enum insn_code out_icode = INSN_CODE (out_insn);
++  enum insn_code in_icode = INSN_CODE (in_insn);
++
++  for (i = 0; i < num_bypass; i++)
++    {
++      if (out_icode == dspalu_bypass_table[i][0]
++        && in_icode == dspalu_bypass_table[i][1])
++       return true;
++    }
++
++  return false;
++}
+ /* Implement ASM_OUTPUT_ASCII.  */
+ void
+@@ -7117,16 +7409,26 @@ mips_file_start (void)
+                "\t.previous\n", TARGET_LONG64 ? 64 : 32);
+ #ifdef HAVE_AS_GNU_ATTRIBUTE
++#ifdef TARGET_MIPS_SDEMTK
++     fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
++             (!TARGET_NO_FLOAT
++              ? (TARGET_HARD_FLOAT
++                 ? (TARGET_DOUBLE_FLOAT
++                    ? ((!TARGET_64BIT && TARGET_FLOAT64) ? 4 : 1) : 2) : 3) : 0));
++#else
+       fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
+              (TARGET_HARD_FLOAT_ABI
+               ? (TARGET_DOUBLE_FLOAT
+                  ? ((!TARGET_64BIT && TARGET_FLOAT64) ? 4 : 1) : 2) : 3));
+ #endif
++#endif
+     }
+   /* If TARGET_ABICALLS, tell GAS to generate -KPIC code.  */
+   if (TARGET_ABICALLS)
+     fprintf (asm_out_file, "\t.abicalls\n");
++  if (TARGET_ABICALLS && !flag_pic)
++    fprintf (asm_out_file, "\t.option\tpic0\n");
+   if (flag_verbose_asm)
+     fprintf (asm_out_file, "\n%s -G value = %d, Arch = %s, ISA = %d\n",
+@@ -7617,6 +7919,7 @@ mips16e_output_save_restore (rtx pattern
+   return buffer;
+ }
\f
++
+ /* Return true if the current function has an insn that implicitly
+    refers to $gp.  */
+@@ -7631,6 +7934,7 @@ mips_function_has_gp_insn (void)
+       push_topmost_sequence ();
+       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+       if (USEFUL_INSN_P (insn)
++
+           && (get_attr_got (insn) != GOT_UNSET
+               || mips_small_data_pattern_p (PATTERN (insn))))
+         {
+@@ -7720,7 +8024,7 @@ mips_save_reg_p (unsigned int regno)
+ {
+   /* We only need to save $gp if TARGET_CALL_SAVED_GP and only then
+      if we have not chosen a call-clobbered substitute.  */
+-  if (regno == GLOBAL_POINTER_REGNUM)
++  if (regno == GLOBAL_POINTER_REGNUM && fixed_regs[regno])
+     return TARGET_CALL_SAVED_GP && cfun->machine->global_pointer == regno;
+   /* Check call-saved registers.  */
+@@ -7944,7 +8248,7 @@ mips_current_loadgp_style (void)
+   if (TARGET_RTP_PIC)
+     return LOADGP_RTP;
+-  if (TARGET_ABSOLUTE_ABICALLS)
++  if (TARGET_ABSOLUTE_ABICALLS || !flag_pic)
+     return LOADGP_ABSOLUTE;
+   return TARGET_NEWABI ? LOADGP_NEWABI : LOADGP_OLDABI;
+@@ -8059,9 +8363,10 @@ mips_restore_gp (void)
+ {
+   rtx base, address;
+-  gcc_assert (TARGET_ABICALLS && TARGET_OLDABI);
++  gcc_assert (TARGET_ABICALLS && TARGET_OLDABI && flag_pic);
+   base = frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx;
++
+   address = mips_add_offset (pic_offset_table_rtx, base,
+                            current_function_outgoing_args_size);
+   mips_emit_move (pic_offset_table_rtx, gen_frame_mem (Pmode, address));
+@@ -8312,7 +8617,18 @@ mips_save_reg (rtx reg, rtx mem)
+ /* The __gnu_local_gp symbol.  */
+-static GTY(()) rtx mips_gnu_local_gp;
++static GTY(()) rtx mips_gnu_local_gp_rtx;
++
++static rtx
++mips_gnu_local_gp (void)
++{
++  if (mips_gnu_local_gp_rtx == NULL)
++    {
++      mips_gnu_local_gp_rtx = gen_rtx_SYMBOL_REF (Pmode, "__gnu_local_gp");
++      SYMBOL_REF_FLAGS (mips_gnu_local_gp_rtx) |= SYMBOL_FLAG_LOCAL;
++    }
++  return mips_gnu_local_gp_rtx;
++}
+ /* If we're generating n32 or n64 abicalls, emit instructions
+    to set up the global pointer.  */
+@@ -8326,14 +8642,9 @@ mips_emit_loadgp (void)
+   switch (mips_current_loadgp_style ())
+     {
+     case LOADGP_ABSOLUTE:
+-      if (mips_gnu_local_gp == NULL)
+-      {
+-        mips_gnu_local_gp = gen_rtx_SYMBOL_REF (Pmode, "__gnu_local_gp");
+-        SYMBOL_REF_FLAGS (mips_gnu_local_gp) |= SYMBOL_FLAG_LOCAL;
+-      }
+       emit_insn (Pmode == SImode
+-               ? gen_loadgp_absolute_si (pic_reg, mips_gnu_local_gp)
+-               : gen_loadgp_absolute_di (pic_reg, mips_gnu_local_gp));
++               ? gen_loadgp_absolute_si (pic_reg, mips_gnu_local_gp ())
++               : gen_loadgp_absolute_di (pic_reg, mips_gnu_local_gp ()));
+       break;
+     case LOADGP_NEWABI:
+@@ -8490,7 +8801,7 @@ mips_expand_prologue (void)
+   mips_emit_loadgp ();
+   /* Initialize the $gp save slot.  */
+-  if (frame->cprestore_size > 0)
++  if (frame->cprestore_size > 0 && flag_pic )
+     emit_insn (gen_cprestore (GEN_INT (current_function_outgoing_args_size)));
+   /* If we are profiling, make sure no instructions are scheduled before
+@@ -8549,6 +8860,11 @@ mips_expand_epilogue (bool sibcall_p)
+   step1 = frame->total_size;
+   step2 = 0;
++  if (mips_warn_framesize >= 0
++      && step1 > mips_warn_framesize)
++    warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC " bytes", 
++           current_function_name (), step1);
++
+   /* Work out which register holds the frame address.  */
+   if (!frame_pointer_needed)
+     base = stack_pointer_rtx;
+@@ -9456,10 +9772,15 @@ mips_output_division (const char *divisi
+         s = "bnez\t%2,1f\n\tbreak\t7\n1:";
+       }
+       else if (GENERATE_DIVIDE_TRAPS)
+-        {
+-        output_asm_insn (s, operands);
+-        s = "teq\t%2,%.,7";
+-        }
++      {
++        if (TUNE_74K)
++          output_asm_insn ("teq\t%2,%.,7", operands);
++        else
++          {
++            output_asm_insn (s, operands);
++            s = "teq\t%2,%.,7";
++          }
++      }
+       else
+       {
+         output_asm_insn ("%(bne\t%2,%.,1f", operands);
+@@ -9552,6 +9873,7 @@ mips_issue_rate (void)
+     case PROCESSOR_R5500:
+     case PROCESSOR_R7000:
+     case PROCESSOR_R9000:
++    case PROCESSOR_OCTEON:
+       return 2;
+     case PROCESSOR_SB1:
+@@ -9577,6 +9899,11 @@ mips_multipass_dfa_lookahead (void)
+   if (TUNE_SB1)
+     return 4;
++  /* Because of the two pipelines we have at most two alternative
++     schedules on Octeon.  */
++  if (mips_tune == PROCESSOR_OCTEON)
++    return 2;
++
+   return 0;
+ }
\f
+@@ -9613,7 +9940,17 @@ mips_maybe_swap_ready (rtx *ready, int p
+       ready[pos2] = temp;
+     }
+ }
+-\f
++
++int
++mips_mult_madd_chain_bypass_p (rtx out_insn ATTRIBUTE_UNUSED,
++                             rtx in_insn ATTRIBUTE_UNUSED)
++{
++  if (reload_completed)
++    return false;
++  else
++    return true;
++}
++
+ /* Used by TUNE_MACC_CHAINS to record the last scheduled instruction
+    that may clobber hi or lo.  */
+ static rtx mips_macc_chains_last_hilo;
+@@ -11908,6 +12245,28 @@ mips_parse_cpu (const char *cpu_string)
+   return NULL;
+ }
++/* Prepare the extv/extzv operands in OPERANDS for a register extraction.
++   The problem here is that the extv interface always provides word_mode
++   register operands, even if the values were originally SImode.
++   We nevertheless want to use SImode operations for naturally-SImode
++   operands because SUBREGs are harder to optimize.  */
++
++void
++mips_adjust_register_ext_operands (rtx *operands)
++{
++  if (GET_CODE (operands[0]) == SUBREG
++      && GET_MODE (operands[0]) == DImode
++      && GET_CODE (operands[1]) == SUBREG
++      && GET_MODE (operands[1]) == DImode
++      && GET_MODE (SUBREG_REG (operands[0])) == SImode
++      && GET_MODE (SUBREG_REG (operands[1])) == SImode
++      && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
++    {
++      operands[0] = SUBREG_REG (operands[0]);
++      operands[1] = SUBREG_REG (operands[1]);
++    }
++}
++
+ /* Set up globals to generate code for the ISA or processor
+    described by INFO.  */
+@@ -11979,6 +12338,9 @@ mips_handle_option (size_t code, const c
+       return false;
+       return true;
++    case OPT_mwarn_framesize_:
++      return sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &mips_warn_framesize) == 1;
++
+     default:
+       return true;
+     }
+@@ -11995,10 +12357,6 @@ mips_override_options (void)
+   SUBTARGET_OVERRIDE_OPTIONS;
+ #endif
+-  /* Set the small data limit.  */
+-  mips_small_data_threshold = (g_switch_set
+-                             ? g_switch_value
+-                             : MIPS_DEFAULT_GVALUE);
+   /* The following code determines the architecture and register size.
+      Similar code was added to GAS 2.14 (see tc-mips.c:md_after_parse_args()).
+@@ -12088,6 +12446,10 @@ mips_override_options (void)
+   /* End of code shared with GAS.  */
++  /* The non-PIC ABI may only be used in conjunction with the o32 ABI.  */
++  if (TARGET_ABICALLS && !flag_pic && mips_abi != ABI_32)
++    sorry ("non-PIC abicalls may only be used with the o32 ABI");
++
+   /* If no -mlong* option was given, infer it from the other options.  */
+   if ((target_flags_explicit & MASK_LONG64) == 0)
+     {
+@@ -12136,23 +12498,21 @@ mips_override_options (void)
+       target_flags &= ~MASK_ABICALLS;
+     }
+-  /* MIPS16 cannot generate PIC yet.  */
++  /* MIPS16 cannot generate PIC or abicalls yet.  */
+   if (TARGET_MIPS16 && (flag_pic || TARGET_ABICALLS))
+     {
+-      sorry ("MIPS16 PIC");
++      sorry ("MIPS16 PIC or abicalls are not yet implemented");
+       target_flags &= ~MASK_ABICALLS;
+       flag_pic = flag_pie = flag_shlib = 0;
+     }
+-  if (TARGET_ABICALLS)
+-    /* We need to set flag_pic for executables as well as DSOs
+-       because we may reference symbols that are not defined in
+-       the final executable.  (MIPS does not use things like
+-       copy relocs, for example.)
+-
+-       Also, there is a body of code that uses __PIC__ to distinguish
+-       between -mabicalls and -mno-abicalls code.  */
+-    flag_pic = 1;
++  /* For SDE, switch on ABICALLS mode if -fpic or -fpie were used, and the
++     user hasn't explicitly disabled these modes.  */
++  if (TARGET_MIPS_SDE
++      && (flag_pic || flag_pie) && !TARGET_ABICALLS
++      && !((target_flags_explicit & MASK_ABICALLS))
++      && mips_abi != ABI_EABI)
++    target_flags |= MASK_ABICALLS;
+   /* -mvr4130-align is a "speed over size" optimization: it usually produces
+      faster code, but at the expense of more nops.  Enable it at -O3 and
+@@ -12167,6 +12527,11 @@ mips_override_options (void)
+   /* If we have a nonzero small-data limit, check that the -mgpopt
+      setting is consistent with the other target flags.  */
++
++  /* Set the small data limit.  */
++  mips_small_data_threshold = (g_switch_set
++                             ? g_switch_value
++                             : MIPS_DEFAULT_GVALUE);
+   if (mips_small_data_threshold > 0)
+     {
+       if (!TARGET_GPOPT)
+@@ -12262,6 +12627,10 @@ mips_override_options (void)
+   /* Function to allocate machine-dependent function status.  */
+   init_machine_status = &mips_init_machine_status;
++  /* __thread_support is not supported by uClibc.  */
++  if (building_for_uclibc)
++    targetm.have_tls = 0;
++
+   /* Default to working around R4000 errata only if the processor
+      was selected explicitly.  */
+   if ((target_flags_explicit & MASK_FIX_R4000) == 0
+@@ -12314,18 +12683,24 @@ mips_swap_registers (unsigned int i)
+ #undef SWAP_STRING
+ #undef SWAP_INT
+ }
+-
+-/* Implement CONDITIONAL_REGISTER_USAGE.  */
+-
+ void
+ mips_conditional_register_usage (void)
+ {
++
++  /* These DSP control register fields are global.  */
++  if (ISA_HAS_DSP)
++    {
++      global_regs[CCDSP_PO_REGNUM] = 1;
++      global_regs[CCDSP_SC_REGNUM] = 1;
++    }
+   if (!ISA_HAS_DSP)
+     {
+       int regno;
+       for (regno = DSP_ACC_REG_FIRST; regno <= DSP_ACC_REG_LAST; regno++)
+       fixed_regs[regno] = call_used_regs[regno] = 1;
++      for (regno = DSP_CTRL_REG_FIRST; regno <= DSP_CTRL_REG_LAST; regno++)
++      fixed_regs[regno] = call_used_regs[regno] = 1;
+     }
+   if (!TARGET_HARD_FLOAT)
+     {
+@@ -12387,6 +12762,24 @@ mips_conditional_register_usage (void)
+       for (regno = DSP_ACC_REG_FIRST; regno <= DSP_ACC_REG_LAST; regno += 2)
+       mips_swap_registers (regno);
+     }
++  /* In non-PIC abicalls, $gp is completely ordinary; we can use a pseudo
++     for TLS GOT entries.  */
++  if (TARGET_NONPIC_ABICALLS)
++    {
++      call_used_regs[GLOBAL_POINTER_REGNUM] = TARGET_OLDABI;
++      call_really_used_regs[GLOBAL_POINTER_REGNUM] = TARGET_OLDABI;
++      fixed_regs[GLOBAL_POINTER_REGNUM] = 0;
++    }
++  /* $f30 is reserved for errata workarounds in ICE9A.  */
++  if (TARGET_FIX_ICE9A)
++    {
++      const int f30 = FP_REG_FIRST + 30;
++      const int f31 = FP_REG_FIRST + 31;
++
++      fixed_regs[f30] = call_really_used_regs[f30] = call_used_regs[f30] = 1;
++      if (MAX_FPRS_PER_FMT == 2)
++      fixed_regs[f31] = call_really_used_regs[f31] = call_used_regs[f31] = 1;
++    }
+ }
+ /* When generating MIPS16 code, we want to allocate $24 (T_REG) before
+@@ -12411,6 +12804,153 @@ mips_order_regs_for_local_alloc (void)
+     }
+ }
\f
++#ifdef CVMX_SHARED_BSS_FLAGS
++/* Handle a "cvmx_shared" attribute; arguments as in 
++   struct attribute_spec.handler.  */
++
++static tree
++octeon_handle_cvmx_shared_attribute (tree *node, tree name, 
++                                   tree args ATTRIBUTE_UNUSED, 
++                                   int flags ATTRIBUTE_UNUSED, 
++                                   bool *no_add_attrs)
++{
++  if (TREE_CODE (*node) != VAR_DECL)
++    {
++      warning (OPT_Wattributes, "%qs attribute only applies to variables",
++              IDENTIFIER_POINTER (name));
++      *no_add_attrs = true;
++    }
++
++  return NULL_TREE;
++}
++\f
++/* Switch to the appropriate section for output of DECL.
++   DECL is either a `VAR_DECL' node or a constant of some sort.
++   RELOC indicates whether forming the initial value of DECL requires
++   link-time relocations.  */
++
++static section *
++octeon_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
++{
++  if (decl && TREE_CODE (decl) == VAR_DECL 
++      && lookup_attribute ("cvmx_shared", DECL_ATTRIBUTES (decl)))
++    {
++      const char *sname = NULL;
++      unsigned int flags = SECTION_WRITE;
++
++      switch (categorize_decl_for_section (decl, reloc))
++        {
++        case SECCAT_DATA:
++        case SECCAT_SDATA:
++        case SECCAT_RODATA:
++        case SECCAT_SRODATA:
++        case SECCAT_RODATA_MERGE_STR:
++        case SECCAT_RODATA_MERGE_STR_INIT:
++        case SECCAT_RODATA_MERGE_CONST:
++        case SECCAT_DATA_REL:
++        case SECCAT_DATA_REL_LOCAL:
++        case SECCAT_DATA_REL_RO:
++        case SECCAT_DATA_REL_RO_LOCAL:
++          sname = ".cvmx_shared";
++          break;
++        case SECCAT_BSS:
++        case SECCAT_SBSS:
++          sname = ".cvmx_shared_bss";
++          flags |= SECTION_BSS;
++          break;
++        case SECCAT_TEXT:
++        case SECCAT_TDATA:
++        case SECCAT_TBSS:
++            break;
++        }
++      if (sname)
++      {
++        return get_section (sname, flags, decl);
++      }
++    }
++  return default_elf_select_section (decl, reloc, align);
++}
++\f
++/* Build up a unique section name, expressed as a
++   STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
++   RELOC indicates whether the initial value of EXP requires
++   link-time relocations.  */
++
++static void 
++octeon_unique_section (tree decl, int reloc)
++{
++  if (decl && TREE_CODE (decl) == VAR_DECL 
++      && lookup_attribute ("cvmx_shared", DECL_ATTRIBUTES (decl)))
++    {
++      const char *sname = NULL;
++
++      if (! DECL_ONE_ONLY (decl))
++      {
++        section *sect;
++        sect = octeon_select_section (decl, reloc, DECL_ALIGN (decl));
++        DECL_SECTION_NAME (decl) = build_string (strlen (sect->named.name),
++                                                 sect->named.name);
++        return;
++      }
++
++      switch (categorize_decl_for_section (decl, reloc))
++        {
++        case SECCAT_BSS:
++        case SECCAT_SBSS:
++          sname = ".cvmx_shared_bss.linkonce."; 
++          break;
++        case SECCAT_SDATA:
++        case SECCAT_DATA:
++        case SECCAT_DATA_REL:
++        case SECCAT_DATA_REL_LOCAL:
++        case SECCAT_DATA_REL_RO:
++        case SECCAT_DATA_REL_RO_LOCAL:
++        case SECCAT_RODATA:
++        case SECCAT_SRODATA:
++        case SECCAT_RODATA_MERGE_STR:
++        case SECCAT_RODATA_MERGE_STR_INIT:
++        case SECCAT_RODATA_MERGE_CONST:
++          sname = ".cvmx_shared.linkonce.";
++          break;
++        case SECCAT_TEXT:
++        case SECCAT_TDATA:
++        case SECCAT_TBSS:
++          break; 
++      }
++      if (sname)
++        {
++        const char *name;
++        size_t plen, nlen;
++        char *string;
++        plen = strlen (sname);
++
++        name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
++        name = targetm.strip_name_encoding (name);
++        nlen = strlen (name);
++
++        string = alloca (plen + nlen + 1);
++        memcpy (string, sname, plen);
++        memcpy (string + plen, name, nlen + 1);
++        DECL_SECTION_NAME (decl) = build_string (nlen + plen, string);
++        return;
++        }
++    }
++  default_unique_section (decl, reloc);
++}
++\f
++/* Emit an uninitialized cvmx_shared variable.  */
++void
++octeon_output_shared_variable (FILE *stream, tree decl, const char *name,
++                               unsigned HOST_WIDE_INT size, int align)
++{
++  switch_to_section (get_section (".cvmx_shared_bss", CVMX_SHARED_BSS_FLAGS,
++                                NULL_TREE));
++  ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
++  ASM_DECLARE_OBJECT_NAME (stream, name, decl);
++  ASM_OUTPUT_SKIP (stream, size != 0 ? size : 1);
++}
++#endif
++\f
+ /* Initialize the GCC target structure.  */
+ #undef TARGET_ASM_ALIGNED_HI_OP
+ #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
+@@ -12571,6 +13111,7 @@ mips_order_regs_for_local_alloc (void)
+ #undef TARGET_DWARF_REGISTER_SPAN
+ #define TARGET_DWARF_REGISTER_SPAN mips_dwarf_register_span
++
+ struct gcc_target targetm = TARGET_INITIALIZER;
\f
+ #include "gt-mips.h"
+--- a/gcc/config/mips/mips.h
++++ b/gcc/config/mips/mips.h
+@@ -67,6 +67,8 @@ enum processor_type {
+   PROCESSOR_SB1,
+   PROCESSOR_SB1A,
+   PROCESSOR_SR71000,
++  PROCESSOR_XLR,
++  PROCESSOR_OCTEON,
+   PROCESSOR_MAX
+ };
+@@ -179,15 +181,19 @@ enum mips_code_readable_setting {
+ #define TARGET_SIBCALLS \
+   (!TARGET_MIPS16 && (!TARGET_USE_GOT || TARGET_EXPLICIT_RELOCS))
+-/* True if we need to use a global offset table to access some symbols.  */
+-#define TARGET_USE_GOT (TARGET_ABICALLS || TARGET_RTP_PIC)
++/* True if we need to use a global offset table to access some symbols.
++   Small data and TLS are not counted.  */
++#define TARGET_USE_GOT ((TARGET_ABICALLS && flag_pic) || TARGET_RTP_PIC)
+ /* True if TARGET_USE_GOT and if $gp is a call-clobbered register.  */
+-#define TARGET_CALL_CLOBBERED_GP (TARGET_ABICALLS && TARGET_OLDABI)
++#define TARGET_CALL_CLOBBERED_GP (TARGET_ABICALLS && flag_pic && TARGET_OLDABI)
+ /* True if TARGET_USE_GOT and if $gp is a call-saved register.  */
+ #define TARGET_CALL_SAVED_GP (TARGET_USE_GOT && !TARGET_CALL_CLOBBERED_GP)
++/* True if using abicalls, but not ourselves PIC.  */
++#define TARGET_NONPIC_ABICALLS (TARGET_ABICALLS && !flag_pic)
++
+ /* True if indirect calls must use register class PIC_FN_ADDR_REG.
+    This is true for both the PIC and non-PIC VxWorks RTP modes.  */
+ #define TARGET_USE_PIC_FN_ADDR_REG (TARGET_ABICALLS || TARGET_VXWORKS_RTP)
+@@ -197,7 +203,8 @@ enum mips_code_readable_setting {
+    Although GAS does understand .gpdword, the SGI linker mishandles
+    the relocations GAS generates (R_MIPS_GPREL32 followed by R_MIPS_64).
+    We therefore disable GP-relative switch tables for n64 on IRIX targets.  */
+-#define TARGET_GPWORD (TARGET_ABICALLS && !(mips_abi == ABI_64 && TARGET_IRIX))
++#define TARGET_GPWORD (TARGET_ABICALLS && flag_pic \
++                     && !(mips_abi == ABI_64 && TARGET_IRIX))
+ /* Generate mips16 code */
+ #define TARGET_MIPS16         ((target_flags & MASK_MIPS16) != 0)
+@@ -237,6 +244,8 @@ enum mips_code_readable_setting {
+ #define TARGET_SB1                  (mips_arch == PROCESSOR_SB1               \
+                                    || mips_arch == PROCESSOR_SB1A)
+ #define TARGET_SR71K                (mips_arch == PROCESSOR_SR71000)
++#define TARGET_OCTEON               (mips_arch == PROCESSOR_OCTEON)
++#define TARGET_XLR                (mips_arch == PROCESSOR_XLR)
+ /* Scheduling target defines.  */
+ #define TUNE_MIPS3000               (mips_tune == PROCESSOR_R3000)
+@@ -311,6 +320,9 @@ enum mips_code_readable_setting {
+ #define TARGET_IRIX      0
+ #define TARGET_IRIX6     0
++/* SDE specific stuff.  */
++#define TARGET_MIPS_SDE    0
++
+ /* Define preprocessor macros for the -march and -mtune options.
+    PREFIX is either _MIPS_ARCH or _MIPS_TUNE, INFO is the selected
+    processor.  If INFO's canonical name is "foo", define PREFIX to
+@@ -435,7 +447,10 @@ enum mips_code_readable_setting {
+       else if (ISA_MIPS64)                                            \
+       {                                                               \
+         builtin_define ("__mips=64");                                 \
+-        builtin_define ("__mips_isa_rev=1");                          \
++        if (TARGET_OCTEON)                                            \
++          builtin_define ("__mips_isa_rev=2");                        \
++        else                                                          \
++          builtin_define ("__mips_isa_rev=1");                        \
+         builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64");                \
+       }                                                               \
+                                                                       \
+@@ -520,6 +535,9 @@ enum mips_code_readable_setting {
+                                                                       \
+       if (mips_abi == ABI_EABI)                                               \
+       builtin_define ("__mips_eabi");                                 \
++                                                                      \
++      if (TARGET_FIX_ICE9A)                                           \
++      builtin_define ("_MIPS_FIX_ICE9A");                             \
+     }                                                                 \
+   while (0)
+@@ -651,7 +669,8 @@ enum mips_code_readable_setting {
+      %{march=mips32|march=4kc|march=4km|march=4kp|march=4ksc:-mips32} \
+      %{march=mips32r2|march=m4k|march=4ke*|march=4ksd|march=24k* \
+        |march=34k*|march=74k*: -mips32r2} \
+-     %{march=mips64|march=5k*|march=20k*|march=sb1*|march=sr71000: -mips64} \
++     %{march=mips64|march=5k*|march=20k*|march=sb1*|march=sr71000 \
++     |march=octeon|march=xlr: -mips64} \
+      %{!march=*: -" MULTILIB_ISA_DEFAULT "}}"
+ /* A spec that infers a -mhard-float or -msoft-float setting from an
+@@ -664,6 +683,11 @@ enum mips_code_readable_setting {
+      |march=34kc|march=74kc|march=5kc: -msoft-float; \
+      march=*: -mhard-float}"
++/* A spec that infers the -mdsp setting from an -march argument.  */
++
++#define MIPS_ARCH_DSP_SPEC \
++  "%{!mno-dsp:%{march=24ke*|march=34k*|march=74k*: -mdsp}}"
++
+ /* A spec condition that matches 32-bit options.  It only works if
+    MIPS_ISA_LEVEL_SPEC has been applied.  */
+@@ -672,19 +696,27 @@ enum mips_code_readable_setting {
+ /* Support for a compile-time default CPU, et cetera.  The rules are:
+    --with-arch is ignored if -march is specified or a -mips is specified
+-     (other than -mips16).
+-   --with-tune is ignored if -mtune is specified.
++     (other than -mips16); likewise --with-arch32 and --with-arch64.
++   --with-tune is ignored if -mtune is specified; likewise
++     --with-tune32 and --with-tune64.
+    --with-abi is ignored if -mabi is specified.
+    --with-float is ignored if -mhard-float or -msoft-float are
+      specified.
+    --with-divide is ignored if -mdivide-traps or -mdivide-breaks are
+-     specified. */
++     specified.
++   --with-fix-ice9a is ignored if -mfix-ice9a or -mno-fix-ice9a are
++     specified.  */
+ #define OPTION_DEFAULT_SPECS \
+   {"arch", "%{" MIPS_ARCH_OPTION_SPEC ":;: -march=%(VALUE)}" }, \
++  {"arch32", "%{!mabi=*|mabi=32:%{" MIPS_ARCH_OPTION_SPEC ":;: -march=%(VALUE)}}" }, \
++  {"arch64", "%{mabi=n32|mabi=64:%{" MIPS_ARCH_OPTION_SPEC ":;: -march=%(VALUE)}}" }, \
+   {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
++  {"tune32", "%{!mabi=*|mabi=32:%{!mtune=*:-mtune=%(VALUE)}}" }, \
++  {"tune64", "%{mabi=n32|mabi=64:%{!mtune=*:-mtune=%(VALUE)}}" }, \
+   {"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \
+   {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }, \
+   {"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }, \
++  {"fix-ice9a", "%{!mfix-ice9a:%{!mno-fix-ice9a:-mfix-ice9a}}" }, \
+   {"llsc", "%{!mllsc:%{!mno-llsc:-m%(VALUE)}}" }
+@@ -783,6 +815,9 @@ enum mips_code_readable_setting {
+                                 || ISA_MIPS64)                        \
+                                && !TARGET_MIPS16)
++/* ISA has Octeon specific pop instruction */
++#define ISA_HAS_POPCOUNT      (TARGET_OCTEON && !TARGET_MIPS16)
++
+ /* ISA has three operand multiply instructions that put
+    the high part in an accumulator: mulhi or mulhiu.  */
+ #define ISA_HAS_MULHI         ((TARGET_MIPS5400                        \
+@@ -823,6 +858,7 @@ enum mips_code_readable_setting {
+                                 || TARGET_MIPS5400                    \
+                                 || TARGET_MIPS5500                    \
+                                 || TARGET_SR71K                       \
++                                || TARGET_OCTEON                      \
+                                 || TARGET_SMARTMIPS)                  \
+                                && !TARGET_MIPS16)
+@@ -848,13 +884,33 @@ enum mips_code_readable_setting {
+ #define ISA_HAS_TRUNC_W               (!ISA_MIPS1)
+ /* ISA includes the MIPS32r2 seb and seh instructions.  */
+-#define ISA_HAS_SEB_SEH               (ISA_MIPS32R2                           \
++#define ISA_HAS_SEB_SEH               ((ISA_MIPS32R2 || TARGET_OCTEON)        \
+                                && !TARGET_MIPS16)
+ /* ISA includes the MIPS32/64 rev 2 ext and ins instructions.  */
+-#define ISA_HAS_EXT_INS               (ISA_MIPS32R2                           \
++#define ISA_HAS_EXT_INS               ((ISA_MIPS32R2 || TARGET_OCTEON)                \
+                                && !TARGET_MIPS16)
++/* ISA includes the exts instructions.  */
++#define ISA_HAS_EXTS          (TARGET_OCTEON && !TARGET_MIPS16)
++
++/* ISA includes the bbit* instructions.  */
++#define ISA_HAS_BBIT          (TARGET_OCTEON && !TARGET_MIPS16)
++
++/* ISA includes the seq and sne instructions.  */
++#define ISA_HAS_SEQ_SNE               (TARGET_OCTEON && !TARGET_MIPS16)
++
++/* ISA includes the baddu instruction.  */
++#define ISA_HAS_BADDU         (TARGET_OCTEON && !TARGET_MIPS16)
++
++/* ISA has single-instruction unalinged load/store support.  */
++#define ISA_HAS_UL_US         (TARGET_OCTEON \
++                               && TARGET_OCTEON_UNALIGNED \
++                               && !TARGET_MIPS16)
++
++/* ISA includes the cins instruction.  */
++#define ISA_HAS_CINS          (TARGET_OCTEON && !TARGET_MIPS16)
++
+ /* ISA has instructions for accessing top part of 64-bit fp regs.  */
+ #define ISA_HAS_MXHC1         (TARGET_FLOAT64 && ISA_MIPS32R2)
+@@ -935,6 +991,49 @@ enum mips_code_readable_setting {
+ #endif
\f
++/* Some targets (most of those with dynamic linking, e.g. Irix,
++   GNU/Linux, BSD) default to -mabicalls.  They mostly default to PIC
++   also.  Force the appropriate -mabicalls setting into the command
++   line for the benefit of the -fno-pic spec just below.  */
++#ifdef TARGET_ABICALLS_DEFAULT
++#define ABICALLS_SPEC "%{!mno-abicalls:%{!mabicalls:-mabicalls}}"
++#else
++#define ABICALLS_SPEC "%{!mno-abicalls:%{!mabicalls:-mno-abicalls}}"
++#endif
++
++/* Make -mabicalls imply PIC unless the target supports non-PIC
++   abicalls.  Targets which do not support non-PIC abicalls must set
++   flag_pic for executables as well as DSOs
++   because we may reference symbols that are not defined in
++   the final executable - these targets do not have copy relocs.
++
++   All 64-bit targets are assumed to not support PIC abicalls.
++   CSL NOTE: It would be nice to remove this restriction before
++   contributing upstream; 64-bit support should be a small project.
++
++   Also, there is a body of code that uses __PIC__ to distinguish
++   between -mabicalls and -mno-abicalls code.  For targets with
++   non-PIC abicalls support any such code will have to be corrected.
++   All you need to do if !__PIC__ is use $t9 for indirect calls
++   and be careful about assuming $gp is set up in inline asm.  */
++#ifdef TARGET_ABICALLS_NONPIC
++#define ABICALLS_SELF_SPECS ABICALLS_SPEC, \
++  "%{mabicalls:%{!fno-pic:%{mabi=o64|mabi=64|mabi=n32:-fpic}}}"
++#else
++#define ABICALLS_SELF_SPECS ABICALLS_SPEC, \
++  "%{mabicalls:%{!fno-pic:-fpic}}"
++#endif
++
++/* Any additional self specs defined by the subtarget.  */
++#ifndef SUBTARGET_SELF_SPECS
++#define SUBTARGET_SELF_SPECS ""
++#endif
++
++#define DRIVER_SELF_SPECS \
++ SUBTARGET_SELF_SPECS, \
++ ABICALLS_SELF_SPECS
++\f
++
+ #ifndef MIPS_ABI_DEFAULT
+ #define MIPS_ABI_DEFAULT ABI_32
+ #endif
+@@ -1003,7 +1102,7 @@ enum mips_code_readable_setting {
+ %{mdspr2} %{mno-dspr2} \
+ %{msmartmips} %{mno-smartmips} \
+ %{mmt} %{mno-mt} \
+-%{mfix-vr4120} %{mfix-vr4130} \
++%{mfix-vr4120} %{mfix-vr4130} %{mfix-ice9a} %{mno-fix-ice9a} \
+ %(subtarget_asm_optimizing_spec) \
+ %(subtarget_asm_debugging_spec) \
+ %{mabi=*} %{!mabi*: %(asm_abi_default_spec)} \
+@@ -1012,6 +1111,7 @@ enum mips_code_readable_setting {
+ %{mshared} %{mno-shared} \
+ %{msym32} %{mno-sym32} \
+ %{mtune=*} %{v} \
++%{mocteon-useun} %{mno-octeon-useun} \
+ %(subtarget_asm_spec)"
+ /* Extra switches sometimes passed to the linker.  */
+@@ -1515,9 +1615,24 @@ enum mips_code_readable_setting {
+ #define DSP_ACC_REG_LAST 181
+ #define DSP_ACC_REG_NUM (DSP_ACC_REG_LAST - DSP_ACC_REG_FIRST + 1)
++#define DSP_CTRL_REG_FIRST 182
++#define DSP_CTRL_REG_LAST 187
++
+ #define AT_REGNUM     (GP_REG_FIRST + 1)
+ #define HI_REGNUM     (TARGET_BIG_ENDIAN ? MD_REG_FIRST : MD_REG_FIRST + 1)
+ #define LO_REGNUM     (TARGET_BIG_ENDIAN ? MD_REG_FIRST + 1 : MD_REG_FIRST)
++#define AC1HI_REGNUM  (TARGET_BIG_ENDIAN \
++                       ? DSP_ACC_REG_FIRST : DSP_ACC_REG_FIRST + 1)
++#define AC1LO_REGNUM  (TARGET_BIG_ENDIAN \
++                       ? DSP_ACC_REG_FIRST + 1 : DSP_ACC_REG_FIRST)
++#define AC2HI_REGNUM  (TARGET_BIG_ENDIAN \
++                       ? DSP_ACC_REG_FIRST + 2 : DSP_ACC_REG_FIRST + 3)
++#define AC2LO_REGNUM  (TARGET_BIG_ENDIAN \
++                       ? DSP_ACC_REG_FIRST + 3 : DSP_ACC_REG_FIRST + 2)
++#define AC3HI_REGNUM  (TARGET_BIG_ENDIAN \
++                       ? DSP_ACC_REG_FIRST + 4 : DSP_ACC_REG_FIRST + 5)
++#define AC3LO_REGNUM  (TARGET_BIG_ENDIAN \
++                       ? DSP_ACC_REG_FIRST + 5 : DSP_ACC_REG_FIRST + 4)
+ /* FPSW_REGNUM is the single condition code used if !ISA_HAS_8CC.
+    If ISA_HAS_8CC, it should not be used, and an arbitrary ST_REG
+@@ -1673,6 +1788,7 @@ enum reg_class
+   ST_REGS,                    /* status registers (fp status) */
+   DSP_ACC_REGS,                       /* DSP accumulator registers */
+   ACC_REGS,                   /* Hi/Lo and DSP accumulator registers */
++  FRAME_REGS,                 /* $arg and $frame */
+   ALL_REGS,                   /* all registers */
+   LIM_REG_CLASSES             /* max value + 1 */
+ };
+@@ -1715,6 +1831,7 @@ enum reg_class
+   "ST_REGS",                                                          \
+   "DSP_ACC_REGS",                                                     \
+   "ACC_REGS",                                                         \
++  "FRAME_REGS",                                                               \
+   "ALL_REGS"                                                          \
+ }
+@@ -1758,7 +1875,8 @@ enum reg_class
+   { 0x00000000, 0x00000000, 0x000007f8, 0x00000000, 0x00000000, 0x00000000 }, /* status registers */  \
+   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x003f0000 }, /* dsp accumulator registers */ \
+   { 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x003f0000 }, /* hi/lo and dsp accumulator registers */       \
+-  { 0xffffffff, 0xffffffff, 0xffff07ff, 0xffffffff, 0xffffffff, 0x0fffffff }  /* all registers */     \
++  { 0x00000000, 0x00000000, 0x00006000, 0x00000000, 0x00000000, 0x00000000 }, /* frame registers */   \
++  { 0xffffffff, 0xffffffff, 0xffff67ff, 0xffffffff, 0xffffffff, 0x0fffffff }  /* all registers */     \
+ }
+@@ -2446,7 +2564,7 @@ typedef struct mips_args {
+    ? "%*" INSN "\t%" #OPNO "%/"                                       \
+    : REG_P (OPERANDS[OPNO])                                   \
+    ? "%*" INSN "r\t%" #OPNO "%/"                              \
+-   : TARGET_ABICALLS                                          \
++   : TARGET_ABICALLS && flag_pic                              \
+    ? (".option\tpic0\n\t"                                     \
+       "%*" INSN "\t%" #OPNO "%/\n\t"                          \
+       ".option\tpic2")                                                \
+--- a/gcc/config/mips/mips.md
++++ b/gcc/config/mips/mips.md
+@@ -60,7 +60,10 @@
+    (UNSPEC_MEMORY_BARRIER     41)
+    (UNSPEC_SET_GOT_VERSION    42)
+    (UNSPEC_UPDATE_GOT_VERSION 43)
+-   
++
++   (UNSPEC_UNALIGNED_LOAD     50)
++   (UNSPEC_UNALIGNED_STORE    51)
++
+    (UNSPEC_ADDRESS_FIRST      100)
+    (TLS_GET_TP_REGNUM         3)
+@@ -269,6 +272,7 @@
+ ;; slt                set less than instructions
+ ;; signext      sign extend instructions
+ ;; clz                the clz and clo instructions
++;; pop                pop and dpop
+ ;; trap               trap if instructions
+ ;; imul               integer multiply 2 operands
+ ;; imul3      integer multiply 3 operands
+@@ -291,11 +295,17 @@
+ ;; frsqrt       floating point reciprocal square root
+ ;; frsqrt1      floating point reciprocal square root step1
+ ;; frsqrt2      floating point reciprocal square root step2
++;; dspmac       DSP MAC instructions not saturating the accumulator
++;; dspmacsat    DSP MAC instructions that saturate the accumulator
++;; accext       DSP accumulator extract instructions
++;; accmod       DSP accumulator modify instructions
++;; dspalu       DSP ALU instructions not saturating the result
++;; dspalusat    DSP ALU instructions that saturate the result
+ ;; multi      multiword sequence (or user asm statements)
+ ;; nop                no operation
+ ;; ghost      an instruction that produces no real code
+ (define_attr "type"
+-  "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,mfc,mtc,mthilo,mfhilo,const,arith,logical,shift,slt,signext,clz,trap,imul,imul3,imadd,idiv,move,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,multi,nop,ghost"
++  "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,mfc,mtc,mthilo,mfhilo,const,arith,logical,shift,slt,signext,clz,pop,trap,imul,imul3,imadd,idiv,move,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,dspmac,dspmacsat,accext,accmod,dspalu,dspalusat,multi,nop,ghost"
+   (cond [(eq_attr "jal" "!unset") (const_string "call")
+        (eq_attr "got" "load") (const_string "load")]
+       (const_string "unknown")))
+@@ -412,7 +422,7 @@
+ ;; Attribute describing the processor.  This attribute must match exactly
+ ;; with the processor_type enumeration in mips.h.
+ (define_attr "cpu"
+-  "r3000,4kc,4kp,5kc,5kf,20kc,24kc,24kf2_1,24kf1_1,74kc,74kf2_1,74kf1_1,74kf3_2,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000"
++  "r3000,4kc,4kp,5kc,5kf,20kc,24kc,24kf2_1,24kf1_1,74kc,74kf2_1,74kf1_1,74kf3_2,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000,xlr,octeon"
+   (const (symbol_ref "mips_tune")))
+ ;; The type of hardware hazard associated with this instruction.
+@@ -461,6 +471,16 @@
+                (const_string "yes")
+                (const_string "no"))))
++;; Attributes defining whether a branch has a branch-likely variant.
++(define_attr "branch_without_likely" "no,yes" (const_string "no"))
++
++(define_attr "branch_with_likely" "no,yes"
++  (if_then_else 
++    (and (eq_attr "type" "branch")
++          (eq_attr "branch_without_likely" "no"))
++    (const_string "yes")
++    (const_string "no")))
++
+ ;; True if an instruction might assign to hi or lo when reloaded.
+ ;; This is used by the TUNE_MACC_CHAINS code.
+ (define_attr "may_clobber_hilo" "no,yes"
+@@ -513,6 +533,30 @@
+    (V2SF "!TARGET_64BIT && TARGET_PAIRED_SINGLE_FLOAT")
+    (TF "TARGET_64BIT && TARGET_FLOAT64")])
++;; The attributes for the ICE9A fix.
++(define_mode_attr ice9a_stallnops [(SF "") (V2SF "")
++                                   (DF "movn.d\t$f30, $f28, $0\;movn.d\t$f30, $f28, $0\;movn.d\t$f30, $f28, $0\;movn.d\t$f30, $f28, $0\;movn.d\t$f30, $f28, $0\;")])
++(define_mode_attr ice9a_round     [(SF "") (V2SF "")
++                                   (DF "\;movn.d\t$f30, %0, $0")])
++
++
++
++;; stall workaround = 5 insns, => length = 4 * (1+5) = 24
++(define_mode_attr ice9a_length_stall    [(SF "4") (V2SF "4")
++                                         (DF "24")])
++
++;; round workaround = 1 insn, => length = 4 * (1+1) = 8
++(define_mode_attr ice9a_length_round    [(SF "4") (V2SF "4")
++                                         (DF "8")])
++
++;; both workarounds = 5+1 insn, => length = 4 * (1+5+1) = 28
++(define_mode_attr ice9a_length_both     [(SF "4") (V2SF "4")
++                                         (DF "28")])
++
++
++
++
++
+ ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
+ ;; 32-bit version and "dsubu" in the 64-bit version.
+ (define_mode_attr d [(SI "") (DI "d")
+@@ -525,9 +569,12 @@
+ ;; instruction.
+ (define_mode_attr size [(QI "b") (HI "h")])
+-;; This attributes gives the mode mask of a SHORT.
++;; This attribute gives the mode mask of a SHORT.
+ (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
++;; This attribute gives the number of the topmost bit of a SUBDI.
++(define_mode_attr topbit [(QI "7") (HI "15") (SI "31")])
++
+ ;; Mode attributes for GPR loads and stores.
+ (define_mode_attr load [(SI "lw") (DI "ld")])
+ (define_mode_attr store [(SI "sw") (DI "sd")])
+@@ -599,14 +646,23 @@
+ ;; to use the same template.
+ (define_code_iterator any_extend [sign_extend zero_extend])
++;; This code iterator allows both sorts of extraction to be treated alike.
++(define_code_iterator any_extract [sign_extract zero_extract])
++
+ ;; This code iterator allows the three shift instructions to be generated
+ ;; from the same template.
+ (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
++;; This code iterator allows both of the right shift codes to be treated alike.
++(define_code_iterator any_shiftrt [ashiftrt lshiftrt])
++
+ ;; This code iterator allows all native floating-point comparisons to be
+ ;; generated from the same template.
+ (define_code_iterator fcond [unordered uneq unlt unle eq lt le])
++;; This code iterator allows both equality operators to be treated alike.
++(define_code_iterator equality_op [eq ne])
++
+ ;; This code iterator is used for comparisons that can be implemented
+ ;; by swapping the operands.
+ (define_code_iterator swapped_fcond [ge gt unge ungt])
+@@ -663,13 +719,19 @@
+ ;;
+ ;; .........................
+-(define_delay (and (eq_attr "type" "branch")
++(define_delay (and (eq_attr "branch_with_likely" "yes")
+                  (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
+   [(eq_attr "can_delay" "yes")
+    (nil)
+    (and (eq_attr "branch_likely" "yes")
+       (eq_attr "can_delay" "yes"))])
++(define_delay (and (eq_attr "branch_without_likely" "yes")
++                 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
++  [(eq_attr "can_delay" "yes")
++   (nil)
++   (nil)])
++
+ (define_delay (eq_attr "type" "jump")
+   [(eq_attr "can_delay" "yes")
+    (nil)
+@@ -720,7 +782,9 @@
+ (include "7000.md")
+ (include "9000.md")
+ (include "sb1.md")
++(include "octeon.md")
+ (include "sr71k.md")
++(include "xlr.md")
+ (include "generic.md")
\f
+ ;;
+@@ -985,6 +1049,51 @@
+   [(set_attr "type" "arith")
+    (set_attr "mode" "SI")
+    (set_attr "extended_mips16" "yes")])
++
++;; Combiner patterns for unsigned byte-add.
++
++(define_insn "*baddu_si"
++  [(set (match_operand:SI 0 "register_operand" "=d")
++        (zero_extend:SI
++       (subreg:QI
++        (plus:SI (match_operand:SI 1 "register_operand" "d")
++                 (match_operand:SI 2 "register_operand" "d")) 3)))]
++  "ISA_HAS_BADDU && TARGET_BIG_ENDIAN"
++  "baddu\\t%0,%1,%2"
++  [(set_attr "type" "arith")])
++
++(define_insn "*baddu_disi"
++  [(set (match_operand:SI 0 "register_operand" "=d")
++        (zero_extend:SI
++       (truncate:QI
++        (plus:DI (match_operand:DI 1 "register_operand" "d")
++                 (match_operand:DI 2 "register_operand" "d")))))]
++  "TARGET_64BIT && ISA_HAS_BADDU"
++  "baddu\\t%0,%1,%2"
++  [(set_attr "type" "arith")])
++
++(define_insn "*baddu_didi"
++  [(set (match_operand:DI 0 "register_operand" "=d")
++        (zero_extend:DI
++       (truncate:QI
++        (plus:DI
++         (subreg:DI
++          (truncate:QI (match_operand:DI 1 "register_operand" "d")) 0)
++         (subreg:DI
++          (truncate:QI (match_operand:DI 2 "register_operand" "d")) 0)))))]
++  "TARGET_64BIT && ISA_HAS_BADDU"
++  "baddu\\t%0,%1,%2"
++  [(set_attr "type" "arith")])
++
++(define_insn "*baddu_didi2"
++  [(set (match_operand:DI 0 "register_operand" "=d")
++        (zero_extend:DI
++       (truncate:QI
++        (plus:DI (match_operand:DI 1 "register_operand" "d")
++                 (match_operand:DI 2 "register_operand" "d")))))]
++  "TARGET_64BIT && ISA_HAS_BADDU"
++  "baddu\\t%0,%1,%2"
++  [(set_attr "type" "arith")])
\f
+ ;;
+ ;;  ....................
+@@ -1041,7 +1150,7 @@
+   [(set (match_operand:SCALARF 0 "register_operand" "=f")
+       (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
+                     (match_operand:SCALARF 2 "register_operand" "f")))]
+-  "!TARGET_4300_MUL_FIX"
++  "!TARGET_4300_MUL_FIX && !TARGET_FIX_ICE9A"
+   "mul.<fmt>\t%0,%1,%2"
+   [(set_attr "type" "fmul")
+    (set_attr "mode" "<MODE>")])
+@@ -1054,12 +1163,22 @@
+   [(set (match_operand:SCALARF 0 "register_operand" "=f")
+       (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
+                     (match_operand:SCALARF 2 "register_operand" "f")))]
+-  "TARGET_4300_MUL_FIX"
++  "TARGET_4300_MUL_FIX && !TARGET_FIX_ICE9A"
+   "mul.<fmt>\t%0,%1,%2\;nop"
+   [(set_attr "type" "fmul")
+    (set_attr "mode" "<MODE>")
+    (set_attr "length" "8")])
++(define_insn "*mul<mode>3_fix_ice9a"
++  [(set (match_operand:SCALARF 0 "register_operand" "=f")
++      (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
++                    (match_operand:SCALARF 2 "register_operand" "f")))]
++  "TARGET_FIX_ICE9A && !TARGET_4300_MUL_FIX"
++  "<ice9a_stallnops>mul.<fmt>\t%0,%1,%2<ice9a_round>"
++  [(set_attr "type" "fmul")
++   (set_attr "mode" "<MODE>")
++   (set_attr "length" "<ice9a_length_both>")])
++
+ (define_insn "mulv2sf3"
+   [(set (match_operand:V2SF 0 "register_operand" "=f")
+       (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
+@@ -1849,21 +1968,43 @@
+       (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
+                             (match_operand:ANYF 2 "register_operand" "f"))
+                  (match_operand:ANYF 3 "register_operand" "f")))]
+-  "ISA_HAS_FP4 && TARGET_FUSED_MADD"
++  "ISA_HAS_FP4 && TARGET_FUSED_MADD && !TARGET_FIX_ICE9A"
+   "madd.<fmt>\t%0,%3,%1,%2"
+   [(set_attr "type" "fmadd")
+    (set_attr "mode" "<UNITMODE>")])
++(define_insn "*madd<mode>_ice9a"
++  [(set (match_operand:ANYF 0 "register_operand" "=f")
++      (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
++                            (match_operand:ANYF 2 "register_operand" "f"))
++                 (match_operand:ANYF 3 "register_operand" "f")))]
++  "ISA_HAS_FP4 && TARGET_FUSED_MADD && TARGET_FIX_ICE9A"
++  "<ice9a_stallnops>madd.<fmt>\t%0,%3,%1,%2<ice9a_round>"
++  [(set_attr "type" "fmadd")
++   (set_attr "mode" "<UNITMODE>")
++   (set_attr "length" "<ice9a_length_both>")])
++
+ (define_insn "*msub<mode>"
+   [(set (match_operand:ANYF 0 "register_operand" "=f")
+       (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
+                              (match_operand:ANYF 2 "register_operand" "f"))
+                   (match_operand:ANYF 3 "register_operand" "f")))]
+-  "ISA_HAS_FP4 && TARGET_FUSED_MADD"
++  "ISA_HAS_FP4 && TARGET_FUSED_MADD && !TARGET_FIX_ICE9A"
+   "msub.<fmt>\t%0,%3,%1,%2"
+   [(set_attr "type" "fmadd")
+    (set_attr "mode" "<UNITMODE>")])
++(define_insn "*msub<mode>_ice9a"
++  [(set (match_operand:ANYF 0 "register_operand" "=f")
++      (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
++                             (match_operand:ANYF 2 "register_operand" "f"))
++                  (match_operand:ANYF 3 "register_operand" "f")))]
++  "ISA_HAS_FP4 && TARGET_FUSED_MADD && TARGET_FIX_ICE9A"
++  "<ice9a_stallnops>msub.<fmt>\t%0,%3,%1,%2<ice9a_round>"
++  [(set_attr "type" "fmadd")
++   (set_attr "mode" "<UNITMODE>")
++   (set_attr "length" "<ice9a_length_both>")])
++
+ (define_insn "*nmadd<mode>"
+   [(set (match_operand:ANYF 0 "register_operand" "=f")
+       (neg:ANYF (plus:ANYF
+@@ -1873,7 +2014,8 @@
+   "ISA_HAS_NMADD_NMSUB (<MODE>mode)
+    && TARGET_FUSED_MADD
+    && HONOR_SIGNED_ZEROS (<MODE>mode)
+-   && !HONOR_NANS (<MODE>mode)"
++   && !HONOR_NANS (<MODE>mode)
++   && !TARGET_FIX_ICE9A"
+   "nmadd.<fmt>\t%0,%3,%1,%2"
+   [(set_attr "type" "fmadd")
+    (set_attr "mode" "<UNITMODE>")])
+@@ -1887,11 +2029,44 @@
+   "ISA_HAS_NMADD_NMSUB (<MODE>mode)
+    && TARGET_FUSED_MADD
+    && !HONOR_SIGNED_ZEROS (<MODE>mode)
+-   && !HONOR_NANS (<MODE>mode)"
++   && !HONOR_NANS (<MODE>mode)
++   && !TARGET_FIX_ICE9A"
+   "nmadd.<fmt>\t%0,%3,%1,%2"
+   [(set_attr "type" "fmadd")
+    (set_attr "mode" "<UNITMODE>")])
++(define_insn "*nmadd<mode>_ice9a"
++  [(set (match_operand:ANYF 0 "register_operand" "=f")
++      (neg:ANYF (plus:ANYF
++                 (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
++                            (match_operand:ANYF 2 "register_operand" "f"))
++                 (match_operand:ANYF 3 "register_operand" "f"))))]
++  "ISA_HAS_NMADD_NMSUB (<MODE>mode)
++   && TARGET_FUSED_MADD
++   && HONOR_SIGNED_ZEROS (<MODE>mode)
++   && !HONOR_NANS (<MODE>mode)
++   && TARGET_FIX_ICE9A"
++  "<ice9a_stallnops>nmadd.<fmt>\t%0,%3,%1,%2<ice9a_round>"
++  [(set_attr "type" "fmadd")
++   (set_attr "length" "<ice9a_length_both>")
++   (set_attr "mode" "<UNITMODE>")])
++
++(define_insn "*nmadd<mode>_fastmath_ice9a"
++  [(set (match_operand:ANYF 0 "register_operand" "=f")
++      (minus:ANYF
++       (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
++                  (match_operand:ANYF 2 "register_operand" "f"))
++       (match_operand:ANYF 3 "register_operand" "f")))]
++  "ISA_HAS_NMADD_NMSUB (<MODE>mode)
++   && TARGET_FUSED_MADD
++   && !HONOR_SIGNED_ZEROS (<MODE>mode)
++   && !HONOR_NANS (<MODE>mode)
++   && TARGET_FIX_ICE9A"
++  "<ice9a_stallnops>nmadd.<fmt>\t%0,%3,%1,%2<ice9a_round>"
++  [(set_attr "type" "fmadd")
++   (set_attr "length" "<ice9a_length_both>")
++   (set_attr "mode" "<UNITMODE>")])
++
+ (define_insn "*nmsub<mode>"
+   [(set (match_operand:ANYF 0 "register_operand" "=f")
+       (neg:ANYF (minus:ANYF
+@@ -1901,7 +2076,8 @@
+   "ISA_HAS_NMADD_NMSUB (<MODE>mode)
+    && TARGET_FUSED_MADD
+    && HONOR_SIGNED_ZEROS (<MODE>mode)
+-   && !HONOR_NANS (<MODE>mode)"
++   && !HONOR_NANS (<MODE>mode)
++   && !TARGET_FIX_ICE9A"
+   "nmsub.<fmt>\t%0,%1,%2,%3"
+   [(set_attr "type" "fmadd")
+    (set_attr "mode" "<UNITMODE>")])
+@@ -1915,10 +2091,43 @@
+   "ISA_HAS_NMADD_NMSUB (<MODE>mode)
+    && TARGET_FUSED_MADD
+    && !HONOR_SIGNED_ZEROS (<MODE>mode)
+-   && !HONOR_NANS (<MODE>mode)"
++   && !HONOR_NANS (<MODE>mode)
++   && !TARGET_FIX_ICE9A"
+   "nmsub.<fmt>\t%0,%1,%2,%3"
+   [(set_attr "type" "fmadd")
+    (set_attr "mode" "<UNITMODE>")])
++
++(define_insn "*nmsub<mode>_ice9a"
++  [(set (match_operand:ANYF 0 "register_operand" "=f")
++      (neg:ANYF (minus:ANYF
++                 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
++                            (match_operand:ANYF 3 "register_operand" "f"))
++                 (match_operand:ANYF 1 "register_operand" "f"))))]
++  "ISA_HAS_NMADD_NMSUB (<MODE>mode)
++   && TARGET_FUSED_MADD
++   && HONOR_SIGNED_ZEROS (<MODE>mode)
++   && !HONOR_NANS (<MODE>mode)
++   && TARGET_FIX_ICE9A"
++  "<ice9a_stallnops>nmsub.<fmt>\t%0,%1,%2,%3<ice9a_round>"
++  [(set_attr "type" "fmadd")
++   (set_attr "length" "<ice9a_length_both>")
++   (set_attr "mode" "<UNITMODE>")])
++
++(define_insn "*nmsub<mode>_fastmath_ice9a"
++  [(set (match_operand:ANYF 0 "register_operand" "=f")
++      (minus:ANYF
++       (match_operand:ANYF 1 "register_operand" "f")
++       (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
++                  (match_operand:ANYF 3 "register_operand" "f"))))]
++  "ISA_HAS_NMADD_NMSUB (<MODE>mode)
++   && TARGET_FUSED_MADD
++   && !HONOR_SIGNED_ZEROS (<MODE>mode)
++   && !HONOR_NANS (<MODE>mode)
++   && TARGET_FIX_ICE9A"
++  "<ice9a_stallnops>nmsub.<fmt>\t%0,%1,%2,%3<ice9a_round>"
++  [(set_attr "type" "fmadd")
++   (set_attr "length" "<ice9a_length_both>")
++   (set_attr "mode" "<UNITMODE>")])
\f
+ ;;
+ ;;  ....................
+@@ -1973,19 +2182,40 @@
+   [(set (match_operand:ANYF 0 "register_operand" "=f")
+       (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
+                 (match_operand:ANYF 2 "register_operand" "f")))]
+-  "<recip_condition> && flag_unsafe_math_optimizations"
+-{
+-  if (TARGET_FIX_SB1)
+-    return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
+-  else
+-    return "recip.<fmt>\t%0,%2";
+-}
++  "<recip_condition> &&
++   flag_unsafe_math_optimizations &&
++   !TARGET_FIX_SB1 &&
++   !TARGET_FIX_ICE9A"
++  "recip.<fmt>\t%0,%2"
++  [(set_attr "type" "frdiv")
++   (set_attr "mode" "<UNITMODE>")])
++
++(define_insn "*recip<mode>3_fix_sb1"
++  [(set (match_operand:ANYF 0 "register_operand" "=f")
++      (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
++                (match_operand:ANYF 2 "register_operand" "f")))]
++  "<recip_condition> &&
++   flag_unsafe_math_optimizations &&
++   TARGET_FIX_SB1 &&
++   !TARGET_FIX_ICE9A"
++  "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0"
+   [(set_attr "type" "frdiv")
+    (set_attr "mode" "<UNITMODE>")
+-   (set (attr "length")
+-        (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
+-                      (const_int 8)
+-                      (const_int 4)))])
++   (set_attr "length" "8")])
++
++(define_insn "*recip<mode>3_fix_ice9a"
++  [(set (match_operand:ANYF 0 "register_operand" "=f")
++      (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
++                (match_operand:ANYF 2 "register_operand" "f")))]
++  "<recip_condition> &&
++   flag_unsafe_math_optimizations &&
++   !TARGET_FIX_SB1 &&
++   TARGET_FIX_ICE9A"
++  "<ice9a_stallnops>recip.<fmt>\t%0,%2"
++  [(set_attr "type" "frdiv")
++   (set_attr "mode" "<UNITMODE>")
++   (set_attr "length" "<ice9a_length_stall>")])
++
+ ;; VR4120 errata MD(A1): signed division instructions do not work correctly
+ ;; with negative operands.  We use special libgcc functions instead.
+@@ -2021,60 +2251,117 @@
+ ;;  ....................
+ ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
+-;; "*div[sd]f3" comment for details).
++;; "*div[sd]f3" comment for details), and ICE9A errata.
+-(define_insn "sqrt<mode>2"
++(define_expand "sqrt<mode>2"
+   [(set (match_operand:ANYF 0 "register_operand" "=f")
+       (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
+   "<sqrt_condition>"
+-{
+-  if (TARGET_FIX_SB1)
+-    return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
+-  else
+-    return "sqrt.<fmt>\t%0,%1";
+-}
++  "")
++
++(define_insn "*sqrt<mode>2"
++  [(set (match_operand:ANYF 0 "register_operand" "=f")
++      (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
++  "<sqrt_condition> &&
++   !TARGET_FIX_SB1 &&
++   !TARGET_FIX_ICE9A"
++  "sqrt.<fmt>\t%0,%1"
++  [(set_attr "type" "fsqrt")
++   (set_attr "mode" "<UNITMODE>")])
++
++(define_insn "*sqrt<mode>2_fix_sb1"
++  [(set (match_operand:ANYF 0 "register_operand" "=f")
++      (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
++  "<sqrt_condition> &&
++   TARGET_FIX_SB1 &&
++   !TARGET_FIX_ICE9A"
++  "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0"
+   [(set_attr "type" "fsqrt")
+    (set_attr "mode" "<UNITMODE>")
+-   (set (attr "length")
+-        (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
+-                      (const_int 8)
+-                      (const_int 4)))])
++   (set_attr "length" "8")])
++
++(define_insn "*sqrt<mode>2_fix_ice9a"
++  [(set (match_operand:ANYF 0 "register_operand" "=f")
++      (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
++  "<sqrt_condition> &&
++   !TARGET_FIX_SB1 &&
++   TARGET_FIX_ICE9A"
++  "sqrt.<fmt>\t%0,%1<ice9a_round>"
++  [(set_attr "type" "fsqrt")
++   (set_attr "mode" "<UNITMODE>")
++   (set_attr "length" "<ice9a_length_round>")])
+ (define_insn "*rsqrt<mode>a"
+   [(set (match_operand:ANYF 0 "register_operand" "=f")
+       (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
+                 (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
+-  "<recip_condition> && flag_unsafe_math_optimizations"
+-{
+-  if (TARGET_FIX_SB1)
+-    return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
+-  else
+-    return "rsqrt.<fmt>\t%0,%2";
+-}
++  "<recip_condition> && 
++   flag_unsafe_math_optimizations &&
++   !TARGET_FIX_SB1 &&
++   !TARGET_FIX_ICE9A"
++  "rsqrt.<fmt>\t%0,%2"
++  [(set_attr "type" "frsqrt")
++   (set_attr "mode" "<UNITMODE>")])
++
++(define_insn "*rsqrt<mode>a_fix_sb1"
++  [(set (match_operand:ANYF 0 "register_operand" "=f")
++      (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
++                (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
++  "<recip_condition> && 
++   flag_unsafe_math_optimizations &&
++   TARGET_FIX_SB1"
++  "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0"
+   [(set_attr "type" "frsqrt")
+    (set_attr "mode" "<UNITMODE>")
+-   (set (attr "length")
+-        (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
+-                      (const_int 8)
+-                      (const_int 4)))])
++   (set_attr "length" "8")])
++
++(define_insn "*rsqrt<mode>a_fix_ice9a"
++  [(set (match_operand:ANYF 0 "register_operand" "=f")
++      (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
++                (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
++  "<recip_condition> && 
++   flag_unsafe_math_optimizations &&
++   TARGET_FIX_ICE9A"
++  "<ice9a_stallnops>rsqrt.<fmt>\t%0,%2<ice9a_round>"
++  [(set_attr "type" "frsqrt")
++   (set_attr "mode" "<UNITMODE>")
++   (set_attr "length" "<ice9a_length_both>")])
+ (define_insn "*rsqrt<mode>b"
+   [(set (match_operand:ANYF 0 "register_operand" "=f")
+       (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
+                            (match_operand:ANYF 2 "register_operand" "f"))))]
+-  "<recip_condition> && flag_unsafe_math_optimizations"
+-{
+-  if (TARGET_FIX_SB1)
+-    return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
+-  else
+-    return "rsqrt.<fmt>\t%0,%2";
+-}
++  "<recip_condition> &&
++   flag_unsafe_math_optimizations &&
++   !TARGET_FIX_SB1 &&
++   !TARGET_FIX_ICE9A"
++  "rsqrt.<fmt>\t%0,%2"
++  [(set_attr "type" "frsqrt")
++   (set_attr "mode" "<UNITMODE>")])
++
++(define_insn "*rsqrt<mode>b_fix_sb1"
++  [(set (match_operand:ANYF 0 "register_operand" "=f")
++      (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
++                           (match_operand:ANYF 2 "register_operand" "f"))))]
++  "<recip_condition> &&
++   flag_unsafe_math_optimizations &&
++   TARGET_FIX_SB1"
++  "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0"
+   [(set_attr "type" "frsqrt")
+    (set_attr "mode" "<UNITMODE>")
+-   (set (attr "length")
+-        (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
+-                      (const_int 8)
+-                      (const_int 4)))])
++   (set_attr "length" "8")])
++
++(define_insn "*rsqrt<mode>b_fix_ice9a"
++  [(set (match_operand:ANYF 0 "register_operand" "=f")
++      (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
++                           (match_operand:ANYF 2 "register_operand" "f"))))]
++  "<recip_condition> &&
++   flag_unsafe_math_optimizations &&
++   TARGET_FIX_ICE9A"
++  "<ice9a_stallnops>rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0<ice9a_round>"
++  [(set_attr "type" "frsqrt")
++   (set_attr "mode" "<UNITMODE>")
++   (set_attr "length" "<ice9a_length_both>")])
\f
+ ;;
+ ;;  ....................
+@@ -2093,7 +2380,9 @@
+ (define_insn "abs<mode>2"
+   [(set (match_operand:ANYF 0 "register_operand" "=f")
+       (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
+-  "!HONOR_NANS (<MODE>mode)"
++  "!HONOR_NANS (<MODE>mode)
++  || (TARGET_MIPS_SDE
++      && TARGET_HARD_FLOAT)"
+   "abs.<fmt>\t%0,%1"
+   [(set_attr "type" "fabs")
+    (set_attr "mode" "<UNITMODE>")])
+@@ -2115,6 +2404,22 @@
+    (set_attr "mode" "<MODE>")])
\f
+ ;;
++;;  ...................
++;;
++;;  Count number of 1-bits.
++;;
++;;  ...................
++;;
++
++(define_insn "popcount<mode>2"
++  [(set (match_operand:GPR 0 "register_operand" "=d")
++      (popcount:GPR (match_operand:GPR 1 "register_operand" "d")))]
++  "ISA_HAS_POPCOUNT"
++  "<d>pop\t%0,%1"
++  [(set_attr "type" "pop")
++   (set_attr "mode" "<MODE>")])
++\f
++;;
+ ;;  ....................
+ ;;
+ ;;    NEGATION and ONE'S COMPLEMENT
+@@ -2347,6 +2652,16 @@
+    (set_attr "mode" "SI")
+    (set_attr "extended_mips16" "yes,*")])
++(define_insn "*<code>_trunc_exts<mode>"
++  [(set (match_operand:SUBDI 0 "register_operand" "=d")
++        (truncate:SUBDI
++       (any_shiftrt:DI (match_operand:DI 1 "register_operand" "d")
++                       (match_operand:DI 2 "const_int_operand" ""))))]
++  "TARGET_64BIT && ISA_HAS_EXTS && INTVAL (operands[2]) < 32"
++  "exts\t%0,%1,%2,31"
++  [(set_attr "type" "shift")
++   (set_attr "mode" "SI")])
++
+ ;; Combiner patterns to optimize shift/truncate combinations.
+ (define_insn ""
+@@ -2447,10 +2762,15 @@
+ ;; Extension insns.
+-(define_insn_and_split "zero_extendsidi2"
++(define_expand "zero_extendsidi2"
++  [(set (match_operand:DI 0 "register_operand")
++        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
++  "TARGET_64BIT")
++
++(define_insn_and_split "*zero_extendsidi2"
+   [(set (match_operand:DI 0 "register_operand" "=d,d")
+         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
+-  "TARGET_64BIT"
++  "TARGET_64BIT && !ISA_HAS_EXT_INS"
+   "@
+    #
+    lwu\t%0,%1"
+@@ -2471,7 +2791,7 @@
+   [(set (match_operand:DI 0 "register_operand" "=d,d")
+         (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,W")
+               (const_int 4294967295)))]
+-  "TARGET_64BIT"
++  "TARGET_64BIT && !ISA_HAS_EXT_INS"
+ {
+   if (which_alternative == 0)
+     return "#";
+@@ -2489,6 +2809,31 @@
+    (set_attr "mode" "DI")
+    (set_attr "length" "8,*")])
++(define_insn "*zero_extendsidi2_dext"
++  [(set (match_operand:DI 0 "register_operand" "=d,d")
++      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
++  "TARGET_64BIT && ISA_HAS_EXT_INS"
++  "@
++   dext\t%0,%1,0,32
++   lwu\t%0,%1"
++  [(set_attr "type" "shift,load")
++   (set_attr "mode" "DI")])
++
++(define_insn "*clear_upper32_dext"
++  [(set (match_operand:DI 0 "register_operand" "=d,d")
++        (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
++              (const_int 4294967295)))]
++  "TARGET_64BIT && ISA_HAS_EXT_INS"
++{
++  if (which_alternative == 0)
++    return "dext\t%0,%1,0,32";
++
++  operands[1] = gen_lowpart (SImode, operands[1]);
++  return "lwu\t%0,%1";
++}
++  [(set_attr "type" "shift,load")
++   (set_attr "mode" "DI")])
++
+ (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
+   [(set (match_operand:GPR 0 "register_operand")
+         (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
+@@ -3026,11 +3371,18 @@
+ ;;
+ ;;  ....................
+-;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
++;; Bit field extract patterns which use lwl/lwr or ldl/ldr or
++;; exts/ext/dext.
++
++;; ??? Using nonimmediate_operand for operand 1 will cause mode_for_extraction
++;; to return word_mode rather than QImode for memories.  That's probably
++;; harmless given the current middle-end code; the RTL expander will only
++;; pass QImode references in any case, and any attempt to recog() a memory
++;; extraction will fail whatever mode the memory has.
+ (define_expand "extv"
+   [(set (match_operand 0 "register_operand")
+-      (sign_extract (match_operand:QI 1 "memory_operand")
++      (sign_extract (match_operand 1 "nonimmediate_operand")
+                     (match_operand 2 "immediate_operand")
+                     (match_operand 3 "immediate_operand")))]
+   "!TARGET_MIPS16"
+@@ -3039,10 +3391,52 @@
+                                        INTVAL (operands[2]),
+                                        INTVAL (operands[3])))
+     DONE;
++  else if (ISA_HAS_EXTS
++         && register_operand (operands[1], VOIDmode)
++         && INTVAL (operands[2]) <= 32)
++    {
++      mips_adjust_register_ext_operands (operands);
++      if (GET_MODE (operands[0]) == SImode)
++      {
++        emit_insn (gen_extvsi (operands[0], operands[1], operands[2],
++                               operands[3]));
++        DONE;
++      }
++      else if (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
++      {
++        emit_insn (gen_extvdi (operands[0], operands[1], operands[2],
++                               operands[3]));
++        DONE;
++      }
++    }
+   else
+     FAIL;
+ })
++(define_insn "extv<mode>"
++  [(set (match_operand:GPR 0 "register_operand" "=d")
++        (sign_extract:GPR (match_operand:GPR 1 "register_operand" "d")
++                        (match_operand 2 "const_int_operand" "")
++                        (match_operand 3 "const_int_operand" "")))]
++  "ISA_HAS_EXTS && INTVAL (operands[2]) <= 32"
++  "exts\t%0,%1,%3,%E2"
++  [(set_attr "type" "shift")
++   (set_attr "mode" "<MODE>")])
++
++;; If we are extracting something no bigger than 32 bits, the destination
++;; register will be a properly sign-extended SImode value.  Truncation
++;; is therefore a no-op in this case.
++(define_insn "*extv_truncdi<mode>"
++  [(set (match_operand:SUBDI 0 "register_operand" "=d")
++        (truncate:SUBDI
++       (sign_extract:DI (match_operand:DI 1 "register_operand" "d")
++                        (match_operand 2 "const_int_operand" "")
++                        (match_operand 3 "const_int_operand" ""))))]
++  "TARGET_64BIT && ISA_HAS_EXTS && INTVAL (operands[2]) <= 32"
++  "exts\t%0,%1,%3,%E2"
++  [(set_attr "type" "shift")
++   (set_attr "mode" "<MODE>")])
++
+ (define_expand "extzv"
+   [(set (match_operand 0 "register_operand")
+       (zero_extract (match_operand 1 "nonimmediate_operand")
+@@ -3055,8 +3449,17 @@
+                                        INTVAL (operands[3])))
+     DONE;
+   else if (mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
+-                             INTVAL (operands[3])))
++                             INTVAL (operands[3]))
++         /* extract_bit_field can invoke us with (subreg:DI (reg:SI))
++            as the output and size more than 31 bits.  We would
++            create incorrect SI values.  Instead, just FAIL.  */
++         && (GET_MODE (operands[0]) != DImode
++             || !(GET_CODE (operands[0]) == SUBREG
++                  && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0])))
++                      < (GET_MODE_SIZE (GET_MODE (operands[0]))))
++                  && INTVAL (operands[2]) >= 32)))
+     {
++      mips_adjust_register_ext_operands (operands);
+       if (GET_MODE (operands[0]) == DImode)
+         emit_insn (gen_extzvdi (operands[0], operands[1], operands[2],
+                               operands[3]));
+@@ -3080,6 +3483,32 @@
+   [(set_attr "type"   "arith")
+    (set_attr "mode"   "<MODE>")])
++;; If we're extracting fewer than 32 bits, the upper 33 bits of the
++;; destination will be zero, and thus truncation will be a no-op.
++(define_insn "*extzv_truncdi<mode>"
++  [(set (match_operand:SUBDI 0 "register_operand" "=d")
++        (truncate:SUBDI
++       (zero_extract:DI (match_operand:DI 1 "register_operand" "d")
++                        (match_operand 2 "const_int_operand" "")
++                        (match_operand 3 "const_int_operand" ""))))]
++  "TARGET_64BIT && ISA_HAS_EXT_INS && INTVAL (operands[2]) < 32"
++  "dext\t%0,%1,%3,%2"
++  [(set_attr "type" "shift")
++   (set_attr "mode" "<MODE>")])
++
++;; If we're truncating an extraction that is at least big as the truncation
++;; mode, we can simply extract the useful bits and sign-extend the rest.
++;; The result will be a properly sign-extended value.
++(define_insn "*extz_truncdi<mode>_exts"
++  [(set (match_operand:SUBDI 0 "register_operand" "=d")
++        (truncate:SUBDI
++       (zero_extract:DI (match_operand:DI 1 "register_operand" "d")
++                        (match_operand 2 "const_int_operand" "")
++                        (match_operand 3 "const_int_operand" ""))))]
++  "TARGET_64BIT && ISA_HAS_EXTS && INTVAL (operands[2]) > <topbit>"
++  "exts\t%0,%1,%3,<topbit>"
++  [(set_attr "type" "shift")
++   (set_attr "mode" "<MODE>")])
+ (define_expand "insv"
+   [(set (zero_extract (match_operand 0 "nonimmediate_operand")
+@@ -3102,9 +3531,9 @@
+         emit_insn (gen_insvsi (operands[0], operands[1], operands[2],
+                              operands[3]));
+       DONE;
+-   }
+-   else
+-     FAIL;
++    }
++  else
++    FAIL;
+ })
+ (define_insn "insv<mode>"
+@@ -3118,6 +3547,62 @@
+   [(set_attr "type"   "arith")
+    (set_attr "mode"   "<MODE>")])
++(define_insn "*insv<mode>di"
++  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
++                         (match_operand 1 "const_int_operand" "")
++                         (match_operand 2 "const_int_operand" ""))
++        (subreg:DI
++       (truncate:SUBDI (match_operand:DI 3 "register_operand" "d")) 0))]
++  "TARGET_64BIT && mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
++                                     INTVAL (operands[2]))"
++  "dins\t%0,%3,%2,%1"
++  [(set_attr "type" "shift")
++   (set_attr "mode" "DI")])
++
++;; Combine does not notice that zero- and sign-extensions have no
++;; effect here.
++;; ??? Should ideally be done in combine instead.
++
++(define_insn "*insv_<code>_<mode>di"
++  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
++                         (match_operand 1 "const_int_operand" "")
++                         (match_operand 2 "const_int_operand" ""))
++        (any_extend:DI (match_operand:SUBDI 3 "register_operand" "d")))]
++  "TARGET_64BIT && ISA_HAS_EXT_INS && INTVAL (operands[1]) <= <topbit> + 1"
++  "dins\t%0,%3,%2,%1"
++  [(set_attr "type" "shift")
++   (set_attr "mode" "DI")])
++
++(define_insn "*insvdi_clear_upper32<mode>"
++  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
++                         (match_operand 1 "const_int_operand" "")
++                         (match_operand 2 "const_int_operand" ""))
++      (subreg:DI
++       (truncate:SUBDI
++        (and:DI (match_operand:DI 3 "register_operand" "d")
++                (const_int 4294967295))) 0))]
++  "TARGET_64BIT && ISA_HAS_EXT_INS && INTVAL (operands[1]) <= 32"
++  "dins\t%0,%3,%2,%1"
++  [(set_attr "type" "shift")
++   (set_attr "mode" "DI")])
++
++;; Combiner pattern for cins.
++
++(define_insn "*cins"
++  [(set (match_operand:DI 0 "register_operand" "=d")
++      (match_operator:DI 1 "mask_low_and_shift_operator"
++                         [(ashift:DI
++                           (match_operand:DI 2 "register_operand" "d")
++                           (match_operand:DI 3 "const_int_operand" ""))
++                          (match_operand:DI 4 "const_int_operand" "")]))]
++  "TARGET_64BIT && ISA_HAS_CINS"
++{
++  operands[4]
++    = GEN_INT (mask_low_and_shift_len (DImode, INTVAL (operands[3]),
++                                     INTVAL (operands[4])));
++  return "cins\t%0,%2,%3,%E4";
++})
++
+ ;; Unaligned word moves generated by the bit field patterns.
+ ;;
+ ;; As far as the rtl is concerned, both the left-part and right-part
+@@ -3135,7 +3620,9 @@
+       (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
+                    (match_operand:QI 2 "memory_operand" "m")]
+                   UNSPEC_LOAD_LEFT))]
+-  "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
++  "!TARGET_MIPS16
++   && !ISA_HAS_UL_US
++   && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
+   "<load>l\t%0,%2"
+   [(set_attr "type" "load")
+    (set_attr "mode" "<MODE>")])
+@@ -3146,7 +3633,9 @@
+                    (match_operand:QI 2 "memory_operand" "m")
+                    (match_operand:GPR 3 "register_operand" "0")]
+                   UNSPEC_LOAD_RIGHT))]
+-  "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
++  "!TARGET_MIPS16
++   && !ISA_HAS_UL_US
++   && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
+   "<load>r\t%0,%2"
+   [(set_attr "type" "load")
+    (set_attr "mode" "<MODE>")])
+@@ -3156,7 +3645,9 @@
+       (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
+                    (match_operand:QI 2 "memory_operand" "m")]
+                   UNSPEC_STORE_LEFT))]
+-  "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
++  "!TARGET_MIPS16
++   && !ISA_HAS_UL_US
++   && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
+   "<store>l\t%z1,%2"
+   [(set_attr "type" "store")
+    (set_attr "mode" "<MODE>")])
+@@ -3172,6 +3663,28 @@
+   [(set_attr "type" "store")
+    (set_attr "mode" "<MODE>")])
++;; Unaligned load and store patterns.
++
++(define_insn "mov_u<load>"
++  [(set (match_operand:GPR 0 "register_operand" "=d")
++      (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
++                   (match_operand:QI 2 "memory_operand" "m")]
++                  UNSPEC_UNALIGNED_LOAD))]
++  "ISA_HAS_UL_US && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
++  "u<load>\t%0,%2"
++  [(set_attr "type" "load")
++   (set_attr "mode" "<MODE>")])
++
++(define_insn "mov_u<store>"
++  [(set (match_operand:BLK 0 "memory_operand" "=m")
++      (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
++                   (match_operand:QI 2 "memory_operand" "m")]
++                  UNSPEC_UNALIGNED_STORE))]
++  "ISA_HAS_UL_US && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
++  "u<store>\t%z1,%2"
++  [(set_attr "type" "store")
++   (set_attr "mode" "<MODE>")])
++
+ ;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE.
+ ;; The required value is:
+ ;;
+@@ -3497,6 +4010,26 @@
+                (const_string "*")
+                (const_string "*")])])
++;; Truncate to QI in two steps.  Combine should probably canonicalize
++;; this to just one truncate:QI.
++
++(define_insn "*truncsi_storeqi"
++  [(set (match_operand:QI 0 "memory_operand" "=m")
++        (subreg:QI
++       (truncate:SI (match_operand:DI 1 "register_operand" "d")) 3))]
++  "TARGET_64BIT && !TARGET_MIPS16 && TARGET_BIG_ENDIAN"
++  "sb\t%z1,%0"
++  [(set_attr "type" "store")
++   (set_attr "mode" "QI")])
++
++(define_insn "*truncsi_storehi"
++  [(set (match_operand:HI 0 "memory_operand" "=m")
++        (subreg:HI
++       (truncate:SI (match_operand:DI 1 "register_operand" "d")) 2))]
++  "TARGET_64BIT && !TARGET_MIPS16 && TARGET_BIG_ENDIAN"
++  "sh\t%z1,%0"
++  [(set_attr "type" "store")
++   (set_attr "mode" "HI")])
+ ;; On the mips16, we can split ld $r,N($r) into an add and a load,
+ ;; when the original load is a 4 byte instruction but the add and the
+@@ -4270,6 +4803,22 @@
+   [(set (match_operand:P 0 "register_operand" "=d")
+       (const:P (unspec:P [(const_int 0)] UNSPEC_GP)))])
++;; Move the constant value of __gnu_local_gp (operand 1) into
++;; operand 0, for non-PIC abicalls code.  All uses of the result
++;; are explicit, so there's no need for unspec_volatile here.
++(define_insn_and_split "loadgp_nonpic"
++  [(set (match_operand 0 "register_operand" "=d")
++      (const (unspec [(match_operand 1 "" "")] UNSPEC_LOADGP)))]
++  "TARGET_ABICALLS && !flag_pic"
++  "#"
++  ""
++  [(const_int 0)]
++{
++  mips_emit_move (operands[0], operands[1]);
++  DONE;
++}
++  [(set_attr "length" "8")])
++
+ ;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
+ ;; of _gp from the start of this function.  Operand 1 is the incoming
+ ;; function address.
+@@ -4820,7 +5369,7 @@
+ (define_insn_and_split ""
+   [(set (match_operand:SI 0 "register_operand" "=d")
+       (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
+-                   (match_operand:SI 2 "immediate_operand" "I")))]
++                   (match_operand:SI 2 "const_int_operand" "")))]
+   "TARGET_MIPS16"
+   "#"
+   ""
+@@ -4997,6 +5546,96 @@
+   [(set_attr "type" "branch")
+    (set_attr "mode" "none")])
++;; Conditional branch on whether a bit is set or clear.
++
++(define_insn "*branch_bit<mode>"
++  [(set (pc)
++        (if_then_else
++         (match_operator 0 "equality_operator"
++                       [(zero_extract:GPR
++                         (match_operand:GPR 2 "register_operand" "d")
++                         (const_int 1)
++                         (match_operand 3 "const_int_operand" ""))
++                       (const_int 0)])
++       (label_ref (match_operand 1 "" ""))
++       (pc)))]
++  "ISA_HAS_BBIT"
++{
++  return mips_output_conditional_branch (insn, operands,
++                                       MIPS_BRANCH ("b%G0", "%2,%3,%1"),
++                                       MIPS_BRANCH ("b%H0", "%2,%3,%1"));
++}
++  [(set_attr "type" "branch")
++   (set_attr "branch_without_likely" "yes")
++   (set_attr "mode" "none")])
++
++(define_insn "*branch_bit_truncdi<mode>"
++  [(set (pc)
++        (if_then_else
++         (match_operator 0 "equality_operator"
++                       [(zero_extract:DI
++                         (subreg:DI
++                          (truncate:SUBDI
++                           (match_operand:DI 2 "register_operand" "d")) 0)
++                         (const_int 1)
++                         (match_operand 3 "const_int_operand" ""))
++                       (const_int 0)])
++       (label_ref (match_operand 1 "" ""))
++       (pc)))]
++  "TARGET_64BIT && ISA_HAS_BBIT"
++{
++  return mips_output_conditional_branch (insn, operands,
++                                       MIPS_BRANCH ("b%G0", "%2,%3,%1"),
++                                       MIPS_BRANCH ("b%H0", "%2,%3,%1"));
++}
++  [(set_attr "type" "branch")
++   (set_attr "branch_without_likely" "yes")
++   (set_attr "mode" "none")])
++
++(define_insn "*branch_bit<mode>_inverted"
++  [(set (pc)
++        (if_then_else
++         (match_operator 0 "equality_operator"
++                       [(zero_extract:GPR
++                         (match_operand:GPR 2 "register_operand" "d")
++                         (const_int 1)
++                         (match_operand 3 "const_int_operand" ""))
++                       (const_int 0)])
++       (pc)
++       (label_ref (match_operand 1 "" ""))))]
++  "ISA_HAS_BBIT"
++{
++  return mips_output_conditional_branch (insn, operands,
++                                       MIPS_BRANCH ("b%H0", "%2,%3,%1"),
++                                       MIPS_BRANCH ("b%G0", "%2,%3,%1"));
++}
++  [(set_attr "type" "branch")
++   (set_attr "branch_without_likely" "yes")
++   (set_attr "mode" "none")])
++
++(define_insn "*branch_bit_truncdi<mode>_inverted"
++  [(set (pc)
++        (if_then_else
++         (match_operator 0 "equality_operator"
++                       [(zero_extract:DI
++                         (subreg:DI
++                          (truncate:SUBDI
++                           (match_operand:DI 2 "register_operand" "d")) 0)
++                         (const_int 1)
++                         (match_operand 3 "const_int_operand" ""))
++                       (const_int 0)])
++       (pc)
++       (label_ref (match_operand 1 "" ""))))]
++  "TARGET_64BIT && ISA_HAS_BBIT"
++{
++  return mips_output_conditional_branch (insn, operands,
++                                       MIPS_BRANCH ("b%H0", "%2,%3,%1"),
++                                       MIPS_BRANCH ("b%G0", "%2,%3,%1"));
++}
++  [(set_attr "type" "branch")
++   (set_attr "branch_without_likely" "yes")
++   (set_attr "mode" "none")])
++
+ ;; MIPS16 branches
+ (define_insn "*branch_equality<mode>_mips16"
+@@ -5065,11 +5704,42 @@
+   [(set (match_operand:GPR 0 "register_operand" "=d")
+       (eq:GPR (match_operand:GPR 1 "register_operand" "d")
+               (const_int 0)))]
+-  "!TARGET_MIPS16"
++  "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
+   "sltu\t%0,%1,1"
+   [(set_attr "type" "slt")
+    (set_attr "mode" "<MODE>")])
++(define_insn "*seq_si_to_di"
++  [(set (match_operand:DI 0 "register_operand" "=d")
++      (eq:DI (match_operand:SI 1 "register_operand" "d")
++             (const_int 0)))]
++  "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
++  "sltu\t%0,%1,1"
++  [(set_attr "type" "slt")
++   (set_attr "mode" "DI")])
++
++(define_insn "*s<code>_<mode>_s<code>"
++  [(set (match_operand:GPR 0 "register_operand" "=d,d")
++        (equality_op:GPR (match_operand:GPR 1 "register_operand" "%d,d")
++                       (match_operand:GPR 2 "reg_imm10_operand" "d,YB")))]
++  "ISA_HAS_SEQ_SNE"
++  "@
++   s<code>\\t%0,%1,%2
++   s<code>i\\t%0,%1,%2"
++  [(set_attr "type" "arith")
++   (set_attr "mode" "<MODE>")])
++
++(define_insn "*s<code>_si_to_di_s<code>"
++  [(set (match_operand:DI 0 "register_operand" "=d,d")
++        (equality_op:DI (match_operand:SI 1 "register_operand" "%d,d")
++                      (match_operand:SI 2 "reg_imm10_operand" "d,YB")))]
++  "TARGET_64BIT && ISA_HAS_SEQ_SNE"
++  "@
++   s<code>\\t%0,%1,%2
++   s<code>i\\t%0,%1,%2"
++  [(set_attr "type" "arith")
++   (set_attr "mode" "SI")])
++
+ (define_insn "*seq_<mode>_mips16"
+   [(set (match_operand:GPR 0 "register_operand" "=t")
+       (eq:GPR (match_operand:GPR 1 "register_operand" "d")
+@@ -5079,6 +5749,15 @@
+   [(set_attr "type" "slt")
+    (set_attr "mode" "<MODE>")])
++(define_insn "*seq_si_to_di_mips16"
++  [(set (match_operand:DI 0 "register_operand" "=d")
++      (eq:DI (match_operand:SI 1 "register_operand" "d")
++             (const_int 0)))]
++  "TARGET_64BIT && TARGET_MIPS16"
++  "sltu\t%1,1"
++  [(set_attr "type" "slt")
++   (set_attr "mode" "DI")])
++
+ ;; "sne" uses sltu instructions in which the first operand is $0.
+ ;; This isn't possible in mips16 code.
+@@ -5093,11 +5772,20 @@
+   [(set (match_operand:GPR 0 "register_operand" "=d")
+       (ne:GPR (match_operand:GPR 1 "register_operand" "d")
+               (const_int 0)))]
+-  "!TARGET_MIPS16"
++  "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
+   "sltu\t%0,%.,%1"
+   [(set_attr "type" "slt")
+    (set_attr "mode" "<MODE>")])
++(define_insn "*sne_si_to_di"
++  [(set (match_operand:DI 0 "register_operand" "=d")
++      (ne:DI (match_operand:SI 1 "register_operand" "d")
++             (const_int 0)))]
++  "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
++  "sltu\t%0,%.,%1"
++  [(set_attr "type" "slt")
++   (set_attr "mode" "DI")])
++
+ (define_expand "sgt"
+   [(set (match_operand:SI 0 "register_operand")
+       (gt:SI (match_dup 1)
+@@ -5353,6 +6041,26 @@
+       return "%*b\t%l0%/";
+       else
+       {
++        if (final_sequence && (mips_abi == ABI_32 || mips_abi == ABI_O64))
++          {
++              /* If the delay slot contains a $gp restore, we need to
++                 do that first, because we need it for the load
++               label.  Other ABIs do not have caller-save $gp.  */
++            rtx next = NEXT_INSN (insn);
++            if (INSN_P (next) && !INSN_DELETED_P (next))
++              {
++                rtx pat = PATTERN (next);
++                if (GET_CODE (pat) == SET
++                    && REG_P (SET_DEST (pat))
++                    && REGNO (SET_DEST (pat)) == PIC_OFFSET_TABLE_REGNUM)
++                  {
++                    rtx ops[2];
++                    ops[0] = SET_DEST (pat);
++                    ops[1] = SET_SRC (pat);
++                    output_asm_insn (mips_output_move (ops[0], ops[1]), ops);
++                  }
++              }
++          }
+         output_asm_insn (mips_output_load_label (), operands);
+         return "%*jr\t%@%/%]";
+       }
+@@ -5371,7 +6079,13 @@
+             (lt (abs (minus (match_dup 0)
+                             (plus (pc) (const_int 4))))
+                 (const_int 131072)))
+-       (const_int 4) (const_int 16)))])
++       (const_int 4)
++         (if_then_else
++          ;; for these two ABIs we may need to move a restore of $gp
++          (ior (eq (symbol_ref "mips_abi") (symbol_ref "ABI_32"))
++               (eq (symbol_ref "mips_abi") (symbol_ref "ABI_O64")))
++          (const_int 20)
++          (const_int 16))))])
+ ;; We need a different insn for the mips16, because a mips16 branch
+ ;; does not have a delay slot.
+@@ -5462,11 +6176,12 @@
+ ;; Restore the gp that we saved above.  Despite the earlier comment, it seems
+ ;; that older code did recalculate the gp from $25.  Continue to jump through
+-;; $25 for compatibility (we lose nothing by doing so).
++;; $25 for compatibility (we lose nothing by doing so).  Similarly restore
++;; $gp if we might be jumping to code which expects that.
+ (define_expand "builtin_longjmp"
+   [(use (match_operand 0 "register_operand"))]
+-  "TARGET_USE_GOT"
++  "TARGET_USE_GOT || TARGET_ABICALLS"
+ {
+   /* The elements of the buffer are, in order:  */
+   int W = GET_MODE_SIZE (Pmode);
+--- a/gcc/config/mips/mips.opt
++++ b/gcc/config/mips/mips.opt
+@@ -124,6 +124,10 @@ mfix-vr4130
+ Target Report Var(TARGET_FIX_VR4130)
+ Work around VR4130 mflo/mfhi errata
++mfix-ice9a
++Target Report Var(TARGET_FIX_ICE9A)
++Work around SiCortex ICE9A errata
++
+ mfix4300
+ Target Report Var(TARGET_4300_MUL_FIX)
+ Work around an early 4300 hardware bug
+@@ -176,6 +180,10 @@ mips16
+ Target Report RejectNegative Mask(MIPS16)
+ Generate MIPS16 code
++mips16e
++Target Report RejectNegative Mask(MIPS16) MaskExists
++Deprecated; alias for -mips16
++
+ mips3d
+ Target Report RejectNegative Mask(MIPS3D)
+ Use MIPS-3D instructions
+@@ -228,6 +236,10 @@ mno-mips3d
+ Target Report RejectNegative InverseMask(MIPS3D)
+ Do not use MIPS-3D instructions
++mocteon-useun
++Target Report Mask(OCTEON_UNALIGNED)
++Use Octeon-specific unaligned loads/stores for 32/64-bit data
++
+ mpaired-single
+ Target Report Mask(PAIRED_SINGLE_FLOAT)
+ Use paired-single floating-point instructions
+@@ -260,6 +272,10 @@ mtune=
+ Target RejectNegative Joined Var(mips_tune_string)
+ -mtune=PROCESSOR      Optimize the output for PROCESSOR
++muclibc
++Target RejectNegative Var(building_for_uclibc)
++Building with -muclibc
++
+ muninit-const-in-rodata
+ Target Report Var(TARGET_UNINIT_CONST_IN_RODATA)
+ Put uninitialized constants in ROM (needs -membedded-data)
+@@ -268,6 +284,10 @@ mvr4130-align
+ Target Report Mask(VR4130_ALIGN)
+ Perform VR4130-specific alignment optimizations
++mwarn-framesize=
++Target RejectNegative Joined
++Warn if a single function's framesize exceeds the given framesize
++
+ mxgot
+ Target Report Var(TARGET_XGOT)
+ Lift restrictions on GOT size
+--- /dev/null
++++ b/gcc/config/mips/montavista-linux.h
+@@ -0,0 +1,54 @@
++/* MontaVista GNU/Linux Configuration.
++   Copyright (C) 2009
++   Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 3, or (at your option)
++any later version.
++
++GCC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++/* Override linux64.h to default to O32.  */
++#undef SUBTARGET_SELF_SPECS
++#define SUBTARGET_SELF_SPECS \
++NO_SHARED_SPECS, \
++"%{!EB:%{!EL:%(endian_spec)}}", \
++"%{!mabi=*: -mabi=32}"
++
++/* We do not need to provide an explicit big-endian multilib.  */
++#undef MULTILIB_DEFAULTS
++#define MULTILIB_DEFAULTS \
++  { "meb", "mabi=32" }
++
++/* The various C libraries each have their own subdirectory.  */
++#undef SYSROOT_SUFFIX_SPEC
++#define SYSROOT_SUFFIX_SPEC                   \
++  "%{mel:%{msoft-float:/mel/soft-float ;      \
++           :/mel} ;                           \
++     msoft-float:/soft-float}"
++
++/* MULTILIB_OSDIRNAMES provides directory names used in two ways:
++   relative to $target/lib/ in the GCC installation, and relative to
++   lib/ and usr/lib/ in a sysroot.  For the latter, we want names such
++   as plain ../lib64, but these cannot be used outside the sysroot
++   because different multilibs would be mapped to the same directory.
++   Directories are searched both with and without the multilib suffix,
++   so it suffices if the directory without the suffix is correct
++   within the sysroot while the directory with the suffix doesn't
++   exist.  We use STARTFILE_PREFIX_SPEC to achieve the desired
++   effect.  */
++#undef STARTFILE_PREFIX_SPEC
++#define STARTFILE_PREFIX_SPEC                         \
++  "%{mabi=32: /usr/local/lib/ /lib/ /usr/lib/}                \
++   %{mabi=n32: /usr/local/lib32/ /lib32/ /usr/lib32/} \
++   %{mabi=64: /usr/local/lib64/ /lib64/ /usr/lib64/}"
+--- /dev/null
++++ b/gcc/config/mips/octeon-elf-unwind.h
+@@ -0,0 +1,57 @@
++/* Stack unwinding support through the first exception frame.
++   Copyright (C) 2007 Cavium Networks.
++
++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, 51 Franklin Street, Fifth Floor,
++Boston, MA 02110-1301, USA.  */
++
++#define MD_FALLBACK_FRAME_STATE_FOR octeon_elf_fallback_frame_state
++
++/* Check whether this is the cvmx_interrupt_stage2 frame.  If the
++   function call was dispatched via k0 assume we are in
++   cvmx_interrupt_stage2.  In this case the sp in point to the saved
++   register array.  */
++
++static _Unwind_Reason_Code
++octeon_elf_fallback_frame_state (struct _Unwind_Context *context,
++                               _Unwind_FrameState *fs)
++{
++  unsigned i;
++  unsigned *pc = context->ra;
++
++  /* Look for "jalr k0".  */
++  if (pc[-2] != 0x0340f809)
++    return _URC_END_OF_STACK;
++  
++  for (i = 0; i < 32; i++)
++    {
++      fs->regs.reg[i].how = REG_SAVED_OFFSET;
++      fs->regs.reg[i].loc.offset = 8 * i;
++    }
++
++  /* Keep the next frame's sp.  This way we have a CFA that points
++     exactly to the register array.  */
++  fs->regs.cfa_how = CFA_REG_OFFSET;
++  fs->regs.cfa_reg = STACK_POINTER_REGNUM;
++  fs->regs.cfa_offset = 0;
++
++  /* DEPC is saved as the 35. register.  */
++  fs->regs.reg[DWARF_ALT_FRAME_RETURN_COLUMN].how = REG_SAVED_OFFSET;
++  fs->regs.reg[DWARF_ALT_FRAME_RETURN_COLUMN].loc.offset = 8 * 35;
++  fs->retaddr_column = DWARF_ALT_FRAME_RETURN_COLUMN;
++
++  return _URC_NO_REASON;
++}
+--- /dev/null
++++ b/gcc/config/mips/octeon-elf.h
+@@ -0,0 +1,98 @@
++/* Macros for mips*-octeon-elf target.
++   Copyright (C) 2004, 2005, 2006 Cavium Networks.
++
++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, 51 Franklin Street, Fifth Floor,
++Boston, MA 02110-1301, USA.  */
++
++/* Add MASK_SOFT_FLOAT and MASK_OCTEON_UNALIGNED.  */
++
++#undef TARGET_DEFAULT
++#define TARGET_DEFAULT (MASK_SOFT_FLOAT_ABI | MASK_OCTEON_UNALIGNED)
++
++/* Forward -m*octeon-useun.  */
++
++#undef SUBTARGET_ASM_SPEC
++#define SUBTARGET_ASM_SPEC "%{mno-octeon-useun} %{!mno-octeon-useun:-mocteon-useun}"
++
++/* Enable backtrace including on machine exceptions by default.  */
++
++#undef SUBTARGET_CC1_SPEC
++#define SUBTARGET_CC1_SPEC "%{!fno-asynchronous-unwind-tables:-fasynchronous-unwind-tables}"
++
++/* Without ASM_PREFERRED_EH_DATA_FORMAT, output_call_frame_info emits
++   pointer-sized addresses for FDE addresses.  For 64-bit targets, it does
++   it without properly "switching over" to 64-bit as described in the DWARF3
++   spec. GDB can fall back on .eh_frames and misinterpret FDE addresses.
++   Instead let's be explicit and use augmentation to describe the encoding if
++   pointer size is 64.  */
++
++#undef ASM_PREFERRED_EH_DATA_FORMAT
++#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
++  ((CODE) == 1 && POINTER_SIZE == 64                                    \
++   ? (ABI_HAS_64BIT_SYMBOLS ? DW_EH_PE_udata8 : DW_EH_PE_udata4)        \
++   : DW_EH_PE_absptr)
++
++/* Link to libc library.  */
++
++#undef LIB_SPEC
++#define LIB_SPEC "-lc"
++
++/* Link to startup file.  */
++
++#undef STARTFILE_SPEC
++#define STARTFILE_SPEC "crti%O%s crtbegin%O%s crt0%O%s"
++
++/* Default our test-only n64 configuration to -G0 since that is what
++   the kernel uses.  */
++
++#undef SUBTARGET_SELF_SPECS
++#define SUBTARGET_SELF_SPECS \
++"%{mabi=64:%{!G*: -G0}}"
++
++/* Pass linker emulation mode for N32.  */
++
++#undef LINK_SPEC
++#define LINK_SPEC "\
++%(endian_spec) \
++%{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips32r2} %{mips64} \
++%{mips64r2} %{bestGnum} %{shared} %{non_shared} \
++%{mabi=n32:-melf32e%{!EL:b}%{EL:l}octeonn32} \
++%{mabi=64:-melf64e%{!EL:b}%{EL:l}octeon}"
++
++/* Override because of N32.  */
++
++#undef LOCAL_LABEL_PREFIX
++#define LOCAL_LABEL_PREFIX ((mips_abi == ABI_N32) ? "." : "$")
++
++/* Append the core number to the GCOV filename FN.  */
++
++#define GCOV_TARGET_SUFFIX_LENGTH 2
++#define ADD_GCOV_TARGET_SUFFIX(FN)            \
++do                                            \
++  {                                           \
++    char *fn = FN;                            \
++    int core;                                 \
++    char s[3];                                        \
++                                              \
++    asm ("rdhwr %0, $0" : "=r"(core));                \
++    sprintf (s, "%d", core);                  \
++    strcat (fn, s);                           \
++  }                                           \
++while (0)
++
++/* Code to unwind through the exception frame.  */
++#define MD_UNWIND_SUPPORT "config/mips/octeon-elf-unwind.h"
+--- /dev/null
++++ b/gcc/config/mips/octeon.h
+@@ -0,0 +1,68 @@
++/* Macros for mips*-octeon-* target.
++   Copyright (C) 2004, 2005, 2006 Cavium Networks.
++
++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, 51 Franklin Street, Fifth Floor,
++Boston, MA 02110-1301, USA.  */
++
++#define CVMX_SHARED_BSS_FLAGS (SECTION_WRITE | SECTION_BSS)
++
++#undef TARGET_ASM_SELECT_SECTION
++#define TARGET_ASM_SELECT_SECTION octeon_select_section
++
++#undef TARGET_ASM_UNIQUE_SECTION
++#define TARGET_ASM_UNIQUE_SECTION octeon_unique_section
++
++/* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. This differs from the 
++   generic version only in the use of cvmx_shared attribute.  */
++ 
++#undef ASM_OUTPUT_ALIGNED_DECL_LOCAL
++#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGN) \
++  do                                                                  \
++    {                                                                 \
++      if ((DECL) && TREE_CODE ((DECL)) == VAR_DECL                    \
++        && lookup_attribute ("cvmx_shared", DECL_ATTRIBUTES (DECL)))  \
++      {                                                               \
++           fprintf ((STREAM), "%s", LOCAL_ASM_OP);                    \
++           assemble_name ((STREAM), (NAME));                          \
++           fprintf ((STREAM), "\n");                                  \
++         octeon_output_shared_variable ((STREAM), (DECL), (NAME),     \
++                                        (SIZE), (ALIGN));             \
++       }                                                              \
++      else                                                            \
++      ASM_OUTPUT_ALIGNED_LOCAL (STREAM, NAME, SIZE, ALIGN);           \
++    }                                                                 \
++  while (0) 
++
++\f
++/* Implement ASM_OUTPUT_ALIGNED_DECL_COMMON.  This differs from the mips 
++   version only in the use of cvmx_shared attribute.  */
++
++#undef ASM_OUTPUT_ALIGNED_DECL_COMMON
++#define ASM_OUTPUT_ALIGNED_DECL_COMMON(STREAM, DECL, NAME, SIZE, ALIGN)          \
++  {                                                                      \
++    if (TREE_CODE ((DECL)) == VAR_DECL                                           \
++        && lookup_attribute ("cvmx_shared", DECL_ATTRIBUTES ((DECL))))           \
++      {                                                                          \
++      if (TREE_PUBLIC ((DECL)) && DECL_NAME ((DECL)))                    \
++        targetm.asm_out.globalize_label (asm_out_file, (NAME));          \
++      octeon_output_shared_variable ((STREAM), (DECL), (NAME),           \
++                                     (SIZE), (ALIGN));                   \
++      }                                                                          \
++    else                                                                 \
++      mips_output_aligned_decl_common ((STREAM), (DECL), (NAME), (SIZE),   \
++                                     (ALIGN));                           \
++   }
+--- /dev/null
++++ b/gcc/config/mips/octeon.md
+@@ -0,0 +1,85 @@
++;; Octeon pipeline description.
++;;   Copyright (C) 2004, 2005, 2006 Cavium Networks.
++;;
++;; 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, 51 Franklin Street, Fifth Floor, Boston,
++;; MA 02110-1301, USA.
++
++;; The OCTEON is a dual-issue processor that can bundle instructions as:
++;; {arith|imul(3)|idiv|*hilo|condmove|load|store|branch|jump|xfer}
++;; {arith|imul(3)|idiv|*hilo|condmove}
++
++(define_automaton "octeon")
++
++(define_cpu_unit "octeon_pipe0" "octeon")
++(define_cpu_unit "octeon_pipe1" "octeon")
++(define_cpu_unit "octeon_mult" "octeon")
++
++(define_insn_reservation "octeon_arith" 1
++  (and (eq_attr "cpu" "octeon")
++       (eq_attr "type" "arith,const,shift,slt,nop,logical,signext,move"))
++  "octeon_pipe0 | octeon_pipe1")
++
++(define_insn_reservation "octeon_condmove" 2
++  (and (eq_attr "cpu" "octeon")
++       (eq_attr "type" "condmove"))
++  "octeon_pipe0 | octeon_pipe1")
++
++;; ??? Unaligned accesses take longer.  We will need to differentiate
++;; between the two.
++
++(define_insn_reservation "octeon_pipe0" 2
++  (and (eq_attr "cpu" "octeon")
++       (eq_attr "type" "load,store,prefetch,mfc,mtc"))
++  "octeon_pipe0")
++
++(define_insn_reservation "octeon_brj" 1
++  (and (eq_attr "cpu" "octeon")
++       (eq_attr "type" "branch,jump,call,trap"))
++  "octeon_pipe0")
++
++(define_insn_reservation "octeon_imul3" 5
++  (and (eq_attr "cpu" "octeon")
++       (eq_attr "type" "imul3,pop,clz"))
++  "(octeon_pipe0 | octeon_pipe1) + octeon_mult")
++
++(define_insn_reservation "octeon_imul" 2
++  (and (eq_attr "cpu" "octeon")
++       (eq_attr "type" "imul,mthilo"))
++  "(octeon_pipe0 | octeon_pipe1) + octeon_mult, octeon_mult")
++
++(define_insn_reservation "octeon_mfhilo" 5
++  (and (eq_attr "cpu" "octeon")
++       (eq_attr "type" "mfhilo"))
++  "(octeon_pipe0 | octeon_pipe1) + octeon_mult")
++
++(define_insn_reservation "octeon_imadd" 4
++  (and (eq_attr "cpu" "octeon")
++       (eq_attr "type" "imadd"))
++  "(octeon_pipe0 | octeon_pipe1) + octeon_mult, (octeon_mult * 3)")
++
++(define_insn_reservation "octeon_idiv" 72
++  (and (eq_attr "cpu" "octeon")
++       (eq_attr "type" "idiv"))
++  "(octeon_pipe0 | octeon_pipe1) + octeon_mult, (octeon_mult * 71)")
++
++;; Assume both pipes are needed for unknown and multiple-instruction
++;; patterns.
++
++(define_insn_reservation "octeon_unknown" 1
++  (and (eq_attr "cpu" "octeon")
++       (eq_attr "type" "unknown,multi"))
++  "octeon_pipe0 + octeon_pipe1")
+--- a/gcc/config/mips/predicates.md
++++ b/gcc/config/mips/predicates.md
+@@ -105,11 +105,15 @@
+       /* We can only use direct calls for TARGET_ABSOLUTE_ABICALLS if we
+        are sure that the target function does not need $25 to be live
+        on entry.  This is true for any locally-defined function because
+-       any such function will use %hi/%lo accesses to set up $gp.  */
++       any such function will use %hi/%lo accesses to set up $gp.
++       Alternatively, if PLTs and copy relocations are available, the
++       static linker will make sure that $25 is valid on entry to the
++       target function.  */
+       if (TARGET_ABSOLUTE_ABICALLS
+           && !(GET_CODE (op) == SYMBOL_REF
+              && SYMBOL_REF_DECL (op)
+-             && !DECL_EXTERNAL (SYMBOL_REF_DECL (op))))
++             && !DECL_EXTERNAL (SYMBOL_REF_DECL (op)))
++        && flag_pic)
+       return false;
+       /* If -mlong-calls or if this function has an explicit long_call
+@@ -209,6 +213,20 @@
+     }
+ })
++(define_predicate "mask_low_and_shift_operator"
++  (and (match_code "and")
++       (match_test "GET_CODE (XEXP (op, 0)) == ASHIFT
++                  && GET_CODE (XEXP (op, 1)) == CONST_INT
++                  && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT"))
++{
++  int len;
++
++  len = mask_low_and_shift_len (GET_MODE (op),
++                              INTVAL (XEXP (XEXP (op, 0), 1)),
++                              INTVAL (XEXP (op, 1)));
++  return 0 < len && len <= 32;
++})
++
+ (define_predicate "consttable_operand"
+   (match_test "CONSTANT_P (op)"))
+--- a/gcc/config/mips/sde.h
++++ b/gcc/config/mips/sde.h
+@@ -19,7 +19,11 @@ You should have received a copy of the G
+ along with GCC; see the file COPYING3.  If not see
+ <http://www.gnu.org/licenses/>.  */
+-#define DRIVER_SELF_SPECS                                             \
++#undef TARGET_MIPS_SDE
++#define TARGET_MIPS_SDE 1
++
++#undef SUBTARGET_SELF_SPECS
++#define SUBTARGET_SELF_SPECS                                          \
+   /* Make sure a -mips option is present.  This helps us to pick      \
+      the right multilib, and also makes the later specs easier                \
+      to write.  */                                                    \
+@@ -28,6 +32,9 @@ along with GCC; see the file COPYING3.  
+   /* Infer the default float setting from -march.  */                 \
+   MIPS_ARCH_FLOAT_SPEC,                                                       \
+                                                                       \
++  /* Infer the default dsp setting from -march.  */                   \
++  MIPS_ARCH_DSP_SPEC,                                                 \
++                                                                      \
+   /* If no ABI option is specified, infer one from the ISA level      \
+      or -mgp setting.  */                                             \
+   "%{!mabi=*: %{" MIPS_32BIT_OPTION_SPEC ": -mabi=32;: -mabi=n32}}",  \
+@@ -56,7 +63,6 @@ along with GCC; see the file COPYING3.  
+ #undef SUBTARGET_ASM_SPEC
+ #define SUBTARGET_ASM_SPEC "\
+ %{!mips1:--trap} \
+-%{fPIC|fpic|fPIE|fpie:%{!mips16*:-KPIC}} \
+ %{mips16:-no-mips16}"
+ #undef LINK_SPEC
+--- a/gcc/config/mips/sdemtk.h
++++ b/gcc/config/mips/sdemtk.h
+@@ -19,6 +19,8 @@ You should have received a copy of the G
+ along with GCC; see the file COPYING3.  If not see
+ <http://www.gnu.org/licenses/>.  */
++#define TARGET_MIPS_SDEMTK    1
++
+ #define TARGET_OS_CPP_BUILTINS()                      \
+   do                                                  \
+     {                                                 \
+@@ -105,3 +107,13 @@ extern void mips_sync_icache (void *beg,
+ /* ...nor does the call sequence preserve $31.  */
+ #undef MIPS_SAVE_REG_FOR_PROFILING_P
+ #define MIPS_SAVE_REG_FOR_PROFILING_P(REGNO) ((REGNO) == GP_REG_FIRST + 31)
++
++/* From mips.h, with mno-float option added.  */
++
++#undef MIPS_ARCH_FLOAT_SPEC
++#define MIPS_ARCH_FLOAT_SPEC \
++  "%{mhard-float|msoft-float|mno-float|march=mips*:; \
++     march=vr41*|march=m4k|march=4k*|march=24kc|march=24kec \
++     |march=34kc|march=74kc|march=5kc: -msoft-float; \
++     march=*: -mhard-float}"
++
+--- /dev/null
++++ b/gcc/config/mips/sicortex.h
+@@ -0,0 +1,30 @@
++/* SiCortex GNU/Linux Configuration.
++   Copyright (C) 2008
++   Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 3, or (at your option)
++any later version.
++
++GCC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++/* Override linux.h default to add __SICORTEX__ define.  */
++#undef TARGET_OS_CPP_BUILTINS
++#define TARGET_OS_CPP_BUILTINS()                              \
++  do {                                                                \
++    LINUX_TARGET_OS_CPP_BUILTINS();                           \
++    builtin_define ("__SICORTEX__");                          \
++    /* The GNU C++ standard library requires this.  */                \
++    if (c_dialect_cxx ())                                     \
++      builtin_define ("_GNU_SOURCE");                         \
++  } while (0)
+--- /dev/null
++++ b/gcc/config/mips/t-crtfm
+@@ -0,0 +1,9 @@
++
++EXTRA_MULTILIB_PARTS += crtfastmath.o
++
++EXTRA_PARTS += crtfastmath.o
++
++$(T)crtfastmath.o: $(srcdir)/config/mips/crtfastmath.c $(GCC_PASSES)
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
++      -c -o $(T)crtfastmath.o $(srcdir)/config/mips/crtfastmath.c
++
+--- /dev/null
++++ b/gcc/config/mips/t-montavista-elf
+@@ -0,0 +1,22 @@
++# MontaVista ELF Configuration.
++# Copyright (C) 2009
++# Free Software Foundation, Inc.
++#
++# This file is part of GCC.
++#
++# GCC is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3, or (at your option)
++# any later version.
++# 
++# GCC is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with GCC; see the file COPYING3.  If not see
++# <http://www.gnu.org/licenses/>.
++
++MULTILIB_OPTIONS =
++MULTILIB_DIRNAMES =
+--- /dev/null
++++ b/gcc/config/mips/t-montavista-linux
+@@ -0,0 +1,43 @@
++# MontaVista GNU/Linux Configuration.
++# Copyright (C) 2009
++# Free Software Foundation, Inc.
++#
++# This file is part of GCC.
++#
++# GCC is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3, or (at your option)
++# any later version.
++# 
++# GCC is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with GCC; see the file COPYING3.  If not see
++# <http://www.gnu.org/licenses/>.
++
++# Build big-endian and little-endian support libraries.
++MULTILIB_OPTIONS = mel msoft-float march=octeon mabi=n32/mabi=64
++MULTILIB_DIRNAMES = mel soft-float octeon n32 64
++MULTILIB_EXCEPTIONS = *mel*/*mabi=n32* *mel*/*mabi=64*
++MULTILIB_EXCEPTIONS += *mel*/*march=octeon* march=octeon march=octeon/mabi=n32
++MULTILIB_EXCEPTIONS += march=octeon/mabi=64 msoft-float/march=octeon
++
++# These files must be built for each multilib.
++EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
++
++# See comment in montavista-linux.h on STARTFILE_PREFIX_SPEC for how the real
++# directories used in the sysroots are determined.  These directories
++# are specified so that (a) they are distinct and (b) removing the
++# components that form part of the sysroot suffix leaves the real
++# directory within the sysroot.
++MULTILIB_OSDIRNAMES = msoft-float/mabi.n32=../lib32/soft-float
++MULTILIB_OSDIRNAMES += msoft-float/mabi.64=../lib64/soft-float
++MULTILIB_OSDIRNAMES += msoft-float/march.octeon/mabi.n32=../lib32/soft-float/octeon
++MULTILIB_OSDIRNAMES += msoft-float/march.octeon/mabi.64=../lib64/soft-float/octeon
++MULTILIB_OSDIRNAMES += mel/msoft-float=!mel/soft-float
++MULTILIB_OSDIRNAMES += msoft-float=!soft-float
++MULTILIB_OSDIRNAMES += mabi.64=../lib64
++MULTILIB_OSDIRNAMES += mabi.n32=../lib32
+--- /dev/null
++++ b/gcc/config/mips/t-octeon-elf
+@@ -0,0 +1,41 @@
++# Don't let CTOR_LIST end up in sdata section.
++
++CRTSTUFF_T_CFLAGS = -G 0 -fno-asynchronous-unwind-tables
++
++# Assemble startup files.
++
++$(T)crti.o: $(srcdir)/config/mips/crti.asm $(GCC_PASSES)
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
++      -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/mips/crti.asm
++
++$(T)crtn.o: $(srcdir)/config/mips/crtn.asm $(GCC_PASSES)
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
++      -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/mips/crtn.asm
++
++# N32 uses TFmode for long double.
++
++TPBIT = tp-bit.c
++
++tp-bit.c: $(srcdir)/config/fp-bit.c
++      echo '#ifdef __MIPSEL__' > tp-bit.c
++      echo '# define FLOAT_BIT_ORDER_MISMATCH' >> tp-bit.c
++      echo '#endif' >> tp-bit.c
++      echo '#if __LDBL_MANT_DIG__ == 113' >> tp-bit.c
++      echo '#define QUIET_NAN_NEGATED' >> tp-bit.c
++      echo '# define TFLOAT' >> tp-bit.c
++      cat $(srcdir)/config/fp-bit.c >> tp-bit.c
++      echo '#endif' >> tp-bit.c
++
++# We must build libgcc2.a with -G 0, in case the user wants to link
++# without the $gp register.
++
++TARGET_LIBGCC2_CFLAGS = -G 0
++ 
++# Build both ABIs.
++
++MULTILIB_OPTIONS = mabi=n32/mabi=eabi/mabi=64
++MULTILIB_DIRNAMES = n32 eabi n64
++EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
++
++LIBGCC = stmp-multilib
++INSTALL_LIBGCC = install-multilib
+--- a/gcc/config/mips/t-sde
++++ b/gcc/config/mips/t-sde
+@@ -10,9 +10,17 @@ $(T)crtn.o: $(srcdir)/config/mips/crtn.a
+       $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
+       -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/mips/crtn.asm
+-MULTILIB_OPTIONS = EL/EB mips32/mips32r2/mips64 mips16 msoft-float/mfp64 mcode-readable=no
++# We must build libgcc2.a with -G 0, in case the user wants to link
++# without the $gp register. Use -fno-optimize-sibling-calls in case
++# we have a mixed mips16/non-mips16 environment where a plain "jump"
++# instuction won't work across the divide (no jx instruction).
++# Compile libraries with -mcode-xonly, so that they are link-compatible
++# with both -mcode-readable=pcrel and -mcode-readable=yes.
++TARGET_LIBGCC2_CFLAGS = -G 0 -fno-optimize-sibling-calls -mcode-xonly
++
++MULTILIB_OPTIONS = EL/EB mips32/mips32r2/mips64 mips16 msoft-float/mfp64 mno-data-in-code
+ MULTILIB_DIRNAMES = el eb mips32 mips32r2 mips64 mips16 sof f64 spram
+-MULTILIB_MATCHES = EL=mel EB=meb
++MULTILIB_MATCHES = EL=mel EB=meb mips16=mips16e
+ # The -mfp64 option is only valid in conjunction with -mips32r2.
+ ifneq ($(filter MIPS_ISA_DEFAULT=33,$(tm_defines)),)
+--- /dev/null
++++ b/gcc/config/mips/t-sdelib
+@@ -0,0 +1,23 @@
++# Override newlib settings in t-sde and set up for building
++# against SDE header files and libraries.
++
++# Remove stdarg.h and stddef.h from USER_H.
++USER_H = $(srcdir)/ginclude/float.h \
++         $(srcdir)/ginclude/iso646.h \
++         $(srcdir)/ginclude/stdbool.h \
++         $(srcdir)/ginclude/varargs.h \
++         $(EXTRA_HEADERS)
++
++# Don't run fixinclude
++STMP_FIXINC = stmp-sdefixinc
++stmp-sdefixinc: gsyslimits.h
++      rm -rf include; mkdir include
++      chmod a+rx include
++      rm -f include/syslimits.h
++      cp $(srcdir)/gsyslimits.h include/syslimits.h
++      chmod a+r include/syslimits.h
++      $(STAMP) stmp-sdefixinc
++
++# Don't build FPBIT and DPBIT; we'll be using the SDE soft-float library.
++FPBIT =
++DPBIT =
+--- a/gcc/config/mips/t-sdemtk
++++ b/gcc/config/mips/t-sdemtk
+@@ -1,26 +1,7 @@
+-# Override newlib settings in t-sde and set up for building
+-# against SDE header files and libraries.
+-MULTILIB_OPTIONS = EL/EB mips32/mips32r2/mips64 mips16 msoft-float/mno-float/mfp64
+-MULTILIB_DIRNAMES = el eb mips32 mips32r2 mips64 mips16 sof nof f64
++MULTILIB_OPTIONS = EL/EB mips32/mips32r2/mips64 mips16 fp64/msoft-float/mno-float
++MULTILIB_DIRNAMES = el eb mips32 mips32r2 mips64 mips16 f64 sof nof
++MULTILIB_MATCHES = EL=mel EB=meb
++MULTILIB_EXCLUSIONS = mfp64/!mips32r2 mips16/mips64 mcode-readable=no/!mips16
++MULTILIB_EXCEPTIONS =
+-# Remove stdarg.h and stddef.h from USER_H.
+-USER_H = $(srcdir)/ginclude/float.h \
+-         $(srcdir)/ginclude/iso646.h \
+-         $(srcdir)/ginclude/stdbool.h \
+-         $(srcdir)/ginclude/varargs.h \
+-         $(EXTRA_HEADERS)
+-
+-# Don't run fixinclude
+-STMP_FIXINC = stmp-sdefixinc
+-stmp-sdefixinc: gsyslimits.h
+-      rm -rf include; mkdir include
+-      chmod a+rx include
+-      rm -f include/syslimits.h
+-      cp $(srcdir)/gsyslimits.h include/syslimits.h
+-      chmod a+r include/syslimits.h
+-      $(STAMP) stmp-sdefixinc
+-
+-# Don't build FPBIT and DPBIT; we'll be using the SDE soft-float library.
+-FPBIT =
+-DPBIT =
+--- /dev/null
++++ b/gcc/config/mips/t-sgxx-linux
+@@ -0,0 +1,11 @@
++MULTILIB_OPTIONS = muclibc march=mips2/march=mips32 msoft-float EL/EB
++MULTILIB_DIRNAMES = uclibc mips2 mips32 soft-float el eb
++MULTILIB_MATCHES := EL=mel EB=meb \
++  march?mips2=mips2 march?mips2=mips3 march?mips2=mips4 \
++  $(foreach cpu,mips3 mips4 r6000 r4000 vr4100 vr4111 vr4120 vr4130 vr4300 \
++                r4400 r4600 orion r4650 r8000 vr5000 vr5400 vr5500 rm7000 \
++                rm9000,march?mips2=march?$(cpu)) \
++  march?mips32=mips32 \
++  $(foreach cpu,4kc 4km 4kp 4ks,march?mips32=march?$(cpu))
++MULTILIB_EXCEPTIONS = *muclibc*/*march?mips2* *muclibc*/*march?mips32*
++EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o 
+--- /dev/null
++++ b/gcc/config/mips/t-sgxx-sde
+@@ -0,0 +1,7 @@
++# SourceryG++ overrides for SDE builds
++
++MULTILIB_OPTIONS = EL/EB mips16 mfp64/msoft-float/mno-float mcode-readable=no
++MULTILIB_DIRNAMES = el eb mips16 fp64 sof nof spram
++MULTILIB_MATCHES = EL=mel EB=meb mips16=mips16e
++MULTILIB_EXCLUSIONS = mcode-readable=no/!mips16
++MULTILIB_EXCEPTIONS = 
+--- /dev/null
++++ b/gcc/config/mips/t-sgxxlite-linux
+@@ -0,0 +1,5 @@
++MULTILIB_OPTIONS = muclibc msoft-float EL/EB
++MULTILIB_DIRNAMES = uclibc soft-float el eb
++MULTILIB_MATCHES := EL=mel EB=meb
++EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
++
+--- /dev/null
++++ b/gcc/config/mips/t-sicortex
+@@ -0,0 +1,24 @@
++# SiCortex GNU/Linux Configuration.
++# Copyright (C) 2008
++# Free Software Foundation, Inc.
++#
++# This file is part of GCC.
++#
++# GCC is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3, or (at your option)
++# any later version.
++# 
++# GCC is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with GCC; see the file COPYING3.  If not see
++# <http://www.gnu.org/licenses/>.
++
++# No O32 libraries for SiCortex.
++MULTILIB_OPTIONS = mabi=n32/mabi=64
++MULTILIB_DIRNAMES = n32 64
++MULTILIB_OSDIRNAMES = ../lib32 ../lib64
+--- /dev/null
++++ b/gcc/config/mips/t-wrs-linux
+@@ -0,0 +1,50 @@
++# Wind River GNU/Linux Configuration.
++# Copyright (C) 2006, 2007
++# Free Software Foundation, Inc.
++#
++# This file is part of GCC.
++#
++# GCC is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3, or (at your option)
++# any later version.
++# 
++# GCC is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with GCC; see the file COPYING3.  If not see
++# <http://www.gnu.org/licenses/>.
++
++# Build big-endian and little-endian support libraries.
++MULTILIB_OPTIONS = muclibc mel mhard-float march=octeon mabi=n32/mabi=64
++MULTILIB_DIRNAMES = uclibc mel hard-float octeon n32 64
++MULTILIB_EXCEPTIONS = *muclibc*/*mhard-float*
++MULTILIB_EXCEPTIONS += *muclibc*/*mabi=n32*
++MULTILIB_EXCEPTIONS += *muclibc*/*mabi=64*
++MULTILIB_EXCEPTIONS += */march=octeon*
++MULTILIB_EXCEPTIONS += march=octeon march=octeon/mabi=32
++MULTILIB_EXCEPTIONS += mel/mabi=n32 mel/mabi=64
++MULTILIB_EXCEPTIONS += mabi=n32
++# These files must be built for each multilib.
++EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
++
++# See comment in wrs-linux.h on STARTFILE_PREFIX_SPEC for how the real
++# directories used in the sysroots are determined.  These directories
++# are specified so that (a) they are distinct and (b) removing the
++# components that form part of the sysroot suffix leaves the real
++# directory within the sysroot.
++MULTILIB_OSDIRNAMES = mel/mhard-float/mabi.n32=../lib32/mel/hard-float
++MULTILIB_OSDIRNAMES += mel/mhard-float/mabi.64=../lib64/mel/hard-float
++MULTILIB_OSDIRNAMES += mhard-float/mabi.n32=../lib32/hard-float
++MULTILIB_OSDIRNAMES += mhard-float/mabi.64=../lib64/hard-float
++MULTILIB_OSDIRNAMES += mel/mhard-float=!mel/hard-float
++MULTILIB_OSDIRNAMES += mhard-float=!hard-float
++MULTILIB_OSDIRNAMES += mabi.64=../lib64
++MULTILIB_OSDIRNAMES += march.octeon/mabi.n32=../lib32/octeon
++MULTILIB_OSDIRNAMES += march.octeon/mabi.64=../lib64/octeon
++MULTILIB_OSDIRNAMES += muclibc/mel=!uclibc/mel
++MULTILIB_OSDIRNAMES += muclibc=!uclibc
++
+--- a/gcc/config/mips/vr.h
++++ b/gcc/config/mips/vr.h
+@@ -26,7 +26,7 @@ along with GCC; see the file COPYING3.  
+         MULTILIB_ABI_DEFAULT,                 \
+         DEFAULT_VR_ARCH }
+-#define DRIVER_SELF_SPECS \
++#define SUBTARGET_SELF_SPECS \
+       /* Enforce the default architecture.  This is mostly for        \
+          the assembler's benefit.  */                                 \
+       "%{!march=*:%{!mfix-vr4120:%{!mfix-vr4130:"                     \
+--- /dev/null
++++ b/gcc/config/mips/wrs-linux.h
+@@ -0,0 +1,63 @@
++/* Wind River GNU/Linux Configuration.
++   Copyright (C) 2006, 2007
++   Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 3, or (at your option)
++any later version.
++
++GCC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++/* Override linux64.h to default to O32.  */
++#undef SUBTARGET_SELF_SPECS
++#define SUBTARGET_SELF_SPECS \
++NO_SHARED_SPECS, \
++"%{!EB:%{!EL:%(endian_spec)}}", \
++"%{!mabi=*: -mabi=32}"
++
++/* We do not need to provide an explicit big-endian multilib.  */
++#undef MULTILIB_DEFAULTS
++#define MULTILIB_DEFAULTS \
++  { "meb", "mabi=32" }
++
++/* The GLIBC headers are in /usr/include, relative to the sysroot; the
++   uClibc headers are in /uclibc/usr/include.  */
++#undef SYSROOT_HEADERS_SUFFIX_SPEC
++#define SYSROOT_HEADERS_SUFFIX_SPEC           \
++  "%{muclibc:/uclibc}" 
++
++/* The various C libraries each have their own subdirectory.  */
++#undef SYSROOT_SUFFIX_SPEC
++#define SYSROOT_SUFFIX_SPEC                   \
++  "%{muclibc:%{mel:/uclibc/mel ;              \
++               :/uclibc} ;                    \
++     mel:%{mhard-float:/mel/hard-float ;      \
++           :/mel} ;                           \
++     march=octeon:/octeon ;                   \
++     mhard-float:/hard-float}"
++
++/* MULTILIB_OSDIRNAMES provides directory names used in two ways:
++   relative to $target/lib/ in the GCC installation, and relative to
++   lib/ and usr/lib/ in a sysroot.  For the latter, we want names such
++   as plain ../lib64, but these cannot be used outside the sysroot
++   because different multilibs would be mapped to the same directory.
++   Directories are searched both with and without the multilib suffix,
++   so it suffices if the directory without the suffix is correct
++   within the sysroot while the directory with the suffix doesn't
++   exist.  We use STARTFILE_PREFIX_SPEC to achieve the desired
++   effect.  */
++#undef STARTFILE_PREFIX_SPEC
++#define STARTFILE_PREFIX_SPEC                         \
++  "%{mabi=32: /usr/local/lib/ /lib/ /usr/lib/}                \
++   %{mabi=n32: /usr/local/lib32/ /lib32/ /usr/lib32/} \
++   %{mabi=64: /usr/local/lib64/ /lib64/ /usr/lib64/}"
+--- /dev/null
++++ b/gcc/config/mips/xlr.md
+@@ -0,0 +1,89 @@
++;; DFA-based pipeline description for the XLR.
++;;   Copyright (C) 2008 Free Software Foundation, Inc.
++;;
++;; xlr.md   Machine Description for the RMI XLR Microprocessor
++;; This file is part of GCC.
++
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published
++;; by the Free Software Foundation; either version 3, or (at your
++;; option) any later version.
++
++;; GCC is distributed in the hope that it will be useful, but WITHOUT
++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
++;; License for more details.
++
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING3.  If not see
++;; <http://www.gnu.org/licenses/>.
++
++(define_automaton "xlr_main,xlr_muldiv")
++
++;; Definitions for xlr_main automaton.
++(define_cpu_unit "xlr_main_pipe" "xlr_main")
++
++(define_insn_reservation "ir_xlr_alu_slt" 2
++  (and (eq_attr "cpu" "xlr") 
++       (eq_attr "type" "slt"))
++  "xlr_main_pipe")
++
++;; Integer arithmetic instructions.
++(define_insn_reservation "ir_xlr_alu" 1
++  (and (eq_attr "cpu" "xlr") 
++       (eq_attr "type" "move,arith,shift,clz,logical,signext,const,unknown,multi,nop,trap"))
++  "xlr_main_pipe")
++
++;; Integer arithmetic instructions.
++(define_insn_reservation "ir_xlr_condmove" 2
++  (and (eq_attr "cpu" "xlr") 
++       (eq_attr "type" "condmove"))
++  "xlr_main_pipe")
++
++;; Load/store instructions.
++(define_insn_reservation "ir_xlr_load" 4
++  (and (eq_attr "cpu" "xlr") 
++       (eq_attr "type" "load"))
++  "xlr_main_pipe")
++
++(define_insn_reservation "ir_xlr_store" 1
++  (and  (eq_attr "cpu" "xlr") 
++        (eq_attr "type" "store"))
++  "xlr_main_pipe")
++
++(define_insn_reservation "ir_xlr_prefetch_x" 1
++  (and (eq_attr "cpu" "xlr")
++       (eq_attr "type" "prefetch,prefetchx"))
++  "xlr_main_pipe")
++
++;; Branch instructions - use branch misprediction latency.
++(define_insn_reservation "ir_xlr_branch" 1
++  (and (eq_attr "cpu" "xlr") 
++       (eq_attr "type" "branch,jump,call"))
++  "xlr_main_pipe")
++
++;; Coprocessor move instructions.
++(define_insn_reservation "ir_xlr_xfer" 2
++  (and (eq_attr "cpu" "xlr") 
++       (eq_attr "type" "mtc,mfc"))
++  "xlr_main_pipe")
++
++(define_bypass 5 "ir_xlr_xfer" "ir_xlr_xfer")
++
++;; Definitions for the xlr_muldiv automaton.
++(define_cpu_unit "xlr_imuldiv_nopipe" "xlr_muldiv")
++
++(define_insn_reservation "ir_xlr_imul" 8
++  (and (eq_attr "cpu" "xlr") 
++       (eq_attr "type" "imul,imul3,imadd"))
++  "xlr_main_pipe,xlr_imuldiv_nopipe*6")
++
++(define_insn_reservation "ir_xlr_div" 68
++  (and (eq_attr "cpu" "xlr") 
++       (eq_attr "type" "idiv"))
++  "xlr_main_pipe,xlr_imuldiv_nopipe*67")
++
++(define_insn_reservation "xlr_hilo" 2
++  (and (eq_attr "cpu" "xlr") 
++       (eq_attr "type" "mfhilo,mthilo"))
++  "xlr_imuldiv_nopipe")
+--- /dev/null
++++ b/gcc/config/print-sysroot-suffix.sh
+@@ -0,0 +1,107 @@
++#! /bin/sh
++# Script to generate SYSROOT_SUFFIX equivalent to MULTILIB_OSDIRNAMES
++# Arguments are MULTILIB_OSDIRNAMES, MULTILIB_OPTIONS, MULTILIB_MATCHES
++# and MULTILIB_ALIASES.
++
++set -e
++
++dirnames="$1"
++options="$2"
++matches="$3"
++aliases="$4"
++
++cat > print-sysroot-suffix3.sh <<\EOF
++#! /bin/sh
++# Print all the multilib matches for this option
++result="$1"
++EOF
++for x in $matches; do
++  l=`echo $x | sed -e 's/=.*$//' -e 's/?/=/g'`
++  r=`echo $x | sed -e 's/^.*=//' -e 's/?/=/g'`
++  echo "[ \"\$1\" = \"$l\" ] && result=\"\$result|$r\"" >> print-sysroot-suffix3.sh
++done
++echo 'echo $result' >> print-sysroot-suffix3.sh
++chmod +x print-sysroot-suffix3.sh
++
++cat > print-sysroot-suffix2.sh <<\EOF
++#! /bin/sh
++# Recursive script to enumerate all multilib combinations, match against
++# multilib directories and optut a spec string of the result.
++# Will fold identical trees.
++
++padding="$1"
++optstring="$2"
++shift 2
++n="\" \\
++$padding\""
++if [ $# = 0 ]; then
++  case $optstring in
++EOF
++for x in $aliases; do
++  l=`echo $x | sed -e 's/=.*$//' -e 's/?/=/g'`
++  r=`echo $x | sed -e 's/^.*=//' -e 's/?/=/g'`
++  echo "/$r/) optstring=\"/$l/\" ;;" >> print-sysroot-suffix2.sh
++done
++echo "  esac" >> print-sysroot-suffix2.sh
++
++pat=
++for x in $dirnames; do
++  p=`echo $x | sed -e 's,=!,/$=/,'`
++  pat="$pat -e 's=^//$p='"
++done
++echo '  optstring=`echo "/$optstring" | sed '"$pat\`" >> print-sysroot-suffix2.sh
++cat >> print-sysroot-suffix2.sh <<\EOF
++  case $optstring in
++  //*)
++    ;;
++  *)
++    echo "$optstring"
++    ;;
++  esac
++else
++  thisopt="$1"
++  shift
++  bit=
++  lastcond=
++  result=
++  for x in `echo "$thisopt" | sed -e 's,/, ,g'`; do
++    case $x in
++EOF
++for x in `echo "$options" | sed -e 's,/, ,g'`; do
++  match=`./print-sysroot-suffix3.sh "$x"`
++  echo "$x) optmatch=\"$match\" ;;" >> print-sysroot-suffix2.sh
++done
++cat >> print-sysroot-suffix2.sh <<\EOF
++    esac
++    bit=`"$0" "$padding  " "$optstring$x/" "$@"`
++    if [ -z "$lastopt" ]; then
++      lastopt="$optmatch"
++    else
++      if [ "$lastbit" = "$bit" ]; then
++      lastopt="$lastopt|$optmatch"
++      else
++      result="$result$lastopt:$lastbit;$n"
++      lastopt="$optmatch"
++      fi
++    fi
++    lastbit="$bit"
++  done
++  bit=`"$0" "$padding  " "$optstring" "$@"`
++  if [ "$bit" = "$lastbit" ]; then
++    if [ -z "$result" ]; then
++      echo "$bit"
++    else
++      echo "$n%{$result:$bit}"
++    fi
++  else
++    echo "$n%{$result$lastopt:$lastbit;$n:$bit}"
++  fi
++fi
++EOF
++
++chmod +x ./print-sysroot-suffix2.sh
++result=`./print-sysroot-suffix2.sh "" "/" $options`
++echo "#undef SYSROOT_SUFFIX_SPEC"
++echo "#define SYSROOT_SUFFIX_SPEC \"$result\""
++rm print-sysroot-suffix2.sh
++rm print-sysroot-suffix3.sh
+--- a/gcc/config/rs6000/aix.h
++++ b/gcc/config/rs6000/aix.h
+@@ -202,6 +202,8 @@
+ /* Define cutoff for using external functions to save floating point.  */
+ #define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63)
++/* And similarly for general purpose registers.  */
++#define GP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 32)
+ /* __throw will restore its own return address to be the same as the
+    return address of the function that the throw is being made to.
+--- a/gcc/config/rs6000/altivec.md
++++ b/gcc/config/rs6000/altivec.md
+@@ -64,7 +64,6 @@
+    (UNSPEC_VPKUWUS      102)
+    (UNSPEC_VPKSWUS      103)
+    (UNSPEC_VRL          104)
+-   (UNSPEC_VSL          107)
+    (UNSPEC_VSLV4SI      110)
+    (UNSPEC_VSLO         111)
+    (UNSPEC_VSR          118)
+@@ -582,7 +581,7 @@
+   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
+   neg0 = gen_reg_rtx (V4SImode);
+   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
+-  emit_insn (gen_altivec_vslw (neg0, neg0, neg0));
++  emit_insn (gen_ashlv4si3 (neg0, neg0, neg0));
+   /* Use the multiply-add.  */
+   emit_insn (gen_altivec_vmaddfp (operands[0], operands[1], operands[2],
+@@ -641,7 +640,7 @@
+    high_product = gen_reg_rtx (V4SImode);
+    emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero));
+  
+-   emit_insn (gen_altivec_vslw (high_product, high_product, sixteen));
++   emit_insn (gen_ashlv4si3 (high_product, high_product, sixteen));
+  
+    emit_insn (gen_addv4si3 (operands[0], high_product, low_product));
+    
+@@ -1227,15 +1226,6 @@
+   "vrl<VI_char> %0,%1,%2"
+   [(set_attr "type" "vecsimple")])
+-(define_insn "altivec_vsl<VI_char>"
+-  [(set (match_operand:VI 0 "register_operand" "=v")
+-        (unspec:VI [(match_operand:VI 1 "register_operand" "v")
+-                    (match_operand:VI 2 "register_operand" "v")]
+-                 UNSPEC_VSL))]
+-  "TARGET_ALTIVEC"
+-  "vsl<VI_char> %0,%1,%2"
+-  [(set_attr "type" "vecsimple")])
+-
+ (define_insn "altivec_vsl"
+   [(set (match_operand:V4SI 0 "register_operand" "=v")
+         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
+@@ -1254,6 +1244,14 @@
+   "vslo %0,%1,%2"
+   [(set_attr "type" "vecperm")])
++(define_insn "ashl<mode>3"
++  [(set (match_operand:VI 0 "register_operand" "=v")
++        (ashift:VI (match_operand:VI 1 "register_operand" "v")
++                   (match_operand:VI 2 "register_operand" "v") ))]
++  "TARGET_ALTIVEC"
++  "vsl<VI_char> %0,%1,%2"
++  [(set_attr "type" "vecsimple")])
++
+ (define_insn "lshr<mode>3"
+   [(set (match_operand:VI 0 "register_operand" "=v")
+         (lshiftrt:VI (match_operand:VI 1 "register_operand" "v")
+@@ -2045,7 +2043,7 @@
+   [(set (match_dup 2)
+       (vec_duplicate:V4SI (const_int -1)))
+    (set (match_dup 3)
+-        (unspec:V4SI [(match_dup 2) (match_dup 2)] UNSPEC_VSL))
++        (ashift:V4SI (match_dup 2) (match_dup 2)))
+    (set (match_operand:V4SF 0 "register_operand" "=v")
+         (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0))
+                   (match_operand:V4SF 1 "register_operand" "v")))]
+@@ -2648,7 +2646,7 @@
+   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
+   neg0 = gen_reg_rtx (V4SImode);
+   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
+-  emit_insn (gen_altivec_vslw (neg0, neg0, neg0));
++  emit_insn (gen_ashlv4si3 (neg0, neg0, neg0));
+   /* XOR */
+   emit_insn (gen_xorv4sf3 (operands[0],
+--- /dev/null
++++ b/gcc/config/rs6000/crtresfpr.asm
+@@ -0,0 +1,90 @@
++/*
++ * Special support for eabi and SVR4
++ *
++ *   Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008
++ *   Free Software Foundation, Inc.
++ *   Written By Michael Meissner
++ *   64-bit support written by David Edelsohn
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++/* Do any initializations needed for the eabi environment */
++
++      .file   "crtresfpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++/* On PowerPC64 Linux, these functions are provided by the linker.  */
++#ifndef __powerpc64__
++
++/* Routines for restoring floating point registers, called by the compiler.  */
++/* Called with r11 pointing to the stack header word of the caller of the */
++/* function, just beyond the end of the floating point save area.  */
++
++HIDDEN_FUNC(_restfpr_14)      lfd     14,-144(11)     /* restore fp registers */
++HIDDEN_FUNC(_restfpr_15)      lfd     15,-136(11)
++HIDDEN_FUNC(_restfpr_16)      lfd     16,-128(11)
++HIDDEN_FUNC(_restfpr_17)      lfd     17,-120(11)
++HIDDEN_FUNC(_restfpr_18)      lfd     18,-112(11)
++HIDDEN_FUNC(_restfpr_19)      lfd     19,-104(11)
++HIDDEN_FUNC(_restfpr_20)      lfd     20,-96(11)
++HIDDEN_FUNC(_restfpr_21)      lfd     21,-88(11)
++HIDDEN_FUNC(_restfpr_22)      lfd     22,-80(11)
++HIDDEN_FUNC(_restfpr_23)      lfd     23,-72(11)
++HIDDEN_FUNC(_restfpr_24)      lfd     24,-64(11)
++HIDDEN_FUNC(_restfpr_25)      lfd     25,-56(11)
++HIDDEN_FUNC(_restfpr_26)      lfd     26,-48(11)
++HIDDEN_FUNC(_restfpr_27)      lfd     27,-40(11)
++HIDDEN_FUNC(_restfpr_28)      lfd     28,-32(11)
++HIDDEN_FUNC(_restfpr_29)      lfd     29,-24(11)
++HIDDEN_FUNC(_restfpr_30)      lfd     30,-16(11)
++HIDDEN_FUNC(_restfpr_31)      lfd     31,-8(11)
++                      blr
++FUNC_END(_restfpr_31)
++FUNC_END(_restfpr_30)
++FUNC_END(_restfpr_29)
++FUNC_END(_restfpr_28)
++FUNC_END(_restfpr_27)
++FUNC_END(_restfpr_26)
++FUNC_END(_restfpr_25)
++FUNC_END(_restfpr_24)
++FUNC_END(_restfpr_23)
++FUNC_END(_restfpr_22)
++FUNC_END(_restfpr_21)
++FUNC_END(_restfpr_20)
++FUNC_END(_restfpr_19)
++FUNC_END(_restfpr_18)
++FUNC_END(_restfpr_17)
++FUNC_END(_restfpr_16)
++FUNC_END(_restfpr_15)
++FUNC_END(_restfpr_14)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/crtresgpr.asm
+@@ -0,0 +1,90 @@
++/*
++ * Special support for eabi and SVR4
++ *
++ *   Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008
++ *   Free Software Foundation, Inc.
++ *   Written By Michael Meissner
++ *   64-bit support written by David Edelsohn
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++/* Do any initializations needed for the eabi environment */
++
++      .file   "crtresgpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++/* On PowerPC64 Linux, these functions are provided by the linker.  */
++#ifndef __powerpc64__
++
++/* Routines for restoring integer registers, called by the compiler.  */
++/* Called with r11 pointing to the stack header word of the caller of the */
++/* function, just beyond the end of the integer restore area.  */
++
++HIDDEN_FUNC(_restgpr_14)      lwz     14,-72(11)      /* restore gp registers */
++HIDDEN_FUNC(_restgpr_15)      lwz     15,-68(11)
++HIDDEN_FUNC(_restgpr_16)      lwz     16,-64(11)
++HIDDEN_FUNC(_restgpr_17)      lwz     17,-60(11)
++HIDDEN_FUNC(_restgpr_18)      lwz     18,-56(11)
++HIDDEN_FUNC(_restgpr_19)      lwz     19,-52(11)
++HIDDEN_FUNC(_restgpr_20)      lwz     20,-48(11)
++HIDDEN_FUNC(_restgpr_21)      lwz     21,-44(11)
++HIDDEN_FUNC(_restgpr_22)      lwz     22,-40(11)
++HIDDEN_FUNC(_restgpr_23)      lwz     23,-36(11)
++HIDDEN_FUNC(_restgpr_24)      lwz     24,-32(11)
++HIDDEN_FUNC(_restgpr_25)      lwz     25,-28(11)
++HIDDEN_FUNC(_restgpr_26)      lwz     26,-24(11)
++HIDDEN_FUNC(_restgpr_27)      lwz     27,-20(11)
++HIDDEN_FUNC(_restgpr_28)      lwz     28,-16(11)
++HIDDEN_FUNC(_restgpr_29)      lwz     29,-12(11)
++HIDDEN_FUNC(_restgpr_30)      lwz     30,-8(11)
++HIDDEN_FUNC(_restgpr_31)      lwz     31,-4(11)
++                      blr
++FUNC_END(_restgpr_31)
++FUNC_END(_restgpr_30)
++FUNC_END(_restgpr_29)
++FUNC_END(_restgpr_28)
++FUNC_END(_restgpr_27)
++FUNC_END(_restgpr_26)
++FUNC_END(_restgpr_25)
++FUNC_END(_restgpr_24)
++FUNC_END(_restgpr_23)
++FUNC_END(_restgpr_22)
++FUNC_END(_restgpr_21)
++FUNC_END(_restgpr_20)
++FUNC_END(_restgpr_19)
++FUNC_END(_restgpr_18)
++FUNC_END(_restgpr_17)
++FUNC_END(_restgpr_16)
++FUNC_END(_restgpr_15)
++FUNC_END(_restgpr_14)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/crtresxfpr.asm
+@@ -0,0 +1,95 @@
++/*
++ * Special support for eabi and SVR4
++ *
++ *   Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008
++ *   Free Software Foundation, Inc.
++ *   Written By Michael Meissner
++ *   64-bit support written by David Edelsohn
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++/* Do any initializations needed for the eabi environment */
++
++      .file   "crtresxfpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++/* On PowerPC64 Linux, these functions are provided by the linker.  */
++#ifndef __powerpc64__
++
++/* Routines for restoring floating point registers, called by the compiler.  */
++/* Called with r11 pointing to the stack header word of the caller of the */
++/* function, just beyond the end of the floating point save area.  */
++/* In addition to restoring the fp registers, it will return to the caller's */
++/* caller */
++
++HIDDEN_FUNC(_restfpr_14_x)    lfd     14,-144(11)     /* restore fp registers */
++HIDDEN_FUNC(_restfpr_15_x)    lfd     15,-136(11)
++HIDDEN_FUNC(_restfpr_16_x)    lfd     16,-128(11)
++HIDDEN_FUNC(_restfpr_17_x)    lfd     17,-120(11)
++HIDDEN_FUNC(_restfpr_18_x)    lfd     18,-112(11)
++HIDDEN_FUNC(_restfpr_19_x)    lfd     19,-104(11)
++HIDDEN_FUNC(_restfpr_20_x)    lfd     20,-96(11)
++HIDDEN_FUNC(_restfpr_21_x)    lfd     21,-88(11)
++HIDDEN_FUNC(_restfpr_22_x)    lfd     22,-80(11)
++HIDDEN_FUNC(_restfpr_23_x)    lfd     23,-72(11)
++HIDDEN_FUNC(_restfpr_24_x)    lfd     24,-64(11)
++HIDDEN_FUNC(_restfpr_25_x)    lfd     25,-56(11)
++HIDDEN_FUNC(_restfpr_26_x)    lfd     26,-48(11)
++HIDDEN_FUNC(_restfpr_27_x)    lfd     27,-40(11)
++HIDDEN_FUNC(_restfpr_28_x)    lfd     28,-32(11)
++HIDDEN_FUNC(_restfpr_29_x)    lfd     29,-24(11)
++HIDDEN_FUNC(_restfpr_30_x)    lfd     30,-16(11)
++HIDDEN_FUNC(_restfpr_31_x)    lwz     0,4(11)
++                              lfd     31,-8(11)
++                              mtlr    0
++                              mr      1,11
++                              blr
++FUNC_END(_restfpr_31_x)
++FUNC_END(_restfpr_30_x)
++FUNC_END(_restfpr_29_x)
++FUNC_END(_restfpr_28_x)
++FUNC_END(_restfpr_27_x)
++FUNC_END(_restfpr_26_x)
++FUNC_END(_restfpr_25_x)
++FUNC_END(_restfpr_24_x)
++FUNC_END(_restfpr_23_x)
++FUNC_END(_restfpr_22_x)
++FUNC_END(_restfpr_21_x)
++FUNC_END(_restfpr_20_x)
++FUNC_END(_restfpr_19_x)
++FUNC_END(_restfpr_18_x)
++FUNC_END(_restfpr_17_x)
++FUNC_END(_restfpr_16_x)
++FUNC_END(_restfpr_15_x)
++FUNC_END(_restfpr_14_x)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/crtresxgpr.asm
+@@ -0,0 +1,93 @@
++/*
++ * Special support for eabi and SVR4
++ *
++ *   Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008
++ *   Free Software Foundation, Inc.
++ *   Written By Michael Meissner
++ *   64-bit support written by David Edelsohn
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++/* Do any initializations needed for the eabi environment */
++
++      .file   "crtresxgpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++/* On PowerPC64 Linux, these functions are provided by the linker.  */
++#ifndef __powerpc64__
++
++/* Routines for restoring integer registers, called by the compiler.  */
++/* Called with r11 pointing to the stack header word of the caller of the */
++/* function, just beyond the end of the integer restore area.  */
++
++HIDDEN_FUNC(_restgpr_14_x)    lwz     14,-72(11)      /* restore gp registers */
++HIDDEN_FUNC(_restgpr_15_x)    lwz     15,-68(11)
++HIDDEN_FUNC(_restgpr_16_x)    lwz     16,-64(11)
++HIDDEN_FUNC(_restgpr_17_x)    lwz     17,-60(11)
++HIDDEN_FUNC(_restgpr_18_x)    lwz     18,-56(11)
++HIDDEN_FUNC(_restgpr_19_x)    lwz     19,-52(11)
++HIDDEN_FUNC(_restgpr_20_x)    lwz     20,-48(11)
++HIDDEN_FUNC(_restgpr_21_x)    lwz     21,-44(11)
++HIDDEN_FUNC(_restgpr_22_x)    lwz     22,-40(11)
++HIDDEN_FUNC(_restgpr_23_x)    lwz     23,-36(11)
++HIDDEN_FUNC(_restgpr_24_x)    lwz     24,-32(11)
++HIDDEN_FUNC(_restgpr_25_x)    lwz     25,-28(11)
++HIDDEN_FUNC(_restgpr_26_x)    lwz     26,-24(11)
++HIDDEN_FUNC(_restgpr_27_x)    lwz     27,-20(11)
++HIDDEN_FUNC(_restgpr_28_x)    lwz     28,-16(11)
++HIDDEN_FUNC(_restgpr_29_x)    lwz     29,-12(11)
++HIDDEN_FUNC(_restgpr_30_x)    lwz     30,-8(11)
++HIDDEN_FUNC(_restgpr_31_x)    lwz     0,4(11)
++                              lwz     31,-4(11)
++                              mtlr    0
++                              mr      1,11
++                              blr
++FUNC_END(_restgpr_31_x)
++FUNC_END(_restgpr_30_x)
++FUNC_END(_restgpr_29_x)
++FUNC_END(_restgpr_28_x)
++FUNC_END(_restgpr_27_x)
++FUNC_END(_restgpr_26_x)
++FUNC_END(_restgpr_25_x)
++FUNC_END(_restgpr_24_x)
++FUNC_END(_restgpr_23_x)
++FUNC_END(_restgpr_22_x)
++FUNC_END(_restgpr_21_x)
++FUNC_END(_restgpr_20_x)
++FUNC_END(_restgpr_19_x)
++FUNC_END(_restgpr_18_x)
++FUNC_END(_restgpr_17_x)
++FUNC_END(_restgpr_16_x)
++FUNC_END(_restgpr_15_x)
++FUNC_END(_restgpr_14_x)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/crtsavfpr.asm
+@@ -0,0 +1,90 @@
++/*
++ * Special support for eabi and SVR4
++ *
++ *   Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008
++ *   Free Software Foundation, Inc.
++ *   Written By Michael Meissner
++ *   64-bit support written by David Edelsohn
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++/* Do any initializations needed for the eabi environment */
++
++      .file   "crtsavfpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++/* On PowerPC64 Linux, these functions are provided by the linker.  */
++#ifndef __powerpc64__
++
++/* Routines for saving floating point registers, called by the compiler.  */
++/* Called with r11 pointing to the stack header word of the caller of the */
++/* function, just beyond the end of the floating point save area.  */
++
++HIDDEN_FUNC(_savefpr_14)      stfd    14,-144(11)     /* save fp registers */
++HIDDEN_FUNC(_savefpr_15)      stfd    15,-136(11)
++HIDDEN_FUNC(_savefpr_16)      stfd    16,-128(11)
++HIDDEN_FUNC(_savefpr_17)      stfd    17,-120(11)
++HIDDEN_FUNC(_savefpr_18)      stfd    18,-112(11)
++HIDDEN_FUNC(_savefpr_19)      stfd    19,-104(11)
++HIDDEN_FUNC(_savefpr_20)      stfd    20,-96(11)
++HIDDEN_FUNC(_savefpr_21)      stfd    21,-88(11)
++HIDDEN_FUNC(_savefpr_22)      stfd    22,-80(11)
++HIDDEN_FUNC(_savefpr_23)      stfd    23,-72(11)
++HIDDEN_FUNC(_savefpr_24)      stfd    24,-64(11)
++HIDDEN_FUNC(_savefpr_25)      stfd    25,-56(11)
++HIDDEN_FUNC(_savefpr_26)      stfd    26,-48(11)
++HIDDEN_FUNC(_savefpr_27)      stfd    27,-40(11)
++HIDDEN_FUNC(_savefpr_28)      stfd    28,-32(11)
++HIDDEN_FUNC(_savefpr_29)      stfd    29,-24(11)
++HIDDEN_FUNC(_savefpr_30)      stfd    30,-16(11)
++HIDDEN_FUNC(_savefpr_31)      stfd    31,-8(11)
++                      blr
++FUNC_END(_savefpr_31)
++FUNC_END(_savefpr_30)
++FUNC_END(_savefpr_29)
++FUNC_END(_savefpr_28)
++FUNC_END(_savefpr_27)
++FUNC_END(_savefpr_26)
++FUNC_END(_savefpr_25)
++FUNC_END(_savefpr_24)
++FUNC_END(_savefpr_23)
++FUNC_END(_savefpr_22)
++FUNC_END(_savefpr_21)
++FUNC_END(_savefpr_20)
++FUNC_END(_savefpr_19)
++FUNC_END(_savefpr_18)
++FUNC_END(_savefpr_17)
++FUNC_END(_savefpr_16)
++FUNC_END(_savefpr_15)
++FUNC_END(_savefpr_14)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/crtsavgpr.asm
+@@ -0,0 +1,90 @@
++/*
++ * Special support for eabi and SVR4
++ *
++ *   Copyright (C) 1995, 1996, 1998, 2000, 2001, 2008
++ *   Free Software Foundation, Inc.
++ *   Written By Michael Meissner
++ *   64-bit support written by David Edelsohn
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++/* Do any initializations needed for the eabi environment */
++
++      .file   "crtsavgpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++/* On PowerPC64 Linux, these functions are provided by the linker.  */
++#ifndef __powerpc64__
++
++/* Routines for saving integer registers, called by the compiler.  */
++/* Called with r11 pointing to the stack header word of the caller of the */
++/* function, just beyond the end of the integer save area.  */
++
++HIDDEN_FUNC(_savegpr_14)      stw     14,-72(11)      /* save gp registers */
++HIDDEN_FUNC(_savegpr_15)      stw     15,-68(11)
++HIDDEN_FUNC(_savegpr_16)      stw     16,-64(11)
++HIDDEN_FUNC(_savegpr_17)      stw     17,-60(11)
++HIDDEN_FUNC(_savegpr_18)      stw     18,-56(11)
++HIDDEN_FUNC(_savegpr_19)      stw     19,-52(11)
++HIDDEN_FUNC(_savegpr_20)      stw     20,-48(11)
++HIDDEN_FUNC(_savegpr_21)      stw     21,-44(11)
++HIDDEN_FUNC(_savegpr_22)      stw     22,-40(11)
++HIDDEN_FUNC(_savegpr_23)      stw     23,-36(11)
++HIDDEN_FUNC(_savegpr_24)      stw     24,-32(11)
++HIDDEN_FUNC(_savegpr_25)      stw     25,-28(11)
++HIDDEN_FUNC(_savegpr_26)      stw     26,-24(11)
++HIDDEN_FUNC(_savegpr_27)      stw     27,-20(11)
++HIDDEN_FUNC(_savegpr_28)      stw     28,-16(11)
++HIDDEN_FUNC(_savegpr_29)      stw     29,-12(11)
++HIDDEN_FUNC(_savegpr_30)      stw     30,-8(11)
++HIDDEN_FUNC(_savegpr_31)      stw     31,-4(11)
++                      blr
++FUNC_END(_savegpr_31)
++FUNC_END(_savegpr_30)
++FUNC_END(_savegpr_29)
++FUNC_END(_savegpr_28)
++FUNC_END(_savegpr_27)
++FUNC_END(_savegpr_26)
++FUNC_END(_savegpr_25)
++FUNC_END(_savegpr_24)
++FUNC_END(_savegpr_23)
++FUNC_END(_savegpr_22)
++FUNC_END(_savegpr_21)
++FUNC_END(_savegpr_20)
++FUNC_END(_savegpr_19)
++FUNC_END(_savegpr_18)
++FUNC_END(_savegpr_17)
++FUNC_END(_savegpr_16)
++FUNC_END(_savegpr_15)
++FUNC_END(_savegpr_14)
++
++#endif
+--- a/gcc/config/rs6000/crtsavres.asm
++++ /dev/null
+@@ -1,307 +0,0 @@
+-/*
+- * Special support for eabi and SVR4
+- *
+- *   Copyright (C) 1995, 1996, 1998, 2000, 2001 Free Software Foundation, Inc.
+- *   Written By Michael Meissner
+- *   64-bit support written by David Edelsohn
+- * 
+- * This file is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License as published by the
+- * Free Software Foundation; either version 2, or (at your option) any
+- * later version.
+- * 
+- * In addition to the permissions in the GNU General Public License, the
+- * Free Software Foundation gives you unlimited permission to link the
+- * compiled version of this file with other programs, and to distribute
+- * those programs without any restriction coming from the use of this
+- * file.  (The General Public License restrictions do apply in other
+- * respects; for example, they cover modification of the file, and
+- * distribution when not linked into another program.)
+- * 
+- * This file is distributed in the hope that it will be useful, but
+- * WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+- * General Public License for more details.
+- * 
+- * You should have received a copy of the GNU General Public License
+- * along with this program; see the file COPYING.  If not, write to
+- * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- * 
+- *    As a special exception, if you link this library with files
+- *    compiled with GCC to produce an executable, this does not cause
+- *    the resulting executable to be covered by the GNU General Public License.
+- *    This exception does not however invalidate any other reasons why
+- *    the executable file might be covered by the GNU General Public License.
+- */ 
+-
+-/* Do any initializations needed for the eabi environment */
+-
+-      .file   "crtsavres.asm"
+-      .section ".text"
+-      #include "ppc-asm.h"
+-
+-/* On PowerPC64 Linux, these functions are provided by the linker.  */
+-#ifndef __powerpc64__
+-
+-/* Routines for saving floating point registers, called by the compiler.  */
+-/* Called with r11 pointing to the stack header word of the caller of the */
+-/* function, just beyond the end of the floating point save area.  */
+-
+-FUNC_START(_savefpr_14)       stfd    14,-144(11)     /* save fp registers */
+-FUNC_START(_savefpr_15)       stfd    15,-136(11)
+-FUNC_START(_savefpr_16)       stfd    16,-128(11)
+-FUNC_START(_savefpr_17)       stfd    17,-120(11)
+-FUNC_START(_savefpr_18)       stfd    18,-112(11)
+-FUNC_START(_savefpr_19)       stfd    19,-104(11)
+-FUNC_START(_savefpr_20)       stfd    20,-96(11)
+-FUNC_START(_savefpr_21)       stfd    21,-88(11)
+-FUNC_START(_savefpr_22)       stfd    22,-80(11)
+-FUNC_START(_savefpr_23)       stfd    23,-72(11)
+-FUNC_START(_savefpr_24)       stfd    24,-64(11)
+-FUNC_START(_savefpr_25)       stfd    25,-56(11)
+-FUNC_START(_savefpr_26)       stfd    26,-48(11)
+-FUNC_START(_savefpr_27)       stfd    27,-40(11)
+-FUNC_START(_savefpr_28)       stfd    28,-32(11)
+-FUNC_START(_savefpr_29)       stfd    29,-24(11)
+-FUNC_START(_savefpr_30)       stfd    30,-16(11)
+-FUNC_START(_savefpr_31)       stfd    31,-8(11)
+-                      blr
+-FUNC_END(_savefpr_31)
+-FUNC_END(_savefpr_30)
+-FUNC_END(_savefpr_29)
+-FUNC_END(_savefpr_28)
+-FUNC_END(_savefpr_27)
+-FUNC_END(_savefpr_26)
+-FUNC_END(_savefpr_25)
+-FUNC_END(_savefpr_24)
+-FUNC_END(_savefpr_23)
+-FUNC_END(_savefpr_22)
+-FUNC_END(_savefpr_21)
+-FUNC_END(_savefpr_20)
+-FUNC_END(_savefpr_19)
+-FUNC_END(_savefpr_18)
+-FUNC_END(_savefpr_17)
+-FUNC_END(_savefpr_16)
+-FUNC_END(_savefpr_15)
+-FUNC_END(_savefpr_14)
+-
+-/* Routines for saving integer registers, called by the compiler.  */
+-/* Called with r11 pointing to the stack header word of the caller of the */
+-/* function, just beyond the end of the integer save area.  */
+-
+-FUNC_START(_savegpr_14)       stw     14,-72(11)      /* save gp registers */
+-FUNC_START(_savegpr_15)       stw     15,-68(11)
+-FUNC_START(_savegpr_16)       stw     16,-64(11)
+-FUNC_START(_savegpr_17)       stw     17,-60(11)
+-FUNC_START(_savegpr_18)       stw     18,-56(11)
+-FUNC_START(_savegpr_19)       stw     19,-52(11)
+-FUNC_START(_savegpr_20)       stw     20,-48(11)
+-FUNC_START(_savegpr_21)       stw     21,-44(11)
+-FUNC_START(_savegpr_22)       stw     22,-40(11)
+-FUNC_START(_savegpr_23)       stw     23,-36(11)
+-FUNC_START(_savegpr_24)       stw     24,-32(11)
+-FUNC_START(_savegpr_25)       stw     25,-28(11)
+-FUNC_START(_savegpr_26)       stw     26,-24(11)
+-FUNC_START(_savegpr_27)       stw     27,-20(11)
+-FUNC_START(_savegpr_28)       stw     28,-16(11)
+-FUNC_START(_savegpr_29)       stw     29,-12(11)
+-FUNC_START(_savegpr_30)       stw     30,-8(11)
+-FUNC_START(_savegpr_31)       stw     31,-4(11)
+-                      blr
+-FUNC_END(_savegpr_31)
+-FUNC_END(_savegpr_30)
+-FUNC_END(_savegpr_29)
+-FUNC_END(_savegpr_28)
+-FUNC_END(_savegpr_27)
+-FUNC_END(_savegpr_26)
+-FUNC_END(_savegpr_25)
+-FUNC_END(_savegpr_24)
+-FUNC_END(_savegpr_23)
+-FUNC_END(_savegpr_22)
+-FUNC_END(_savegpr_21)
+-FUNC_END(_savegpr_20)
+-FUNC_END(_savegpr_19)
+-FUNC_END(_savegpr_18)
+-FUNC_END(_savegpr_17)
+-FUNC_END(_savegpr_16)
+-FUNC_END(_savegpr_15)
+-FUNC_END(_savegpr_14)
+-
+-/* Routines for restoring floating point registers, called by the compiler.  */
+-/* Called with r11 pointing to the stack header word of the caller of the */
+-/* function, just beyond the end of the floating point save area.  */
+-
+-FUNC_START(_restfpr_14)       lfd     14,-144(11)     /* restore fp registers */
+-FUNC_START(_restfpr_15)       lfd     15,-136(11)
+-FUNC_START(_restfpr_16)       lfd     16,-128(11)
+-FUNC_START(_restfpr_17)       lfd     17,-120(11)
+-FUNC_START(_restfpr_18)       lfd     18,-112(11)
+-FUNC_START(_restfpr_19)       lfd     19,-104(11)
+-FUNC_START(_restfpr_20)       lfd     20,-96(11)
+-FUNC_START(_restfpr_21)       lfd     21,-88(11)
+-FUNC_START(_restfpr_22)       lfd     22,-80(11)
+-FUNC_START(_restfpr_23)       lfd     23,-72(11)
+-FUNC_START(_restfpr_24)       lfd     24,-64(11)
+-FUNC_START(_restfpr_25)       lfd     25,-56(11)
+-FUNC_START(_restfpr_26)       lfd     26,-48(11)
+-FUNC_START(_restfpr_27)       lfd     27,-40(11)
+-FUNC_START(_restfpr_28)       lfd     28,-32(11)
+-FUNC_START(_restfpr_29)       lfd     29,-24(11)
+-FUNC_START(_restfpr_30)       lfd     30,-16(11)
+-FUNC_START(_restfpr_31)       lfd     31,-8(11)
+-                      blr
+-FUNC_END(_restfpr_31)
+-FUNC_END(_restfpr_30)
+-FUNC_END(_restfpr_29)
+-FUNC_END(_restfpr_28)
+-FUNC_END(_restfpr_27)
+-FUNC_END(_restfpr_26)
+-FUNC_END(_restfpr_25)
+-FUNC_END(_restfpr_24)
+-FUNC_END(_restfpr_23)
+-FUNC_END(_restfpr_22)
+-FUNC_END(_restfpr_21)
+-FUNC_END(_restfpr_20)
+-FUNC_END(_restfpr_19)
+-FUNC_END(_restfpr_18)
+-FUNC_END(_restfpr_17)
+-FUNC_END(_restfpr_16)
+-FUNC_END(_restfpr_15)
+-FUNC_END(_restfpr_14)
+-
+-/* Routines for restoring integer registers, called by the compiler.  */
+-/* Called with r11 pointing to the stack header word of the caller of the */
+-/* function, just beyond the end of the integer restore area.  */
+-
+-FUNC_START(_restgpr_14)       lwz     14,-72(11)      /* restore gp registers */
+-FUNC_START(_restgpr_15)       lwz     15,-68(11)
+-FUNC_START(_restgpr_16)       lwz     16,-64(11)
+-FUNC_START(_restgpr_17)       lwz     17,-60(11)
+-FUNC_START(_restgpr_18)       lwz     18,-56(11)
+-FUNC_START(_restgpr_19)       lwz     19,-52(11)
+-FUNC_START(_restgpr_20)       lwz     20,-48(11)
+-FUNC_START(_restgpr_21)       lwz     21,-44(11)
+-FUNC_START(_restgpr_22)       lwz     22,-40(11)
+-FUNC_START(_restgpr_23)       lwz     23,-36(11)
+-FUNC_START(_restgpr_24)       lwz     24,-32(11)
+-FUNC_START(_restgpr_25)       lwz     25,-28(11)
+-FUNC_START(_restgpr_26)       lwz     26,-24(11)
+-FUNC_START(_restgpr_27)       lwz     27,-20(11)
+-FUNC_START(_restgpr_28)       lwz     28,-16(11)
+-FUNC_START(_restgpr_29)       lwz     29,-12(11)
+-FUNC_START(_restgpr_30)       lwz     30,-8(11)
+-FUNC_START(_restgpr_31)       lwz     31,-4(11)
+-                      blr
+-FUNC_END(_restgpr_31)
+-FUNC_END(_restgpr_30)
+-FUNC_END(_restgpr_29)
+-FUNC_END(_restgpr_28)
+-FUNC_END(_restgpr_27)
+-FUNC_END(_restgpr_26)
+-FUNC_END(_restgpr_25)
+-FUNC_END(_restgpr_24)
+-FUNC_END(_restgpr_23)
+-FUNC_END(_restgpr_22)
+-FUNC_END(_restgpr_21)
+-FUNC_END(_restgpr_20)
+-FUNC_END(_restgpr_19)
+-FUNC_END(_restgpr_18)
+-FUNC_END(_restgpr_17)
+-FUNC_END(_restgpr_16)
+-FUNC_END(_restgpr_15)
+-FUNC_END(_restgpr_14)
+-
+-/* Routines for restoring floating point registers, called by the compiler.  */
+-/* Called with r11 pointing to the stack header word of the caller of the */
+-/* function, just beyond the end of the floating point save area.  */
+-/* In addition to restoring the fp registers, it will return to the caller's */
+-/* caller */
+-
+-FUNC_START(_restfpr_14_x)     lfd     14,-144(11)     /* restore fp registers */
+-FUNC_START(_restfpr_15_x)     lfd     15,-136(11)
+-FUNC_START(_restfpr_16_x)     lfd     16,-128(11)
+-FUNC_START(_restfpr_17_x)     lfd     17,-120(11)
+-FUNC_START(_restfpr_18_x)     lfd     18,-112(11)
+-FUNC_START(_restfpr_19_x)     lfd     19,-104(11)
+-FUNC_START(_restfpr_20_x)     lfd     20,-96(11)
+-FUNC_START(_restfpr_21_x)     lfd     21,-88(11)
+-FUNC_START(_restfpr_22_x)     lfd     22,-80(11)
+-FUNC_START(_restfpr_23_x)     lfd     23,-72(11)
+-FUNC_START(_restfpr_24_x)     lfd     24,-64(11)
+-FUNC_START(_restfpr_25_x)     lfd     25,-56(11)
+-FUNC_START(_restfpr_26_x)     lfd     26,-48(11)
+-FUNC_START(_restfpr_27_x)     lfd     27,-40(11)
+-FUNC_START(_restfpr_28_x)     lfd     28,-32(11)
+-FUNC_START(_restfpr_29_x)     lfd     29,-24(11)
+-FUNC_START(_restfpr_30_x)     lfd     30,-16(11)
+-FUNC_START(_restfpr_31_x)     lwz     0,4(11)
+-                              lfd     31,-8(11)
+-                              mtlr    0
+-                              mr      1,11
+-                              blr
+-FUNC_END(_restfpr_31_x)
+-FUNC_END(_restfpr_30_x)
+-FUNC_END(_restfpr_29_x)
+-FUNC_END(_restfpr_28_x)
+-FUNC_END(_restfpr_27_x)
+-FUNC_END(_restfpr_26_x)
+-FUNC_END(_restfpr_25_x)
+-FUNC_END(_restfpr_24_x)
+-FUNC_END(_restfpr_23_x)
+-FUNC_END(_restfpr_22_x)
+-FUNC_END(_restfpr_21_x)
+-FUNC_END(_restfpr_20_x)
+-FUNC_END(_restfpr_19_x)
+-FUNC_END(_restfpr_18_x)
+-FUNC_END(_restfpr_17_x)
+-FUNC_END(_restfpr_16_x)
+-FUNC_END(_restfpr_15_x)
+-FUNC_END(_restfpr_14_x)
+-
+-/* Routines for restoring integer registers, called by the compiler.  */
+-/* Called with r11 pointing to the stack header word of the caller of the */
+-/* function, just beyond the end of the integer restore area.  */
+-
+-FUNC_START(_restgpr_14_x)     lwz     14,-72(11)      /* restore gp registers */
+-FUNC_START(_restgpr_15_x)     lwz     15,-68(11)
+-FUNC_START(_restgpr_16_x)     lwz     16,-64(11)
+-FUNC_START(_restgpr_17_x)     lwz     17,-60(11)
+-FUNC_START(_restgpr_18_x)     lwz     18,-56(11)
+-FUNC_START(_restgpr_19_x)     lwz     19,-52(11)
+-FUNC_START(_restgpr_20_x)     lwz     20,-48(11)
+-FUNC_START(_restgpr_21_x)     lwz     21,-44(11)
+-FUNC_START(_restgpr_22_x)     lwz     22,-40(11)
+-FUNC_START(_restgpr_23_x)     lwz     23,-36(11)
+-FUNC_START(_restgpr_24_x)     lwz     24,-32(11)
+-FUNC_START(_restgpr_25_x)     lwz     25,-28(11)
+-FUNC_START(_restgpr_26_x)     lwz     26,-24(11)
+-FUNC_START(_restgpr_27_x)     lwz     27,-20(11)
+-FUNC_START(_restgpr_28_x)     lwz     28,-16(11)
+-FUNC_START(_restgpr_29_x)     lwz     29,-12(11)
+-FUNC_START(_restgpr_30_x)     lwz     30,-8(11)
+-FUNC_START(_restgpr_31_x)     lwz     0,4(11)
+-                              lwz     31,-4(11)
+-                              mtlr    0
+-                              mr      1,11
+-                              blr
+-FUNC_END(_restgpr_31_x)
+-FUNC_END(_restgpr_30_x)
+-FUNC_END(_restgpr_29_x)
+-FUNC_END(_restgpr_28_x)
+-FUNC_END(_restgpr_27_x)
+-FUNC_END(_restgpr_26_x)
+-FUNC_END(_restgpr_25_x)
+-FUNC_END(_restgpr_24_x)
+-FUNC_END(_restgpr_23_x)
+-FUNC_END(_restgpr_22_x)
+-FUNC_END(_restgpr_21_x)
+-FUNC_END(_restgpr_20_x)
+-FUNC_END(_restgpr_19_x)
+-FUNC_END(_restgpr_18_x)
+-FUNC_END(_restgpr_17_x)
+-FUNC_END(_restgpr_16_x)
+-FUNC_END(_restgpr_15_x)
+-FUNC_END(_restgpr_14_x)
+-
+-#endif
+--- a/gcc/config/rs6000/darwin-ldouble.c
++++ b/gcc/config/rs6000/darwin-ldouble.c
+@@ -422,15 +422,13 @@ fmsub (double a, double b, double c)
+     FP_UNPACK_SEMIRAW_Q(U,u);
+     FP_UNPACK_SEMIRAW_Q(Z,z);
+     FP_SUB_Q(V,U,Z);
+-    FP_PACK_SEMIRAW_Q(v,V);
+-    FP_HANDLE_EXCEPTIONS;
+     /* Truncate quad to double.  */
+-    FP_INIT_ROUNDMODE;
+-    FP_UNPACK_SEMIRAW_Q(V,v);
+ #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
++    V_f[3] &= 0x0007ffff;
+     FP_TRUNC(D,Q,2,4,R,V);
+ #else
++    V_f1 &= 0x0007ffffffffffffL;
+     FP_TRUNC(D,Q,1,2,R,V);
+ #endif
+     FP_PACK_SEMIRAW_D(r,R);
+--- a/gcc/config/rs6000/darwin.h
++++ b/gcc/config/rs6000/darwin.h
+@@ -191,6 +191,8 @@
+ #undef        FP_SAVE_INLINE
+ #define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64)
++#undef GP_SAVE_INLINE
++#define GP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 32)
+ /* Darwin uses a function call if everything needs to be saved/restored.  */
+ #undef WORLD_SAVE_P
+--- a/gcc/config/rs6000/dfp.md
++++ b/gcc/config/rs6000/dfp.md
+@@ -155,7 +155,7 @@
+ (define_expand "negdd2"
+   [(set (match_operand:DD 0 "gpc_reg_operand" "")
+       (neg:DD (match_operand:DD 1 "gpc_reg_operand" "")))]
+-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
++  "TARGET_HARD_FLOAT && TARGET_FPRS"
+   "")
+ (define_insn "*negdd2_fpr"
+@@ -168,7 +168,7 @@
+ (define_expand "absdd2"
+   [(set (match_operand:DD 0 "gpc_reg_operand" "")
+       (abs:DD (match_operand:DD 1 "gpc_reg_operand" "")))]
+-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
++  "TARGET_HARD_FLOAT && TARGET_FPRS"
+   "")
+ (define_insn "*absdd2_fpr"
+@@ -376,7 +376,7 @@
+ (define_insn "*movdd_softfloat32"
+   [(set (match_operand:DD 0 "nonimmediate_operand" "=r,r,m,r,r,r")
+       (match_operand:DD 1 "input_operand" "r,m,r,G,H,F"))]
+-  "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT
++  "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
+    && (gpc_reg_operand (operands[0], DDmode)
+        || gpc_reg_operand (operands[1], DDmode))"
+   "*
+@@ -486,7 +486,7 @@
+ (define_expand "negtd2"
+   [(set (match_operand:TD 0 "gpc_reg_operand" "")
+       (neg:TD (match_operand:TD 1 "gpc_reg_operand" "")))]
+-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
++  "TARGET_HARD_FLOAT && TARGET_FPRS"
+   "")
+ (define_insn "*negtd2_fpr"
+@@ -499,7 +499,7 @@
+ (define_expand "abstd2"
+   [(set (match_operand:TD 0 "gpc_reg_operand" "")
+       (abs:TD (match_operand:TD 1 "gpc_reg_operand" "")))]
+-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
++  "TARGET_HARD_FLOAT && TARGET_FPRS"
+   "")
+ (define_insn "*abstd2_fpr"
+--- /dev/null
++++ b/gcc/config/rs6000/e300c2c3.md
+@@ -0,0 +1,189 @@
++;; Pipeline description for Motorola PowerPC e300c3 core.
++;;   Copyright (C) 2008 Free Software Foundation, Inc.
++;;   Contributed by Edmar Wienskoski (edmar@freescale.com)
++;;
++;; This file is part of GCC.
++;;
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published
++;; by the Free Software Foundation; either version 3, or (at your
++;; option) any later version.
++;;
++;; GCC is distributed in the hope that it will be useful, but WITHOUT
++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
++;; License for more details.
++;;
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING3.  If not see
++;; <http://www.gnu.org/licenses/>.
++
++(define_automaton "ppce300c3_most,ppce300c3_long,ppce300c3_retire")
++(define_cpu_unit "ppce300c3_decode_0,ppce300c3_decode_1" "ppce300c3_most")
++
++;; We don't simulate general issue queue (GIC).  If we have SU insn
++;; and then SU1 insn, they can not be issued on the same cycle
++;; (although SU1 insn and then SU insn can be issued) because the SU
++;; insn will go to SU1 from GIC0 entry.  Fortunately, the first cycle
++;; multipass insn scheduling will find the situation and issue the SU1
++;; insn and then the SU insn.
++(define_cpu_unit "ppce300c3_issue_0,ppce300c3_issue_1"   "ppce300c3_most")
++
++;; We could describe completion buffers slots in combination with the
++;; retirement units and the order of completion but the result
++;; automaton would behave in the same way because we can not describe
++;; real latency time with taking in order completion into account.
++;; Actually we could define the real latency time by querying reserved
++;; automaton units but the current scheduler uses latency time before
++;; issuing insns and making any reservations.
++;;
++;; So our description is aimed to achieve a insn schedule in which the
++;; insns would not wait in the completion buffer.
++(define_cpu_unit "ppce300c3_retire_0,ppce300c3_retire_1" "ppce300c3_retire")
++
++;; Branch unit:
++(define_cpu_unit "ppce300c3_bu" "ppce300c3_most")
++
++;; IU:
++(define_cpu_unit "ppce300c3_iu0_stage0,ppce300c3_iu1_stage0" "ppce300c3_most")
++
++;; IU: This used to describe non-pipelined division.
++(define_cpu_unit "ppce300c3_mu_div" "ppce300c3_long")
++
++;; SRU:
++(define_cpu_unit "ppce300c3_sru_stage0" "ppce300c3_most")
++
++;; Here we simplified LSU unit description not describing the stages.
++(define_cpu_unit "ppce300c3_lsu" "ppce300c3_most")
++
++;; FPU:
++(define_cpu_unit "ppce300c3_fpu" "ppce300c3_most")
++
++;; The following units are used to make automata deterministic
++(define_cpu_unit "present_ppce300c3_decode_0" "ppce300c3_most")
++(define_cpu_unit "present_ppce300c3_issue_0" "ppce300c3_most")
++(define_cpu_unit "present_ppce300c3_retire_0" "ppce300c3_retire")
++(define_cpu_unit "present_ppce300c3_iu0_stage0" "ppce300c3_most")
++
++;; The following sets to make automata deterministic when option ndfa is used.
++(presence_set "present_ppce300c3_decode_0" "ppce300c3_decode_0")
++(presence_set "present_ppce300c3_issue_0" "ppce300c3_issue_0")
++(presence_set "present_ppce300c3_retire_0" "ppce300c3_retire_0")
++(presence_set "present_ppce300c3_iu0_stage0" "ppce300c3_iu0_stage0")
++
++;; Some useful abbreviations.
++(define_reservation "ppce300c3_decode"
++    "ppce300c3_decode_0|ppce300c3_decode_1+present_ppce300c3_decode_0")
++(define_reservation "ppce300c3_issue"
++    "ppce300c3_issue_0|ppce300c3_issue_1+present_ppce300c3_issue_0")
++(define_reservation "ppce300c3_retire"
++   "ppce300c3_retire_0|ppce300c3_retire_1+present_ppce300c3_retire_0")
++(define_reservation "ppce300c3_iu_stage0"
++   "ppce300c3_iu0_stage0|ppce300c3_iu1_stage0+present_ppce300c3_iu0_stage0")
++
++;; Compares can be executed either one of the IU or SRU
++(define_insn_reservation "ppce300c3_cmp" 1
++  (and (eq_attr "type" "cmp,compare,delayed_compare,fast_compare")
++       (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3")))
++  "ppce300c3_decode,ppce300c3_issue+(ppce300c3_iu_stage0|ppce300c3_sru_stage0) \
++        +ppce300c3_retire")
++
++;; Other one cycle IU insns
++(define_insn_reservation "ppce300c3_iu" 1
++  (and (eq_attr "type" "integer,insert_word")
++       (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3")))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_iu_stage0+ppce300c3_retire")
++
++;; Branch.  Actually this latency time is not used by the scheduler.
++(define_insn_reservation "ppce300c3_branch" 1
++  (and (eq_attr "type" "jmpreg,branch")
++       (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3")))
++  "ppce300c3_decode,ppce300c3_bu,ppce300c3_retire")
++
++;; Multiply is non-pipelined but can be executed in any IU
++(define_insn_reservation "ppce300c3_multiply" 2
++  (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
++       (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3")))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_iu_stage0, \
++   ppce300c3_iu_stage0+ppce300c3_retire")
++
++;; Divide.  We use the average latency time here.  We omit reserving a
++;; retire unit because of the result automata will be huge.
++(define_insn_reservation "ppce300c3_divide" 20
++  (and (eq_attr "type" "idiv")
++       (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3")))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_iu_stage0+ppce300c3_mu_div,\
++   ppce300c3_mu_div*19")
++
++;; CR logical
++(define_insn_reservation "ppce300c3_cr_logical" 1
++  (and (eq_attr "type" "cr_logical,delayed_cr")
++       (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3")))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire")
++
++;; Mfcr
++(define_insn_reservation "ppce300c3_mfcr" 1
++  (and (eq_attr "type" "mfcr")
++       (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3")))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire")
++
++;; Mtcrf
++(define_insn_reservation "ppce300c3_mtcrf" 1
++  (and (eq_attr "type" "mtcr")
++       (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3")))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire")
++
++;; Mtjmpr
++(define_insn_reservation "ppce300c3_mtjmpr" 1
++  (and (eq_attr "type" "mtjmpr,mfjmpr")
++       (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3")))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire")
++
++;; Float point instructions
++(define_insn_reservation "ppce300c3_fpcompare" 3
++  (and (eq_attr "type" "fpcompare")
++       (eq_attr "cpu" "ppce300c3"))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,nothing,ppce300c3_retire")
++
++(define_insn_reservation "ppce300c3_fp" 3
++  (and (eq_attr "type" "fp")
++       (eq_attr "cpu" "ppce300c3"))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,nothing,ppce300c3_retire")
++
++(define_insn_reservation "ppce300c3_dmul" 4
++  (and (eq_attr "type" "dmul")
++       (eq_attr "cpu" "ppce300c3"))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,ppce300c3_fpu,nothing,ppce300c3_retire")
++
++; Divides are not pipelined
++(define_insn_reservation "ppce300c3_sdiv" 18
++  (and (eq_attr "type" "sdiv")
++       (eq_attr "cpu" "ppce300c3"))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,ppce300c3_fpu*17")
++
++(define_insn_reservation "ppce300c3_ddiv" 33
++  (and (eq_attr "type" "ddiv")
++       (eq_attr "cpu" "ppce300c3"))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,ppce300c3_fpu*32")
++
++;; Loads
++(define_insn_reservation "ppce300c3_load" 2
++  (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
++       (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3")))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire")
++
++(define_insn_reservation "ppce300c3_fpload" 2
++  (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
++       (eq_attr "cpu" "ppce300c3"))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire")
++
++;; Stores.
++(define_insn_reservation "ppce300c3_store" 2
++  (and (eq_attr "type" "store,store_ux,store_u")
++       (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3")))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire")
++
++(define_insn_reservation "ppce300c3_fpstore" 2
++  (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u")
++       (eq_attr "cpu" "ppce300c3"))
++  "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire")
+--- a/gcc/config/rs6000/e500.h
++++ b/gcc/config/rs6000/e500.h
+@@ -19,7 +19,6 @@
+ #undef TARGET_SPE_ABI
+ #undef TARGET_SPE
+ #undef TARGET_E500
+-#undef TARGET_ISEL
+ #undef TARGET_FPRS
+ #undef TARGET_E500_SINGLE
+ #undef TARGET_E500_DOUBLE
+@@ -28,13 +27,12 @@
+ #define TARGET_SPE_ABI rs6000_spe_abi
+ #define TARGET_SPE rs6000_spe
+ #define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540)
+-#define TARGET_ISEL rs6000_isel
+ #define TARGET_FPRS (rs6000_float_gprs == 0)
+ #define TARGET_E500_SINGLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 1)
+ #define TARGET_E500_DOUBLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 2)
+ #define CHECK_E500_OPTIONS                                            \
+   do {                                                                        \
+-    if (TARGET_E500 || TARGET_SPE || TARGET_SPE_ABI || TARGET_ISEL    \
++    if (TARGET_E500 || TARGET_SPE || TARGET_SPE_ABI                   \
+       || TARGET_E500_SINGLE || TARGET_E500_DOUBLE)                    \
+       {                                                                       \
+       if (TARGET_ALTIVEC)                                             \
+--- /dev/null
++++ b/gcc/config/rs6000/e500crtres32gpr.asm
+@@ -0,0 +1,84 @@
++/*
++ * Special support for e500 eabi and SVR4
++ *
++ *   Copyright (C) 2008 Free Software Foundation, Inc.
++ *   Written by Nathan Froyd
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++      .file   "e500crtres32gpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++#ifdef __SPE__
++
++/* Routines for restoring 32-bit integer registers, called by the compiler.  */
++/* "Bare" versions that simply return to their caller.  */
++
++HIDDEN_FUNC(_rest32gpr_14)    lwz 14,-72(11)
++HIDDEN_FUNC(_rest32gpr_15)    lwz 15,-68(11)
++HIDDEN_FUNC(_rest32gpr_16)    lwz 16,-64(11)
++HIDDEN_FUNC(_rest32gpr_17)    lwz 17,-60(11)
++HIDDEN_FUNC(_rest32gpr_18)    lwz 18,-56(11)
++HIDDEN_FUNC(_rest32gpr_19)    lwz 19,-52(11)
++HIDDEN_FUNC(_rest32gpr_20)    lwz 20,-48(11)
++HIDDEN_FUNC(_rest32gpr_21)    lwz 21,-44(11)
++HIDDEN_FUNC(_rest32gpr_22)    lwz 22,-40(11)
++HIDDEN_FUNC(_rest32gpr_23)    lwz 23,-36(11)
++HIDDEN_FUNC(_rest32gpr_24)    lwz 24,-32(11)
++HIDDEN_FUNC(_rest32gpr_25)    lwz 25,-28(11)
++HIDDEN_FUNC(_rest32gpr_26)    lwz 26,-24(11)
++HIDDEN_FUNC(_rest32gpr_27)    lwz 27,-20(11)
++HIDDEN_FUNC(_rest32gpr_28)    lwz 28,-16(11)
++HIDDEN_FUNC(_rest32gpr_29)    lwz 29,-12(11)
++HIDDEN_FUNC(_rest32gpr_30)    lwz 30,-8(11)
++HIDDEN_FUNC(_rest32gpr_31)    lwz 31,-4(11)
++                              blr
++FUNC_END(_rest32gpr_31)
++FUNC_END(_rest32gpr_30)
++FUNC_END(_rest32gpr_29)
++FUNC_END(_rest32gpr_28)
++FUNC_END(_rest32gpr_27)
++FUNC_END(_rest32gpr_26)
++FUNC_END(_rest32gpr_25)
++FUNC_END(_rest32gpr_24)
++FUNC_END(_rest32gpr_23)
++FUNC_END(_rest32gpr_22)
++FUNC_END(_rest32gpr_21)
++FUNC_END(_rest32gpr_20)
++FUNC_END(_rest32gpr_19)
++FUNC_END(_rest32gpr_18)
++FUNC_END(_rest32gpr_17)
++FUNC_END(_rest32gpr_16)
++FUNC_END(_rest32gpr_15)
++FUNC_END(_rest32gpr_14)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/e500crtres64gpr.asm
+@@ -0,0 +1,84 @@
++/*
++ * Special support for e500 eabi and SVR4
++ *
++ *   Copyright (C) 2008 Free Software Foundation, Inc.
++ *   Written by Nathan Froyd
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++      .file   "e500crtres64gpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++#ifdef __SPE__
++
++/* Routines for restoring 64-bit integer registers, called by the compiler.  */
++/* "Bare" versions that return to their caller.  */
++
++HIDDEN_FUNC(_rest64gpr_14)    evldd 14,0(11)
++HIDDEN_FUNC(_rest64gpr_15)    evldd 15,8(11)
++HIDDEN_FUNC(_rest64gpr_16)    evldd 16,16(11)
++HIDDEN_FUNC(_rest64gpr_17)    evldd 17,24(11)
++HIDDEN_FUNC(_rest64gpr_18)    evldd 18,32(11)
++HIDDEN_FUNC(_rest64gpr_19)    evldd 19,40(11)
++HIDDEN_FUNC(_rest64gpr_20)    evldd 20,48(11)
++HIDDEN_FUNC(_rest64gpr_21)    evldd 21,56(11)
++HIDDEN_FUNC(_rest64gpr_22)    evldd 22,64(11)
++HIDDEN_FUNC(_rest64gpr_23)    evldd 23,72(11)
++HIDDEN_FUNC(_rest64gpr_24)    evldd 24,80(11)
++HIDDEN_FUNC(_rest64gpr_25)    evldd 25,88(11)
++HIDDEN_FUNC(_rest64gpr_26)    evldd 26,96(11)
++HIDDEN_FUNC(_rest64gpr_27)    evldd 27,104(11)
++HIDDEN_FUNC(_rest64gpr_28)    evldd 28,112(11)
++HIDDEN_FUNC(_rest64gpr_29)    evldd 29,120(11)
++HIDDEN_FUNC(_rest64gpr_30)    evldd 30,128(11)
++HIDDEN_FUNC(_rest64gpr_31)    evldd 31,136(11)
++                              blr
++FUNC_END(_rest64gpr_31)
++FUNC_END(_rest64gpr_30)
++FUNC_END(_rest64gpr_29)
++FUNC_END(_rest64gpr_28)
++FUNC_END(_rest64gpr_27)
++FUNC_END(_rest64gpr_26)
++FUNC_END(_rest64gpr_25)
++FUNC_END(_rest64gpr_24)
++FUNC_END(_rest64gpr_23)
++FUNC_END(_rest64gpr_22)
++FUNC_END(_rest64gpr_21)
++FUNC_END(_rest64gpr_20)
++FUNC_END(_rest64gpr_19)
++FUNC_END(_rest64gpr_18)
++FUNC_END(_rest64gpr_17)
++FUNC_END(_rest64gpr_16)
++FUNC_END(_rest64gpr_15)
++FUNC_END(_rest64gpr_14)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/e500crtres64gprctr.asm
+@@ -0,0 +1,83 @@
++/*
++ * Special support for e500 eabi and SVR4
++ *
++ *   Copyright (C) 2008 Free Software Foundation, Inc.
++ *   Written by Nathan Froyd
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++      .file   "e500crtres64gprctr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++#ifdef __SPE__
++
++/* Routines for restoring 64-bit integer registers where the number of
++   registers to be restored is passed in CTR, called by the compiler.  */
++
++HIDDEN_FUNC(_rest64gpr_ctr_14)        evldd 14,0(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_15)        evldd 15,8(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_16)        evldd 16,16(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_17)        evldd 17,24(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_18)        evldd 18,32(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_19)        evldd 19,40(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_20)        evldd 20,48(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_21)        evldd 21,56(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_22)        evldd 22,64(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_23)        evldd 23,72(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_24)        evldd 24,80(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_25)        evldd 25,88(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_26)        evldd 26,96(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_27)        evldd 27,104(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_28)        evldd 28,112(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_29)        evldd 29,120(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_30)        evldd 30,128(11)
++                              bdz _rest64_gpr_ctr_done
++HIDDEN_FUNC(_rest64gpr_ctr_31)        evldd 31,136(11)
++_rest64gpr_ctr_done:          blr
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/e500crtrest32gpr.asm
+@@ -0,0 +1,86 @@
++/*
++ * Special support for e500 eabi and SVR4
++ *
++ *   Copyright (C) 2008 Free Software Foundation, Inc.
++ *   Written by Nathan Froyd
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++      .file   "e500crtrest32gpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++#ifdef __SPE__
++
++/* Routines for restoring 32-bit integer registers, called by the compiler.  */
++/* "Tail" versions that perform a tail call.  */
++
++HIDDEN_FUNC(_rest32gpr_14_t)  lwz 14,-72(11)
++HIDDEN_FUNC(_rest32gpr_15_t)  lwz 15,-68(11)
++HIDDEN_FUNC(_rest32gpr_16_t)  lwz 16,-64(11)
++HIDDEN_FUNC(_rest32gpr_17_t)  lwz 17,-60(11)
++HIDDEN_FUNC(_rest32gpr_18_t)  lwz 18,-56(11)
++HIDDEN_FUNC(_rest32gpr_19_t)  lwz 19,-52(11)
++HIDDEN_FUNC(_rest32gpr_20_t)  lwz 20,-48(11)
++HIDDEN_FUNC(_rest32gpr_21_t)  lwz 21,-44(11)
++HIDDEN_FUNC(_rest32gpr_22_t)  lwz 22,-40(11)
++HIDDEN_FUNC(_rest32gpr_23_t)  lwz 23,-36(11)
++HIDDEN_FUNC(_rest32gpr_24_t)  lwz 24,-32(11)
++HIDDEN_FUNC(_rest32gpr_25_t)  lwz 25,-28(11)
++HIDDEN_FUNC(_rest32gpr_26_t)  lwz 26,-24(11)
++HIDDEN_FUNC(_rest32gpr_27_t)  lwz 27,-20(11)
++HIDDEN_FUNC(_rest32gpr_28_t)  lwz 28,-16(11)
++HIDDEN_FUNC(_rest32gpr_29_t)  lwz 29,-12(11)
++HIDDEN_FUNC(_rest32gpr_30_t)  lwz 30,-8(11)
++HIDDEN_FUNC(_rest32gpr_31_t)  lwz 31,-4(11)
++                              lwz 0,4(11)
++                              mr 1,11
++                              blr
++FUNC_END(_rest32gpr_31_t)
++FUNC_END(_rest32gpr_30_t)
++FUNC_END(_rest32gpr_29_t)
++FUNC_END(_rest32gpr_28_t)
++FUNC_END(_rest32gpr_27_t)
++FUNC_END(_rest32gpr_26_t)
++FUNC_END(_rest32gpr_25_t)
++FUNC_END(_rest32gpr_24_t)
++FUNC_END(_rest32gpr_23_t)
++FUNC_END(_rest32gpr_22_t)
++FUNC_END(_rest32gpr_21_t)
++FUNC_END(_rest32gpr_20_t)
++FUNC_END(_rest32gpr_19_t)
++FUNC_END(_rest32gpr_18_t)
++FUNC_END(_rest32gpr_17_t)
++FUNC_END(_rest32gpr_16_t)
++FUNC_END(_rest32gpr_15_t)
++FUNC_END(_rest32gpr_14_t)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/e500crtrest64gpr.asm
+@@ -0,0 +1,85 @@
++/*
++ * Special support for e500 eabi and SVR4
++ *
++ *   Copyright (C) 2008 Free Software Foundation, Inc.
++ *   Written by Nathan Froyd
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++      .file   "e500crtrest64gpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++#ifdef __SPE__
++
++/* "Tail" versions that perform a tail call.  */
++
++HIDDEN_FUNC(_rest64gpr_14_t)  evldd 14,0(11)
++HIDDEN_FUNC(_rest64gpr_15_t)  evldd 15,8(11)
++HIDDEN_FUNC(_rest64gpr_16_t)  evldd 16,16(11)
++HIDDEN_FUNC(_rest64gpr_17_t)  evldd 17,24(11)
++HIDDEN_FUNC(_rest64gpr_18_t)  evldd 18,32(11)
++HIDDEN_FUNC(_rest64gpr_19_t)  evldd 19,40(11)
++HIDDEN_FUNC(_rest64gpr_20_t)  evldd 20,48(11)
++HIDDEN_FUNC(_rest64gpr_21_t)  evldd 21,56(11)
++HIDDEN_FUNC(_rest64gpr_22_t)  evldd 22,64(11)
++HIDDEN_FUNC(_rest64gpr_23_t)  evldd 23,72(11)
++HIDDEN_FUNC(_rest64gpr_24_t)  evldd 24,80(11)
++HIDDEN_FUNC(_rest64gpr_25_t)  evldd 25,88(11)
++HIDDEN_FUNC(_rest64gpr_26_t)  evldd 26,96(11)
++HIDDEN_FUNC(_rest64gpr_27_t)  evldd 27,104(11)
++HIDDEN_FUNC(_rest64gpr_28_t)  evldd 28,112(11)
++HIDDEN_FUNC(_rest64gpr_29_t)  evldd 29,120(11)
++HIDDEN_FUNC(_rest64gpr_30_t)  evldd 30,128(11)
++HIDDEN_FUNC(_rest64gpr_31_t)  lwz 0,148(11)
++                              evldd 31,136(11)
++                              addi 1,11,144
++                              blr
++FUNC_END(_rest64gpr_31_t)
++FUNC_END(_rest64gpr_30_t)
++FUNC_END(_rest64gpr_29_t)
++FUNC_END(_rest64gpr_28_t)
++FUNC_END(_rest64gpr_27_t)
++FUNC_END(_rest64gpr_26_t)
++FUNC_END(_rest64gpr_25_t)
++FUNC_END(_rest64gpr_24_t)
++FUNC_END(_rest64gpr_23_t)
++FUNC_END(_rest64gpr_22_t)
++FUNC_END(_rest64gpr_21_t)
++FUNC_END(_rest64gpr_20_t)
++FUNC_END(_rest64gpr_19_t)
++FUNC_END(_rest64gpr_18_t)
++FUNC_END(_rest64gpr_17_t)
++FUNC_END(_rest64gpr_16_t)
++FUNC_END(_rest64gpr_15_t)
++FUNC_END(_rest64gpr_14_t)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/e500crtresx32gpr.asm
+@@ -0,0 +1,87 @@
++/*
++ * Special support for e500 eabi and SVR4
++ *
++ *   Copyright (C) 2008 Free Software Foundation, Inc.
++ *   Written by Nathan Froyd
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++      .file   "e500crtresx32gpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++#ifdef __SPE__
++
++/* Routines for restoring 32-bit integer registers, called by the compiler.  */
++/* "Exit" versions that return to the caller's caller.  */
++
++HIDDEN_FUNC(_rest32gpr_14_x)  lwz 14,-72(11)
++HIDDEN_FUNC(_rest32gpr_15_x)  lwz 15,-68(11)
++HIDDEN_FUNC(_rest32gpr_16_x)  lwz 16,-64(11)
++HIDDEN_FUNC(_rest32gpr_17_x)  lwz 17,-60(11)
++HIDDEN_FUNC(_rest32gpr_18_x)  lwz 18,-56(11)
++HIDDEN_FUNC(_rest32gpr_19_x)  lwz 19,-52(11)
++HIDDEN_FUNC(_rest32gpr_20_x)  lwz 20,-48(11)
++HIDDEN_FUNC(_rest32gpr_21_x)  lwz 21,-44(11)
++HIDDEN_FUNC(_rest32gpr_22_x)  lwz 22,-40(11)
++HIDDEN_FUNC(_rest32gpr_23_x)  lwz 23,-36(11)
++HIDDEN_FUNC(_rest32gpr_24_x)  lwz 24,-32(11)
++HIDDEN_FUNC(_rest32gpr_25_x)  lwz 25,-28(11)
++HIDDEN_FUNC(_rest32gpr_26_x)  lwz 26,-24(11)
++HIDDEN_FUNC(_rest32gpr_27_x)  lwz 27,-20(11)
++HIDDEN_FUNC(_rest32gpr_28_x)  lwz 28,-16(11)
++HIDDEN_FUNC(_rest32gpr_29_x)  lwz 29,-12(11)
++HIDDEN_FUNC(_rest32gpr_30_x)  lwz 30,-8(11)
++HIDDEN_FUNC(_rest32gpr_31_x)  lwz 0,4(11)
++                              lwz 31,-4(11)
++                              mr 1,11
++                              mtlr 0
++                              blr
++FUNC_END(_rest32gpr_31_x)
++FUNC_END(_rest32gpr_30_x)
++FUNC_END(_rest32gpr_29_x)
++FUNC_END(_rest32gpr_28_x)
++FUNC_END(_rest32gpr_27_x)
++FUNC_END(_rest32gpr_26_x)
++FUNC_END(_rest32gpr_25_x)
++FUNC_END(_rest32gpr_24_x)
++FUNC_END(_rest32gpr_23_x)
++FUNC_END(_rest32gpr_22_x)
++FUNC_END(_rest32gpr_21_x)
++FUNC_END(_rest32gpr_20_x)
++FUNC_END(_rest32gpr_19_x)
++FUNC_END(_rest32gpr_18_x)
++FUNC_END(_rest32gpr_17_x)
++FUNC_END(_rest32gpr_16_x)
++FUNC_END(_rest32gpr_15_x)
++FUNC_END(_rest32gpr_14_x)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/e500crtresx64gpr.asm
+@@ -0,0 +1,86 @@
++/*
++ * Special support for e500 eabi and SVR4
++ *
++ *   Copyright (C) 2008 Free Software Foundation, Inc.
++ *   Written by Nathan Froyd
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++      .file   "e500crtresx64gpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++#ifdef __SPE__
++
++/* "Exit" versions that return to their caller's caller.  */
++
++HIDDEN_FUNC(_rest64gpr_14_x)  evldd 14,0(11)
++HIDDEN_FUNC(_rest64gpr_15_x)  evldd 15,8(11)
++HIDDEN_FUNC(_rest64gpr_16_x)  evldd 16,16(11)
++HIDDEN_FUNC(_rest64gpr_17_x)  evldd 17,24(11)
++HIDDEN_FUNC(_rest64gpr_18_x)  evldd 18,32(11)
++HIDDEN_FUNC(_rest64gpr_19_x)  evldd 19,40(11)
++HIDDEN_FUNC(_rest64gpr_20_x)  evldd 20,48(11)
++HIDDEN_FUNC(_rest64gpr_21_x)  evldd 21,56(11)
++HIDDEN_FUNC(_rest64gpr_22_x)  evldd 22,64(11)
++HIDDEN_FUNC(_rest64gpr_23_x)  evldd 23,72(11)
++HIDDEN_FUNC(_rest64gpr_24_x)  evldd 24,80(11)
++HIDDEN_FUNC(_rest64gpr_25_x)  evldd 25,88(11)
++HIDDEN_FUNC(_rest64gpr_26_x)  evldd 26,96(11)
++HIDDEN_FUNC(_rest64gpr_27_x)  evldd 27,104(11)
++HIDDEN_FUNC(_rest64gpr_28_x)  evldd 28,112(11)
++HIDDEN_FUNC(_rest64gpr_29_x)  evldd 29,120(11)
++HIDDEN_FUNC(_rest64gpr_30_x)  evldd 30,128(11)
++HIDDEN_FUNC(_rest64gpr_31_x)  lwz 0,148(11)
++                              evldd 31,136(11)
++                              addi 1,11,144
++                              mtlr 0
++                              blr
++FUNC_END(_rest64gpr_31_x)
++FUNC_END(_rest64gpr_30_x)
++FUNC_END(_rest64gpr_29_x)
++FUNC_END(_rest64gpr_28_x)
++FUNC_END(_rest64gpr_27_x)
++FUNC_END(_rest64gpr_26_x)
++FUNC_END(_rest64gpr_25_x)
++FUNC_END(_rest64gpr_24_x)
++FUNC_END(_rest64gpr_23_x)
++FUNC_END(_rest64gpr_22_x)
++FUNC_END(_rest64gpr_21_x)
++FUNC_END(_rest64gpr_20_x)
++FUNC_END(_rest64gpr_19_x)
++FUNC_END(_rest64gpr_18_x)
++FUNC_END(_rest64gpr_17_x)
++FUNC_END(_rest64gpr_16_x)
++FUNC_END(_rest64gpr_15_x)
++FUNC_END(_rest64gpr_14_x)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/e500crtsav32gpr.asm
+@@ -0,0 +1,84 @@
++/*
++ * Special support for e500 eabi and SVR4
++ *
++ *   Copyright (C) 2008 Free Software Foundation, Inc.
++ *   Written by Nathan Froyd
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++      .file   "e500crtsav32gpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++#ifdef __SPE__
++
++/* Routines for saving 32-bit integer registers, called by the compiler.  */
++/* "Bare" versions that simply return to their caller.  */
++
++HIDDEN_FUNC(_save32gpr_14)    stw 14,-72(11)
++HIDDEN_FUNC(_save32gpr_15)    stw 15,-68(11)
++HIDDEN_FUNC(_save32gpr_16)    stw 16,-64(11)
++HIDDEN_FUNC(_save32gpr_17)    stw 17,-60(11)
++HIDDEN_FUNC(_save32gpr_18)    stw 18,-56(11)
++HIDDEN_FUNC(_save32gpr_19)    stw 19,-52(11)
++HIDDEN_FUNC(_save32gpr_20)    stw 20,-48(11)
++HIDDEN_FUNC(_save32gpr_21)    stw 21,-44(11)
++HIDDEN_FUNC(_save32gpr_22)    stw 22,-40(11)
++HIDDEN_FUNC(_save32gpr_23)    stw 23,-36(11)
++HIDDEN_FUNC(_save32gpr_24)    stw 24,-32(11)
++HIDDEN_FUNC(_save32gpr_25)    stw 25,-28(11)
++HIDDEN_FUNC(_save32gpr_26)    stw 26,-24(11)
++HIDDEN_FUNC(_save32gpr_27)    stw 27,-20(11)
++HIDDEN_FUNC(_save32gpr_28)    stw 28,-16(11)
++HIDDEN_FUNC(_save32gpr_29)    stw 29,-12(11)
++HIDDEN_FUNC(_save32gpr_30)    stw 30,-8(11)
++HIDDEN_FUNC(_save32gpr_31)    stw 31,-4(11)
++                              blr
++FUNC_END(_save32gpr_31)
++FUNC_END(_save32gpr_30)
++FUNC_END(_save32gpr_29)
++FUNC_END(_save32gpr_28)
++FUNC_END(_save32gpr_27)
++FUNC_END(_save32gpr_26)
++FUNC_END(_save32gpr_25)
++FUNC_END(_save32gpr_24)
++FUNC_END(_save32gpr_23)
++FUNC_END(_save32gpr_22)
++FUNC_END(_save32gpr_21)
++FUNC_END(_save32gpr_20)
++FUNC_END(_save32gpr_19)
++FUNC_END(_save32gpr_18)
++FUNC_END(_save32gpr_17)
++FUNC_END(_save32gpr_16)
++FUNC_END(_save32gpr_15)
++FUNC_END(_save32gpr_14)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/e500crtsav64gpr.asm
+@@ -0,0 +1,83 @@
++/*
++ * Special support for e500 eabi and SVR4
++ *
++ *   Copyright (C) 2008 Free Software Foundation, Inc.
++ *   Written by Nathan Froyd
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++      .file   "e500crtsav64gpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++#ifdef __SPE__
++
++/* Routines for saving 64-bit integer registers, called by the compiler.  */
++
++HIDDEN_FUNC(_save64gpr_14)    evstdd 14,0(11)
++HIDDEN_FUNC(_save64gpr_15)    evstdd 15,8(11)
++HIDDEN_FUNC(_save64gpr_16)    evstdd 16,16(11)
++HIDDEN_FUNC(_save64gpr_17)    evstdd 17,24(11)
++HIDDEN_FUNC(_save64gpr_18)    evstdd 18,32(11)
++HIDDEN_FUNC(_save64gpr_19)    evstdd 19,40(11)
++HIDDEN_FUNC(_save64gpr_20)    evstdd 20,48(11)
++HIDDEN_FUNC(_save64gpr_21)    evstdd 21,56(11)
++HIDDEN_FUNC(_save64gpr_22)    evstdd 22,64(11)
++HIDDEN_FUNC(_save64gpr_23)    evstdd 23,72(11)
++HIDDEN_FUNC(_save64gpr_24)    evstdd 24,80(11)
++HIDDEN_FUNC(_save64gpr_25)    evstdd 25,88(11)
++HIDDEN_FUNC(_save64gpr_26)    evstdd 26,96(11)
++HIDDEN_FUNC(_save64gpr_27)    evstdd 27,104(11)
++HIDDEN_FUNC(_save64gpr_28)    evstdd 28,112(11)
++HIDDEN_FUNC(_save64gpr_29)    evstdd 29,120(11)
++HIDDEN_FUNC(_save64gpr_30)    evstdd 30,128(11)
++HIDDEN_FUNC(_save64gpr_31)    evstdd 31,136(11)
++                              blr
++FUNC_END(_save64gpr_31)
++FUNC_END(_save64gpr_30)
++FUNC_END(_save64gpr_29)
++FUNC_END(_save64gpr_28)
++FUNC_END(_save64gpr_27)
++FUNC_END(_save64gpr_26)
++FUNC_END(_save64gpr_25)
++FUNC_END(_save64gpr_24)
++FUNC_END(_save64gpr_23)
++FUNC_END(_save64gpr_22)
++FUNC_END(_save64gpr_21)
++FUNC_END(_save64gpr_20)
++FUNC_END(_save64gpr_19)
++FUNC_END(_save64gpr_18)
++FUNC_END(_save64gpr_17)
++FUNC_END(_save64gpr_16)
++FUNC_END(_save64gpr_15)
++FUNC_END(_save64gpr_14)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/e500crtsav64gprctr.asm
+@@ -0,0 +1,102 @@
++/*
++ * Special support for e500 eabi and SVR4
++ *
++ *   Copyright (C) 2008 Free Software Foundation, Inc.
++ *   Written by Nathan Froyd
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++      .file   "e500crtsav64gprctr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++#ifdef __SPE__
++
++/* Routines for saving 64-bit integer registers where the number of
++   registers to be saved is passed in CTR, called by the compiler.  */
++/* "Bare" versions that return to their caller.  */
++
++HIDDEN_FUNC(_save64gpr_ctr_14)        evstdd 14,0(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_15)        evstdd 15,8(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_16)        evstdd 16,16(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_17)        evstdd 17,24(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_18)        evstdd 18,32(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_19)        evstdd 19,40(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_20)        evstdd 20,48(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_21)        evstdd 21,56(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_22)        evstdd 22,64(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_23)        evstdd 23,72(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_24)        evstdd 24,80(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_25)        evstdd 25,88(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_26)        evstdd 26,96(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_27)        evstdd 27,104(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_28)        evstdd 28,112(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_29)        evstdd 29,120(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_30)        evstdd 30,128(11)
++                              bdz _save64_gpr_ctr_done
++HIDDEN_FUNC(_save64gpr_ctr_31)        evstdd 31,136(11)
++_save64gpr_ctr_done:          blr
++FUNC_END(_save64gpr_ctr_31)
++FUNC_END(_save64gpr_ctr_30)
++FUNC_END(_save64gpr_ctr_29)
++FUNC_END(_save64gpr_ctr_28)
++FUNC_END(_save64gpr_ctr_27)
++FUNC_END(_save64gpr_ctr_26)
++FUNC_END(_save64gpr_ctr_25)
++FUNC_END(_save64gpr_ctr_24)
++FUNC_END(_save64gpr_ctr_23)
++FUNC_END(_save64gpr_ctr_22)
++FUNC_END(_save64gpr_ctr_21)
++FUNC_END(_save64gpr_ctr_20)
++FUNC_END(_save64gpr_ctr_19)
++FUNC_END(_save64gpr_ctr_18)
++FUNC_END(_save64gpr_ctr_17)
++FUNC_END(_save64gpr_ctr_16)
++FUNC_END(_save64gpr_ctr_15)
++FUNC_END(_save64gpr_ctr_14)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/e500crtsavg32gpr.asm
+@@ -0,0 +1,84 @@
++/*
++ * Special support for e500 eabi and SVR4
++ *
++ *   Copyright (C) 2008 Free Software Foundation, Inc.
++ *   Written by Nathan Froyd
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++      .file   "e500crtsavg32gpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++#ifdef __SPE__
++
++/* Routines for saving 32-bit integer registers, called by the compiler.  */
++/* "GOT" versions that load the address of the GOT into lr before returning.  */
++
++HIDDEN_FUNC(_save32gpr_14_g)  stw 14,-72(11)
++HIDDEN_FUNC(_save32gpr_15_g)  stw 15,-68(11)
++HIDDEN_FUNC(_save32gpr_16_g)  stw 16,-64(11)
++HIDDEN_FUNC(_save32gpr_17_g)  stw 17,-60(11)
++HIDDEN_FUNC(_save32gpr_18_g)  stw 18,-56(11)
++HIDDEN_FUNC(_save32gpr_19_g)  stw 19,-52(11)
++HIDDEN_FUNC(_save32gpr_20_g)  stw 20,-48(11)
++HIDDEN_FUNC(_save32gpr_21_g)  stw 21,-44(11)
++HIDDEN_FUNC(_save32gpr_22_g)  stw 22,-40(11)
++HIDDEN_FUNC(_save32gpr_23_g)  stw 23,-36(11)
++HIDDEN_FUNC(_save32gpr_24_g)  stw 24,-32(11)
++HIDDEN_FUNC(_save32gpr_25_g)  stw 25,-28(11)
++HIDDEN_FUNC(_save32gpr_26_g)  stw 26,-24(11)
++HIDDEN_FUNC(_save32gpr_27_g)  stw 27,-20(11)
++HIDDEN_FUNC(_save32gpr_28_g)  stw 28,-16(11)
++HIDDEN_FUNC(_save32gpr_29_g)  stw 29,-12(11)
++HIDDEN_FUNC(_save32gpr_30_g)  stw 30,-8(11)
++HIDDEN_FUNC(_save32gpr_31_g)  stw 31,-4(11)
++                              b _GLOBAL_OFFSET_TABLE_-4
++FUNC_END(_save32gpr_31_g)
++FUNC_END(_save32gpr_30_g)
++FUNC_END(_save32gpr_29_g)
++FUNC_END(_save32gpr_28_g)
++FUNC_END(_save32gpr_27_g)
++FUNC_END(_save32gpr_26_g)
++FUNC_END(_save32gpr_25_g)
++FUNC_END(_save32gpr_24_g)
++FUNC_END(_save32gpr_23_g)
++FUNC_END(_save32gpr_22_g)
++FUNC_END(_save32gpr_21_g)
++FUNC_END(_save32gpr_20_g)
++FUNC_END(_save32gpr_19_g)
++FUNC_END(_save32gpr_18_g)
++FUNC_END(_save32gpr_17_g)
++FUNC_END(_save32gpr_16_g)
++FUNC_END(_save32gpr_15_g)
++FUNC_END(_save32gpr_14_g)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/e500crtsavg64gpr.asm
+@@ -0,0 +1,84 @@
++/*
++ * Special support for e500 eabi and SVR4
++ *
++ *   Copyright (C) 2008 Free Software Foundation, Inc.
++ *   Written by Nathan Froyd
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++      .file   "e500crtsavg64gpr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++#ifdef __SPE__
++
++/* Routines for saving 64-bit integer registers, called by the compiler.  */
++/* "GOT" versions that load the address of the GOT into lr before returning.  */
++
++HIDDEN_FUNC(_save64gpr_14_g)  evstdd 14,0(11)
++HIDDEN_FUNC(_save64gpr_15_g)  evstdd 15,8(11)
++HIDDEN_FUNC(_save64gpr_16_g)  evstdd 16,16(11)
++HIDDEN_FUNC(_save64gpr_17_g)  evstdd 17,24(11)
++HIDDEN_FUNC(_save64gpr_18_g)  evstdd 18,32(11)
++HIDDEN_FUNC(_save64gpr_19_g)  evstdd 19,40(11)
++HIDDEN_FUNC(_save64gpr_20_g)  evstdd 20,48(11)
++HIDDEN_FUNC(_save64gpr_21_g)  evstdd 21,56(11)
++HIDDEN_FUNC(_save64gpr_22_g)  evstdd 22,64(11)
++HIDDEN_FUNC(_save64gpr_23_g)  evstdd 23,72(11)
++HIDDEN_FUNC(_save64gpr_24_g)  evstdd 24,80(11)
++HIDDEN_FUNC(_save64gpr_25_g)  evstdd 25,88(11)
++HIDDEN_FUNC(_save64gpr_26_g)  evstdd 26,96(11)
++HIDDEN_FUNC(_save64gpr_27_g)  evstdd 27,104(11)
++HIDDEN_FUNC(_save64gpr_28_g)  evstdd 28,112(11)
++HIDDEN_FUNC(_save64gpr_29_g)  evstdd 29,120(11)
++HIDDEN_FUNC(_save64gpr_30_g)  evstdd 30,128(11)
++HIDDEN_FUNC(_save64gpr_31_g)  evstdd 31,136(11)
++                              b _GLOBAL_OFFSET_TABLE_-4
++FUNC_END(_save64gpr_31_g)
++FUNC_END(_save64gpr_30_g)
++FUNC_END(_save64gpr_29_g)
++FUNC_END(_save64gpr_28_g)
++FUNC_END(_save64gpr_27_g)
++FUNC_END(_save64gpr_26_g)
++FUNC_END(_save64gpr_25_g)
++FUNC_END(_save64gpr_24_g)
++FUNC_END(_save64gpr_23_g)
++FUNC_END(_save64gpr_22_g)
++FUNC_END(_save64gpr_21_g)
++FUNC_END(_save64gpr_20_g)
++FUNC_END(_save64gpr_19_g)
++FUNC_END(_save64gpr_18_g)
++FUNC_END(_save64gpr_17_g)
++FUNC_END(_save64gpr_16_g)
++FUNC_END(_save64gpr_15_g)
++FUNC_END(_save64gpr_14_g)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/e500crtsavg64gprctr.asm
+@@ -0,0 +1,101 @@
++/*
++ * Special support for e500 eabi and SVR4
++ *
++ *   Copyright (C) 2008 Free Software Foundation, Inc.
++ *   Written by Nathan Froyd
++ * 
++ * This file is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2, or (at your option) any
++ * later version.
++ * 
++ * In addition to the permissions in the GNU General Public License, the
++ * Free Software Foundation gives you unlimited permission to link the
++ * compiled version of this file with other programs, and to distribute
++ * those programs without any restriction coming from the use of this
++ * file.  (The General Public License restrictions do apply in other
++ * respects; for example, they cover modification of the file, and
++ * distribution when not linked into another program.)
++ * 
++ * This file is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ * 
++ *    As a special exception, if you link this library with files
++ *    compiled with GCC to produce an executable, this does not cause
++ *    the resulting executable to be covered by the GNU General Public License.
++ *    This exception does not however invalidate any other reasons why
++ *    the executable file might be covered by the GNU General Public License.
++ */ 
++
++      .file   "e500crtsavg64gprctr.asm"
++      .section ".text"
++      #include "ppc-asm.h"
++
++#ifdef __SPE__
++
++/* Routines for saving 64-bit integer registers, called by the compiler.  */
++/* "GOT" versions that load the address of the GOT into lr before returning.  */
++
++HIDDEN_FUNC(_save64gpr_ctr_14_g)      evstdd 14,0(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_15_g)      evstdd 15,8(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_16_g)      evstdd 16,16(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_17_g)      evstdd 17,24(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_18_g)      evstdd 18,32(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_19_g)      evstdd 19,40(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_20_g)      evstdd 20,48(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_21_g)      evstdd 21,56(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_22_g)      evstdd 22,64(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_23_g)      evstdd 23,72(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_24_g)      evstdd 24,80(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_25_g)      evstdd 25,88(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_26_g)      evstdd 26,96(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_27_g)      evstdd 27,104(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_28_g)      evstdd 28,112(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_29_g)      evstdd 29,120(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_30_g)      evstdd 30,128(11)
++                              bdz _save64_gpr_ctr_g_done
++HIDDEN_FUNC(_save64gpr_ctr_31_g)      evstdd 31,136(11)
++_save64gpr_ctr_g_done:                b _GLOBAL_OFFSET_TABLE_-4
++FUNC_END(_save64gpr_ctr_31_g)
++FUNC_END(_save64gpr_ctr_30_g)
++FUNC_END(_save64gpr_ctr_29_g)
++FUNC_END(_save64gpr_ctr_28_g)
++FUNC_END(_save64gpr_ctr_27_g)
++FUNC_END(_save64gpr_ctr_26_g)
++FUNC_END(_save64gpr_ctr_25_g)
++FUNC_END(_save64gpr_ctr_24_g)
++FUNC_END(_save64gpr_ctr_23_g)
++FUNC_END(_save64gpr_ctr_22_g)
++FUNC_END(_save64gpr_ctr_21_g)
++FUNC_END(_save64gpr_ctr_20_g)
++FUNC_END(_save64gpr_ctr_19_g)
++FUNC_END(_save64gpr_ctr_18_g)
++FUNC_END(_save64gpr_ctr_17_g)
++FUNC_END(_save64gpr_ctr_16_g)
++FUNC_END(_save64gpr_ctr_15_g)
++FUNC_END(_save64gpr_ctr_14_g)
++
++#endif
+--- /dev/null
++++ b/gcc/config/rs6000/e500mc.h
+@@ -0,0 +1,46 @@
++/* Core target definitions for GNU compiler
++   for IBM RS/6000 PowerPC targeted to embedded ELF systems.
++   Copyright (C) 1995, 1996, 2000, 2003, 2004, 2007 Free Software Foundation, Inc.
++   Contributed by Cygnus Support.
++
++   This file is part of GCC.
++
++   GCC is free software; you can redistribute it and/or modify it
++   under the terms of the GNU General Public License as published
++   by the Free Software Foundation; either version 3, or (at your
++   option) any later version.
++
++   GCC is distributed in the hope that it will be useful, but WITHOUT
++   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
++   License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with GCC; see the file COPYING3.  If not see
++   <http://www.gnu.org/licenses/>.  */
++
++/* Add -meabi to target flags.  */
++#undef TARGET_DEFAULT
++#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_EABI)
++
++#undef TARGET_VERSION
++#define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded)");
++
++#undef TARGET_OS_CPP_BUILTINS
++#define TARGET_OS_CPP_BUILTINS()          \
++  do                                      \
++    {                                     \
++      builtin_define_std ("PPC");         \
++      builtin_define ("__embedded__");    \
++      builtin_assert ("system=embedded"); \
++      builtin_assert ("cpu=powerpc");     \
++      builtin_assert ("machine=powerpc"); \
++      TARGET_OS_SYSV_CPP_BUILTINS ();     \
++    }                                     \
++  while (0)
++
++#undef CC1_EXTRA_SPEC
++#define CC1_EXTRA_SPEC "-maix-struct-return"
++
++#undef ASM_DEFAULT_SPEC
++#define ASM_DEFAULT_SPEC "-mppc%{m64:64} -me500mc"
+--- /dev/null
++++ b/gcc/config/rs6000/e500mc.md
+@@ -0,0 +1,198 @@
++;; Pipeline description for Motorola PowerPC e500mc core.
++;;   Copyright (C) 2008 Free Software Foundation, Inc.
++;;   Contributed by Edmar Wienskoski (edmar@freescale.com)
++;;
++;; This file is part of GCC.
++;;
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published
++;; by the Free Software Foundation; either version 3, or (at your
++;; option) any later version.
++;;
++;; GCC is distributed in the hope that it will be useful, but WITHOUT
++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
++;; License for more details.
++;;
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING3.  If not see
++;; <http://www.gnu.org/licenses/>.
++;;
++;; e500mc 32-bit SU(2), LSU, FPU, BPU
++;; Max issue 3 insns/clock cycle (includes 1 branch)
++;; FP is half clocked, timings of other instructions are as in the e500v2.
++
++(define_automaton "e500mc_most,e500mc_long,e500mc_retire")
++(define_cpu_unit "e500mc_decode_0,e500mc_decode_1" "e500mc_most")
++(define_cpu_unit "e500mc_issue_0,e500mc_issue_1"   "e500mc_most")
++(define_cpu_unit "e500mc_retire_0,e500mc_retire_1" "e500mc_retire")
++
++;; SU.
++(define_cpu_unit "e500mc_su0_stage0,e500mc_su1_stage0" "e500mc_most")
++
++;; MU.
++(define_cpu_unit "e500mc_mu_stage0,e500mc_mu_stage1" "e500mc_most")
++(define_cpu_unit "e500mc_mu_stage2,e500mc_mu_stage3" "e500mc_most")
++
++;; Non-pipelined division.
++(define_cpu_unit "e500mc_mu_div" "e500mc_long")
++
++;; LSU.
++(define_cpu_unit "e500mc_lsu" "e500mc_most")
++
++;; FPU.
++(define_cpu_unit "e500mc_fpu" "e500mc_most")
++
++;; Branch unit.
++(define_cpu_unit "e500mc_bu" "e500mc_most")
++
++;; The following units are used to make the automata deterministic.
++(define_cpu_unit "present_e500mc_decode_0" "e500mc_most")
++(define_cpu_unit "present_e500mc_issue_0" "e500mc_most")
++(define_cpu_unit "present_e500mc_retire_0" "e500mc_retire")
++(define_cpu_unit "present_e500mc_su0_stage0" "e500mc_most")
++
++;; The following sets to make automata deterministic when option ndfa is used.
++(presence_set "present_e500mc_decode_0" "e500mc_decode_0")
++(presence_set "present_e500mc_issue_0" "e500mc_issue_0")
++(presence_set "present_e500mc_retire_0" "e500mc_retire_0")
++(presence_set "present_e500mc_su0_stage0" "e500mc_su0_stage0")
++
++;; Some useful abbreviations.
++(define_reservation "e500mc_decode"
++    "e500mc_decode_0|e500mc_decode_1+present_e500mc_decode_0")
++(define_reservation "e500mc_issue"
++    "e500mc_issue_0|e500mc_issue_1+present_e500mc_issue_0")
++(define_reservation "e500mc_retire"
++   "e500mc_retire_0|e500mc_retire_1+present_e500mc_retire_0")
++(define_reservation "e500mc_su_stage0"
++   "e500mc_su0_stage0|e500mc_su1_stage0+present_e500mc_su0_stage0")
++
++;; Simple SU insns.
++(define_insn_reservation "e500mc_su" 1
++  (and (eq_attr "type" "integer,insert_word,insert_dword,cmp,compare,\
++                        delayed_compare,var_delayed_compare,fast_compare,\
++                        shift,trap,var_shift_rotate,cntlz,exts")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire")
++
++(define_insn_reservation "e500mc_two" 1
++  (and (eq_attr "type" "two")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire,\
++   e500mc_issue+e500mc_su_stage0+e500mc_retire")
++
++(define_insn_reservation "e500mc_three" 1
++  (and (eq_attr "type" "three")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire,\
++   e500mc_issue+e500mc_su_stage0+e500mc_retire,\
++   e500mc_issue+e500mc_su_stage0+e500mc_retire")
++
++;; Multiply.
++(define_insn_reservation "e500mc_multiply" 4
++  (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_mu_stage0,e500mc_mu_stage1,\
++   e500mc_mu_stage2,e500mc_mu_stage3+e500mc_retire")
++
++;; Divide. We use the average latency time here.
++(define_insn_reservation "e500mc_divide" 14
++  (and (eq_attr "type" "idiv")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_mu_stage0+e500mc_mu_div,\
++   e500mc_mu_div*13")
++
++;; Branch.
++(define_insn_reservation "e500mc_branch" 1
++  (and (eq_attr "type" "jmpreg,branch,isync")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_bu,e500mc_retire")
++
++;; CR logical.
++(define_insn_reservation "e500mc_cr_logical" 1
++  (and (eq_attr "type" "cr_logical,delayed_cr")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_bu,e500mc_retire")
++
++;; Mfcr.
++(define_insn_reservation "e500mc_mfcr" 1
++  (and (eq_attr "type" "mfcr")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_su1_stage0+e500mc_retire")
++
++;; Mtcrf.
++(define_insn_reservation "e500mc_mtcrf" 1
++  (and (eq_attr "type" "mtcr")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_su1_stage0+e500mc_retire")
++
++;; Mtjmpr.
++(define_insn_reservation "e500mc_mtjmpr" 1
++  (and (eq_attr "type" "mtjmpr,mfjmpr")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire")
++
++;; Brinc.
++(define_insn_reservation "e500mc_brinc" 1
++  (and (eq_attr "type" "brinc")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire")
++
++;; Loads.
++(define_insn_reservation "e500mc_load" 3
++  (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\
++                       load_l,sync")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_lsu,nothing,e500mc_retire")
++
++(define_insn_reservation "e500mc_fpload" 4
++  (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_lsu,nothing*2,e500mc_retire")
++
++;; Stores.
++(define_insn_reservation "e500mc_store" 3
++  (and (eq_attr "type" "store,store_ux,store_u,store_c")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_lsu,nothing,e500mc_retire")
++
++(define_insn_reservation "e500mc_fpstore" 3
++  (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_lsu,nothing,e500mc_retire")
++
++;; Simple FP.
++(define_insn_reservation "e500mc_simple_float" 8
++  (and (eq_attr "type" "fpsimple")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_fpu,nothing*6,e500mc_retire")
++
++;; FP.
++(define_insn_reservation "e500mc_float" 8
++  (and (eq_attr "type" "fp")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_fpu,nothing*6,e500mc_retire")
++
++(define_insn_reservation "e500mc_fpcompare" 8
++  (and (eq_attr "type" "fpcompare")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_fpu,nothing*6,e500mc_retire")
++
++;; The following ignores the retire unit to avoid a large automata.
++
++(define_insn_reservation "e500mc_dmul" 10
++  (and (eq_attr "type" "dmul")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_fpu")
++
++;; FP divides are not pipelined.
++(define_insn_reservation "e500mc_sdiv" 36
++  (and (eq_attr "type" "sdiv")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_fpu,e500mc_fpu*35")
++
++(define_insn_reservation "e500mc_ddiv" 66
++  (and (eq_attr "type" "ddiv")
++       (eq_attr "cpu" "ppce500mc"))
++  "e500mc_decode,e500mc_issue+e500mc_fpu,e500mc_fpu*65")
+--- a/gcc/config/rs6000/eabi-ci.asm
++++ b/gcc/config/rs6000/eabi-ci.asm
+@@ -111,6 +111,7 @@ __EH_FRAME_BEGIN__:
+ /* Head of __init function used for static constructors.  */
+       .section ".init","ax"
+       .align 2
++FUNC_START(_init)
+ FUNC_START(__init)
+       stwu 1,-16(1)
+       mflr 0
+@@ -119,6 +120,7 @@ FUNC_START(__init)
+ /* Head of __fini function used for static destructors.  */
+       .section ".fini","ax"
+       .align 2
++FUNC_START(_fini)
+ FUNC_START(__fini)
+       stwu 1,-16(1)
+       mflr 0
+--- a/gcc/config/rs6000/eabi-cn.asm
++++ b/gcc/config/rs6000/eabi-cn.asm
+@@ -36,7 +36,6 @@ Boston, MA 02110-1301, USA.
+ /* This file just supplies labeled ending points for the .got* and other
+    special sections.  It is linked in last after other modules.  */
+  
+-      .file   "crtn.s"
+       .ident  "GNU C crtn.s"
+ #ifndef __powerpc64__
+--- a/gcc/config/rs6000/eabi.asm
++++ b/gcc/config/rs6000/eabi.asm
+@@ -114,6 +114,9 @@
+ .Linit = .-.LCTOC1
+       .long   .Linit_p                        /* address of variable to say we've been called */
++.Lfini = .-.LCTOC1
++      .long   __fini                          /* global destructors in .fini */
++
+       .text
+       .align  2
+ .Lptr:
+@@ -226,10 +229,12 @@ FUNC_START(__eabi)
+       lwz     2,.Lsda2(11)                    /* load r2 with _SDA2_BASE_ address */
+-/* Done adjusting pointers, return by way of doing the C++ global constructors.  */
++/* Done adjusting pointers.  We used to return here by way of doing the
++   C++ global constructors, but we currently let newlib take care of
++   running them and registering finalizers.  */
+ .Ldone:
+-      b       FUNC_NAME(__init)       /* do any C++ global constructors (which returns to caller) */
++      blr
+ FUNC_END(__eabi)
+ /* Special subroutine to convert a bunch of pointers directly.
+@@ -240,7 +245,7 @@ FUNC_END(__eabi)
+    r11                has the address of .LCTOC1 in it.
+    r12                has the value to add to each pointer
+    r13 .. r31 are unchanged */
+-      
++#ifdef _RELOCATABLE   
+ FUNC_START(__eabi_convert)
+         cmplw 1,3,4                           /* any pointers to convert? */
+         subf  5,3,4                           /* calculate number of words to convert */
+@@ -295,5 +300,6 @@ FUNC_START(__eabi_uconvert)
+         blr
+ FUNC_END(__eabi_uconvert)
++#endif /* _RELOCATABLE */
+ #endif
+--- a/gcc/config/rs6000/eabi.h
++++ b/gcc/config/rs6000/eabi.h
+@@ -23,10 +23,6 @@
+ #undef TARGET_DEFAULT
+ #define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_EABI)
+-/* Invoke an initializer function to set up the GOT.  */
+-#define NAME__MAIN "__eabi"
+-#define INVOKE__main
+-
+ #undef TARGET_VERSION
+ #define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded)");
+@@ -42,3 +38,20 @@
+       TARGET_OS_SYSV_CPP_BUILTINS ();     \
+     }                                     \
+   while (0)
++
++/* Add -te500v1 and -te500v2 options for convenience in generating
++   multilibs.  */
++#undef CC1_EXTRA_SPEC
++#define CC1_EXTRA_SPEC \
++  "%{te500v1: -mcpu=8540 -mfloat-gprs=single -mspe=yes -mabi=spe} " \
++  "%{te500v2: -mcpu=8548 -mfloat-gprs=double -mspe=yes -mabi=spe} " \
++  "%{te600: -mcpu=7400 -maltivec -mabi=altivec}"                  \
++  "%{te500mc: -mcpu=e500mc -maix-struct-return}"
++
++#undef ASM_DEFAULT_SPEC
++#define ASM_DEFAULT_SPEC                      \
++  "%{te500v1:-mppc -mspe -me500 ;             \
++     te500v2:-mppc -mspe -me500 ;             \
++     te600:-mppc -maltivec ;                  \
++     te500mc:-mppc -me500mc ;                 \
++     :-mppc%{m64:64}}"
+--- a/gcc/config/rs6000/linux.h
++++ b/gcc/config/rs6000/linux.h
+@@ -128,3 +128,29 @@
+ #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
+ #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 128
+ #endif
++
++/* Add -te500v1 and -te500v2 options for convenience in generating
++   multilibs.  */
++#undef CC1_EXTRA_SPEC
++#define CC1_EXTRA_SPEC \
++  "%{te500v1: -mcpu=8540 -mfloat-gprs=single -mspe=yes -mabi=spe} " \
++  "%{te500v2: -mcpu=8548 -mfloat-gprs=double -mspe=yes -mabi=spe} " \
++  "%{te600: -mcpu=7400 -maltivec -mabi=altivec}" \
++  "%{te500mc: -mcpu=e500mc}"
++
++#undef ASM_DEFAULT_SPEC
++#define ASM_DEFAULT_SPEC                      \
++  "%{te500v1:-mppc -mspe -me500 ;             \
++     te500v2:-mppc -mspe -me500 ;             \
++     te600:-mppc -maltivec ;                  \
++     te500mc:-me500mc ;                               \
++     :-mppc%{m64:64}}"
++
++/* The various C libraries each have their own subdirectory.  */
++#undef SYSROOT_SUFFIX_SPEC
++#define SYSROOT_SUFFIX_SPEC                   \
++  "%{msoft-float:/nof ;                               \
++     te600:/te600 ;                           \
++     te500v1:/te500v1 ;                               \
++     te500v2:/te500v2 ;                               \
++     te500mc:/te500mc}"
+--- /dev/null
++++ b/gcc/config/rs6000/montavista-linux.h
+@@ -0,0 +1,41 @@
++/* MontaVista GNU/Linux Configuration.
++   Copyright (C) 2009
++   Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 3, or (at your option)
++any later version.
++
++GCC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++/* Add -te500v2 option for convenience in generating multilibs.  */
++#undef CC1_EXTRA_SPEC
++#define CC1_EXTRA_SPEC \
++  "%{te500v2: -mcpu=8548 -mfloat-gprs=double -mspe=yes -mabi=spe} " \
++  "%{te600: -mcpu=7400 -maltivec -mabi=altivec}" \
++  "%{te500mc: -mcpu=e500mc}"
++
++#undef ASM_DEFAULT_SPEC
++#define ASM_DEFAULT_SPEC                        \
++  "%{te500v2:-mppc -mspe -me500 ;               \
++     te600:-mppc -maltivec ;                    \
++     te500mc:-me500mc ;                         \
++     :-mppc}"
++
++/* The various C libraries each have their own subdirectory.  */
++#undef SYSROOT_SUFFIX_SPEC
++#define SYSROOT_SUFFIX_SPEC                   \
++  "%{msoft-float:/soft-float ;                        \
++     te600:/te600 ;                             \
++     te500v2:/te500v2 ;                         \
++     te500mc:/te500mc}"
+--- a/gcc/config/rs6000/netbsd.h
++++ b/gcc/config/rs6000/netbsd.h
+@@ -75,8 +75,7 @@
+ #define STARTFILE_SPEC NETBSD_STARTFILE_SPEC
+ #undef  ENDFILE_SPEC
+-#define ENDFILE_SPEC \
+-  "crtsavres%O%s %(netbsd_endfile_spec)"
++#define ENDFILE_SPEC "%(netbsd_endfile_spec)"
+ #undef  LIB_SPEC
+ #define LIB_SPEC NETBSD_LIB_SPEC
+--- a/gcc/config/rs6000/paired.md
++++ b/gcc/config/rs6000/paired.md
+@@ -28,7 +28,7 @@
+  (UNSPEC_EXTODD_V2SF      333)
+ ])
+-(define_insn "negv2sf2"
++(define_insn "paired_negv2sf2"
+   [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+       (neg:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))]
+   "TARGET_PAIRED_FLOAT"
+@@ -42,7 +42,7 @@
+   "ps_rsqrte %0,%1"
+   [(set_attr "type" "fp")])
+-(define_insn "absv2sf2"
++(define_insn "paired_absv2sf2"
+   [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+       (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))]
+   "TARGET_PAIRED_FLOAT"
+@@ -56,7 +56,7 @@
+   "ps_nabs %0,%1"
+   [(set_attr "type" "fp")])
+-(define_insn "addv2sf3"
++(define_insn "paired_addv2sf3"
+   [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+       (plus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f")
+                  (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
+@@ -64,7 +64,7 @@
+   "ps_add %0,%1,%2"
+   [(set_attr "type" "fp")])
+-(define_insn "subv2sf3"
++(define_insn "paired_subv2sf3"
+   [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+         (minus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
+                     (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
+@@ -72,7 +72,7 @@
+   "ps_sub %0,%1,%2"
+   [(set_attr "type" "fp")])
+-(define_insn "mulv2sf3"
++(define_insn "paired_mulv2sf3"
+   [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+       (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f")
+                  (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
+@@ -87,7 +87,7 @@
+   "ps_res %0,%1"
+   [(set_attr "type" "fp")])
+-(define_insn "divv2sf3"
++(define_insn "paired_divv2sf3"
+   [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+       (div:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
+                 (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
+--- a/gcc/config/rs6000/ppc-asm.h
++++ b/gcc/config/rs6000/ppc-asm.h
+@@ -110,6 +110,11 @@ name: \
+       .globl GLUE(.,name); \
+ GLUE(.,name):
++#define HIDDEN_FUNC(name) \
++  FUNC_START(name) \
++  .hidden name;       \
++  .hidden GLUE(.,name);
++
+ #define FUNC_END(name) \
+ GLUE(.L,name): \
+       .size GLUE(.,name),GLUE(.L,name)-GLUE(.,name)
+@@ -136,6 +141,11 @@ name: \
+       .globl GLUE(.,name); \
+ GLUE(.,name):
++#define HIDDEN_FUNC(name) \
++  FUNC_START(name) \
++  .hidden name; \
++  .hidden GLUE(.,name);
++
+ #define FUNC_END(name) \
+ GLUE(.L,name): \
+       .size GLUE(.,name),GLUE(.L,name)-GLUE(.,name)
+@@ -153,6 +163,10 @@ GLUE(.L,name): \
+       .globl FUNC_NAME(name); \
+ FUNC_NAME(name):
++#define HIDDEN_FUNC(name) \
++  FUNC_START(name) \
++  .hidden FUNC_NAME(name);
++
+ #define FUNC_END(name) \
+ GLUE(.L,name): \
+       .size FUNC_NAME(name),GLUE(.L,name)-FUNC_NAME(name)
+--- a/gcc/config/rs6000/predicates.md
++++ b/gcc/config/rs6000/predicates.md
+@@ -915,7 +915,7 @@
+   rtx elt;
+   int count = XVECLEN (op, 0);
+-  if (count != 55)
++  if (count != 54)
+     return 0;
+   index = 0;
+@@ -964,9 +964,8 @@
+       || GET_MODE (SET_SRC (elt)) != Pmode)
+     return 0;
+-  if (GET_CODE (XVECEXP (op, 0, index++)) != USE
+-      || GET_CODE (XVECEXP (op, 0, index++)) != USE
+-      || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER)
++  if (GET_CODE (XVECEXP (op, 0, index++)) != SET
++      || GET_CODE (XVECEXP (op, 0, index++)) != SET)
+     return 0;
+   return 1;
+ })
+--- a/gcc/config/rs6000/rs6000.c
++++ b/gcc/config/rs6000/rs6000.c
+@@ -174,9 +174,15 @@ int rs6000_ieeequad;
+ /* Nonzero to use AltiVec ABI.  */
+ int rs6000_altivec_abi;
++/* Nonzero if we want SPE SIMD instructions.  */
++int rs6000_spe;
++
+ /* Nonzero if we want SPE ABI extensions.  */
+ int rs6000_spe_abi;
++/* Nonzero to use isel instructions.  */
++int rs6000_isel;
++
+ /* Nonzero if floating point operations are done in the GPRs.  */
+ int rs6000_float_gprs = 0;
+@@ -669,6 +675,44 @@ struct processor_costs ppc8540_cost = {
+   1,                  /* prefetch streams /*/
+ };
++/* Instruction costs on E300C2 and E300C3 cores.  */
++static const
++struct processor_costs ppce300c2c3_cost = {
++  COSTS_N_INSNS (4),    /* mulsi */
++  COSTS_N_INSNS (4),    /* mulsi_const */
++  COSTS_N_INSNS (4),    /* mulsi_const9 */
++  COSTS_N_INSNS (4),    /* muldi */
++  COSTS_N_INSNS (19),   /* divsi */
++  COSTS_N_INSNS (19),   /* divdi */
++  COSTS_N_INSNS (3),    /* fp */
++  COSTS_N_INSNS (4),    /* dmul */
++  COSTS_N_INSNS (18),   /* sdiv */
++  COSTS_N_INSNS (33),   /* ddiv */
++  32,
++  16,                 /* l1 cache */
++  16,                 /* l2 cache */
++  1,                  /* prefetch streams /*/
++};
++
++/* Instruction costs on PPCE500MC processors.  */                                                                                  
++static const                                                                                                                       
++struct processor_costs ppce500mc_cost = {                                                                                          
++  COSTS_N_INSNS (4),    /* mulsi */                                                                                                
++  COSTS_N_INSNS (4),    /* mulsi_const */                                                                                          
++  COSTS_N_INSNS (4),    /* mulsi_const9 */                                                                                         
++  COSTS_N_INSNS (4),    /* muldi */                                                                                                
++  COSTS_N_INSNS (14),   /* divsi */                                                                                                
++  COSTS_N_INSNS (14),   /* divdi */                                                                                                
++  COSTS_N_INSNS (8),    /* fp */                                                                                                   
++  COSTS_N_INSNS (10),   /* dmul */                                                                                                 
++  COSTS_N_INSNS (36),   /* sdiv */                                                                                                 
++  COSTS_N_INSNS (66),   /* ddiv */                                                                                                 
++  64,                  /* cache line size */                                                                                       
++  32,                  /* l1 cache */                                                                                              
++  128,                 /* l2 cache */                                                                                              
++  1,                   /* prefetch streams /*/                                                                                     
++};                                                                                                                                 
++
+ /* Instruction costs on POWER4 and POWER5 processors.  */
+ static const
+ struct processor_costs power4_cost = {
+@@ -713,12 +757,11 @@ static const char *rs6000_invalid_within
+ static rtx rs6000_generate_compare (enum rtx_code);
+ static void rs6000_emit_stack_tie (void);
+ static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
+-static rtx spe_synthesize_frame_save (rtx);
+ static bool spe_func_has_64bit_regs_p (void);
+ static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
+                            int, HOST_WIDE_INT);
+ static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
+-static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int);
++static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int, int);
+ static unsigned rs6000_hash_constant (rtx);
+ static unsigned toc_hash_function (const void *);
+ static int toc_hash_eq (const void *, const void *);
+@@ -728,7 +771,7 @@ static bool legitimate_small_data_p (enu
+ static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
+ static struct machine_function * rs6000_init_machine_status (void);
+ static bool rs6000_assemble_integer (rtx, unsigned int, int);
+-static bool no_global_regs_above (int);
++static bool no_global_regs_above (int, bool);
+ #ifdef HAVE_GAS_HIDDEN
+ static void rs6000_assemble_visibility (tree, int);
+ #endif
+@@ -741,7 +784,13 @@ static void rs6000_eliminate_indexed_mem
+ static const char *rs6000_mangle_type (const_tree);
+ extern const struct attribute_spec rs6000_attribute_table[];
+ static void rs6000_set_default_type_attributes (tree);
++static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
++static void rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
++static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
++                                 enum machine_mode, bool, bool, bool);
+ static bool rs6000_reg_live_or_pic_offset_p (int);
++static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
++static void rs6000_restore_saved_cr (rtx, int);
+ static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
+ static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
+ static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
+@@ -1420,6 +1469,9 @@ rs6000_override_options (const char *def
+        {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN},
+        /* 8548 has a dummy entry for now.  */
+        {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN},
++       {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
++       {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
++       {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+        {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+        {"970", PROCESSOR_POWER4,
+         POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
+@@ -1523,9 +1575,20 @@ rs6000_override_options (const char *def
+       }
+     }
+-  if (TARGET_E500)
++  if ((TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC)
++      && !rs6000_explicit_options.isel)
+     rs6000_isel = 1;
++  if (rs6000_cpu == PROCESSOR_PPCE300C2
++      || rs6000_cpu == PROCESSOR_PPCE300C3
++      || rs6000_cpu == PROCESSOR_PPCE500MC)
++    {
++      if (TARGET_ALTIVEC)
++       error ("AltiVec not supported in this target");
++      if (TARGET_SPE)
++       error ("Spe not supported in this target");
++    }
++
+   /* If we are optimizing big endian systems for space, use the load/store
+      multiple and string instructions.  */
+   if (BYTES_BIG_ENDIAN && optimize_size)
+@@ -1635,9 +1698,9 @@ rs6000_override_options (const char *def
+   SUB3TARGET_OVERRIDE_OPTIONS;
+ #endif
+-  if (TARGET_E500)
++  if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC)
+     {
+-      /* The e500 does not have string instructions, and we set
++      /* The e500 and e500mc do not have string instructions, and we set
+        MASK_STRING above when optimizing for size.  */
+       if ((target_flags & MASK_STRING) != 0)
+       target_flags = target_flags & ~MASK_STRING;
+@@ -1845,6 +1908,15 @@ rs6000_override_options (const char *def
+       rs6000_cost = &ppc8540_cost;
+       break;
++      case PROCESSOR_PPCE300C2:
++      case PROCESSOR_PPCE300C3:
++      rs6000_cost = &ppce300c2c3_cost;
++      break;
++
++      case PROCESSOR_PPCE500MC:
++      rs6000_cost = &ppce500mc_cost;
++      break;
++
+       case PROCESSOR_POWER4:
+       case PROCESSOR_POWER5:
+       rs6000_cost = &power4_cost;
+@@ -2144,11 +2216,21 @@ rs6000_handle_option (size_t code, const
+       rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
+       break;
++    case OPT_misel:
++      rs6000_explicit_options.isel = true;
++      rs6000_isel = value;
++      break;
++
+     case OPT_misel_:
+       rs6000_explicit_options.isel = true;
+       rs6000_parse_yes_no_option ("isel", arg, &(rs6000_isel));
+       break;
++    case OPT_mspe:
++      rs6000_explicit_options.spe = true;
++      rs6000_spe = value;
++      break;
++
+     case OPT_mspe_:
+       rs6000_explicit_options.spe = true;
+       rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
+@@ -2395,6 +2477,8 @@ rs6000_file_start (void)
+              (TARGET_ALTIVEC_ABI ? 2
+               : TARGET_SPE_ABI ? 3
+               : 1));
++      fprintf (file, "\t.gnu_attribute 12, %d\n",
++             aix_struct_return ? 2 : 1);
+     }
+ #endif
+@@ -3145,24 +3229,26 @@ invalid_e500_subreg (rtx op, enum machin
+   if (TARGET_E500_DOUBLE)
+     {
+       /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
+-       subreg:TI and reg:TF.  */
++       subreg:TI and reg:TF.  Decimal float modes are like integer
++       modes (only low part of each register used) for this
++       purpose.  */
+       if (GET_CODE (op) == SUBREG
+-        && (mode == SImode || mode == DImode || mode == TImode)
++        && (mode == SImode || mode == DImode || mode == TImode
++            || mode == DDmode || mode == TDmode)
+         && REG_P (SUBREG_REG (op))
+         && (GET_MODE (SUBREG_REG (op)) == DFmode
+-            || GET_MODE (SUBREG_REG (op)) == TFmode
+-            || GET_MODE (SUBREG_REG (op)) == DDmode
+-            || GET_MODE (SUBREG_REG (op)) == TDmode))
++            || GET_MODE (SUBREG_REG (op)) == TFmode))
+       return true;
+       /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
+        reg:TI.  */
+       if (GET_CODE (op) == SUBREG
+-        && (mode == DFmode || mode == TFmode
+-            || mode == DDmode || mode == TDmode)
++        && (mode == DFmode || mode == TFmode)
+         && REG_P (SUBREG_REG (op))
+         && (GET_MODE (SUBREG_REG (op)) == DImode
+-            || GET_MODE (SUBREG_REG (op)) == TImode))
++            || GET_MODE (SUBREG_REG (op)) == TImode
++            || GET_MODE (SUBREG_REG (op)) == DDmode
++            || GET_MODE (SUBREG_REG (op)) == TDmode))
+       return true;
+     }
+@@ -3413,10 +3499,10 @@ rs6000_legitimate_offset_address_p (enum
+       return SPE_CONST_OFFSET_OK (offset);
+     case DFmode:
+-    case DDmode:
+       if (TARGET_E500_DOUBLE)
+       return SPE_CONST_OFFSET_OK (offset);
++    case DDmode:
+     case DImode:
+       /* On e500v2, we may have:
+@@ -3433,11 +3519,11 @@ rs6000_legitimate_offset_address_p (enum
+       break;
+     case TFmode:
+-    case TDmode:
+       if (TARGET_E500_DOUBLE)
+       return (SPE_CONST_OFFSET_OK (offset)
+               && SPE_CONST_OFFSET_OK (offset + 8));
++    case TDmode:
+     case TImode:
+       if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
+       extra = 12;
+@@ -3582,8 +3668,10 @@ rs6000_legitimize_address (rtx x, rtx ol
+       && GET_CODE (XEXP (x, 1)) == CONST_INT
+       && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000
+       && !(SPE_VECTOR_MODE (mode)
++         || ALTIVEC_VECTOR_MODE (mode)
+          || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
+-                                    || mode == DImode))))
++                                    || mode == DImode || mode == DDmode
++                                    || mode == TDmode))))
+     {
+       HOST_WIDE_INT high_int, low_int;
+       rtx sum;
+@@ -3591,7 +3679,14 @@ rs6000_legitimize_address (rtx x, rtx ol
+       high_int = INTVAL (XEXP (x, 1)) - low_int;
+       sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
+                                        GEN_INT (high_int)), 0);
+-      return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
++      /* Using a REG+CONST 64-bit integer load on 64-bit platforms
++       requires that CONST be word-aligned.  */
++      if (TARGET_POWERPC64
++        && (mode == DImode || mode == DDmode)
++        && (low_int & 0x3))
++      return gen_rtx_PLUS (Pmode, sum, force_reg (Pmode, GEN_INT (low_int)));
++      else
++      return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
+     }
+   else if (GET_CODE (x) == PLUS
+          && GET_CODE (XEXP (x, 0)) == REG
+@@ -3599,11 +3694,12 @@ rs6000_legitimize_address (rtx x, rtx ol
+          && GET_MODE_NUNITS (mode) == 1
+          && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+              || TARGET_POWERPC64
+-             || (((mode != DImode && mode != DFmode && mode != DDmode)
+-                  || TARGET_E500_DOUBLE)
+-                 && mode != TFmode && mode != TDmode))
++             || ((mode != DImode && mode != DFmode && mode != DDmode)
++                 || (TARGET_E500_DOUBLE && mode != DDmode)))
+          && (TARGET_POWERPC64 || mode != DImode)
+-         && mode != TImode)
++         && mode != TImode
++         && mode != TFmode
++         && mode != TDmode)
+     {
+       return gen_rtx_PLUS (Pmode, XEXP (x, 0),
+                          force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
+@@ -3630,19 +3726,29 @@ rs6000_legitimize_address (rtx x, rtx ol
+       /* We accept [reg + reg] and [reg + OFFSET].  */
+       if (GET_CODE (x) == PLUS)
+-      {
+-        rtx op1 = XEXP (x, 0);
+-        rtx op2 = XEXP (x, 1);
+-
+-        op1 = force_reg (Pmode, op1);
+-
+-        if (GET_CODE (op2) != REG
+-            && (GET_CODE (op2) != CONST_INT
+-                || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
+-          op2 = force_reg (Pmode, op2);
+-
+-        return gen_rtx_PLUS (Pmode, op1, op2);
+-      }
++       {
++         rtx op1 = XEXP (x, 0);
++         rtx op2 = XEXP (x, 1);
++         rtx y;
++
++         op1 = force_reg (Pmode, op1);
++
++         if (GET_CODE (op2) != REG
++             && (GET_CODE (op2) != CONST_INT
++                 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
++                 || (GET_MODE_SIZE (mode) > 8
++                     && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
++           op2 = force_reg (Pmode, op2);
++
++         /* We can't always do [reg + reg] for these, because [reg +
++            reg + offset] is not a legitimate addressing mode.  */
++         y = gen_rtx_PLUS (Pmode, op1, op2);
++
++         if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
++           return force_reg (Pmode, y);
++         else
++           return y;
++       }
+       return force_reg (Pmode, x);
+     }
+@@ -4190,7 +4296,8 @@ rs6000_legitimate_address (enum machine_
+       && mode != TDmode
+       && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+         || TARGET_POWERPC64
+-        || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
++        || (mode != DFmode && mode != DDmode)
++        || (TARGET_E500_DOUBLE && mode != DDmode))
+       && (TARGET_POWERPC64 || mode != DImode)
+       && legitimate_indexed_address_p (x, reg_ok_strict))
+     return 1;
+@@ -4314,7 +4421,8 @@ rs6000_hard_regno_nregs (int regno, enum
+      would require function_arg and rs6000_spe_function_arg to handle
+      SCmode so as to pass the value correctly in a pair of
+      registers.  */
+-  if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode)
++  if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
++      && !DECIMAL_FLOAT_MODE_P (mode))
+     return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
+   return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+@@ -4394,16 +4502,19 @@ rs6000_conditional_register_usage (void)
+   if (TARGET_ALTIVEC)
+     global_regs[VSCR_REGNO] = 1;
+-  if (TARGET_ALTIVEC_ABI)
+-    {
+-      for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
+-      call_used_regs[i] = call_really_used_regs[i] = 1;
++  /* If we are not using the AltiVec ABI, pretend that the normally
++     call-saved registers are also call-used.  We could use them
++     normally if we saved and restored them in the prologue; that
++     would require using the alignment padding around the register
++     save area, and some care with unwinding information.  */
++  if (! TARGET_ALTIVEC_ABI)
++    for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
++      call_used_regs[i] = call_really_used_regs[i] = 1;
+-      /* AIX reserves VR20:31 in non-extended ABI mode.  */
+-      if (TARGET_XCOFF)
+-      for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
+-        fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
+-    }
++  if (TARGET_ALTIVEC_ABI && TARGET_XCOFF)
++    /* AIX reserves VR20:31 in non-extended ABI mode.  */
++    for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
++      fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
+ }
\f
+ /* Try to output insns to set TARGET equal to the constant C if it can
+@@ -5588,14 +5699,12 @@ spe_build_register_parallel (enum machin
+   switch (mode)
+     {
+     case DFmode:
+-    case DDmode:
+       r1 = gen_rtx_REG (DImode, gregno);
+       r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
+       return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
+     case DCmode:
+     case TFmode:
+-    case TDmode:
+       r1 = gen_rtx_REG (DImode, gregno);
+       r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
+       r3 = gen_rtx_REG (DImode, gregno + 2);
+@@ -5628,13 +5737,12 @@ rs6000_spe_function_arg (CUMULATIVE_ARGS
+   /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
+      are passed and returned in a pair of GPRs for ABI compatibility.  */
+   if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
+-                           || mode == DDmode || mode == TDmode
+                            || mode == DCmode || mode == TCmode))
+     {
+       int n_words = rs6000_arg_size (mode, type);
+       /* Doubles go in an odd/even register pair (r5/r6, etc).  */
+-      if (mode == DFmode || mode == DDmode)
++      if (mode == DFmode)
+       gregno += (1 - gregno) & 1;
+       /* Multi-reg args are not split between registers and stack.  */
+@@ -6047,10 +6155,8 @@ function_arg (CUMULATIVE_ARGS *cum, enum
+   else if (TARGET_SPE_ABI && TARGET_SPE
+          && (SPE_VECTOR_MODE (mode)
+              || (TARGET_E500_DOUBLE && (mode == DFmode
+-                                        || mode == DDmode
+                                         || mode == DCmode
+                                         || mode == TFmode
+-                                        || mode == TDmode
+                                         || mode == TCmode))))
+     return rs6000_spe_function_arg (cum, mode, type);
+@@ -7049,9 +7155,9 @@ static struct builtin_description bdesc_
+   { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
+   { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
+   { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
+-  { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
+-  { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
+-  { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
++  { MASK_ALTIVEC, CODE_FOR_ashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
++  { MASK_ALTIVEC, CODE_FOR_ashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
++  { MASK_ALTIVEC, CODE_FOR_ashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
+   { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
+   { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
+   { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
+@@ -7211,10 +7317,10 @@ static struct builtin_description bdesc_
+   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
+   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
+-  { 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
+-  { 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
+-  { 0, CODE_FOR_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
+-  { 0, CODE_FOR_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
++  { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
++  { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
++  { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
++  { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
+   { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
+   { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
+   { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
+@@ -7223,10 +7329,10 @@ static struct builtin_description bdesc_
+   { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
+   /* Place holder, leave as first spe builtin.  */
+-  { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
+-  { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
++  { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
++  { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
+   { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
+-  { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
++  { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
+   { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
+   { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
+   { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
+@@ -7502,7 +7608,7 @@ static struct builtin_description bdesc_
+   /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
+      end with SPE_BUILTIN_EVSUBFUSIAAW.  */
+-  { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
++  { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
+   { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
+   { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
+   { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
+@@ -7534,9 +7640,9 @@ static struct builtin_description bdesc_
+   /* Place-holder.  Leave as last unary SPE builtin.  */
+   { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
+-  { 0, CODE_FOR_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
++  { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
+   { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
+-  { 0, CODE_FOR_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
++  { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
+   { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
+   { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
+ };
+@@ -9051,6 +9157,8 @@ build_opaque_vector_type (tree node, int
+ static void
+ rs6000_init_builtins (void)
+ {
++  tree tdecl;
++  
+   V2SI_type_node = build_vector_type (intSI_type_node, 2);
+   V2SF_type_node = build_vector_type (float_type_node, 2);
+   V4HI_type_node = build_vector_type (intHI_type_node, 4);
+@@ -9088,60 +9196,75 @@ rs6000_init_builtins (void)
+   float_type_internal_node = float_type_node;
+   void_type_internal_node = void_type_node;
+-  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-                                          get_identifier ("__bool char"),
+-                                          bool_char_type_node));
+-  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-                                          get_identifier ("__bool short"),
+-                                          bool_short_type_node));
+-  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-                                          get_identifier ("__bool int"),
+-                                          bool_int_type_node));
+-  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-                                          get_identifier ("__pixel"),
+-                                          pixel_type_node));
++  tdecl = build_decl (TYPE_DECL, get_identifier ("__bool char"),
++                    bool_char_type_node);
++  TYPE_NAME (bool_char_type_node) = tdecl;
++  (*lang_hooks.decls.pushdecl) (tdecl);
++  tdecl = build_decl (TYPE_DECL, get_identifier ("__bool short"),
++                    bool_short_type_node);
++  TYPE_NAME (bool_short_type_node) = tdecl;
++  (*lang_hooks.decls.pushdecl) (tdecl);
++  tdecl = build_decl (TYPE_DECL, get_identifier ("__bool int"),
++                    bool_int_type_node);
++  TYPE_NAME (bool_int_type_node) = tdecl;
++  (*lang_hooks.decls.pushdecl) (tdecl);
++  tdecl = build_decl (TYPE_DECL, get_identifier ("__pixel"),
++                    pixel_type_node);
++  TYPE_NAME (pixel_type_node) = tdecl;
++  (*lang_hooks.decls.pushdecl) (tdecl);
+   bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
+   bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
+   bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
+   pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
+-  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-                                          get_identifier ("__vector unsigned char"),
+-                                          unsigned_V16QI_type_node));
+-  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-                                          get_identifier ("__vector signed char"),
+-                                          V16QI_type_node));
+-  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-                                          get_identifier ("__vector __bool char"),
+-                                          bool_V16QI_type_node));
+-
+-  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-                                          get_identifier ("__vector unsigned short"),
+-                                          unsigned_V8HI_type_node));
+-  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-                                          get_identifier ("__vector signed short"),
+-                                          V8HI_type_node));
+-  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-                                          get_identifier ("__vector __bool short"),
+-                                          bool_V8HI_type_node));
+-
+-  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-                                          get_identifier ("__vector unsigned int"),
+-                                          unsigned_V4SI_type_node));
+-  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-                                          get_identifier ("__vector signed int"),
+-                                          V4SI_type_node));
+-  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-                                          get_identifier ("__vector __bool int"),
+-                                          bool_V4SI_type_node));
+-
+-  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-                                          get_identifier ("__vector float"),
+-                                          V4SF_type_node));
+-  (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-                                          get_identifier ("__vector __pixel"),
+-                                          pixel_V8HI_type_node));
++  tdecl = build_decl (TYPE_DECL, get_identifier ("__vector unsigned char"),
++                    unsigned_V16QI_type_node);
++  TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
++  (*lang_hooks.decls.pushdecl) (tdecl);
++  tdecl = build_decl (TYPE_DECL, get_identifier ("__vector signed char"),
++                    V16QI_type_node);
++  TYPE_NAME (V16QI_type_node) = tdecl;
++  (*lang_hooks.decls.pushdecl) (tdecl);
++  tdecl = build_decl (TYPE_DECL, get_identifier ("__vector __bool char"),
++                    bool_V16QI_type_node);
++  TYPE_NAME ( bool_V16QI_type_node) = tdecl;
++  (*lang_hooks.decls.pushdecl) (tdecl);
++
++  tdecl = build_decl (TYPE_DECL, get_identifier ("__vector unsigned short"),
++                    unsigned_V8HI_type_node);
++  TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
++  (*lang_hooks.decls.pushdecl) (tdecl);
++  tdecl = build_decl (TYPE_DECL, get_identifier ("__vector signed short"),
++                    V8HI_type_node);
++  TYPE_NAME (V8HI_type_node) = tdecl;
++  (*lang_hooks.decls.pushdecl) (tdecl);
++  tdecl = build_decl (TYPE_DECL, get_identifier ("__vector __bool short"),
++                    bool_V8HI_type_node);
++  TYPE_NAME (bool_V8HI_type_node) = tdecl;
++  (*lang_hooks.decls.pushdecl) (tdecl);
++
++  tdecl = build_decl (TYPE_DECL, get_identifier ("__vector unsigned int"),
++                    unsigned_V4SI_type_node);
++  TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
++  (*lang_hooks.decls.pushdecl) (tdecl);
++  tdecl = build_decl (TYPE_DECL, get_identifier ("__vector signed int"),
++                    V4SI_type_node);
++  TYPE_NAME (V4SI_type_node) = tdecl;
++  (*lang_hooks.decls.pushdecl) (tdecl);
++  tdecl = build_decl (TYPE_DECL, get_identifier ("__vector __bool int"),
++                    bool_V4SI_type_node);
++  TYPE_NAME (bool_V4SI_type_node) = tdecl;
++  (*lang_hooks.decls.pushdecl) (tdecl);
++
++  tdecl = build_decl (TYPE_DECL, get_identifier ("__vector float"),
++                    V4SF_type_node);
++  TYPE_NAME (V4SF_type_node) = tdecl;
++  (*lang_hooks.decls.pushdecl) (tdecl);
++  tdecl = build_decl (TYPE_DECL, get_identifier ("__vector __pixel"),
++                    pixel_V8HI_type_node);
++  TYPE_NAME (pixel_V8HI_type_node) = tdecl;
++  (*lang_hooks.decls.pushdecl) (tdecl);
+   if (TARGET_PAIRED_FLOAT)
+     paired_init_builtins ();
+@@ -12472,7 +12595,7 @@ rs6000_generate_compare (enum rtx_code c
+         switch (op_mode)
+           {
+           case SFmode:
+-            cmp = flag_unsafe_math_optimizations
++            cmp = (flag_finite_math_only && !flag_trapping_math)
+               ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
+                                  rs6000_compare_op1)
+               : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
+@@ -12480,7 +12603,7 @@ rs6000_generate_compare (enum rtx_code c
+             break;
+           case DFmode:
+-            cmp = flag_unsafe_math_optimizations
++            cmp = (flag_finite_math_only && !flag_trapping_math)
+               ? gen_tstdfeq_gpr (compare_result, rs6000_compare_op0,
+                                  rs6000_compare_op1)
+               : gen_cmpdfeq_gpr (compare_result, rs6000_compare_op0,
+@@ -12488,7 +12611,7 @@ rs6000_generate_compare (enum rtx_code c
+             break;
+           case TFmode:
+-            cmp = flag_unsafe_math_optimizations
++            cmp = (flag_finite_math_only && !flag_trapping_math)
+               ? gen_tsttfeq_gpr (compare_result, rs6000_compare_op0,
+                                  rs6000_compare_op1)
+               : gen_cmptfeq_gpr (compare_result, rs6000_compare_op0,
+@@ -12504,7 +12627,7 @@ rs6000_generate_compare (enum rtx_code c
+         switch (op_mode)
+           {
+           case SFmode:
+-            cmp = flag_unsafe_math_optimizations
++            cmp = (flag_finite_math_only && !flag_trapping_math)
+               ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
+                                  rs6000_compare_op1)
+               : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
+@@ -12512,7 +12635,7 @@ rs6000_generate_compare (enum rtx_code c
+             break;
+           case DFmode:
+-            cmp = flag_unsafe_math_optimizations
++            cmp = (flag_finite_math_only && !flag_trapping_math)
+               ? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0,
+                                  rs6000_compare_op1)
+               : gen_cmpdfgt_gpr (compare_result, rs6000_compare_op0,
+@@ -12520,7 +12643,7 @@ rs6000_generate_compare (enum rtx_code c
+             break;
+           case TFmode:
+-            cmp = flag_unsafe_math_optimizations
++            cmp = (flag_finite_math_only && !flag_trapping_math)
+               ? gen_tsttfgt_gpr (compare_result, rs6000_compare_op0,
+                                  rs6000_compare_op1)
+               : gen_cmptfgt_gpr (compare_result, rs6000_compare_op0,
+@@ -12536,7 +12659,7 @@ rs6000_generate_compare (enum rtx_code c
+         switch (op_mode)
+           {
+           case SFmode:
+-            cmp = flag_unsafe_math_optimizations
++            cmp = (flag_finite_math_only && !flag_trapping_math)
+               ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
+                                  rs6000_compare_op1)
+               : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
+@@ -12544,7 +12667,7 @@ rs6000_generate_compare (enum rtx_code c
+             break;
+           case DFmode:
+-            cmp = flag_unsafe_math_optimizations
++            cmp = (flag_finite_math_only && !flag_trapping_math)
+               ? gen_tstdflt_gpr (compare_result, rs6000_compare_op0,
+                                  rs6000_compare_op1)
+               : gen_cmpdflt_gpr (compare_result, rs6000_compare_op0,
+@@ -12552,7 +12675,7 @@ rs6000_generate_compare (enum rtx_code c
+             break;
+           case TFmode:
+-            cmp = flag_unsafe_math_optimizations
++            cmp = (flag_finite_math_only && !flag_trapping_math)
+               ? gen_tsttflt_gpr (compare_result, rs6000_compare_op0,
+                                  rs6000_compare_op1)
+               : gen_cmptflt_gpr (compare_result, rs6000_compare_op0,
+@@ -12587,7 +12710,7 @@ rs6000_generate_compare (enum rtx_code c
+         switch (op_mode)
+           {
+           case SFmode:
+-            cmp = flag_unsafe_math_optimizations
++            cmp = (flag_finite_math_only && !flag_trapping_math)
+               ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
+                                  rs6000_compare_op1)
+               : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
+@@ -12595,7 +12718,7 @@ rs6000_generate_compare (enum rtx_code c
+             break;
+           case DFmode:
+-            cmp = flag_unsafe_math_optimizations
++            cmp = (flag_finite_math_only && !flag_trapping_math)
+               ? gen_tstdfeq_gpr (compare_result2, rs6000_compare_op0,
+                                  rs6000_compare_op1)
+               : gen_cmpdfeq_gpr (compare_result2, rs6000_compare_op0,
+@@ -12603,7 +12726,7 @@ rs6000_generate_compare (enum rtx_code c
+             break;
+           case TFmode:
+-            cmp = flag_unsafe_math_optimizations
++            cmp = (flag_finite_math_only && !flag_trapping_math)
+               ? gen_tsttfeq_gpr (compare_result2, rs6000_compare_op0,
+                                  rs6000_compare_op1)
+               : gen_cmptfeq_gpr (compare_result2, rs6000_compare_op0,
+@@ -13946,8 +14069,8 @@ rs6000_split_multireg_move (rtx dst, rtx
+     reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
+   else if (ALTIVEC_REGNO_P (reg))
+     reg_mode = V16QImode;
+-  else if (TARGET_E500_DOUBLE && (mode == TFmode || mode == TDmode))
+-    reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
++  else if (TARGET_E500_DOUBLE && mode == TFmode)
++    reg_mode = DFmode;
+   else
+     reg_mode = word_mode;
+   reg_mode_size = GET_MODE_SIZE (reg_mode);
+@@ -14535,7 +14658,7 @@ rs6000_stack_info (void)
+       {
+         /* Align stack so SPE GPR save area is aligned on a
+            double-word boundary.  */
+-        if (info_ptr->spe_gp_size != 0)
++        if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
+           info_ptr->spe_padding_size
+             = 8 - (-info_ptr->cr_save_offset % 8);
+         else
+@@ -14686,8 +14809,7 @@ spe_func_has_64bit_regs_p (void)
+             if (SPE_VECTOR_MODE (mode))
+               return true;
+-            if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
+-                                       || mode == DDmode || mode == TDmode))
++            if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
+               return true;
+           }
+       }
+@@ -15191,10 +15313,12 @@ rs6000_emit_stack_tie (void)
+ /* Emit the correct code for allocating stack space, as insns.
+    If COPY_R12, make sure a copy of the old frame is left in r12.
++   If COPY_R11, make sure a copy of the old frame is left in r11,
++   in preference to r12 if COPY_R12.
+    The generated code may use hard register 0 as a temporary.  */
+ static void
+-rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12)
++rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
+ {
+   rtx insn;
+   rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
+@@ -15243,8 +15367,11 @@ rs6000_emit_allocate_stack (HOST_WIDE_IN
+       warning (0, "stack limit expression is not supported");
+     }
+-  if (copy_r12 || ! TARGET_UPDATE)
+-    emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
++  if (copy_r12 || copy_r11 || ! TARGET_UPDATE)
++    emit_move_insn (copy_r11
++                    ? gen_rtx_REG (Pmode, 11)
++                    : gen_rtx_REG (Pmode, 12),
++                    stack_reg);
+   if (TARGET_UPDATE)
+     {
+@@ -15270,7 +15397,9 @@ rs6000_emit_allocate_stack (HOST_WIDE_IN
+                       ? gen_addsi3 (stack_reg, stack_reg, todec)
+                       : gen_adddi3 (stack_reg, stack_reg, todec));
+       emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
+-                    gen_rtx_REG (Pmode, 12));
++                    copy_r11
++                      ? gen_rtx_REG (Pmode, 11)
++                      : gen_rtx_REG (Pmode, 12));
+     }
+   RTX_FRAME_RELATED_P (insn) = 1;
+@@ -15359,77 +15488,12 @@ rs6000_frame_related (rtx insn, rtx reg,
+         }
+     }
+-  if (TARGET_SPE)
+-    real = spe_synthesize_frame_save (real);
+-
+   RTX_FRAME_RELATED_P (insn) = 1;
+   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+                                       real,
+                                       REG_NOTES (insn));
+ }
+-/* Given an SPE frame note, return a PARALLEL of SETs with the
+-   original note, plus a synthetic register save.  */
+-
+-static rtx
+-spe_synthesize_frame_save (rtx real)
+-{
+-  rtx synth, offset, reg, real2;
+-
+-  if (GET_CODE (real) != SET
+-      || GET_MODE (SET_SRC (real)) != V2SImode)
+-    return real;
+-
+-  /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
+-     frame related note.  The parallel contains a set of the register
+-     being saved, and another set to a synthetic register (n+1200).
+-     This is so we can differentiate between 64-bit and 32-bit saves.
+-     Words cannot describe this nastiness.  */
+-
+-  gcc_assert (GET_CODE (SET_DEST (real)) == MEM
+-            && GET_CODE (XEXP (SET_DEST (real), 0)) == PLUS
+-            && GET_CODE (SET_SRC (real)) == REG);
+-
+-  /* Transform:
+-       (set (mem (plus (reg x) (const y)))
+-            (reg z))
+-     into:
+-       (set (mem (plus (reg x) (const y+4)))
+-            (reg z+1200))
+-  */
+-
+-  real2 = copy_rtx (real);
+-  PUT_MODE (SET_DEST (real2), SImode);
+-  reg = SET_SRC (real2);
+-  real2 = replace_rtx (real2, reg, gen_rtx_REG (SImode, REGNO (reg)));
+-  synth = copy_rtx (real2);
+-
+-  if (BYTES_BIG_ENDIAN)
+-    {
+-      offset = XEXP (XEXP (SET_DEST (real2), 0), 1);
+-      real2 = replace_rtx (real2, offset, GEN_INT (INTVAL (offset) + 4));
+-    }
+-
+-  reg = SET_SRC (synth);
+-
+-  synth = replace_rtx (synth, reg,
+-                     gen_rtx_REG (SImode, REGNO (reg) + 1200));
+-
+-  offset = XEXP (XEXP (SET_DEST (synth), 0), 1);
+-  synth = replace_rtx (synth, offset,
+-                     GEN_INT (INTVAL (offset)
+-                              + (BYTES_BIG_ENDIAN ? 0 : 4)));
+-
+-  RTX_FRAME_RELATED_P (synth) = 1;
+-  RTX_FRAME_RELATED_P (real2) = 1;
+-  if (BYTES_BIG_ENDIAN)
+-    real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, synth, real2));
+-  else
+-    real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, real2, synth));
+-
+-  return real;
+-}
+-
+ /* Returns an insn that has a vrsave set operation with the
+    appropriate CLOBBERs.  */
+@@ -15503,7 +15567,7 @@ emit_frame_save (rtx frame_reg, rtx fram
+   /* Some cases that need register indexed addressing.  */
+   if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+-      || (TARGET_E500_DOUBLE && (mode == DFmode || mode == DDmode))
++      || (TARGET_E500_DOUBLE && mode == DFmode)
+       || (TARGET_SPE_ABI
+         && SPE_VECTOR_MODE (mode)
+         && !SPE_CONST_OFFSET_OK (offset)))
+@@ -15543,7 +15607,7 @@ gen_frame_mem_offset (enum machine_mode 
+   int_rtx = GEN_INT (offset);
+   if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
+-      || (TARGET_E500_DOUBLE && (mode == DFmode || mode == DDmode)))
++      || (TARGET_E500_DOUBLE && mode == DFmode))
+     {
+       offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
+       emit_move_insn (offset_rtx, int_rtx);
+@@ -15558,11 +15622,11 @@ gen_frame_mem_offset (enum machine_mode 
+    and cannot use stmw/lmw if there are any in its range.  */
+ static bool
+-no_global_regs_above (int first_greg)
++no_global_regs_above (int first, bool gpr)
+ {
+   int i;
+-  for (i = 0; i < 32 - first_greg; i++)
+-    if (global_regs[first_greg + i])
++  for (i = first; i < (gpr ? 32 : 64); i++)
++    if (global_regs[i])
+       return false;
+   return true;
+ }
+@@ -15571,6 +15635,164 @@ no_global_regs_above (int first_greg)
+ #define TARGET_FIX_AND_CONTINUE 0
+ #endif
++/* It's really GPR 13 and FPR 14, but we need the smaller of the two.  */
++#define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
++#define LAST_SAVRES_REGISTER 31
++#define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
++
++static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
++
++/* Return the symbol for an out-of-line register save/restore routine.
++   We are saving/restoring GPRs if GPR is true.  */
++
++static rtx
++rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep, bool gpr, bool exitp)
++{
++  int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
++  rtx sym;
++  int select = ((savep ? 1 : 0) << 2
++              | (TARGET_SPE_ABI
++                 /* On the SPE, we never have any FPRs, but we do have
++                    32/64-bit versions of the routines.  */
++                 ? (info->spe_64bit_regs_used ? 1 : 0)
++                 : (gpr ? 1 : 0)) << 1
++              | (exitp ? 1: 0));
++
++  /* Don't generate bogus routine names.  */
++  gcc_assert (FIRST_SAVRES_REGISTER <= regno && regno <= LAST_SAVRES_REGISTER);
++
++  sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
++
++  if (sym == NULL)
++    {
++      char name[30];
++      const char *action;
++      const char *regkind;
++      const char *exit_suffix;
++
++      action = savep ? "save" : "rest";
++
++      /* SPE has slightly different names for its routines depending on
++       whether we are saving 32-bit or 64-bit registers.  */
++      if (TARGET_SPE_ABI)
++      {
++        /* No floating point saves on the SPE.  */
++        gcc_assert (gpr);
++
++        regkind = info->spe_64bit_regs_used ? "64gpr" : "32gpr";
++      }
++      else
++      regkind = gpr ? "gpr" : "fpr";
++
++      exit_suffix = exitp ? "_x" : "";
++
++      sprintf (name, "_%s%s_%d%s", action, regkind, regno, exit_suffix);
++
++      sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
++      = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
++      SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
++    }
++
++  return sym;
++}
++
++/* Emit a sequence of insns, including a stack tie if needed, for
++   resetting the stack pointer.  If SAVRES is true, then don't reset the
++   stack pointer, but move the base of the frame into r11 for use by
++   out-of-line register restore routines.  */
++
++static void
++rs6000_emit_stack_reset (rs6000_stack_t *info,
++                       rtx sp_reg_rtx, rtx frame_reg_rtx,
++                       int sp_offset, bool savres)
++{
++  /* This blockage is needed so that sched doesn't decide to move
++     the sp change before the register restores.  */
++  if (frame_reg_rtx != sp_reg_rtx
++      || (TARGET_SPE_ABI
++        && info->spe_64bit_regs_used != 0
++        && info->first_gp_reg_save != 32))
++    rs6000_emit_stack_tie ();
++  
++  if (frame_reg_rtx != sp_reg_rtx)
++    {
++      rs6000_emit_stack_tie ();
++      if (sp_offset != 0)
++      emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx,
++                             GEN_INT (sp_offset)));
++      else if (!savres)
++      emit_move_insn (sp_reg_rtx, frame_reg_rtx);
++    }
++  else if (sp_offset != 0)
++    {
++      /* If we are restoring registers out-of-line, we will be using the
++       "exit" variants of the restore routines, which will reset the
++       stack for us.  But we do need to point r11 into the right place
++       for those routines.  */
++      rtx dest_reg = (savres
++                    ? gen_rtx_REG (Pmode, 11)
++                    : sp_reg_rtx);
++
++      emit_insn (TARGET_32BIT
++               ? gen_addsi3 (dest_reg, sp_reg_rtx,
++                             GEN_INT (sp_offset))
++               : gen_adddi3 (dest_reg, sp_reg_rtx,
++                             GEN_INT (sp_offset)));
++    }
++}
++
++/* Construct a parallel rtx describing the effect of a call to an
++   out-of-line register save/restore routine.  */
++
++static rtx
++rs6000_make_savres_rtx (rs6000_stack_t *info,
++                      rtx frame_reg_rtx, int save_area_offset,
++                      enum machine_mode reg_mode,
++                      bool savep, bool gpr, bool exitp)
++{
++  int i;
++  int offset, start_reg, end_reg, n_regs;
++  int reg_size = GET_MODE_SIZE (reg_mode);
++  rtx sym;
++  rtvec p;
++
++  offset = 0;
++  start_reg = (gpr
++             ? info->first_gp_reg_save
++             : info->first_fp_reg_save);
++  end_reg = gpr ? 32 : 64;
++  n_regs = end_reg - start_reg;
++  p = rtvec_alloc ((exitp ? 4 : 3) + n_regs);
++
++  /* If we're saving registers, then we should never say we're exiting.        */
++  gcc_assert ((savep && !exitp) || !savep);
++
++  if (exitp)
++    RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
++
++  RTVEC_ELT (p, offset++)
++    = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
++
++  sym = rs6000_savres_routine_sym (info, savep, gpr, exitp);
++  RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
++  RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 11));
++
++  for (i = 0; i < end_reg - start_reg; i++)
++    {
++      rtx addr, reg, mem;
++      reg = gen_rtx_REG (reg_mode, start_reg + i);
++      addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
++                         GEN_INT (save_area_offset + reg_size*i));
++      mem = gen_frame_mem (reg_mode, addr);
++
++      RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
++                                             savep ? mem : reg,
++                                             savep ? reg : mem);
++    }
++
++  return gen_rtx_PARALLEL (VOIDmode, p);
++}
++
+ /* Determine whether the gp REG is really used.  */
+ static bool
+@@ -15585,6 +15807,93 @@ rs6000_reg_live_or_pic_offset_p (int reg
+                   || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
+ }
++enum {
++  SAVRES_MULTIPLE = 0x1,
++  SAVRES_INLINE_FPRS = 0x2,
++  SAVRES_INLINE_GPRS = 0x4
++};
++
++/* Determine the strategy for savings/restoring registers.  */
++
++static int
++rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
++                      int using_static_chain_p, int sibcall)
++{
++  bool using_multiple_p;
++  bool common;
++  bool savres_fprs_inline;
++  bool savres_gprs_inline;
++  bool noclobber_global_gprs
++    = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
++
++  using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
++                    && (!TARGET_SPE_ABI
++                        || info->spe_64bit_regs_used == 0)
++                    && info->first_gp_reg_save < 31
++                    && noclobber_global_gprs);
++  /* Don't bother to try to save things out-of-line if r11 is occupied
++     by the static chain.  It would require too much fiddling and the
++     static chain is rarely used anyway.  */
++  common = (using_static_chain_p
++          || sibcall
++          || current_function_calls_eh_return
++          || !info->lr_save_p
++          || cfun->machine->ra_need_lr
++          || info->total_size > 32767);
++  savres_fprs_inline = (common
++                      || info->first_fp_reg_save == 64
++                      || !no_global_regs_above (info->first_fp_reg_save,
++                                                /*gpr=*/false)
++                      || FP_SAVE_INLINE (info->first_fp_reg_save));
++  savres_gprs_inline = (common
++                      /* Saving CR interferes with the exit routines
++                         used on the SPE, so just punt here.  */
++                      || (!savep
++                          && TARGET_SPE_ABI
++                          && info->spe_64bit_regs_used != 0
++                          && info->cr_save_p != 0)
++                      || info->first_gp_reg_save == 32
++                      || !noclobber_global_gprs
++                      || GP_SAVE_INLINE (info->first_gp_reg_save));
++
++  if (savep)
++    /* If we are going to use store multiple, then don't even bother
++     with the out-of-line routines, since the store-multiple instruction
++     will always be smaller.  */
++    savres_gprs_inline = savres_gprs_inline || using_multiple_p;
++  else
++    {
++      /* The situation is more complicated with load multiple.  We'd
++         prefer to use the out-of-line routines for restores, since the
++         "exit" out-of-line routines can handle the restore of LR and
++         the frame teardown.  But we can only use the out-of-line
++         routines if we know that we've used store multiple or
++         out-of-line routines in the prologue, i.e. if we've saved all
++         the registers from first_gp_reg_save.  Otherwise, we risk
++         loading garbage from the stack.  Furthermore, we can only use
++         the "exit" out-of-line gpr restore if we haven't saved any
++         fprs.  */
++      bool saved_all = !savres_gprs_inline || using_multiple_p;
++
++      if (saved_all && info->first_fp_reg_save != 64)
++      /* We can't use the exit routine; use load multiple if it's
++         available.  */
++      savres_gprs_inline = savres_gprs_inline || using_multiple_p;
++    }
++
++  /* Code intended for use in shared libraries cannot be reliably linked
++     with out-of-line prologues and epilogues.  */
++  if (flag_pic)
++    {
++      savres_gprs_inline = 1;
++      savres_fprs_inline = 1;
++    }
++
++  return (using_multiple_p
++        | (savres_fprs_inline << 1)
++        | (savres_gprs_inline << 2));
++}
++
+ /* Emit function prologue as insns.  */
+ void
+@@ -15598,8 +15907,13 @@ rs6000_emit_prologue (void)
+   rtx frame_reg_rtx = sp_reg_rtx;
+   rtx cr_save_rtx = NULL_RTX;
+   rtx insn;
++  int strategy;
+   int saving_FPRs_inline;
++  int saving_GPRs_inline;
+   int using_store_multiple;
++  int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
++                              && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
++                              && call_used_regs[STATIC_CHAIN_REGNUM]);
+   HOST_WIDE_INT sp_offset = 0;
+   if (TARGET_FIX_AND_CONTINUE)
+@@ -15622,15 +15936,12 @@ rs6000_emit_prologue (void)
+       reg_size = 8;
+     }
+-  using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
+-                        && (!TARGET_SPE_ABI
+-                            || info->spe_64bit_regs_used == 0)
+-                        && info->first_gp_reg_save < 31
+-                        && no_global_regs_above (info->first_gp_reg_save));
+-  saving_FPRs_inline = (info->first_fp_reg_save == 64
+-                      || FP_SAVE_INLINE (info->first_fp_reg_save)
+-                      || current_function_calls_eh_return
+-                      || cfun->machine->ra_need_lr);
++  strategy = rs6000_savres_strategy (info, /*savep=*/true,
++                                   /*static_chain_p=*/using_static_chain_p,
++                                   /*sibcall=*/0);
++  using_store_multiple = strategy & SAVRES_MULTIPLE;
++  saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
++  saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
+   /* For V.4, update stack before we do any saving and set back pointer.  */
+   if (! WORLD_SAVE_P (info)
+@@ -15638,17 +15949,24 @@ rs6000_emit_prologue (void)
+       && (DEFAULT_ABI == ABI_V4
+         || current_function_calls_eh_return))
+     {
++      bool need_r11 = (TARGET_SPE
++                     ? (!saving_GPRs_inline
++                        && info->spe_64bit_regs_used == 0)
++                     : (!saving_FPRs_inline || !saving_GPRs_inline));
+       if (info->total_size < 32767)
+       sp_offset = info->total_size;
+       else
+-      frame_reg_rtx = frame_ptr_rtx;
++      frame_reg_rtx = (need_r11
++                       ? gen_rtx_REG (Pmode, 11)
++                       : frame_ptr_rtx);
+       rs6000_emit_allocate_stack (info->total_size,
+                                 (frame_reg_rtx != sp_reg_rtx
+                                  && (info->cr_save_p
+                                      || info->lr_save_p
+                                      || info->first_fp_reg_save < 64
+                                      || info->first_gp_reg_save < 32
+-                                     )));
++                                     )),
++                                need_r11);
+       if (frame_reg_rtx != sp_reg_rtx)
+       rs6000_emit_stack_tie ();
+     }
+@@ -15825,40 +16143,147 @@ rs6000_emit_prologue (void)
+     }
+   else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
+     {
++      rtx par;
++
++      par = rs6000_make_savres_rtx (info, frame_reg_rtx,
++                                  info->fp_save_offset + sp_offset,
++                                  DFmode,
++                                  /*savep=*/true, /*gpr=*/false,
++                                  /*exitp=*/false);
++      insn = emit_insn (par);
++      rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
++                          NULL_RTX, NULL_RTX);
++    }
++
++  /* Save GPRs.  This is done as a PARALLEL if we are using
++     the store-multiple instructions.  */
++  if (!WORLD_SAVE_P (info)
++      && TARGET_SPE_ABI
++      && info->spe_64bit_regs_used != 0
++      && info->first_gp_reg_save != 32)
++    {
+       int i;
+-      char rname[30];
+-      const char *alloc_rname;
+-      rtvec p;
+-      p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
++      rtx spe_save_area_ptr;
++ 
++      /* Determine whether we can address all of the registers that need
++       to be saved with an offset from the stack pointer that fits in
++       the small const field for SPE memory instructions.  */
++      int spe_regs_addressable_via_sp
++      = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
++                             + (32 - info->first_gp_reg_save - 1) * reg_size)
++         && saving_GPRs_inline);
++      int spe_offset;
++ 
++      if (spe_regs_addressable_via_sp)
++      {
++        spe_save_area_ptr = frame_reg_rtx;
++        spe_offset = info->spe_gp_save_offset + sp_offset;
++      }
++      else
++      {
++        /* Make r11 point to the start of the SPE save area.  We need
++           to be careful here if r11 is holding the static chain.  If
++           it is, then temporarily save it in r0.  We would use r0 as
++           our base register here, but using r0 as a base register in
++           loads and stores means something different from what we
++           would like.  */
++        int ool_adjust = (saving_GPRs_inline
++                          ? 0
++                          : (info->first_gp_reg_save
++                             - (FIRST_SAVRES_REGISTER+1))*8);
++        HOST_WIDE_INT offset = (info->spe_gp_save_offset
++                                + sp_offset - ool_adjust);
+-      RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
+-                                        gen_rtx_REG (Pmode,
+-                                                     LR_REGNO));
+-      sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
+-             info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
+-      alloc_rname = ggc_strdup (rname);
+-      RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
+-                                    gen_rtx_SYMBOL_REF (Pmode,
+-                                                        alloc_rname));
+-      for (i = 0; i < 64 - info->first_fp_reg_save; i++)
++        if (using_static_chain_p)
++          {
++            rtx r0 = gen_rtx_REG (Pmode, 0);
++            gcc_assert (info->first_gp_reg_save > 11);
++ 
++            emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
++          }
++ 
++        spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
++        insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
++                                      frame_reg_rtx,
++                                      GEN_INT (offset)));
++        /* We need to make sure the move to r11 gets noted for
++           properly outputting unwind information.  */
++        if (!saving_GPRs_inline)
++          rs6000_frame_related (insn, frame_reg_rtx, offset,
++                                NULL_RTX, NULL_RTX);
++        spe_offset = 0;
++      }
++ 
++      if (saving_GPRs_inline)
+       {
+-        rtx addr, reg, mem;
+-        reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
+-        addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+-                             GEN_INT (info->fp_save_offset
+-                                      + sp_offset + 8*i));
+-        mem = gen_frame_mem (DFmode, addr);
++        for (i = 0; i < 32 - info->first_gp_reg_save; i++)
++          if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
++            {
++              rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
++              rtx offset, addr, mem;
++
++              /* We're doing all this to ensure that the offset fits into
++                 the immediate offset of 'evstdd'.  */
++              gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
++ 
++              offset = GEN_INT (reg_size * i + spe_offset);
++              addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
++              mem = gen_rtx_MEM (V2SImode, addr);
++  
++              insn = emit_move_insn (mem, reg);
++         
++              rs6000_frame_related (insn, spe_save_area_ptr,
++                                    info->spe_gp_save_offset
++                                    + sp_offset + reg_size * i,
++                                    offset, const0_rtx);
++            }
++      }
++      else
++      {
++        rtx par;
+-        RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
++        par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
++                                      0, reg_mode,
++                                      /*savep=*/true, /*gpr=*/true,
++                                      /*exitp=*/false);
++        insn = emit_insn (par);
++        rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
++                              NULL_RTX, NULL_RTX);
+       }
+-      insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
++                                      
++ 
++      /* Move the static chain pointer back.  */
++      if (using_static_chain_p && !spe_regs_addressable_via_sp)
++      emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
++    }
++  else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
++    {
++      rtx par;
++
++      /* Need to adjust r11 if we saved any FPRs.  */
++      if (info->first_fp_reg_save != 64)
++        {
++          rtx r11 = gen_rtx_REG (reg_mode, 11);
++          rtx offset = GEN_INT (info->total_size
++                                + (-8 * (64-info->first_fp_reg_save)));
++          rtx ptr_reg = (sp_reg_rtx == frame_reg_rtx
++                         ? sp_reg_rtx : r11);
++
++          emit_insn (TARGET_32BIT
++                     ? gen_addsi3 (r11, ptr_reg, offset)
++                     : gen_adddi3 (r11, ptr_reg, offset));
++        }
++
++      par = rs6000_make_savres_rtx (info, frame_reg_rtx,
++                                  info->gp_save_offset + sp_offset,
++                                  reg_mode,
++                                  /*savep=*/true, /*gpr=*/true,
++                                  /*exitp=*/false);
++      insn = emit_insn (par);
+       rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+                           NULL_RTX, NULL_RTX);
+     }
+-
+-  /* Save GPRs.  This is done as a PARALLEL if we are using
+-     the store-multiple instructions.  */
+-  if (!WORLD_SAVE_P (info) && using_store_multiple)
++  else if (!WORLD_SAVE_P (info) && using_store_multiple)
+     {
+       rtvec p;
+       int i;
+@@ -15879,80 +16304,6 @@ rs6000_emit_prologue (void)
+       rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+                           NULL_RTX, NULL_RTX);
+     }
+-   else if (!WORLD_SAVE_P (info)
+-            && TARGET_SPE_ABI
+-            && info->spe_64bit_regs_used != 0
+-            && info->first_gp_reg_save != 32)
+-     {
+-       int i;
+-       rtx spe_save_area_ptr;
+-       int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
+-                                   && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
+-                                   && !call_used_regs[STATIC_CHAIN_REGNUM]);
+- 
+-       /* Determine whether we can address all of the registers that need
+-          to be saved with an offset from the stack pointer that fits in
+-          the small const field for SPE memory instructions.  */
+-       int spe_regs_addressable_via_sp
+-         = SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
+-                               + (32 - info->first_gp_reg_save - 1) * reg_size);
+-       int spe_offset;
+- 
+-       if (spe_regs_addressable_via_sp)
+-         {
+-           spe_save_area_ptr = frame_reg_rtx;
+-           spe_offset = info->spe_gp_save_offset + sp_offset;
+-         }
+-       else
+-         {
+-           /* Make r11 point to the start of the SPE save area.  We need
+-              to be careful here if r11 is holding the static chain.  If
+-              it is, then temporarily save it in r0.  We would use r0 as
+-              our base register here, but using r0 as a base register in
+-              loads and stores means something different from what we
+-              would like.  */
+-           if (using_static_chain_p)
+-             {
+-               rtx r0 = gen_rtx_REG (Pmode, 0);
+- 
+-               gcc_assert (info->first_gp_reg_save > 11);
+- 
+-               emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
+-             }
+- 
+-           spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
+-           emit_insn (gen_addsi3 (spe_save_area_ptr, frame_reg_rtx,
+-                                  GEN_INT (info->spe_gp_save_offset + sp_offset)));
+- 
+-           spe_offset = 0;
+-         }
+- 
+-       for (i = 0; i < 32 - info->first_gp_reg_save; i++)
+-         if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
+-           {
+-             rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
+-             rtx offset, addr, mem;
+- 
+-             /* We're doing all this to ensure that the offset fits into
+-                the immediate offset of 'evstdd'.  */
+-             gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
+- 
+-             offset = GEN_INT (reg_size * i + spe_offset);
+-             addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
+-             mem = gen_rtx_MEM (V2SImode, addr);
+- 
+-             insn = emit_move_insn (mem, reg);
+-           
+-             rs6000_frame_related (insn, spe_save_area_ptr,
+-                                   info->spe_gp_save_offset
+-                                   + sp_offset + reg_size * i,
+-                                   offset, const0_rtx);
+-           }
+- 
+-       /* Move the static chain pointer back.  */
+-       if (using_static_chain_p && !spe_regs_addressable_via_sp)
+-         emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
+-     }
+   else if (!WORLD_SAVE_P (info))
+     {
+       int i;
+@@ -16052,7 +16403,8 @@ rs6000_emit_prologue (void)
+                                 (frame_reg_rtx != sp_reg_rtx
+                                  && ((info->altivec_size != 0)
+                                      || (info->vrsave_mask != 0)
+-                                     )));
++                                     )),
++                                FALSE);
+       if (frame_reg_rtx != sp_reg_rtx)
+       rs6000_emit_stack_tie ();
+     }
+@@ -16208,8 +16560,7 @@ rs6000_output_function_prologue (FILE *f
+       && !FP_SAVE_INLINE (info->first_fp_reg_save))
+     fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
+            SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
+-           RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
+-           RESTORE_FP_SUFFIX);
++           RESTORE_FP_PREFIX, info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
+   /* Write .extern for AIX common mode routines, if needed.  */
+   if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
+@@ -16253,6 +16604,54 @@ rs6000_output_function_prologue (FILE *f
+   rs6000_pic_labelno++;
+ }
++/* Reload CR from REG.  */
++
++static void
++rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
++{
++  int count = 0;
++  int i;
++
++  if (using_mfcr_multiple)
++    {
++      for (i = 0; i < 8; i++)
++      if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
++        count++;
++      gcc_assert (count);
++    }
++
++  if (using_mfcr_multiple && count > 1)
++    {
++      rtvec p;
++      int ndx;
++
++      p = rtvec_alloc (count);
++
++      ndx = 0;
++      for (i = 0; i < 8; i++)
++      if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
++        {
++          rtvec r = rtvec_alloc (2);
++          RTVEC_ELT (r, 0) = reg;
++          RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
++          RTVEC_ELT (p, ndx) =
++            gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
++                         gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
++          ndx++;
++        }
++      emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
++      gcc_assert (ndx == count);
++    }
++  else
++    for (i = 0; i < 8; i++)
++      if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
++      {
++        emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
++                                                     CR0_REGNO+i),
++                                        reg));
++      }
++}
++
+ /* Emit function epilogue as insns.
+    At present, dwarf2out_frame_debug_expr doesn't understand
+@@ -16264,10 +16663,13 @@ void
+ rs6000_emit_epilogue (int sibcall)
+ {
+   rs6000_stack_t *info;
++  int restoring_GPRs_inline;
+   int restoring_FPRs_inline;
+   int using_load_multiple;
+   int using_mtcr_multiple;
+   int use_backchain_to_restore_sp;
++  int restore_lr;
++  int strategy;
+   int sp_offset = 0;
+   rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
+   rtx frame_reg_rtx = sp_reg_rtx;
+@@ -16283,15 +16685,11 @@ rs6000_emit_epilogue (int sibcall)
+       reg_size = 8;
+     }
+-  using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
+-                       && (!TARGET_SPE_ABI
+-                           || info->spe_64bit_regs_used == 0)
+-                       && info->first_gp_reg_save < 31
+-                       && no_global_regs_above (info->first_gp_reg_save));
+-  restoring_FPRs_inline = (sibcall
+-                         || current_function_calls_eh_return
+-                         || info->first_fp_reg_save == 64
+-                         || FP_SAVE_INLINE (info->first_fp_reg_save));
++  strategy = rs6000_savres_strategy (info, /*savep=*/false,
++                                   /*static_chain_p=*/0, sibcall);
++  using_load_multiple = strategy & SAVRES_MULTIPLE;
++  restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
++  restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
+   use_backchain_to_restore_sp = (frame_pointer_needed
+                                || current_function_calls_alloca
+                                || info->total_size > 32767);
+@@ -16299,6 +16697,10 @@ rs6000_emit_epilogue (int sibcall)
+                        || rs6000_cpu == PROCESSOR_PPC603
+                        || rs6000_cpu == PROCESSOR_PPC750
+                        || optimize_size);
++  restore_lr = (info->lr_save_p
++              && (restoring_GPRs_inline
++                  || (restoring_FPRs_inline
++                      && info->first_fp_reg_save < 64)));
+   if (WORLD_SAVE_P (info))
+     {
+@@ -16537,8 +16939,9 @@ rs6000_emit_epilogue (int sibcall)
+       emit_insn (generate_set_vrsave (reg, info, 1));
+     }
+-  /* Get the old lr if we saved it.  */
+-  if (info->lr_save_p)
++  /* Get the old lr if we saved it.  If we are restoring registers
++     out-of-line, then the out-of-line routines can do this for us.  */
++  if (restore_lr && restoring_GPRs_inline)
+     {
+       rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
+                                     info->lr_save_offset + sp_offset);
+@@ -16557,7 +16960,7 @@ rs6000_emit_epilogue (int sibcall)
+     }
+   /* Set LR here to try to overlap restores below.  */
+-  if (info->lr_save_p)
++  if (restore_lr && restoring_GPRs_inline)
+     emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
+                   gen_rtx_REG (Pmode, 0));
+@@ -16593,35 +16996,17 @@ rs6000_emit_epilogue (int sibcall)
+   /* Restore GPRs.  This is done as a PARALLEL if we are using
+      the load-multiple instructions.  */
+-  if (using_load_multiple)
+-    {
+-      rtvec p;
+-      p = rtvec_alloc (32 - info->first_gp_reg_save);
+-      for (i = 0; i < 32 - info->first_gp_reg_save; i++)
+-      {
+-        rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+-                                 GEN_INT (info->gp_save_offset
+-                                          + sp_offset
+-                                          + reg_size * i));
+-        rtx mem = gen_frame_mem (reg_mode, addr);
+-
+-        RTVEC_ELT (p, i) =
+-          gen_rtx_SET (VOIDmode,
+-                       gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
+-                       mem);
+-      }
+-      emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
+-    }
+-  else if (TARGET_SPE_ABI
+-           && info->spe_64bit_regs_used != 0
+-           && info->first_gp_reg_save != 32)
++  if (TARGET_SPE_ABI
++      && info->spe_64bit_regs_used != 0
++      && info->first_gp_reg_save != 32)
+     {
+       /* Determine whether we can address all of the registers that need
+          to be saved with an offset from the stack pointer that fits in
+          the small const field for SPE memory instructions.  */
+       int spe_regs_addressable_via_sp
+-        = SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
+-                              + (32 - info->first_gp_reg_save - 1) * reg_size);
++      = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
++                             + (32 - info->first_gp_reg_save - 1) * reg_size)
++         && restoring_GPRs_inline);
+       int spe_offset;
+       if (spe_regs_addressable_via_sp)
+@@ -16633,10 +17018,17 @@ rs6000_emit_epilogue (int sibcall)
+              not clobbering it when we were saving registers in the prologue.
+              There's no need to worry here because the static chain is passed
+              anew to every function.  */
++        int ool_adjust = (restoring_GPRs_inline
++                          ? 0
++                          : (info->first_gp_reg_save
++                             - (FIRST_SAVRES_REGISTER+1))*8);
++
+         if (frame_reg_rtx == sp_reg_rtx)
+           frame_reg_rtx = gen_rtx_REG (Pmode, 11);
+           emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
+-                                 GEN_INT (info->spe_gp_save_offset + sp_offset)));
++                               GEN_INT (info->spe_gp_save_offset
++                                        + sp_offset
++                                        - ool_adjust)));
+         /* Keep the invariant that frame_reg_rtx + sp_offset points
+            at the top of the stack frame.  */
+         sp_offset = -info->spe_gp_save_offset;
+@@ -16644,26 +17036,80 @@ rs6000_emit_epilogue (int sibcall)
+           spe_offset = 0;
+         }
+-      for (i = 0; i < 32 - info->first_gp_reg_save; i++)
+-        if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
+-          {
+-            rtx offset, addr, mem;
++      if (restoring_GPRs_inline)
++      {
++        for (i = 0; i < 32 - info->first_gp_reg_save; i++)
++          if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
++            {
++              rtx offset, addr, mem;
+-            /* We're doing all this to ensure that the immediate offset
+-               fits into the immediate field of 'evldd'.  */
+-            gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
+-
+-            offset = GEN_INT (spe_offset + reg_size * i);
+-            addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
+-            mem = gen_rtx_MEM (V2SImode, addr);
++              /* We're doing all this to ensure that the immediate offset
++                 fits into the immediate field of 'evldd'.  */
++              gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
++
++              offset = GEN_INT (spe_offset + reg_size * i);
++              addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
++              mem = gen_rtx_MEM (V2SImode, addr);
+-            emit_move_insn (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
+-                            mem);
+-          }
++              emit_move_insn (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
++                              mem);
++            }
++      }
++      else
++      {
++        rtx par;
++
++        par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
++                                      0, reg_mode,
++                                      /*savep=*/false, /*gpr=*/true,
++                                      /*exitp=*/true);
++        emit_jump_insn (par);
++
++        /* We don't want anybody else emitting things after we jumped
++           back.  */
++        return;
++      }
+     }
+-  else
+-    for (i = 0; i < 32 - info->first_gp_reg_save; i++)
+-      if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
++  else if (!restoring_GPRs_inline)
++    {
++      /* We are jumping to an out-of-line function.  */
++      bool can_use_exit = info->first_fp_reg_save == 64;
++      rtx par;
++
++      /* Emit stack reset code if we need it.  */
++      if (can_use_exit)
++      rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
++                               sp_offset, can_use_exit);
++      else
++      emit_insn (gen_addsi3 (gen_rtx_REG (Pmode, 11),
++                             sp_reg_rtx,
++                             GEN_INT (sp_offset - info->fp_size)));
++
++      par = rs6000_make_savres_rtx (info, frame_reg_rtx,
++                                  info->gp_save_offset, reg_mode,
++                                  /*savep=*/false, /*gpr=*/true,
++                                  /*exitp=*/can_use_exit);
++
++      if (can_use_exit)
++      {
++        if (info->cr_save_p)
++          rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12),
++                                   using_mtcr_multiple);
++
++        emit_jump_insn (par);
++
++        /* We don't want anybody else emitting things after we jumped
++           back.  */
++        return;
++      }
++      else
++      emit_insn (par);
++    }
++  else if (using_load_multiple)
++    {
++      rtvec p;
++      p = rtvec_alloc (32 - info->first_gp_reg_save);
++      for (i = 0; i < 32 - info->first_gp_reg_save; i++)
+       {
+         rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+                                  GEN_INT (info->gp_save_offset
+@@ -16671,9 +17117,40 @@ rs6000_emit_epilogue (int sibcall)
+                                           + reg_size * i));
+         rtx mem = gen_frame_mem (reg_mode, addr);
+-        emit_move_insn (gen_rtx_REG (reg_mode,
+-                                     info->first_gp_reg_save + i), mem);
++        RTVEC_ELT (p, i) =
++          gen_rtx_SET (VOIDmode,
++                       gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
++                       mem);
+       }
++      emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
++    }
++  else
++    {
++      for (i = 0; i < 32 - info->first_gp_reg_save; i++)
++        if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
++        {
++            rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
++                                     GEN_INT (info->gp_save_offset
++                                              + sp_offset
++                                              + reg_size * i));
++            rtx mem = gen_frame_mem (reg_mode, addr);
++
++            emit_move_insn (gen_rtx_REG (reg_mode,
++                                         info->first_gp_reg_save + i), mem);
++          }
++    }
++
++  if (restore_lr && !restoring_GPRs_inline)
++    {
++      rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
++                                    info->lr_save_offset + sp_offset);
++
++      emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
++    }
++
++  if (restore_lr && !restoring_GPRs_inline)
++    emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
++                  gen_rtx_REG (Pmode, 0));
+   /* Restore fpr's if we need to do it without calling a function.  */
+   if (restoring_FPRs_inline)
+@@ -16695,69 +17172,12 @@ rs6000_emit_epilogue (int sibcall)
+   /* If we saved cr, restore it here.  Just those that were used.  */
+   if (info->cr_save_p)
+-    {
+-      rtx r12_rtx = gen_rtx_REG (SImode, 12);
+-      int count = 0;
+-
+-      if (using_mtcr_multiple)
+-      {
+-        for (i = 0; i < 8; i++)
+-          if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
+-            count++;
+-        gcc_assert (count);
+-      }
+-
+-      if (using_mtcr_multiple && count > 1)
+-      {
+-        rtvec p;
+-        int ndx;
+-
+-        p = rtvec_alloc (count);
+-
+-        ndx = 0;
+-        for (i = 0; i < 8; i++)
+-          if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
+-            {
+-              rtvec r = rtvec_alloc (2);
+-              RTVEC_ELT (r, 0) = r12_rtx;
+-              RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
+-              RTVEC_ELT (p, ndx) =
+-                gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
+-                             gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
+-              ndx++;
+-            }
+-        emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
+-        gcc_assert (ndx == count);
+-      }
+-      else
+-      for (i = 0; i < 8; i++)
+-        if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
+-          {
+-            emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
+-                                                         CR0_REGNO+i),
+-                                            r12_rtx));
+-          }
+-    }
++    rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12), using_mtcr_multiple);
+   /* If this is V.4, unwind the stack pointer after all of the loads
+      have been done.  */
+-  if (frame_reg_rtx != sp_reg_rtx)
+-    {
+-      /* This blockage is needed so that sched doesn't decide to move
+-       the sp change before the register restores.  */
+-      rs6000_emit_stack_tie ();
+-      if (sp_offset != 0)
+-        emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx,
+-                             GEN_INT (sp_offset)));
+-      else
+-        emit_move_insn (sp_reg_rtx, frame_reg_rtx);
+-    }
+-  else if (sp_offset != 0)
+-    emit_insn (TARGET_32BIT
+-             ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
+-                           GEN_INT (sp_offset))
+-             : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
+-                           GEN_INT (sp_offset)));
++  rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
++                         sp_offset, !restoring_FPRs_inline);
+   if (current_function_calls_eh_return)
+     {
+@@ -16771,30 +17191,30 @@ rs6000_emit_epilogue (int sibcall)
+     {
+       rtvec p;
+       if (! restoring_FPRs_inline)
+-      p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
++      p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
+       else
+       p = rtvec_alloc (2);
+       RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
+-      RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
+-                                    gen_rtx_REG (Pmode,
+-                                                 LR_REGNO));
++      RTVEC_ELT (p, 1) = (restoring_FPRs_inline
++                        ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
++                        : gen_rtx_CLOBBER (VOIDmode,
++                                           gen_rtx_REG (Pmode, 65)));
+       /* If we have to restore more than two FP registers, branch to the
+        restore function.  It will return to our caller.  */
+       if (! restoring_FPRs_inline)
+       {
+         int i;
+-        char rname[30];
+-        const char *alloc_rname;
+-
+-        sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
+-                 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
+-        alloc_rname = ggc_strdup (rname);
+-        RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
+-                                        gen_rtx_SYMBOL_REF (Pmode,
+-                                                            alloc_rname));
++        rtx sym;
++        sym = rs6000_savres_routine_sym (info,
++                                         /*savep=*/false,
++                                         /*gpr=*/false,
++                                         /*exitp=*/true);
++        RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
++        RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
++                                        gen_rtx_REG (Pmode, 11));
+         for (i = 0; i < 64 - info->first_fp_reg_save; i++)
+           {
+             rtx addr, mem;
+@@ -16802,7 +17222,7 @@ rs6000_emit_epilogue (int sibcall)
+                                  GEN_INT (info->fp_save_offset + 8*i));
+             mem = gen_frame_mem (DFmode, addr);
+-            RTVEC_ELT (p, i+3) =
++            RTVEC_ELT (p, i+4) =
+               gen_rtx_SET (VOIDmode,
+                            gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
+                            mem);
+@@ -18611,6 +19031,9 @@ rs6000_issue_rate (void)
+   case CPU_PPC7400:
+   case CPU_PPC8540:
+   case CPU_CELL:
++  case CPU_PPCE300C2:
++  case CPU_PPCE300C3:
++  case CPU_PPCE500MC:
+     return 2;
+   case CPU_RIOS2:
+   case CPU_PPC604:
+@@ -21814,8 +22237,8 @@ rs6000_function_value (const_tree valtyp
+          && ALTIVEC_VECTOR_MODE (mode))
+     regno = ALTIVEC_ARG_RETURN;
+   else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
+-         && (mode == DFmode || mode == DDmode || mode == DCmode
+-             || mode == TFmode || mode == TDmode || mode == TCmode))
++         && (mode == DFmode || mode == DCmode
++             || mode == TFmode || mode == TCmode))
+     return spe_build_register_parallel (mode, GP_ARG_RETURN);
+   else
+     regno = GP_ARG_RETURN;
+@@ -21856,8 +22279,8 @@ rs6000_libcall_value (enum machine_mode 
+   else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
+     return rs6000_complex_function_value (mode);
+   else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
+-         && (mode == DFmode || mode == DDmode || mode == DCmode
+-             || mode == TFmode || mode == TDmode || mode == TCmode))
++         && (mode == DFmode || mode == DCmode
++             || mode == TFmode || mode == TCmode))
+     return spe_build_register_parallel (mode, GP_ARG_RETURN);
+   else
+     regno = GP_ARG_RETURN;
+@@ -21904,19 +22327,22 @@ rs6000_is_opaque_type (const_tree type)
+ {
+   return (type == opaque_V2SI_type_node
+             || type == opaque_V2SF_type_node
+-            || type == opaque_p_V2SI_type_node
+             || type == opaque_V4SI_type_node);
+ }
+ static rtx
+ rs6000_dwarf_register_span (rtx reg)
+ {
+-  unsigned regno;
++  rtx parts[8];
++  int i, words;
++  unsigned regno = REGNO (reg);
++  enum machine_mode mode = GET_MODE (reg);
+   if (TARGET_SPE
++      && regno < 32
+       && (SPE_VECTOR_MODE (GET_MODE (reg))
+-        || (TARGET_E500_DOUBLE
+-            && (GET_MODE (reg) == DFmode || GET_MODE (reg) == DDmode))))
++        || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
++            && mode != SFmode && mode != SDmode && mode != SCmode)))
+     ;
+   else
+     return NULL_RTX;
+@@ -21926,15 +22352,23 @@ rs6000_dwarf_register_span (rtx reg)
+   /* The duality of the SPE register size wreaks all kinds of havoc.
+      This is a way of distinguishing r0 in 32-bits from r0 in
+      64-bits.  */
+-  return
+-    gen_rtx_PARALLEL (VOIDmode,
+-                    BYTES_BIG_ENDIAN
+-                    ? gen_rtvec (2,
+-                                 gen_rtx_REG (SImode, regno + 1200),
+-                                 gen_rtx_REG (SImode, regno))
+-                    : gen_rtvec (2,
+-                                 gen_rtx_REG (SImode, regno),
+-                                 gen_rtx_REG (SImode, regno + 1200)));
++  words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
++  gcc_assert (words <= 4);
++  for (i = 0; i < words; i++, regno++)
++    {
++      if (BYTES_BIG_ENDIAN)
++      {
++        parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
++        parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
++      }
++      else
++      {
++        parts[2 * i] = gen_rtx_REG (SImode, regno);
++        parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
++      }
++    }
++
++  return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
+ }
+ /* Fill in sizes for SPE register high parts in table used by unwinder.  */
+--- a/gcc/config/rs6000/rs6000.h
++++ b/gcc/config/rs6000/rs6000.h
+@@ -117,6 +117,9 @@
+ %{mcpu=G5: -mpower4 -maltivec} \
+ %{mcpu=8540: -me500} \
+ %{mcpu=8548: -me500} \
++%{mcpu=e300c2: -mppc} \
++%{mcpu=e300c3: -mppc -mpmr} \
++%{mcpu=e500mc: -me500mc} \
+ %{maltivec: -maltivec} \
+ -many"
+@@ -262,6 +265,9 @@ enum processor_type
+    PROCESSOR_PPC7400,
+    PROCESSOR_PPC7450,
+    PROCESSOR_PPC8540,
++   PROCESSOR_PPCE300C2,
++   PROCESSOR_PPCE300C3,
++   PROCESSOR_PPCE500MC,
+    PROCESSOR_POWER4,
+    PROCESSOR_POWER5,
+    PROCESSOR_POWER6,
+@@ -313,12 +319,15 @@ enum group_termination
+   };
+ /* Support for a compile-time default CPU, et cetera.  The rules are:
+-   --with-cpu is ignored if -mcpu is specified.
++   --with-cpu is ignored if -mcpu is specified; likewise --with-cpu32
++     and --with-cpu64.
+    --with-tune is ignored if -mtune is specified.
+    --with-float is ignored if -mhard-float or -msoft-float are
+     specified.  */
+ #define OPTION_DEFAULT_SPECS \
+-  {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }, \
++  {"cpu", "%{mcpu=*|te500mc|te500v1|te500v2|te600:;:-mcpu=%(VALUE)}" }, \
++  {"cpu32", "%{m64|mcpu=*|te500mc|te500v1|te500v2|te600:;:-mcpu=%(VALUE)}" }, \
++  {"cpu64", "%{m32|mcpu=*|te500mc|te500v1|te500v2|te600:;:-mcpu=%(VALUE)}" }, \
+   {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
+   {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }
+@@ -349,6 +358,8 @@ extern int rs6000_long_double_type_size;
+ extern int rs6000_ieeequad;
+ extern int rs6000_altivec_abi;
+ extern int rs6000_spe_abi;
++extern int rs6000_spe;
++extern int rs6000_isel;
+ extern int rs6000_float_gprs;
+ extern int rs6000_alignment_flags;
+ extern const char *rs6000_sched_insert_nops_str;
+@@ -378,7 +389,7 @@ extern enum rs6000_nop_insertion rs6000_
+ #define TARGET_SPE_ABI 0
+ #define TARGET_SPE 0
+ #define TARGET_E500 0
+-#define TARGET_ISEL 0
++#define TARGET_ISEL rs6000_isel
+ #define TARGET_FPRS 1
+ #define TARGET_E500_SINGLE 0
+ #define TARGET_E500_DOUBLE 0
+@@ -561,7 +572,7 @@ extern enum rs6000_nop_insertion rs6000_
+ #define LOCAL_ALIGNMENT(TYPE, ALIGN)                          \
+   ((TARGET_ALTIVEC && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 :        \
+     (TARGET_E500_DOUBLE                                               \
+-     && (TYPE_MODE (TYPE) == DFmode || TYPE_MODE (TYPE) == DDmode)) ? 64 : \
++     && TYPE_MODE (TYPE) == DFmode) ? 64 : \
+     ((TARGET_SPE && TREE_CODE (TYPE) == VECTOR_TYPE \
+      && SPE_VECTOR_MODE (TYPE_MODE (TYPE))) || (TARGET_PAIRED_FLOAT \
+         && TREE_CODE (TYPE) == VECTOR_TYPE \
+@@ -587,7 +598,7 @@ extern enum rs6000_nop_insertion rs6000_
+    fit into 1, whereas DI still needs two.  */
+ #define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) \
+   ((TARGET_SPE && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
+-   || (TARGET_E500_DOUBLE && ((MODE) == DFmode || (MODE) == DDmode)))
++   || (TARGET_E500_DOUBLE && (MODE) == DFmode))
+ /* A bit-field declared as `int' forces `int' alignment for the struct.  */
+ #define PCC_BITFIELD_TYPE_MATTERS 1
+@@ -596,6 +607,7 @@ extern enum rs6000_nop_insertion rs6000_
+    Make vector constants quadword aligned.  */
+ #define CONSTANT_ALIGNMENT(EXP, ALIGN)                           \
+   (TREE_CODE (EXP) == STRING_CST                               \
++   && (STRICT_ALIGNMENT || !optimize_size)                     \
+    && (ALIGN) < BITS_PER_WORD                                    \
+    ? BITS_PER_WORD                                               \
+    : (ALIGN))
+@@ -607,7 +619,7 @@ extern enum rs6000_nop_insertion rs6000_
+   (TREE_CODE (TYPE) == VECTOR_TYPE ? ((TARGET_SPE_ABI \
+    || TARGET_PAIRED_FLOAT) ? 64 : 128)        \
+    : (TARGET_E500_DOUBLE                      \
+-      && (TYPE_MODE (TYPE) == DFmode || TYPE_MODE (TYPE) == DDmode)) ? 64 \
++      && TYPE_MODE (TYPE) == DFmode) ? 64 \
+    : TREE_CODE (TYPE) == ARRAY_TYPE           \
+    && TYPE_MODE (TREE_TYPE (TYPE)) == QImode  \
+    && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
+@@ -731,8 +743,8 @@ extern enum rs6000_nop_insertion rs6000_
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,        \
+    /* AltiVec registers.  */                     \
+-   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+-   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
++   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
++   1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    1, 1                                                  \
+    , 1, 1, 1                                       \
+ }
+@@ -750,8 +762,8 @@ extern enum rs6000_nop_insertion rs6000_
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,        \
+    /* AltiVec registers.  */                     \
+-   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+-   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
++   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
++   1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    0, 0                                                  \
+    , 0, 0, 0                                       \
+ }
+@@ -1189,7 +1201,7 @@ enum reg_class
+  (((CLASS) == FLOAT_REGS)                                             \
+   ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
+   : (TARGET_E500_DOUBLE && (CLASS) == GENERAL_REGS                    \
+-     && ((MODE) == DFmode || (MODE) == DDmode))                               \
++     && (MODE) == DFmode)                             \
+   ? 1                                                                   \
+   : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+--- a/gcc/config/rs6000/rs6000.md
++++ b/gcc/config/rs6000/rs6000.md
+@@ -133,7 +133,7 @@
+ ;; Processor type -- this attribute must exactly match the processor_type
+ ;; enumeration in rs6000.h.
+-(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,power4,power5,power6,cell"
++(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,power4,power5,power6,cell"
+   (const (symbol_ref "rs6000_cpu_attr")))
+@@ -166,6 +166,8 @@
+ (include "7xx.md")
+ (include "7450.md")
+ (include "8540.md")
++(include "e300c2c3.md")
++(include "e500mc.md")
+ (include "power4.md")
+ (include "power5.md")
+ (include "power6.md")
+@@ -8887,7 +8889,7 @@
+   rtx label = gen_label_rtx ();
+   if (TARGET_E500_DOUBLE)
+     {
+-      if (flag_unsafe_math_optimizations)
++      if (flag_finite_math_only && !flag_trapping_math)
+       emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
+       else
+       emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
+@@ -11642,7 +11644,7 @@
+ (define_expand "bltgt"
+   [(use (match_operand 0 "" ""))]
+-  ""
++  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
+   "{ rs6000_emit_cbranch (LTGT, operands[0]); DONE; }")
+ ;; For SNE, we would prefer that the xor/abs sequence be used for integers.
+@@ -11776,7 +11778,7 @@
+ (define_expand "sltgt"
+   [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+-  ""
++  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
+   "{ rs6000_emit_sCOND (LTGT, operands[0]); DONE; }")
+ (define_expand "stack_protect_set"
+@@ -12084,7 +12086,7 @@
+ (define_insn "move_from_CR_gt_bit"
+   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+       (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
+-  "TARGET_E500"
++  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+   "mfcr %0\;{rlinm|rlwinm} %0,%0,%D1,31,31"
+   [(set_attr "type" "mfcr")
+    (set_attr "length" "8")])
+@@ -14469,10 +14471,23 @@
+   "{stm|stmw} %2,%1"
+   [(set_attr "type" "store_ux")])
++(define_insn "*save_gpregs_<mode>"
++  [(match_parallel 0 "any_parallel_operand"
++                 [(clobber (reg:P 65))
++                  (use (match_operand:P 1 "symbol_ref_operand" "s"))
++                    (use (reg:P 11))
++                  (set (match_operand:P 2 "memory_operand" "=m")
++                       (match_operand:P 3 "gpc_reg_operand" "r"))])]
++  ""
++  "bl %z1"
++  [(set_attr "type" "branch")
++   (set_attr "length" "4")])
++
+ (define_insn "*save_fpregs_<mode>"
+   [(match_parallel 0 "any_parallel_operand"
+                  [(clobber (reg:P 65))
+-                  (use (match_operand:P 1 "call_operand" "s"))
++                  (use (match_operand:P 1 "symbol_ref_operand" "s"))
++                    (use (reg:P 11))
+                   (set (match_operand:DF 2 "memory_operand" "=m")
+                        (match_operand:DF 3 "gpc_reg_operand" "f"))])]
+   ""
+@@ -14562,15 +14577,43 @@
+ ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
+ ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
++(define_insn "*restore_gpregs_<mode>"
++ [(match_parallel 0 "any_parallel_operand"
++                  [(clobber (match_operand:P 1 "register_operand" "=l"))
++                   (use (match_operand:P 2 "symbol_ref_operand" "s"))
++                   (use (reg:P 11))
++                 (set (match_operand:P 3 "gpc_reg_operand" "=r")
++                      (match_operand:P 4 "memory_operand" "m"))])]
++ ""
++ "bl %z2"
++ [(set_attr "type" "branch")
++  (set_attr "length" "4")])
++
++(define_insn "*return_and_restore_gpregs_<mode>"
++ [(match_parallel 0 "any_parallel_operand"
++                  [(return)
++                 (clobber (match_operand:P 1 "register_operand" "=l"))
++                 (use (match_operand:P 2 "symbol_ref_operand" "s"))
++                   (use (reg:P 11))
++                 (set (match_operand:P 3 "gpc_reg_operand" "=r")
++                      (match_operand:P 4 "memory_operand" "m"))])]
++ ""
++ "b %z2"
++ [(set_attr "type" "branch")
++  (set_attr "length" "4")])
++
+ (define_insn "*return_and_restore_fpregs_<mode>"
+  [(match_parallel 0 "any_parallel_operand"
+                   [(return)
+-                 (use (reg:P 65))
+-                 (use (match_operand:P 1 "call_operand" "s"))
+-                 (set (match_operand:DF 2 "gpc_reg_operand" "=f")
+-                      (match_operand:DF 3 "memory_operand" "m"))])]
++                 (clobber (match_operand:P 1 "register_operand" "=l"))
++                 (use (match_operand:P 2 "symbol_ref_operand" "s"))
++                   (use (reg:P 11))
++                 (set (match_operand:DF 3 "gpc_reg_operand" "=f")
++                      (match_operand:DF 4 "memory_operand" "m"))])]
+  ""
+- "b %z1")
++ "b %z2"
++ [(set_attr "type" "branch")
++  (set_attr "length" "4")])
+ ; This is used in compiling the unwind routines.
+ (define_expand "eh_return"
+@@ -14617,6 +14660,120 @@
+ }"
+   [(set_attr "type" "load")])
\f
++;;; Expanders for vector insn patterns shared between the SPE and TARGET_PAIRED systems.
++
++(define_expand "absv2sf2"
++  [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
++      (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")))]
++  "TARGET_PAIRED_FLOAT || TARGET_SPE"
++  "
++{
++  if (TARGET_SPE)
++    {
++      /* We need to make a note that we clobber SPEFSCR.  */
++      emit_insn (gen_rtx_SET (VOIDmode, operands[0],
++                              gen_rtx_ABS (V2SFmode, operands[1])));
++      emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO)));
++      DONE;
++    }
++}")
++
++(define_expand "negv2sf2"
++  [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
++      (neg:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")))]
++  "TARGET_PAIRED_FLOAT || TARGET_SPE"
++  "
++{
++  if (TARGET_SPE)
++    {
++      /* We need to make a note that we clobber SPEFSCR.  */
++      emit_insn (gen_rtx_SET (VOIDmode, operands[0],
++                              gen_rtx_NEG (V2SFmode, operands[1])));
++      emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO)));
++      DONE;
++    }
++}")
++
++(define_expand "addv2sf3"
++  [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
++      (plus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")
++                 (match_operand:V2SF 2 "gpc_reg_operand" "")))]
++  "TARGET_PAIRED_FLOAT || TARGET_SPE"
++  "
++{
++  if (TARGET_SPE)
++    {
++      /* We need to make a note that we clobber SPEFSCR.  */
++      rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
++
++      XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0],
++                                         gen_rtx_PLUS (V2SFmode, operands[1], operands[2]));
++      XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO));
++      emit_insn (par);
++      DONE;
++    }
++}")
++
++(define_expand "subv2sf3"
++  [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
++      (minus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")
++                  (match_operand:V2SF 2 "gpc_reg_operand" "")))]
++  "TARGET_PAIRED_FLOAT || TARGET_SPE"
++  "
++{
++  if (TARGET_SPE)
++    {
++      /* We need to make a note that we clobber SPEFSCR.  */
++      rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
++
++      XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0],
++                                         gen_rtx_MINUS (V2SFmode, operands[1], operands[2]));
++      XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO));
++      emit_insn (par);
++      DONE;
++    }
++}")
++
++(define_expand "mulv2sf3"
++  [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
++      (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")
++                 (match_operand:V2SF 2 "gpc_reg_operand" "")))]
++  "TARGET_PAIRED_FLOAT || TARGET_SPE"
++  "
++{
++  if (TARGET_SPE)
++    {
++      /* We need to make a note that we clobber SPEFSCR.  */
++      rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
++
++      XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0],
++                                         gen_rtx_MULT (V2SFmode, operands[1], operands[2]));
++      XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO));
++      emit_insn (par);
++      DONE;
++    }
++}")
++
++(define_expand "divv2sf3"
++  [(set (match_operand:V2SF 0 "gpc_reg_operand" "")
++      (div:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")
++                (match_operand:V2SF 2 "gpc_reg_operand" "")))]
++  "TARGET_PAIRED_FLOAT || TARGET_SPE"
++  "
++{
++  if (TARGET_SPE)
++    {
++      /* We need to make a note that we clobber SPEFSCR.  */
++      rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
++
++      XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0],
++                                         gen_rtx_DIV (V2SFmode, operands[1], operands[2]));
++      XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO));
++      emit_insn (par);
++      DONE;
++    }
++}")
++\f
+ (include "sync.md")
+ (include "altivec.md")
+--- a/gcc/config/rs6000/rs6000.opt
++++ b/gcc/config/rs6000/rs6000.opt
+@@ -190,7 +190,7 @@ Target RejectNegative Joined
+ -mvrsave=yes/no       Deprecated option.  Use -mvrsave/-mno-vrsave instead
+ misel
+-Target Var(rs6000_isel)
++Target
+ Generate isel instructions
+ misel=
+@@ -198,7 +198,7 @@ Target RejectNegative Joined
+ -misel=yes/no Deprecated option.  Use -misel/-mno-isel instead
+ mspe
+-Target Var(rs6000_spe)
++Target
+ Generate SPE SIMD instructions on E500
+ mpaired
+--- a/gcc/config/rs6000/sol-ci.asm
++++ b/gcc/config/rs6000/sol-ci.asm
+@@ -36,7 +36,6 @@
+ # This file just supplies labeled starting points for the .got* and other
+ # special sections.  It is linked in first before other modules.
+  
+-      .file   "scrti.s"
+       .ident  "GNU C scrti.s"
+ #ifndef __powerpc64__
+--- a/gcc/config/rs6000/sol-cn.asm
++++ b/gcc/config/rs6000/sol-cn.asm
+@@ -36,7 +36,6 @@
+ # This file just supplies labeled ending points for the .got* and other
+ # special sections.  It is linked in last after other modules.
+  
+-      .file   "scrtn.s"
+       .ident  "GNU C scrtn.s"
+ #ifndef __powerpc64__
+--- a/gcc/config/rs6000/spe.md
++++ b/gcc/config/rs6000/spe.md
+@@ -164,7 +164,7 @@
+ ;; SPE SIMD instructions
+-(define_insn "spe_evabs"
++(define_insn "absv2si2"
+   [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
+       (abs:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")))]
+   "TARGET_SPE"
+@@ -181,7 +181,7 @@
+   [(set_attr "type" "vecsimple")
+    (set_attr  "length" "4")])
+-(define_insn "spe_evand"
++(define_insn "andv2si3"
+   [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
+         (and:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")
+                 (match_operand:V2SI 2 "gpc_reg_operand" "r")))]
+@@ -1898,7 +1898,7 @@
+   [(set_attr "type" "veccomplex")
+    (set_attr  "length" "4")])
+-(define_insn "spe_evaddw"
++(define_insn "addv2si3"
+   [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
+         (plus:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")
+                  (match_operand:V2SI 2 "gpc_reg_operand" "r")))]
+@@ -2028,7 +2028,7 @@
+   [(set_attr "type" "veccomplex")
+    (set_attr  "length" "4")])
+-(define_insn "spe_evdivws"
++(define_insn "divv2si3"
+   [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
+         (div:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")
+                 (match_operand:V2SI 2 "gpc_reg_operand" "r")))
+@@ -2933,7 +2933,8 @@
+        [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+                       (match_operand:SF 2 "gpc_reg_operand" "r"))]
+        1000))]
+-  "TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
++  "TARGET_HARD_FLOAT && !TARGET_FPRS
++   && !(flag_finite_math_only && !flag_trapping_math)"
+   "efscmpeq %0,%1,%2"
+   [(set_attr "type" "veccmp")])
+@@ -2943,7 +2944,8 @@
+        [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+                       (match_operand:SF 2 "gpc_reg_operand" "r"))]
+        1001))]
+-  "TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
++  "TARGET_HARD_FLOAT && !TARGET_FPRS
++   && flag_finite_math_only && !flag_trapping_math"
+   "efststeq %0,%1,%2"
+   [(set_attr "type" "veccmpsimple")])
+@@ -2953,7 +2955,8 @@
+        [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+                       (match_operand:SF 2 "gpc_reg_operand" "r"))]
+        1002))]
+-  "TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
++  "TARGET_HARD_FLOAT && !TARGET_FPRS
++   && !(flag_finite_math_only && !flag_trapping_math)"
+   "efscmpgt %0,%1,%2"
+   [(set_attr "type" "veccmp")])
+@@ -2963,7 +2966,8 @@
+        [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+                       (match_operand:SF 2 "gpc_reg_operand" "r"))]
+        1003))]
+-  "TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
++  "TARGET_HARD_FLOAT && !TARGET_FPRS
++   && flag_finite_math_only && !flag_trapping_math"
+   "efststgt %0,%1,%2"
+   [(set_attr "type" "veccmpsimple")])
+@@ -2973,7 +2977,8 @@
+        [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+                       (match_operand:SF 2 "gpc_reg_operand" "r"))]
+        1004))]
+-  "TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
++  "TARGET_HARD_FLOAT && !TARGET_FPRS
++   && !(flag_finite_math_only && !flag_trapping_math)"
+   "efscmplt %0,%1,%2"
+   [(set_attr "type" "veccmp")])
+@@ -2983,7 +2988,8 @@
+        [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+                       (match_operand:SF 2 "gpc_reg_operand" "r"))]
+        1005))]
+-  "TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
++  "TARGET_HARD_FLOAT && !TARGET_FPRS
++   && flag_finite_math_only && !flag_trapping_math"
+   "efststlt %0,%1,%2"
+   [(set_attr "type" "veccmpsimple")])
+@@ -2995,7 +3001,8 @@
+        [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
+                       (match_operand:DF 2 "gpc_reg_operand" "r"))]
+        CMPDFEQ_GPR))]
+-  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && !flag_unsafe_math_optimizations"
++  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE
++   && !(flag_finite_math_only && !flag_trapping_math)"
+   "efdcmpeq %0,%1,%2"
+   [(set_attr "type" "veccmp")])
+@@ -3005,7 +3012,8 @@
+        [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
+                       (match_operand:DF 2 "gpc_reg_operand" "r"))]
+        TSTDFEQ_GPR))]
+-  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && flag_unsafe_math_optimizations"
++  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE
++   && flag_finite_math_only && !flag_trapping_math"
+   "efdtsteq %0,%1,%2"
+   [(set_attr "type" "veccmpsimple")])
+@@ -3015,7 +3023,8 @@
+        [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
+                       (match_operand:DF 2 "gpc_reg_operand" "r"))]
+        CMPDFGT_GPR))]
+-  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && !flag_unsafe_math_optimizations"
++  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE
++   && !(flag_finite_math_only && !flag_trapping_math)"
+   "efdcmpgt %0,%1,%2"
+   [(set_attr "type" "veccmp")])
+@@ -3025,7 +3034,8 @@
+        [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
+                       (match_operand:DF 2 "gpc_reg_operand" "r"))]
+        TSTDFGT_GPR))]
+-  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && flag_unsafe_math_optimizations"
++  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE
++   && flag_finite_math_only && !flag_trapping_math"
+   "efdtstgt %0,%1,%2"
+   [(set_attr "type" "veccmpsimple")])
+@@ -3035,7 +3045,8 @@
+        [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
+                       (match_operand:DF 2 "gpc_reg_operand" "r"))]
+        CMPDFLT_GPR))]
+-  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && !flag_unsafe_math_optimizations"
++  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE
++   && !(flag_finite_math_only && !flag_trapping_math)"
+   "efdcmplt %0,%1,%2"
+   [(set_attr "type" "veccmp")])
+@@ -3045,7 +3056,8 @@
+        [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
+                       (match_operand:DF 2 "gpc_reg_operand" "r"))]
+        TSTDFLT_GPR))]
+-  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && flag_unsafe_math_optimizations"
++  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE
++   && flag_finite_math_only && !flag_trapping_math"
+   "efdtstlt %0,%1,%2"
+   [(set_attr "type" "veccmpsimple")])
+@@ -3059,7 +3071,7 @@
+        CMPTFEQ_GPR))]
+   "!TARGET_IEEEQUAD
+    && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
+-   && !flag_unsafe_math_optimizations"
++   && !(flag_finite_math_only && !flag_trapping_math)"
+   "efdcmpeq %0,%1,%2\;bng %0,$+8\;efdcmpeq %0,%L1,%L2"
+   [(set_attr "type" "veccmp")
+    (set_attr "length" "12")])
+@@ -3072,7 +3084,7 @@
+        TSTTFEQ_GPR))]
+   "!TARGET_IEEEQUAD
+    && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
+-   && flag_unsafe_math_optimizations"
++   && flag_finite_math_only && !flag_trapping_math"
+   "efdtsteq %0,%1,%2\;bng %0,$+8\;efdtsteq %0,%L1,%L2"
+   [(set_attr "type" "veccmpsimple")
+    (set_attr "length" "12")])
+@@ -3085,7 +3097,7 @@
+        CMPTFGT_GPR))]
+   "!TARGET_IEEEQUAD
+    && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
+-   && !flag_unsafe_math_optimizations"
++   && !(flag_finite_math_only && !flag_trapping_math)"
+   "efdcmpgt %0,%1,%2\;bgt %0,$+16\;efdcmpeq %0,%1,%2\;bng %0,$+8\;efdcmpgt %0,%L1,%L2"
+   [(set_attr "type" "veccmp")
+    (set_attr "length" "20")])
+@@ -3098,7 +3110,7 @@
+        TSTTFGT_GPR))]
+   "!TARGET_IEEEQUAD
+    && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
+-   && flag_unsafe_math_optimizations"
++   && flag_finite_math_only && !flag_trapping_math"
+   "efdtstgt %0,%1,%2\;bgt %0,$+16\;efdtsteq %0,%1,%2\;bng %0,$+8\;efdtstgt %0,%L1,%L2"
+   [(set_attr "type" "veccmpsimple")
+    (set_attr "length" "20")])
+@@ -3111,7 +3123,7 @@
+        CMPTFLT_GPR))]
+   "!TARGET_IEEEQUAD
+    && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
+-   && !flag_unsafe_math_optimizations"
++   && !(flag_finite_math_only && !flag_trapping_math)"
+   "efdcmplt %0,%1,%2\;bgt %0,$+16\;efdcmpeq %0,%1,%2\;bng %0,$+8\;efdcmplt %0,%L1,%L2"
+   [(set_attr "type" "veccmp")
+    (set_attr "length" "20")])
+@@ -3124,7 +3136,7 @@
+        TSTTFLT_GPR))]
+   "!TARGET_IEEEQUAD
+    && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
+-   && flag_unsafe_math_optimizations"
++   && flag_finite_math_only && !flag_trapping_math"
+   "efdtstlt %0,%1,%2\;bgt %0,$+16\;efdtsteq %0,%1,%2\;bng %0,$+8\;efdtstlt %0,%L1,%L2"
+   [(set_attr "type" "veccmpsimple")
+    (set_attr "length" "20")])
+@@ -3135,6 +3147,44 @@
+       (unspec:CCFP [(match_operand 1 "cc_reg_operand" "y")
+                     (match_operand 2 "cc_reg_operand" "y")]
+                    E500_CR_IOR_COMPARE))]
+-  "TARGET_E500"
++  "TARGET_HARD_FLOAT && !TARGET_FPRS"
+   "cror 4*%0+gt,4*%1+gt,4*%2+gt"
+   [(set_attr "type" "cr_logical")])
++
++;; Out-of-line prologues and epilogues.
++(define_insn "*save_gpregs_spe"
++  [(match_parallel 0 "any_parallel_operand"
++                 [(clobber (reg:P 65))
++                  (use (match_operand:P 1 "symbol_ref_operand" "s"))
++                  (use (reg:P 11))
++                  (set (match_operand:V2SI 2 "memory_operand" "=m")
++                       (match_operand:V2SI 3 "gpc_reg_operand" "r"))])]
++  "TARGET_SPE_ABI"
++  "bl %z1"
++  [(set_attr "type" "branch")
++   (set_attr "length" "4")])
++
++(define_insn "*restore_gpregs_spe"
++ [(match_parallel 0 "any_parallel_operand"
++                [(clobber (reg:P 65))
++                 (use (match_operand:P 1 "symbol_ref_operand" "s"))
++                 (use (reg:P 11))
++                 (set (match_operand:V2SI 2 "gpc_reg_operand" "=r")
++                      (match_operand:V2SI 3 "memory_operand" "m"))])]
++ "TARGET_SPE_ABI"
++ "bl %z1"
++ [(set_attr "type" "branch")
++  (set_attr "length" "4")])
++
++(define_insn "*return_and_restore_gpregs_spe"
++ [(match_parallel 0 "any_parallel_operand"
++                [(return)
++                 (clobber (reg:P 65))
++                 (use (match_operand:P 1 "symbol_ref_operand" "s"))
++                 (use (reg:P 11))
++                 (set (match_operand:V2SI 2 "gpc_reg_operand" "=r")
++                      (match_operand:V2SI 3 "memory_operand" "m"))])]
++ "TARGET_SPE_ABI"
++ "b %z1"
++ [(set_attr "type" "branch")
++  (set_attr "length" "4")])
+--- a/gcc/config/rs6000/sysv4.h
++++ b/gcc/config/rs6000/sysv4.h
+@@ -266,19 +266,27 @@ do {                                                                     \
+ #endif
+ /* Define cutoff for using external functions to save floating point.
+-   Currently on V.4, always use inline stores.  */
+-#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64)
++   Currently on 64-bit V.4, always use inline stores.  When optimizing
++   for size on 32-bit targets, use external functions when
++   profitable.  */
++#define FP_SAVE_INLINE(FIRST_REG) (optimize_size && !TARGET_64BIT     \
++                                 ? ((FIRST_REG) == 62                 \
++                                    || (FIRST_REG) == 63)             \
++                                 : (FIRST_REG) < 64)
++/* And similarly for general purpose registers.  */
++#define GP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 32   \
++                                 && (TARGET_64BIT || !optimize_size))
+ /* Put jump tables in read-only memory, rather than in .text.  */
+ #define JUMP_TABLES_IN_TEXT_SECTION 0
+ /* Prefix and suffix to use to saving floating point.  */
+ #define       SAVE_FP_PREFIX "_savefpr_"
+-#define SAVE_FP_SUFFIX "_l"
++#define SAVE_FP_SUFFIX (TARGET_64BIT ? "_l" : "")
+ /* Prefix and suffix to use to restoring floating point.  */
+ #define       RESTORE_FP_PREFIX "_restfpr_"
+-#define RESTORE_FP_SUFFIX "_l"
++#define RESTORE_FP_SUFFIX (TARGET_64BIT ? "_l" : "")
+ /* Type used for ptrdiff_t, as a string used in a declaration.  */
+ #define PTRDIFF_TYPE "int"
+@@ -577,9 +585,9 @@ extern int fixuplabelno;
+ /* Override svr4.h definition.  */
+ #undef        ASM_SPEC
+ #define       ASM_SPEC "%(asm_cpu) \
+-%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}} \
+-%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
+-%{mrelocatable} %{mrelocatable-lib} %{fpic|fpie|fPIC|fPIE:-K PIC} \
++%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}}" \
++SVR4_ASM_SPEC \
++"%{mrelocatable} %{mrelocatable-lib} %{fpic|fpie|fPIC|fPIE:-K PIC} \
+ %{memb|msdata|msdata=eabi: -memb} \
+ %{mlittle|mlittle-endian:-mlittle; \
+   mbig|mbig-endian      :-mbig;    \
+@@ -606,6 +614,9 @@ extern int fixuplabelno;
+ #define CC1_SECURE_PLT_DEFAULT_SPEC ""
+ #endif
++#undef CC1_EXTRA_SPEC
++#define CC1_EXTRA_SPEC ""
++
+ /* Pass -G xxx to the compiler and set correct endian mode.  */
+ #define       CC1_SPEC "%{G*} %(cc1_cpu) \
+ %{mlittle|mlittle-endian: %(cc1_endian_little);           \
+@@ -630,7 +641,7 @@ extern int fixuplabelno;
+ %{msdata: -msdata=default} \
+ %{mno-sdata: -msdata=none} \
+ %{!mbss-plt: %{!msecure-plt: %(cc1_secure_plt_default)}} \
+-%{profile: -p}"
++%{profile: -p}" CC1_EXTRA_SPEC
+ /* Don't put -Y P,<path> for cross compilers.  */
+ #ifndef CROSS_DIRECTORY_STRUCTURE
+@@ -777,19 +788,19 @@ extern int fixuplabelno;
+ /* Override svr4.h definition.  */
+ #undef        ENDFILE_SPEC
+ #define       ENDFILE_SPEC "\
+-%{mads         : crtsavres.o%s        %(endfile_ads)         ; \
+-  myellowknife : crtsavres.o%s        %(endfile_yellowknife) ; \
+-  mmvme        : crtsavres.o%s        %(endfile_mvme)        ; \
+-  msim         : crtsavres.o%s        %(endfile_sim)         ; \
++%{mads         : %(endfile_ads)         ; \
++  myellowknife : %(endfile_yellowknife) ; \
++  mmvme        : %(endfile_mvme)        ; \
++  msim         : %(endfile_sim)         ; \
+   mwindiss     :                      %(endfile_windiss)     ; \
+-  mcall-freebsd: crtsavres.o%s        %(endfile_freebsd)     ; \
+-  mcall-linux  : crtsavres.o%s        %(endfile_linux)       ; \
+-  mcall-gnu    : crtsavres.o%s        %(endfile_gnu)         ; \
+-  mcall-netbsd : crtsavres.o%s        %(endfile_netbsd)      ; \
+-  mcall-openbsd: crtsavres.o%s        %(endfile_openbsd)     ; \
++  mcall-freebsd: %(endfile_freebsd)     ; \
++  mcall-linux  : %(endfile_linux)       ; \
++  mcall-gnu    : %(endfile_gnu)         ; \
++  mcall-netbsd : %(endfile_netbsd)      ; \
++  mcall-openbsd: %(endfile_openbsd)     ; \
+                : %(crtsavres_default) %(endfile_default)     }"
+-#define CRTSAVRES_DEFAULT_SPEC "crtsavres.o%s"
++#define CRTSAVRES_DEFAULT_SPEC ""
+ #define       ENDFILE_DEFAULT_SPEC "crtend.o%s ecrtn.o%s"
+@@ -833,15 +844,15 @@ extern int fixuplabelno;
+ #define CPP_OS_MVME_SPEC ""
+ /* PowerPC simulator based on netbsd system calls support.  */
+-#define LIB_SIM_SPEC "--start-group -lsim -lc --end-group"
++#define LIB_SIM_SPEC LIB_DEFAULT_SPEC
+-#define       STARTFILE_SIM_SPEC "ecrti.o%s sim-crt0.o%s crtbegin.o%s"
++#define       STARTFILE_SIM_SPEC "ecrti.o%s crtbegin.o%s"
+-#define       ENDFILE_SIM_SPEC "crtend.o%s ecrtn.o%s"
++#define       ENDFILE_SIM_SPEC "crtend.o%s ecrtn.o%s -Tsim-hosted.ld"
+ #define LINK_START_SIM_SPEC ""
+-#define LINK_OS_SIM_SPEC "-m elf32ppcsim"
++#define LINK_OS_SIM_SPEC ""
+ #define CPP_OS_SIM_SPEC ""
+--- /dev/null
++++ b/gcc/config/rs6000/t-cs-eabi
+@@ -0,0 +1,17 @@
++# Multilibs for powerpc embedded ELF targets.
++
++MULTILIB_OPTIONS      = te500v1/te500v2/te600/te500mc \
++                        msoft-float
++
++MULTILIB_DIRNAMES     = te500v1 te500v2 te600 te500mc \
++                        nof
++
++MULTILIB_EXCEPTIONS   = *te600*/*msoft-float* \
++                        *te500v1*/*msoft-float* \
++                        *te500v2*/*msoft-float* \
++                        *te500mc*/*msoft-float*
++
++MULTILIB_EXTRA_OPTS   = mno-eabi mstrict-align
++
++MULTILIB_MATCHES      = ${MULTILIB_MATCHES_FLOAT} \
++                        ${MULTILIB_MATCHES_ENDIAN}
+--- /dev/null
++++ b/gcc/config/rs6000/t-linux
+@@ -0,0 +1,12 @@
++# Multilibs for powerpc-linux-gnu targets.
++
++MULTILIB_OPTIONS      = te500v1/te500v2/te600/te500mc \
++                        msoft-float
++
++MULTILIB_DIRNAMES     = te500v1 te500v2 te600 te500mc \
++                        nof
++
++MULTILIB_EXCEPTIONS   = *te600*/*msoft-float* \
++                        *te500v1*/*msoft-float* \
++                        *te500v2*/*msoft-float* \
++                        *te500mc*/*msoft-float*
+--- /dev/null
++++ b/gcc/config/rs6000/t-montavista-linux
+@@ -0,0 +1,26 @@
++# MontaVista GNU/Linux Configuration.
++# Copyright (C) 2009
++# Free Software Foundation, Inc.
++#
++# This file is part of GCC.
++#
++# GCC is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3, or (at your option)
++# any later version.
++# 
++# GCC is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with GCC; see the file COPYING3.  If not see
++# <http://www.gnu.org/licenses/>.
++
++# Build hard-float, soft-float, E500mc, E500v2 and E600
++# libraries.
++MULTILIB_OPTIONS = msoft-float/te500mc/te500v2/te600
++MULTILIB_DIRNAMES = soft-float te500mc te500v2 te600
++MULTILIB_EXCEPTIONS =
++MULTILIB_OSDIRNAMES = msoft-float=!soft-float
+--- a/gcc/config/rs6000/t-netbsd
++++ b/gcc/config/rs6000/t-netbsd
+@@ -2,13 +2,32 @@
+ LIB2FUNCS_EXTRA = tramp.S
++LIB2FUNCS_STATIC_EXTRA = crtsavfpr.S crtresfpr.S \
++  crtsavgpr.S crtresgpr.S \
++  crtresxfpr.S crtresxgpr.S
++
+ tramp.S: $(srcdir)/config/rs6000/tramp.asm
+       cat $(srcdir)/config/rs6000/tramp.asm > tramp.S
+-crtsavres.S: $(srcdir)/config/rs6000/crtsavres.asm
+-      cat $(srcdir)/config/rs6000/crtsavres.asm >crtsavres.S
++crtsavfpr.S: $(srcdir)/config/rs6000/crtsavfpr.asm
++      cat $(srcdir)/config/rs6000/crtsavfpr.asm >crtsavfpr.S
++
++crtresfpr.S: $(srcdir)/config/rs6000/crtresfpr.asm
++      cat $(srcdir)/config/rs6000/crtresfpr.asm >crtresfpr.S
++
++crtsavgpr.S: $(srcdir)/config/rs6000/crtsavgpr.asm
++      cat $(srcdir)/config/rs6000/crtsavgpr.asm >crtsavgpr.S
++
++crtresgpr.S: $(srcdir)/config/rs6000/crtresgpr.asm
++      cat $(srcdir)/config/rs6000/crtresgpr.asm >crtresgpr.S
++
++crtresxfpr.S: $(srcdir)/config/rs6000/crtresxfpr.asm
++      cat $(srcdir)/config/rs6000/crtresxfpr.asm >crtresxfpr.S
++
++crtresxgpr.S: $(srcdir)/config/rs6000/crtresxgpr.asm
++      cat $(srcdir)/config/rs6000/crtresxgpr.asm >crtresxgpr.S
+-EXTRA_PARTS += crtsavres$(objext)
++EXTRA_PARTS += libcrtsavres.a
+ # It is important that crtbegin.o, etc., aren't surprised by stuff in .sdata.
+ CRTSTUFF_T_CFLAGS += -msdata=none
+@@ -37,6 +56,20 @@ EXTRA_MULTILIB_PARTS = crtbegin$(objext)
+   crtbeginS$(objext) crtendS$(objext) crtbeginT$(objext) \
+   crtsavres$(objext)
+-$(T)crtsavres$(objext): crtsavres.S
+-      $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \
+-        -c crtsavres.S -o $(T)crtsavres$(objext)
++$(T)crtsavfpr$(objext): crtsavfpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtsavfpr.S -o $(T)crtsavfpr$(objext)
++
++$(T)crtresfpr$(objext): crtresfpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresfpr.S -o $(T)crtresfpr$(objext)
++
++$(T)crtsavgpr$(objext): crtsavgpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtsavgpr.S -o $(T)crtsavgpr$(objext)
++
++$(T)crtresgpr$(objext): crtresgpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresgpr.S -o $(T)crtresgpr$(objext)
++
++$(T)crtresxfpr$(objext): crtresxfpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresxfpr.S -o $(T)crtresxfpr$(objext)
++
++$(T)crtresxgpr$(objext): crtresxgpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresxgpr.S -o $(T)crtresxgpr$(objext)
+--- /dev/null
++++ b/gcc/config/rs6000/t-ppc-e500mc
+@@ -0,0 +1,12 @@
++# Multilibs for powerpc embedded ELF targets.
++
++MULTILIB_OPTIONS      = 
++
++MULTILIB_DIRNAMES     = 
++
++MULTILIB_EXCEPTIONS   = 
++
++MULTILIB_EXTRA_OPTS   = mno-eabi mstrict-align
++
++MULTILIB_MATCHES      = ${MULTILIB_MATCHES_FLOAT} \
++                        ${MULTILIB_MATCHES_ENDIAN}
+--- a/gcc/config/rs6000/t-ppccomm
++++ b/gcc/config/rs6000/t-ppccomm
+@@ -2,11 +2,24 @@
+ LIB2FUNCS_EXTRA += tramp.S $(srcdir)/config/rs6000/darwin-ldouble.c
+-# This one can't end up in shared libgcc
+-LIB2FUNCS_STATIC_EXTRA = eabi.S
+-
+-eabi.S: $(srcdir)/config/rs6000/eabi.asm
+-      cat $(srcdir)/config/rs6000/eabi.asm > eabi.S
++# These can't end up in shared libgcc
++LIB2FUNCS_STATIC_EXTRA = \
++  crtsavfpr.S crtresfpr.S \
++  crtsavgpr.S crtresgpr.S \
++  crtresxfpr.S crtresxgpr.S \
++  e500crtres32gpr.S \
++  e500crtres64gpr.S \
++  e500crtres64gprctr.S \
++  e500crtrest32gpr.S \
++  e500crtrest64gpr.S \
++  e500crtresx32gpr.S \
++  e500crtresx64gpr.S \
++  e500crtsav32gpr.S \
++  e500crtsav64gpr.S \
++  e500crtsav64gprctr.S \
++  e500crtsavg32gpr.S \
++  e500crtsavg64gpr.S \
++  e500crtsavg64gprctr.S
+ tramp.S: $(srcdir)/config/rs6000/tramp.asm
+       cat $(srcdir)/config/rs6000/tramp.asm > tramp.S
+@@ -18,8 +31,7 @@ MULTILIB_MATCHES_SYSV        = mcall-sysv=mcall
+ EXTRA_MULTILIB_PARTS = crtbegin$(objext) crtend$(objext) \
+   crtbeginS$(objext) crtendS$(objext) crtbeginT$(objext) \
+   ecrti$(objext) ecrtn$(objext) \
+-  ncrti$(objext) ncrtn$(objext) \
+-  crtsavres$(objext)
++  ncrti$(objext) ncrtn$(objext)
+ # We build {e,n}crti.o and {e,n}crtn.o, which serve to add begin and
+ # end labels to all of the special sections used when we link using gcc.
+@@ -37,8 +49,62 @@ ncrti.S: $(srcdir)/config/rs6000/sol-ci.
+ ncrtn.S: $(srcdir)/config/rs6000/sol-cn.asm
+       cat $(srcdir)/config/rs6000/sol-cn.asm >ncrtn.S
+-crtsavres.S: $(srcdir)/config/rs6000/crtsavres.asm
+-      cat $(srcdir)/config/rs6000/crtsavres.asm >crtsavres.S
++crtsavfpr.S: $(srcdir)/config/rs6000/crtsavfpr.asm
++      cat $(srcdir)/config/rs6000/crtsavfpr.asm >crtsavfpr.S
++
++crtresfpr.S: $(srcdir)/config/rs6000/crtresfpr.asm
++      cat $(srcdir)/config/rs6000/crtresfpr.asm >crtresfpr.S
++
++crtsavgpr.S: $(srcdir)/config/rs6000/crtsavgpr.asm
++      cat $(srcdir)/config/rs6000/crtsavgpr.asm >crtsavgpr.S
++
++crtresgpr.S: $(srcdir)/config/rs6000/crtresgpr.asm
++      cat $(srcdir)/config/rs6000/crtresgpr.asm >crtresgpr.S
++
++crtresxfpr.S: $(srcdir)/config/rs6000/crtresxfpr.asm
++      cat $(srcdir)/config/rs6000/crtresxfpr.asm >crtresxfpr.S
++
++crtresxgpr.S: $(srcdir)/config/rs6000/crtresxgpr.asm
++      cat $(srcdir)/config/rs6000/crtresxgpr.asm >crtresxgpr.S
++
++e500crtres32gpr.S: $(srcdir)/config/rs6000/e500crtres32gpr.asm
++      cat $(srcdir)/config/rs6000/e500crtres32gpr.asm >e500crtres32gpr.S
++
++e500crtres64gpr.S: $(srcdir)/config/rs6000/e500crtres64gpr.asm
++      cat $(srcdir)/config/rs6000/e500crtres64gpr.asm >e500crtres64gpr.S
++
++e500crtres64gprctr.S: $(srcdir)/config/rs6000/e500crtres64gprctr.asm
++      cat $(srcdir)/config/rs6000/e500crtres64gprctr.asm >e500crtres64gprctr.S
++
++e500crtrest32gpr.S: $(srcdir)/config/rs6000/e500crtrest32gpr.asm
++      cat $(srcdir)/config/rs6000/e500crtrest32gpr.asm >e500crtrest32gpr.S
++
++e500crtrest64gpr.S: $(srcdir)/config/rs6000/e500crtrest64gpr.asm
++      cat $(srcdir)/config/rs6000/e500crtrest64gpr.asm >e500crtrest64gpr.S
++
++e500crtresx32gpr.S: $(srcdir)/config/rs6000/e500crtresx32gpr.asm
++      cat $(srcdir)/config/rs6000/e500crtresx32gpr.asm >e500crtresx32gpr.S
++
++e500crtresx64gpr.S: $(srcdir)/config/rs6000/e500crtresx64gpr.asm
++      cat $(srcdir)/config/rs6000/e500crtresx64gpr.asm >e500crtresx64gpr.S
++
++e500crtsav32gpr.S: $(srcdir)/config/rs6000/e500crtsav32gpr.asm
++      cat $(srcdir)/config/rs6000/e500crtsav32gpr.asm >e500crtsav32gpr.S
++
++e500crtsav64gpr.S: $(srcdir)/config/rs6000/e500crtsav64gpr.asm
++      cat $(srcdir)/config/rs6000/e500crtsav64gpr.asm >e500crtsav64gpr.S
++
++e500crtsav64gprctr.S: $(srcdir)/config/rs6000/e500crtsav64gprctr.asm
++      cat $(srcdir)/config/rs6000/e500crtsav64gprctr.asm >e500crtsav64gprctr.S
++
++e500crtsavg32gpr.S: $(srcdir)/config/rs6000/e500crtsavg32gpr.asm
++      cat $(srcdir)/config/rs6000/e500crtsavg32gpr.asm >e500crtsavg32gpr.S
++
++e500crtsavg64gpr.S: $(srcdir)/config/rs6000/e500crtsavg64gpr.asm
++      cat $(srcdir)/config/rs6000/e500crtsavg64gpr.asm >e500crtsavg64gpr.S
++
++e500crtsavg64gprctr.S: $(srcdir)/config/rs6000/e500crtsavg64gprctr.asm
++      cat $(srcdir)/config/rs6000/e500crtsavg64gprctr.asm >e500crtsavg64gprctr.S
+ # Build multiple copies of ?crt{i,n}.o, one for each target switch.
+ $(T)ecrti$(objext): ecrti.S
+@@ -53,8 +119,62 @@ $(T)ncrti$(objext): ncrti.S
+ $(T)ncrtn$(objext): ncrtn.S
+       $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c ncrtn.S -o $(T)ncrtn$(objext)
+-$(T)crtsavres$(objext): crtsavres.S
+-      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtsavres.S -o $(T)crtsavres$(objext)
++$(T)crtsavfpr$(objext): crtsavfpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtsavfpr.S -o $(T)crtsavfpr$(objext)
++
++$(T)crtresfpr$(objext): crtresfpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresfpr.S -o $(T)crtresfpr$(objext)
++
++$(T)crtsavgpr$(objext): crtsavgpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtsavgpr.S -o $(T)crtsavgpr$(objext)
++
++$(T)crtresgpr$(objext): crtresgpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresgpr.S -o $(T)crtresgpr$(objext)
++
++$(T)crtresxfpr$(objext): crtresxfpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresxfpr.S -o $(T)crtresxfpr$(objext)
++
++$(T)crtresxgpr$(objext): crtresxgpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtresxgpr.S -o $(T)crtresxgpr$(objext)
++
++$(T)e500crtres32gpr$(objext): e500crtres32gpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtres32gpr.S -o $(T)e500crtres32gpr$(objext)
++
++$(T)e500crtres64gpr$(objext): e500crtres64gpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtres64gpr.S -o $(T)e500crtres64gpr$(objext)
++
++$(T)e500crtres64gprctr$(objext): e500crtres64gprctr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtres64gprctr.S -o $(T)e500crtres64gprctr$(objext)
++
++$(T)e500crtrest32gpr$(objext): e500crtrest32gpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtrest32gpr.S -o $(T)e500crtrest32gpr$(objext)
++
++$(T)e500crtrest64gpr$(objext): e500crtrest64gpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtrest64gpr.S -o $(T)e500crtrest64gpr$(objext)
++
++$(T)e500crtresx32gpr$(objext): e500crtresx32gpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtresx32gpr.S -o $(T)e500crtresx32gpr$(objext)
++
++$(T)e500crtresx64gpr$(objext): e500crtresx64gpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtresx64gpr.S -o $(T)e500crtresx64gpr$(objext)
++
++$(T)e500crtsav32gpr$(objext): e500crtsav32gpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsav32gpr.S -o $(T)e500crtsav32gpr$(objext)
++
++$(T)e500crtsav64gpr$(objext): e500crtsav64gpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsav64gpr.S -o $(T)e500crtsav64gpr$(objext)
++
++$(T)e500crtsav64gprctr$(objext): e500crtsav64gprctr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsav64gprctr.S -o $(T)e500crtsav64gprctr$(objext)
++
++$(T)e500crtsavg32gpr$(objext): e500crtsavg32gpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsavg32gpr.S -o $(T)e500crtsavg32gpr$(objext)
++
++$(T)e500crtsavg64gpr$(objext): e500crtsavg64gpr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsavg64gpr.S -o $(T)e500crtsavg64gpr$(objext)
++
++$(T)e500crtsavg64gprctr$(objext): e500crtsavg64gprctr.S
++      $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c e500crtsavg64gprctr.S -o $(T)e500crtsavg64gprctr$(objext)
+ # It is important that crtbegin.o, etc., aren't surprised by stuff in .sdata.
+ CRTSTUFF_T_CFLAGS = -msdata=none
+--- a/gcc/config/rs6000/t-ppcgas
++++ b/gcc/config/rs6000/t-ppcgas
+@@ -1,14 +1,16 @@
+ # Multilibs for powerpc embedded ELF targets.
+-MULTILIB_OPTIONS      = msoft-float \
+-                        mlittle/mbig \
+-                        fleading-underscore
++MULTILIB_OPTIONS      = te500v1/te500v2/te600 \
++                        msoft-float
+-MULTILIB_DIRNAMES     = nof \
+-                        le be \
+-                        und
++MULTILIB_DIRNAMES     = te500v1 te500v2 te600 \
++                        nof
+-MULTILIB_EXTRA_OPTS   = mrelocatable-lib mno-eabi mstrict-align
++MULTILIB_EXCEPTIONS   = *te600*/*msoft-float* \
++                        *te500v1*/*msoft-float* \
++                        *te500v2*/*msoft-float*
++
++MULTILIB_EXTRA_OPTS   = mno-eabi mstrict-align
+ MULTILIB_MATCHES      = ${MULTILIB_MATCHES_FLOAT} \
+                         ${MULTILIB_MATCHES_ENDIAN}
+--- /dev/null
++++ b/gcc/config/rs6000/t-timesys
+@@ -0,0 +1,17 @@
++# Overrides for timesys
++
++# We want to build six multilibs:
++# .           (default, -mcpu=740)
++# 4xx         (-mcpu=405)
++# 44x         (-mcpu=440)
++# 8xx         (-mcpu=801)
++# 85xx                (-te500v1)
++# 74xx                (-te600)
++
++MULTILIB_OPTIONS = mcpu=405/mcpu=440/mcpu=801/te500v1/te600
++
++MULTILIB_DIRNAMES = 4xx 44x 8xx 85xx 74xx
++
++MULTILIB_MATCHES = 
++
++MULTILIB_EXCEPTIONS = 
+--- /dev/null
++++ b/gcc/config/rs6000/t-wrs-linux
+@@ -0,0 +1,30 @@
++# Wind River GNU/Linux Configuration.
++# Copyright (C) 2006, 2007
++# Free Software Foundation, Inc.
++#
++# This file is part of GCC.
++#
++# GCC is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3, or (at your option)
++# any later version.
++# 
++# GCC is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with GCC; see the file COPYING3.  If not see
++# <http://www.gnu.org/licenses/>.
++
++# Build hard-float (32-bit and 64-bit), soft-float, E500v1 and E500v2
++# libraries.
++MULTILIB_OPTIONS = muclibc m64 msoft-float te500v1 te500v2
++MULTILIB_DIRNAMES = uclibc 64 soft-float te500v1 te500v2
++MULTILIB_EXCEPTIONS = *muclibc*/*m64* *muclibc*/*msoft-float*
++MULTILIB_EXCEPTIONS += *muclibc*/*te500v1* *muclibc*/*te500v2*
++MULTILIB_EXCEPTIONS += *m64*/*msoft-float* *m64*/*te500v1* *m64*/*te500v2*
++MULTILIB_EXCEPTIONS += *msoft-float*/*te500v1* *msoft-float*/*te500v2*
++MULTILIB_EXCEPTIONS += *te500v1*/*te500v2*
++MULTILIB_OSDIRNAMES = muclibc=!uclibc m64=../lib64 msoft-float=!soft-float
+--- /dev/null
++++ b/gcc/config/rs6000/timesys-linux.h
+@@ -0,0 +1,41 @@
++/* Configuration file for timesys ARM GNU/Linux EABI targets.
++   Copyright (C) 2007
++   Free Software Foundation, Inc.
++   Contributed by CodeSourcery, LLC   
++
++   This file is part of GCC.
++
++   GCC is free software; you can redistribute it and/or modify it
++   under the terms of the GNU General Public License as published
++   by the Free Software Foundation; either version 3, or (at your
++   option) any later version.
++
++   GCC is distributed in the hope that it will be useful, but WITHOUT
++   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
++   License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with GCC; see the file COPYING3.  If not see
++   <http://www.gnu.org/licenses/>.  */
++
++/* Add -t flags for convenience in generating multilibs.  */
++#undef CC1_EXTRA_SPEC
++#define CC1_EXTRA_SPEC \
++  "%{te500v1: -mcpu=8540 -mfloat-gprs=single -mspe=yes -mabi=spe} "   \
++  "%{te600: -mcpu=7400 -maltivec -mabi=altivec} "
++
++#undef ASM_DEFAULT_SPEC
++#define ASM_DEFAULT_SPEC                      \
++  "%{te500v1:-mppc -mspe -me500 ;             \
++     te600:-mppc -maltivec ;                  \
++     mcpu=405:-m405 ;                         \
++     mcpu=440:-m440 ;                         \
++     :-mppc%{m64:64}}"
++
++
++/* FIXME:We should be dynamically creating this from the makefile.
++   See m68k for an example.  */
++#undef SYSROOT_SUFFIX_SPEC
++#define SYSROOT_SUFFIX_SPEC \
++  "%{mcpu=405:/4xx ; mcpu=440:/44x ; mcpu=801:/8xx ; te500v1:/85xx ; te600:/74xx}"
+--- /dev/null
++++ b/gcc/config/rs6000/wrs-linux.h
+@@ -0,0 +1,44 @@
++/* Wind River GNU/Linux Configuration.
++   Copyright (C) 2006, 2007
++   Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 3, or (at your option)
++any later version.
++
++GCC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++/* Add -te500v1 and -te500v2 options for convenience in generating
++   multilibs.  */
++#undef CC1_EXTRA_SPEC
++#define CC1_EXTRA_SPEC "%{te500v1: -mcpu=8540 -mfloat-gprs=single -mspe=yes -mabi=spe} %{te500v2: -mcpu=8548 -mfloat-gprs=double -mspe=yes -mabi=spe}"
++
++#undef ASM_DEFAULT_SPEC
++#define ASM_DEFAULT_SPEC                      \
++  "%{te500v1:-mppc -mspe -me500 ;             \
++     te500v2:-mppc -mspe -me500 ;             \
++     :-mppc%{m64:64}}"
++
++/* The GLIBC headers are in /usr/include, relative to the sysroot; the
++   uClibc headers are in /uclibc/usr/include.  */
++#undef SYSROOT_HEADERS_SUFFIX_SPEC
++#define SYSROOT_HEADERS_SUFFIX_SPEC           \
++  "%{muclibc:/uclibc}" 
++
++/* The various C libraries each have their own subdirectory.  */
++#undef SYSROOT_SUFFIX_SPEC
++#define SYSROOT_SUFFIX_SPEC                   \
++  "%{muclibc:/uclibc ;                                \
++     msoft-float:/soft-float ;                        \
++     te500v1:/te500v1 ;                               \
++     te500v2:/te500v2}"
+--- /dev/null
++++ b/gcc/config/sh/cs-sgxxlite-linux.h
+@@ -0,0 +1,23 @@
++/* SH SourceryG++ GNU/Linux Configuration.
++   Copyright (C) 2008
++   Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 3, or (at your option)
++any later version.
++
++GCC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++#undef SYSROOT_HEADERS_SUFFIX_SPEC
++#define SYSROOT_HEADERS_SUFFIX_SPEC \
++  "%{muclibc:/uclibc}"
+--- a/gcc/config/sh/lib1funcs.asm
++++ b/gcc/config/sh/lib1funcs.asm
+@@ -2084,8 +2084,9 @@ GLOBAL(ic_invalidate):
+ GLOBAL(ic_invalidate):
+       ocbwb   @r4
+       synco
+-      rts
+       icbi    @r4
++      rts
++        nop
+       ENDFUNC(GLOBAL(ic_invalidate))
+ #elif defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__) || (defined(__SH4_NOFPU__) && !defined(__SH5__))
+       /* For system code, we use ic_invalidate_line_i, but user code
+--- a/gcc/config/sh/linux-unwind.h
++++ b/gcc/config/sh/linux-unwind.h
+@@ -27,7 +27,10 @@ the Free Software Foundation, 51 Frankli
+ Boston, MA 02110-1301, USA.  */
+ /* Do code reading to identify a signal frame, and set the frame
+-   state data appropriately.  See unwind-dw2.c for the structs.  */
++   state data appropriately.  See unwind-dw2.c for the structs.
++   Don't use this at all if inhibit_libc is used.  */
++
++#ifndef inhibit_libc
+ #include <signal.h>
+ #include <sys/ucontext.h>
+@@ -251,3 +254,5 @@ sh_fallback_frame_state (struct _Unwind_
+   return _URC_NO_REASON;
+ }
+ #endif /* defined (__SH5__) */
++
++#endif /* inhibit_libc */
+--- a/gcc/config/sh/t-1e
++++ /dev/null
+@@ -1 +0,0 @@
+-MULTILIB_ENDIAN =
+--- a/gcc/config/sh/t-linux
++++ b/gcc/config/sh/t-linux
+@@ -4,6 +4,5 @@ LIB2FUNCS_EXTRA= $(srcdir)/config/sh/lin
+ MULTILIB_DIRNAMES= 
+ MULTILIB_MATCHES = 
+-MULTILIB_EXCEPTIONS=
+ EXTRA_MULTILIB_PARTS= crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
+--- a/gcc/config/sh/t-mlib-sh1
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh1=m1/
+--- a/gcc/config/sh/t-mlib-sh2
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh2=m2/
+--- a/gcc/config/sh/t-mlib-sh2a
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh2a=m2a/
+--- a/gcc/config/sh/t-mlib-sh2a-nofpu
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh2a_nofpu=m2a-nofpu/
+--- a/gcc/config/sh/t-mlib-sh2a-single
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh2a_single=m2a-single/
+--- a/gcc/config/sh/t-mlib-sh2a-single-only
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh2a_single_only=m2a-single-only/
+--- a/gcc/config/sh/t-mlib-sh2e
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh2e=m2e/
+--- a/gcc/config/sh/t-mlib-sh3
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh3=m3/
+--- a/gcc/config/sh/t-mlib-sh3e
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh3e=m3e/
+--- a/gcc/config/sh/t-mlib-sh4
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh4=m4/
+--- a/gcc/config/sh/t-mlib-sh4-nofpu
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh4_nofpu=m4-nofpu/
+--- a/gcc/config/sh/t-mlib-sh4-single
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh4_single=m4-single/
+--- a/gcc/config/sh/t-mlib-sh4-single-only
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh4_single_only=m4-single-only/
+--- a/gcc/config/sh/t-mlib-sh4a
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh4a=m4a/
+--- a/gcc/config/sh/t-mlib-sh4a-nofpu
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh4a_nofpu=m4a-nofpu/
+--- a/gcc/config/sh/t-mlib-sh4a-single
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh4a_single=m4a-single/
+--- a/gcc/config/sh/t-mlib-sh4a-single-only
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh4a_single_only=m4a-single-only/
+--- a/gcc/config/sh/t-mlib-sh4al
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh4al=m4al/
+--- a/gcc/config/sh/t-mlib-sh5-32media
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh5_32media=m5-32media/
+--- a/gcc/config/sh/t-mlib-sh5-32media-nofpu
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh5_32media_nofpu=m5-32media-nofpu/
+--- a/gcc/config/sh/t-mlib-sh5-64media
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh5_64media=m5-64media/
+--- a/gcc/config/sh/t-mlib-sh5-64media-nofpu
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh5_64media_nofpu=m5-64media-nofpu/
+--- a/gcc/config/sh/t-mlib-sh5-compact
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh5_compact=m5-compact/
+--- a/gcc/config/sh/t-mlib-sh5-compact-nofpu
++++ /dev/null
+@@ -1 +0,0 @@
+-ML_sh5_compact_nofpu=m5-compact-nofpu/
+--- /dev/null
++++ b/gcc/config/sh/t-sgxxlite-linux
+@@ -0,0 +1,3 @@
++MULTILIB_OPTIONS += muclibc
++MULTILIB_OSDIRNAMES += muclibc=!uclibc m4al/muclibc=!m4al/uclibc mb/muclibc=!mb/uclibc
++MULTILIB_EXCEPTIONS += mb/m4al/muclibc
+--- a/gcc/config/sh/t-sh
++++ b/gcc/config/sh/t-sh
+@@ -27,10 +27,10 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
+       echo '#endif'           >> fp-bit.c
+       cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+-MULTILIB_ENDIAN = ml/mb
+-MULTILIB_CPUS= $(ML_sh1)$(ML_sh2a)$(ML_sh2a_nofpu)$(ML_sh2a_single_only)$(ML_sh2a_single)$(ML_sh2e)$(ML_sh2)$(ML_sh3e)$(ML_sh3)$(ML_sh4_nofpu)$(ML_sh4_single_only)$(ML_sh4_single)$(ML_sh4)$(ML_sh4a_nofpu)$(ML_sh4a_single_only)$(ML_sh4a_single)$(ML_sh4a)$(ML_sh5_32media)$(ML_sh5_32media_nofpu)$(ML_sh5_compact)$(ML_sh5_compact_nofpu)$(ML_sh5_64media)$(ML_sh5_64media_nofpu)
++DEFAULT_ENDIAN = $(word 1,$(TM_ENDIAN_CONFIG))
++OTHER_ENDIAN = $(word 2,$(TM_ENDIAN_CONFIG))
+-MULTILIB_OPTIONS= $(MULTILIB_ENDIAN) $(MULTILIB_CPUS:/=)
++MULTILIB_OPTIONS= $(OTHER_ENDIAN) $(TM_MULTILIB_CONFIG)
+ MULTILIB_DIRNAMES= 
+ # The separate entries for m2a-nofpu and m2a-single-only with
+@@ -58,7 +58,34 @@ MULTILIB_MATCHES = $(shell \
+   done)
+ # SH1 only supports big endian.
+-MULTILIB_EXCEPTIONS = ml/m1 ml/m2a*
++MULTILIB_EXCEPTIONS = ml/m1 ml/m2a* $(TM_MULTILIB_EXCEPTIONS_CONFIG)
++
++MULTILIB_OSDIRNAMES = \
++      $(OTHER_ENDIAN)=!$(OTHER_ENDIAN) \
++      m1=!m1 $(OTHER_ENDIAN)/m1=!$(OTHER_ENDIAN)/m1 \
++      m2a=!m2a $(OTHER_ENDIAN)/m2a=!$(OTHER_ENDIAN)/m2a \
++      m2a-nofpu=!m2a-nofpu $(OTHER_ENDIAN)/m2a-nofpu=!$(OTHER_ENDIAN)/m2a-nofpu \
++      m2a-single-only=!m2a-single-only $(OTHER_ENDIAN)/m2a-single-only=!$(OTHER_ENDIAN)/m2a-single-only \
++      m2a-single=!m2a-single $(OTHER_ENDIAN)/m2a-single=!$(OTHER_ENDIAN)/m2a-single \
++      m2e=!m2e $(OTHER_ENDIAN)/m2e=!$(OTHER_ENDIAN)/m2e \
++      m2=!m2 $(OTHER_ENDIAN)/m2=!$(OTHER_ENDIAN)/m2 \
++      m3e=!m3e $(OTHER_ENDIAN)/m3e=!$(OTHER_ENDIAN)/m3e \
++      m3=!m3 $(OTHER_ENDIAN)/m3=!$(OTHER_ENDIAN)/m3 \
++      m4-nofpu=!m4-nofpu $(OTHER_ENDIAN)/m4-nofpu=!$(OTHER_ENDIAN)/m4-nofpu \
++      m4-single-only=!m4-single-only $(OTHER_ENDIAN)/m4-single-only=!$(OTHER_ENDIAN)/m4-single-only \
++      m4-single=!m4-single $(OTHER_ENDIAN)/m4-single=!$(OTHER_ENDIAN)/m4-single \
++      m4=!m4 $(OTHER_ENDIAN)/m4=!$(OTHER_ENDIAN)/m4 \
++      m4a-nofpu=!m4a-nofpu $(OTHER_ENDIAN)/m4a-nofpu=!$(OTHER_ENDIAN)/m4a-nofpu \
++      m4a-single-only=!m4a-single-only $(OTHER_ENDIAN)/m4a-single-only=!$(OTHER_ENDIAN)/m4a-single-only \
++      m4a-single=!m4a-single $(OTHER_ENDIAN)/m4a-single=!$(OTHER_ENDIAN)/m4a-single \
++      m4a=!m4a $(OTHER_ENDIAN)/m4a=!$(OTHER_ENDIAN)/m4a \
++      m4al=!m4al $(OTHER_ENDIAN)/m4al=!$(OTHER_ENDIAN)/m4al \
++      m5-32media=!m5-32media $(OTHER_ENDIAN)/m5-32media=!$(OTHER_ENDIAN)/m5-32media \
++      m5-32media-nofpu=!m5-32media-nofpu $(OTHER_ENDIAN)/m5-32media-nofpu=!$(OTHER_ENDIAN)/m5-32media-nofpu \
++      m5-compact=!m5-compact $(OTHER_ENDIAN)/m5-compact=!$(OTHER_ENDIAN)/m5-compact \
++      m5-compact-nofpu=!m5-compact-nofpu $(OTHER_ENDIAN)/m5-compact-nofpu=!$(OTHER_ENDIAN)/m5-compact-nofpu \
++      m5-64media=!m5-64media $(OTHER_ENDIAN)/m5-64media=!$(OTHER_ENDIAN)/m5-64media \
++      m5-64media-nofpu=!m5-64media-nofpu $(OTHER_ENDIAN)/m5-64media-nofpu=!$(OTHER_ENDIAN)/m5-64media-nofpu
+ LIBGCC = stmp-multilib
+ INSTALL_LIBGCC = install-multilib
+--- a/gcc/config/sol2.h
++++ b/gcc/config/sol2.h
+@@ -123,12 +123,12 @@ along with GCC; see the file COPYING3.  
+    %{YP,*} \
+    %{R*} \
+    %{compat-bsd: \
+-     %{!YP,*:%{p|pg:-Y P,/usr/ucblib:/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \
+-             %{!p:%{!pg:-Y P,/usr/ucblib:/usr/ccs/lib:/usr/lib}}} \
+-             -R /usr/ucblib} \
++     %{!YP,*:%{p|pg:-Y P,%R/usr/ucblib:%R/usr/ccs/lib/libp:%R/usr/lib/libp:%R/usr/ccs/lib:%R/usr/lib} \
++             %{!p:%{!pg:-Y P,%R/usr/ucblib:%R/usr/ccs/lib:%R/usr/lib}}} \
++             -R %R/usr/ucblib} \
+    %{!compat-bsd: \
+-     %{!YP,*:%{p|pg:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \
+-             %{!p:%{!pg:-Y P,/usr/ccs/lib:/usr/lib}}}}"
++     %{!YP,*:%{p|pg:-Y P,%R/usr/ccs/lib/libp:%R/usr/lib/libp:%R/usr/ccs/lib:%R/usr/lib} \
++             %{!p:%{!pg:-Y P,%R/usr/ccs/lib:%R/usr/lib}}}}"
+ #undef LINK_ARCH32_SPEC
+ #define LINK_ARCH32_SPEC LINK_ARCH32_SPEC_BASE
+--- a/gcc/config/sparc/linux64.h
++++ b/gcc/config/sparc/linux64.h
+@@ -49,10 +49,15 @@ along with GCC; see the file COPYING3.  
+    in a Medium/Low code model environment.  */
+ #undef TARGET_DEFAULT
++#ifdef BIARCH_32BIT_DEFAULT
++#define TARGET_DEFAULT \
++  (MASK_APP_REGS + MASK_FPU)
++#else
+ #define TARGET_DEFAULT \
+   (MASK_V9 + MASK_PTR64 + MASK_64BIT /* + MASK_HARD_QUAD */ \
+    + MASK_STACK_BIAS + MASK_APP_REGS + MASK_FPU + MASK_LONG_DOUBLE_128)
+ #endif
++#endif
+ #undef ASM_CPU_DEFAULT_SPEC
+ #define ASM_CPU_DEFAULT_SPEC "-Av9a"
+@@ -167,7 +172,7 @@ along with GCC; see the file COPYING3.  
+   { "link_arch_default", LINK_ARCH_DEFAULT_SPEC },      \
+   { "link_arch",       LINK_ARCH_SPEC },
+-#define LINK_ARCH32_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \
++#define LINK_ARCH32_SPEC "-m elf32_sparc -Y P,%R/usr/lib %{shared:-shared} \
+   %{!shared: \
+     %{!ibcs: \
+       %{!static: \
+@@ -176,7 +181,7 @@ along with GCC; see the file COPYING3.  
+         %{static:-static}}} \
+ "
+-#define LINK_ARCH64_SPEC "-m elf64_sparc -Y P,/usr/lib64 %{shared:-shared} \
++#define LINK_ARCH64_SPEC "-m elf64_sparc -Y P,%R/usr/lib64 %{shared:-shared} \
+   %{!shared: \
+     %{!ibcs: \
+       %{!static: \
+@@ -257,7 +262,7 @@ along with GCC; see the file COPYING3.  
+ #else /* !SPARC_BI_ARCH */
+ #undef LINK_SPEC
+-#define LINK_SPEC "-m elf64_sparc -Y P,/usr/lib64 %{shared:-shared} \
++#define LINK_SPEC "-m elf64_sparc -Y P,%R/usr/lib64 %{shared:-shared} \
+   %{!shared: \
+     %{!ibcs: \
+       %{!static: \
+--- a/gcc/config/sparc/sol2-bi.h
++++ b/gcc/config/sparc/sol2-bi.h
+@@ -172,12 +172,12 @@
+    %{YP,*} \
+    %{R*} \
+    %{compat-bsd: \
+-     %{!YP,*:%{p|pg:-Y P,/usr/ucblib/sparcv9:/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \
+-       %{!p:%{!pg:-Y P,/usr/ucblib/sparcv9:/usr/lib/sparcv9}}} \
+-     -R /usr/ucblib/sparcv9} \
++     %{!YP,*:%{p|pg:-Y P,%R/usr/ucblib/sparcv9:%R/usr/lib/libp/sparcv9:%R/usr/lib/sparcv9} \
++       %{!p:%{!pg:-Y P,%R/usr/ucblib/sparcv9:%R/usr/lib/sparcv9}}} \
++     -R %R/usr/ucblib/sparcv9} \
+    %{!compat-bsd: \
+-     %{!YP,*:%{p|pg:-Y P,/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \
+-       %{!p:%{!pg:-Y P,/usr/lib/sparcv9}}}}"
++     %{!YP,*:%{p|pg:-Y P,%R/usr/lib/libp/sparcv9:%R/usr/lib/sparcv9} \
++       %{!p:%{!pg:-Y P,%R/usr/lib/sparcv9}}}}"
+ #define LINK_ARCH64_SPEC LINK_ARCH64_SPEC_BASE
+--- a/gcc/config/sparc/sparc.c
++++ b/gcc/config/sparc/sparc.c
+@@ -2371,6 +2371,8 @@ emit_soft_tfmode_cvt (enum rtx_code code
+       {
+       case SImode:
+         func = "_Qp_itoq";
++        if (TARGET_ARCH64)
++          operands[1] = gen_rtx_SIGN_EXTEND (DImode, operands[1]);
+         break;
+       case DImode:
+         func = "_Qp_xtoq";
+@@ -2385,6 +2387,8 @@ emit_soft_tfmode_cvt (enum rtx_code code
+       {
+       case SImode:
+         func = "_Qp_uitoq";
++        if (TARGET_ARCH64)
++          operands[1] = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
+         break;
+       case DImode:
+         func = "_Qp_uxtoq";
+@@ -4623,6 +4627,7 @@ function_arg_slotno (const struct sparc_
+     {
+     case MODE_FLOAT:
+     case MODE_COMPLEX_FLOAT:
++    case MODE_VECTOR_INT:
+       if (TARGET_ARCH64 && TARGET_FPU && named)
+       {
+         if (slotno >= SPARC_FP_ARG_MAX)
+@@ -6097,7 +6102,7 @@ void
+ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
+ {
+   const char *qpfunc;
+-  rtx slot0, slot1, result, tem, tem2;
++  rtx slot0, slot1, result, tem, tem2, libfunc;
+   enum machine_mode mode;
+   switch (comparison)
+@@ -6159,7 +6164,8 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, 
+       else
+       slot1 = y;
+-      emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL,
++      libfunc = gen_rtx_SYMBOL_REF (Pmode, qpfunc);
++      emit_library_call (libfunc, LCT_NORMAL,
+                        DImode, 2,
+                        XEXP (slot0, 0), Pmode,
+                        XEXP (slot1, 0), Pmode);
+@@ -6168,7 +6174,8 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, 
+     }
+   else
+     {
+-      emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL,
++      libfunc = gen_rtx_SYMBOL_REF (Pmode, qpfunc);
++      emit_library_call (libfunc, LCT_NORMAL,
+                        SImode, 2,
+                        x, TFmode, y, TFmode);
+@@ -6180,7 +6187,7 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, 
+      register so reload doesn't clobber the value if it needs
+      the return register for a spill reg.  */
+   result = gen_reg_rtx (mode);
+-  emit_move_insn (result, hard_libcall_value (mode));
++  emit_move_insn (result, hard_libcall_value (mode, libfunc));
+   switch (comparison)
+     {
+--- a/gcc/config/svr4.h
++++ b/gcc/config/svr4.h
+@@ -55,7 +55,8 @@ along with GCC; see the file COPYING3.  
+   && strcmp (STR, "Tdata") && strcmp (STR, "Ttext")   \
+   && strcmp (STR, "Tbss"))
+-/* Provide an ASM_SPEC appropriate for svr4.  Here we try to support as
++/* Provide an ASM_SPEC appropriate for svr4.
++   If we're not using GAS, we try to support as
+    many of the specialized svr4 assembler options as seems reasonable,
+    given that there are certain options which we can't (or shouldn't)
+    support directly due to the fact that they conflict with other options
+@@ -74,9 +75,16 @@ along with GCC; see the file COPYING3.  
+    read its stdin.
+ */
+-#undef  ASM_SPEC
+-#define ASM_SPEC \
++#ifdef USE_GAS
++#define SVR4_ASM_SPEC \
++  "%{v:-V} %{Wa,*:%*}"
++#else
++#define SVR4_ASM_SPEC \
+   "%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}"
++#endif
++
++#undef  ASM_SPEC
++#define ASM_SPEC SVR4_ASM_SPEC
+ #define AS_NEEDS_DASH_FOR_PIPED_INPUT
+--- /dev/null
++++ b/gcc/config/t-eglibc
+@@ -0,0 +1,25 @@
++# multilibs  -*- mode:Makefile -*-
++
++MULTILIB_EXCEPTIONS :=
++MULTILIB_MATCHES    :=
++MULTILIB_ALIASES    :=
++
++# For all items in EGLIBC_CONFIGS except for the last one
++# do $1.  For the last one do $2.  The items are separated with ",".
++EGLIBC_AWK = $(shell echo $(EGLIBC_CONFIGS) | $(AWK) \
++      '{ \
++      N=split ($$0, configs, ","); \
++      for (i = 1; i < N; ++i) $1; \
++      $2; \
++      }')
++
++MULTILIB_OPTIONS    := $(call EGLIBC_AWK, \
++      printf ("feglibc=%s/", configs[i]), \
++      printf ("feglibc=%s\n", configs[i]))
++MULTILIB_DIRNAMES   := $(call EGLIBC_AWK, \
++      printf ("%s ", configs[i]), \
++      printf ("%s\n", configs[i]))
++MULTILIB_OSDIRNAMES := $(call EGLIBC_AWK, \
++      printf ("feglibc.%s=!%s ", configs[i], configs[i]), \
++      printf ("feglibc.%s=!%s\n", configs[i], configs[i]))
++
+--- /dev/null
++++ b/gcc/config/t-sysroot-suffix
+@@ -0,0 +1,6 @@
++# Generate SYSROOT_SUFFIX_SPEC from MULTILIB_OSDIRNAMES
++
++sysroot-suffix.h: $(srcdir)/config/print-sysroot-suffix.sh
++      $(SHELL) $(srcdir)/config/print-sysroot-suffix.sh \
++        "$(MULTILIB_OSDIRNAMES)" "$(MULTILIB_OPTIONS)" \
++        "$(MULTILIB_MATCHES)" "$(MULTILIB_ALIASES)" > $@
+--- a/gcc/configure
++++ b/gcc/configure
+@@ -458,7 +458,7 @@ ac_includes_default="\
+ # include <unistd.h>
+ #endif"
+-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os target_noncanonical build_libsubdir build_subdir host_subdir target_subdir GENINSRC CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT NO_MINUS_C_MINUS_O OUTPUT_OPTION CPP EGREP loose_warn cxx_compat_warn strict_warn warn_cflags nocommon_flag TREEBROWSER valgrind_path valgrind_path_defines valgrind_command coverage_flags enable_multilib enable_decimal_float enable_fixed_point enable_shared TARGET_SYSTEM_ROOT TARGET_SYSTEM_ROOT_DEFINE CROSS_SYSTEM_HEADER_DIR onestep PKGVERSION REPORT_BUGS_TO REPORT_BUGS_TEXI datarootdir docdir htmldir SET_MAKE AWK LN_S LN RANLIB ac_ct_RANLIB ranlib_flags INSTALL INSTALL_PROGRAM INSTALL_DATA make_compare_target have_mktemp_command MAKEINFO BUILD_INFO GENERATED_MANPAGES FLEX BISON NM AR COLLECT2_LIBS GNAT_LIBEXC LDEXP_LIB TARGET_GETGROUPS_T LIBICONV LTLIBICONV LIBICONV_DEP manext objext gthread_flags extra_modes_file extra_opt_files USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT host_cc_for_libada CROSS ALL SYSTEM_HEADER_DIR inhibit_libc CC_FOR_BUILD BUILD_CFLAGS STMP_FIXINC STMP_FIXPROTO collect2 LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN ac_ct_AR STRIP ac_ct_STRIP lt_ECHO objdir enable_fast_install gcc_cv_as ORIGINAL_AS_FOR_TARGET gcc_cv_ld ORIGINAL_LD_FOR_TARGET gcc_cv_nm ORIGINAL_NM_FOR_TARGET gcc_cv_objdump libgcc_visibility GGC zlibdir zlibinc MAINT gcc_tooldir dollar slibdir subdirs srcdir all_compilers all_gtfiles all_lang_makefrags all_lang_makefiles all_languages all_selected_languages build_exeext build_install_headers_dir build_xm_file_list build_xm_include_list build_xm_defines build_file_translate check_languages cpp_install_dir xmake_file tmake_file extra_gcc_objs extra_headers_list extra_objs extra_parts extra_passes extra_programs float_h_file gcc_config_arguments gcc_gxx_include_dir host_exeext host_xm_file_list host_xm_include_list host_xm_defines out_host_hook_obj install lang_opt_files lang_specs_files lang_tree_files local_prefix md_file objc_boehm_gc out_file out_object_file thread_file tm_file_list tm_include_list tm_defines tm_p_file_list tm_p_include_list xm_file_list xm_include_list xm_defines c_target_objs cxx_target_objs target_cpu_default GMPLIBS GMPINC LIBOBJS LTLIBOBJS'
++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os target_noncanonical licensedir build_libsubdir build_subdir host_subdir target_subdir GENINSRC CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT NO_MINUS_C_MINUS_O OUTPUT_OPTION CPP EGREP loose_warn cxx_compat_warn strict_warn warn_cflags nocommon_flag TREEBROWSER valgrind_path valgrind_path_defines valgrind_command coverage_flags enable_multilib enable_decimal_float enable_fixed_point enable_shared TARGET_SYSTEM_ROOT TARGET_SYSTEM_ROOT_DEFINE CROSS_SYSTEM_HEADER_DIR CONFIGURE_SPECS EGLIBC_CONFIGS onestep PKGVERSION REPORT_BUGS_TO REPORT_BUGS_TEXI datarootdir docdir htmldir SET_MAKE AWK LN_S LN RANLIB ac_ct_RANLIB ranlib_flags INSTALL INSTALL_PROGRAM INSTALL_DATA make_compare_target have_mktemp_command MAKEINFO BUILD_INFO GENERATED_MANPAGES FLEX BISON NM AR COLLECT2_LIBS GNAT_LIBEXC LDEXP_LIB TARGET_GETGROUPS_T LIBICONV LTLIBICONV LIBICONV_DEP manext objext gthread_flags extra_modes_file extra_opt_files USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT host_cc_for_libada CROSS ALL SYSTEM_HEADER_DIR inhibit_libc CC_FOR_BUILD BUILD_CFLAGS STMP_FIXINC STMP_FIXPROTO collect2 LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN ac_ct_AR STRIP ac_ct_STRIP lt_ECHO objdir enable_fast_install gcc_cv_as ORIGINAL_AS_FOR_TARGET gcc_cv_ld ORIGINAL_LD_FOR_TARGET gcc_cv_nm ORIGINAL_NM_FOR_TARGET gcc_cv_objdump libgcc_visibility GGC zlibdir zlibinc MAINT gcc_tooldir dollar slibdir subdirs srcdir all_compilers all_gtfiles all_lang_makefrags all_lang_makefiles all_languages all_selected_languages build_exeext build_install_headers_dir build_xm_file_list build_xm_include_list build_xm_defines build_file_translate check_languages cpp_install_dir xmake_file tmake_file TM_ENDIAN_CONFIG TM_CPU_CONFIG TM_MULTILIB_CONFIG TM_MULTILIB_EXCEPTIONS_CONFIG extra_gcc_objs extra_headers_list extra_objs extra_parts extra_passes extra_programs float_h_file gcc_config_arguments gcc_gxx_include_dir host_exeext host_xm_file_list host_xm_include_list host_xm_defines out_host_hook_obj install lang_opt_files lang_specs_files lang_tree_files local_prefix md_file objc_boehm_gc out_file out_object_file thread_file tm_file_list tm_include_list tm_defines tm_p_file_list tm_p_include_list xm_file_list xm_include_list xm_defines c_target_objs cxx_target_objs target_cpu_default GMPLIBS GMPINC LIBOBJS LTLIBOBJS'
+ ac_subst_files='language_hooks'
+ # Initialize some variables set by options.
+@@ -1048,6 +1048,7 @@ Optional Features:
+                           arrange to use setjmp/longjmp exception handling
+   --enable-secureplt      enable -msecure-plt by default for PowerPC
+   --enable-cld            enable -mcld by default for 32bit x86
++  --enable-mips-nonpic    enable non-PIC ABI by default for MIPS GNU/Linux o32
+   --disable-win32-registry
+                           disable lookup of installation paths in the
+                           Registry on Windows hosts
+@@ -1068,6 +1069,8 @@ Optional Features:
+   --enable-version-specific-runtime-libs
+                           specify that runtime libraries should be
+                           installed in a compiler-specific directory
++  --enable-poison-system-directories
++                          warn for use of native system header directories
+ Optional Packages:
+   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+@@ -1089,6 +1092,9 @@ Optional Packages:
+   --with-build-sysroot=sysroot
+                           use sysroot as the system root during the build
+   --with-sysroot=DIR Search for usr/lib, usr/include, et al, within DIR.
++  --with-specs=SPECS      add SPECS to driver command-line processing
++  --with-eglibc-configs=CONFIGS
++                          build multilibs for these EGLIBC configurations
+   --with-pkgversion=PKG   Use PKG in the version string in place of "GCC"
+   --with-bugurl=URL       Direct users to URL to report a bug
+   --with-gnu-ld           assume the C compiler uses GNU ld default=no
+@@ -7367,6 +7373,28 @@ fi;
++
++# Check whether --with-specs or --without-specs was given.
++if test "${with_specs+set}" = set; then
++  withval="$with_specs"
++  CONFIGURE_SPECS=$withval
++else
++  CONFIGURE_SPECS=
++
++fi;
++
++
++
++# Check whether --with-eglibc-configs or --without-eglibc-configs was given.
++if test "${with_eglibc_configs+set}" = set; then
++  withval="$with_eglibc_configs"
++  EGLIBC_CONFIGS=$withval
++else
++  EGLIBC_CONFIGS=
++
++fi;
++
++
+ # Build with intermodule optimisations
+ # Check whether --enable-intermodule or --disable-intermodule was given.
+ if test "${enable_intermodule+set}" = set; then
+@@ -12971,7 +12999,7 @@ else
+       *) realsrcdir=../${srcdir};;
+       esac
+       saved_CFLAGS="${CFLAGS}"
+-      CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" \
++      CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" LDFLAGS="" \
+       ${realsrcdir}/configure \
+               --enable-languages=${enable_languages-all} \
+               --target=$target_alias --host=$build_alias --build=$build_alias
+@@ -13119,6 +13147,12 @@ else
+   enable_cld=no
+ fi;
++# Check whether --enable-mips-nonpic or --disable-mips-nonpic was given.
++if test "${enable_mips_nonpic+set}" = set; then
++  enableval="$enable_mips_nonpic"
++
++fi;
++
+ # Windows32 Registry support for specifying GCC installation paths.
+ # Check whether --enable-win32-registry or --disable-win32-registry was given.
+ if test "${enable_win32_registry+set}" = set; then
+@@ -14064,13 +14098,13 @@ if test "${lt_cv_nm_interface+set}" = se
+ else
+   lt_cv_nm_interface="BSD nm"
+   echo "int some_variable = 0;" > conftest.$ac_ext
+-  (eval echo "\"\$as_me:14067: $ac_compile\"" >&5)
++  (eval echo "\"\$as_me:14173: $ac_compile\"" >&5)
+   (eval "$ac_compile" 2>conftest.err)
+   cat conftest.err >&5
+-  (eval echo "\"\$as_me:14070: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
++  (eval echo "\"\$as_me:14176: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+   cat conftest.err >&5
+-  (eval echo "\"\$as_me:14073: output\"" >&5)
++  (eval echo "\"\$as_me:14179: output\"" >&5)
+   cat conftest.out >&5
+   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+     lt_cv_nm_interface="MS dumpbin"
+@@ -15125,7 +15159,7 @@ ia64-*-hpux*)
+   ;;
+ *-*-irix6*)
+   # Find out which ABI we are using.
+-  echo '#line 15128 "configure"' > conftest.$ac_ext
++  echo '#line 15234 "configure"' > conftest.$ac_ext
+   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+   (eval $ac_compile) 2>&5
+   ac_status=$?
+@@ -15745,11 +15779,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:15748: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:15854: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>conftest.err)
+    ac_status=$?
+    cat conftest.err >&5
+-   echo "$as_me:15752: \$? = $ac_status" >&5
++   echo "$as_me:15858: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s "$ac_outfile"; then
+      # The compiler can only warn and ignore the option if not recognized
+      # So say no if there are warnings other than the usual output.
+@@ -16067,11 +16101,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:16070: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:16176: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>conftest.err)
+    ac_status=$?
+    cat conftest.err >&5
+-   echo "$as_me:16074: \$? = $ac_status" >&5
++   echo "$as_me:16180: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s "$ac_outfile"; then
+      # The compiler can only warn and ignore the option if not recognized
+      # So say no if there are warnings other than the usual output.
+@@ -16172,11 +16206,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:16175: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:16281: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>out/conftest.err)
+    ac_status=$?
+    cat out/conftest.err >&5
+-   echo "$as_me:16179: \$? = $ac_status" >&5
++   echo "$as_me:16285: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s out/conftest2.$ac_objext
+    then
+      # The compiler can only warn and ignore the option if not recognized
+@@ -16227,11 +16261,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:16230: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:16336: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>out/conftest.err)
+    ac_status=$?
+    cat out/conftest.err >&5
+-   echo "$as_me:16234: \$? = $ac_status" >&5
++   echo "$as_me:16340: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s out/conftest2.$ac_objext
+    then
+      # The compiler can only warn and ignore the option if not recognized
+@@ -19024,7 +19058,7 @@ else
+   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+   lt_status=$lt_dlunknown
+   cat > conftest.$ac_ext <<_LT_EOF
+-#line 19027 "configure"
++#line 19133 "configure"
+ #include "confdefs.h"
+ #if HAVE_DLFCN_H
+@@ -19124,7 +19158,7 @@ else
+   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+   lt_status=$lt_dlunknown
+   cat > conftest.$ac_ext <<_LT_EOF
+-#line 19127 "configure"
++#line 19233 "configure"
+ #include "confdefs.h"
+ #if HAVE_DLFCN_H
+@@ -20592,6 +20626,22 @@ x:
+       tls_first_minor=16
+       tls_as_opt='-32 --fatal-warnings'
+       ;;
++  m68k-*-*)
++    conftest_s='
++      .section .tdata,"awT",@progbits
++x:
++      .word 2
++      .text
++foo:
++      move.l x@TLSGD(%a5),%a0
++      move.l x@TLSLDM(%a5),%a0
++      move.l x@TLSLDO(%a5),%a0
++      move.l x@TLSIE(%a5),%a0
++      move.l x@TLSLE(%a5),%a0'
++      tls_first_major=2
++      tls_first_minor=19
++      tls_as_opt='--fatal-warnings'
++      ;;
+   powerpc-*-*)
+     conftest_s='
+       .section ".tdata","awT",@progbits
+@@ -22098,7 +22148,8 @@ esac
+ case "$target" in
+   i?86*-*-* | mips*-*-* | alpha*-*-* | powerpc*-*-* | sparc*-*-* | m68*-*-* \
+   | x86_64*-*-* | hppa*-*-* | arm*-*-* | strongarm*-*-* | xscale*-*-* \
+-  | xstormy16*-*-* | cris-*-* | xtensa-*-* | bfin-*-* | score*-*-* | spu-*-*)
++  | xstormy16*-*-* | cris-*-* | xtensa-*-* | bfin-*-* | score*-*-* \
++  | spu-*-* | fido*-*-*)
+     insn="nop"
+     ;;
+   ia64*-*-* | s390*-*-*)
+@@ -23088,6 +23139,21 @@ fi
+ fi;
++# Check whether --enable-poison-system-directories or --disable-poison-system-directories was given.
++if test "${enable_poison_system_directories+set}" = set; then
++  enableval="$enable_poison_system_directories"
++
++else
++  enable_poison_system_directories=no
++fi;
++if test "x${enable_poison_system_directories}" = "xyes"; then
++
++cat >>confdefs.h <<\_ACEOF
++#define ENABLE_POISON_SYSTEM_DIRECTORIES 1
++_ACEOF
++
++fi
++
+ # Check whether --with-datarootdir or --without-datarootdir was given.
+ if test "${with_datarootdir+set}" = set; then
+@@ -23175,6 +23241,10 @@ fi;
++
++
++
++
+ # Echo link setup.
+ if test x${build} = x${host} ; then
+   if test x${host} = x${target} ; then
+@@ -23844,6 +23914,7 @@ s,@target_cpu@,$target_cpu,;t t
+ s,@target_vendor@,$target_vendor,;t t
+ s,@target_os@,$target_os,;t t
+ s,@target_noncanonical@,$target_noncanonical,;t t
++s,@licensedir@,$licensedir,;t t
+ s,@build_libsubdir@,$build_libsubdir,;t t
+ s,@build_subdir@,$build_subdir,;t t
+ s,@host_subdir@,$host_subdir,;t t
+@@ -23877,6 +23948,8 @@ s,@enable_shared@,$enable_shared,;t t
+ s,@TARGET_SYSTEM_ROOT@,$TARGET_SYSTEM_ROOT,;t t
+ s,@TARGET_SYSTEM_ROOT_DEFINE@,$TARGET_SYSTEM_ROOT_DEFINE,;t t
+ s,@CROSS_SYSTEM_HEADER_DIR@,$CROSS_SYSTEM_HEADER_DIR,;t t
++s,@CONFIGURE_SPECS@,$CONFIGURE_SPECS,;t t
++s,@EGLIBC_CONFIGS@,$EGLIBC_CONFIGS,;t t
+ s,@onestep@,$onestep,;t t
+ s,@PKGVERSION@,$PKGVERSION,;t t
+ s,@REPORT_BUGS_TO@,$REPORT_BUGS_TO,;t t
+@@ -23983,6 +24056,10 @@ s,@check_languages@,$check_languages,;t 
+ s,@cpp_install_dir@,$cpp_install_dir,;t t
+ s,@xmake_file@,$xmake_file,;t t
+ s,@tmake_file@,$tmake_file,;t t
++s,@TM_ENDIAN_CONFIG@,$TM_ENDIAN_CONFIG,;t t
++s,@TM_CPU_CONFIG@,$TM_CPU_CONFIG,;t t
++s,@TM_MULTILIB_CONFIG@,$TM_MULTILIB_CONFIG,;t t
++s,@TM_MULTILIB_EXCEPTIONS_CONFIG@,$TM_MULTILIB_EXCEPTIONS_CONFIG,;t t
+ s,@extra_gcc_objs@,$extra_gcc_objs,;t t
+ s,@extra_headers_list@,$extra_headers_list,;t t
+ s,@extra_objs@,$extra_objs,;t t
+--- a/gcc/configure.ac
++++ b/gcc/configure.ac
+@@ -767,6 +767,22 @@ AC_SUBST(TARGET_SYSTEM_ROOT)
+ AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE)
+ AC_SUBST(CROSS_SYSTEM_HEADER_DIR)
++AC_ARG_WITH(specs,
++  [AS_HELP_STRING([--with-specs=SPECS],
++                  [add SPECS to driver command-line processing])],
++  [CONFIGURE_SPECS=$withval],
++  [CONFIGURE_SPECS=]
++)
++AC_SUBST(CONFIGURE_SPECS)
++
++AC_ARG_WITH(eglibc-configs,
++  [AS_HELP_STRING([--with-eglibc-configs=CONFIGS],
++                  [build multilibs for these EGLIBC configurations])],
++  [EGLIBC_CONFIGS=$withval],
++  [EGLIBC_CONFIGS=]
++)
++AC_SUBST(EGLIBC_CONFIGS)
++
+ # Build with intermodule optimisations
+ AC_ARG_ENABLE(intermodule,
+ [  --enable-intermodule    build the compiler in one step],
+@@ -1479,7 +1495,7 @@ else
+       *) realsrcdir=../${srcdir};;
+       esac
+       saved_CFLAGS="${CFLAGS}"
+-      CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" \
++      CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" LDFLAGS="" \
+       ${realsrcdir}/configure \
+               --enable-languages=${enable_languages-all} \
+               --target=$target_alias --host=$build_alias --build=$build_alias
+@@ -1552,6 +1568,10 @@ AC_ARG_ENABLE(cld,
+ [  --enable-cld            enable -mcld by default for 32bit x86], [],
+ [enable_cld=no])
++AC_ARG_ENABLE(mips-nonpic,
++[  --enable-mips-nonpic    enable non-PIC ABI by default for MIPS GNU/Linux o32],
++[], [])
++
+ # Windows32 Registry support for specifying GCC installation paths.
+ AC_ARG_ENABLE(win32-registry,
+ [  --disable-win32-registry
+@@ -2455,6 +2475,22 @@ x:
+       tls_first_minor=16
+       tls_as_opt='-32 --fatal-warnings'
+       ;;
++  m68k-*-*)
++    conftest_s='
++      .section .tdata,"awT",@progbits
++x:
++      .word 2
++      .text
++foo:
++      move.l x@TLSGD(%a5),%a0
++      move.l x@TLSLDM(%a5),%a0
++      move.l x@TLSLDO(%a5),%a0
++      move.l x@TLSIE(%a5),%a0
++      move.l x@TLSLE(%a5),%a0'
++      tls_first_major=2
++      tls_first_minor=19
++      tls_as_opt='--fatal-warnings'
++      ;;
+   powerpc-*-*)
+     conftest_s='
+       .section ".tdata","awT",@progbits
+@@ -3077,7 +3113,8 @@ esac
+ case "$target" in
+   i?86*-*-* | mips*-*-* | alpha*-*-* | powerpc*-*-* | sparc*-*-* | m68*-*-* \
+   | x86_64*-*-* | hppa*-*-* | arm*-*-* | strongarm*-*-* | xscale*-*-* \
+-  | xstormy16*-*-* | cris-*-* | xtensa-*-* | bfin-*-* | score*-*-* | spu-*-*)
++  | xstormy16*-*-* | cris-*-* | xtensa-*-* | bfin-*-* | score*-*-* \
++  | spu-*-* | fido*-*-*)
+     insn="nop"
+     ;;
+   ia64*-*-* | s390*-*-*)
+@@ -3731,6 +3768,16 @@ else
+ fi)
+ AC_SUBST(slibdir)
++AC_ARG_ENABLE([poison-system-directories],
++            AS_HELP_STRING([--enable-poison-system-directories],
++                           [warn for use of native system header directories]),,
++            [enable_poison_system_directories=no])
++if test "x${enable_poison_system_directories}" = "xyes"; then
++  AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES],
++          [1],
++          [Define to warn for use of native system header directories])
++fi
++
+ AC_ARG_WITH(datarootdir,
+ [  --with-datarootdir=DIR  Use DIR as the data root [[PREFIX/share]]],
+ datarootdir="\${prefix}/$with_datarootdir",
+@@ -3768,6 +3815,10 @@ AC_SUBST(check_languages)
+ AC_SUBST(cpp_install_dir)
+ AC_SUBST(xmake_file)
+ AC_SUBST(tmake_file)
++AC_SUBST(TM_ENDIAN_CONFIG)
++AC_SUBST(TM_CPU_CONFIG)
++AC_SUBST(TM_MULTILIB_CONFIG)
++AC_SUBST(TM_MULTILIB_EXCEPTIONS_CONFIG)
+ AC_SUBST(extra_gcc_objs)
+ AC_SUBST(extra_headers_list)
+ AC_SUBST(extra_objs)
+--- a/gcc/cp/class.c
++++ b/gcc/cp/class.c
+@@ -6030,7 +6030,7 @@ resolve_address_of_overloaded_function (
+       if (flags & tf_error)
+       {
+         error ("no matches converting function %qD to type %q#T",
+-               DECL_NAME (OVL_FUNCTION (overload)),
++               DECL_NAME (OVL_CURRENT (overload)),
+                target_type);
+         /* print_candidates expects a chain with the functions in
+@@ -6179,13 +6179,8 @@ instantiate_type (tree lhstype, tree rhs
+      dependent on overload resolution.  */
+   gcc_assert (TREE_CODE (rhs) == ADDR_EXPR
+             || TREE_CODE (rhs) == COMPONENT_REF
+-            || TREE_CODE (rhs) == COMPOUND_EXPR
+-            || really_overloaded_fn (rhs));
+-
+-  /* We don't overwrite rhs if it is an overloaded function.
+-     Copying it would destroy the tree link.  */
+-  if (TREE_CODE (rhs) != OVERLOAD)
+-    rhs = copy_node (rhs);
++            || really_overloaded_fn (rhs)
++            || (flag_ms_extensions && TREE_CODE (rhs) == FUNCTION_DECL));
+   /* This should really only be used when attempting to distinguish
+      what sort of a pointer to function we have.  For now, any
+@@ -6237,19 +6232,6 @@ instantiate_type (tree lhstype, tree rhs
+                                               /*explicit_targs=*/NULL_TREE,
+                                               access_path);
+-    case COMPOUND_EXPR:
+-      TREE_OPERAND (rhs, 0)
+-      = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
+-      if (TREE_OPERAND (rhs, 0) == error_mark_node)
+-      return error_mark_node;
+-      TREE_OPERAND (rhs, 1)
+-      = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
+-      if (TREE_OPERAND (rhs, 1) == error_mark_node)
+-      return error_mark_node;
+-
+-      TREE_TYPE (rhs) = lhstype;
+-      return rhs;
+-
+     case ADDR_EXPR:
+     {
+       if (PTRMEM_OK_P (rhs))
+--- a/gcc/cp/cvt.c
++++ b/gcc/cp/cvt.c
+@@ -580,6 +580,7 @@ ocp_convert (tree type, tree expr, int c
+   tree e = expr;
+   enum tree_code code = TREE_CODE (type);
+   const char *invalid_conv_diag;
++  tree e1;
+   if (error_operand_p (e) || type == error_mark_node)
+     return error_mark_node;
+@@ -628,6 +629,9 @@ ocp_convert (tree type, tree expr, int c
+       }
+     }
++  if (e1 = targetm.convert_to_type (type, e))
++    return e1;
++
+   if (code == VOID_TYPE && (convtype & CONV_STATIC))
+     {
+       e = convert_to_void (e, /*implicit=*/NULL);
+@@ -1190,11 +1194,18 @@ build_expr_type_conversion (int desires,
+ tree
+ type_promotes_to (tree type)
+ {
++  tree promoted_type;
++
+   if (type == error_mark_node)
+     return error_mark_node;
+   type = TYPE_MAIN_VARIANT (type);
++  /* Check for promotions of target-defined types first.  */
++  promoted_type = targetm.promoted_type (type);
++  if (promoted_type)
++    return promoted_type;
++
+   /* bool always promotes to int (not unsigned), even if it's the same
+      size.  */
+   if (type == boolean_type_node)
+--- a/gcc/cp/decl.c
++++ b/gcc/cp/decl.c
+@@ -4379,7 +4379,7 @@ maybe_deduce_size_from_array_init (tree 
+       cp_apply_type_quals_to_decl (cp_type_quals (TREE_TYPE (decl)), decl);
+-      layout_decl (decl, 0);
++      relayout_decl (decl);
+     }
+ }
+@@ -7413,6 +7413,7 @@ grokdeclarator (const cp_declarator *dec
+   bool type_was_error_mark_node = false;
+   bool parameter_pack_p = declarator? declarator->parameter_pack_p : false;
+   bool set_no_warning = false;
++  const char *errmsg;
+   signed_p = declspecs->specs[(int)ds_signed];
+   unsigned_p = declspecs->specs[(int)ds_unsigned];
+@@ -8092,6 +8093,12 @@ grokdeclarator (const cp_declarator *dec
+               error ("%qs declared as function returning an array", name);
+               type = integer_type_node;
+             }
++          errmsg = targetm.invalid_return_type (type);
++          if (errmsg)
++            {
++              error (errmsg);
++              type = integer_type_node;
++            }
+           /* Pick up type qualifiers which should be applied to `this'.  */
+           memfn_quals = declarator->u.function.qualifiers;
+@@ -8585,8 +8592,14 @@ grokdeclarator (const cp_declarator *dec
+         /* Replace the anonymous name with the real name everywhere.  */
+         for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+-          if (TYPE_NAME (t) == oldname)
+-            TYPE_NAME (t) = decl;
++          {
++            if (TYPE_NAME (t) == oldname)
++              {
++                debug_hooks->set_name (t, decl);
++                TYPE_NAME (t) = decl;
++              }
++          }
++                
+         if (TYPE_LANG_SPECIFIC (type))
+           TYPE_WAS_ANONYMOUS (type) = 1;
+@@ -9378,6 +9391,7 @@ grokparms (cp_parameter_declarator *firs
+       tree init = parm->default_argument;
+       tree attrs;
+       tree decl;
++      const char *errmsg;
+       if (parm == no_parameters)
+       break;
+@@ -9418,6 +9432,14 @@ grokparms (cp_parameter_declarator *firs
+         init = NULL_TREE;
+       }
++      if (type != error_mark_node
++        && (errmsg = targetm.invalid_parameter_type (type)))
++      {
++        error (errmsg);
++        type = error_mark_node;
++        TREE_TYPE (decl) = error_mark_node;
++      }
++
+       if (type != error_mark_node)
+       {
+         /* Top-level qualifiers on the parameters are
+--- a/gcc/cp/decl2.c
++++ b/gcc/cp/decl2.c
+@@ -1682,6 +1682,10 @@ decl_needed_p (tree decl)
+       || (DECL_ASSEMBLER_NAME_SET_P (decl)
+         && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
+       return true;
++  /* Functions marked "dllexport" must be emitted so that they are
++     visible to other DLLs.  */
++  if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
++    return true;
+   /* Otherwise, DECL does not need to be emitted -- yet.  A subsequent
+      reference to DECL might cause it to be emitted later.  */
+   return false;
+@@ -1963,6 +1967,14 @@ determine_visibility (tree decl)
+         /* tinfo visibility is based on the type it's for.  */
+         constrain_visibility
+           (decl, type_visibility (TREE_TYPE (DECL_NAME (decl))));
++
++        /* Give the target a chance to override the visibility associated
++           with DECL.  */
++        if (TREE_PUBLIC (decl)
++            && !DECL_REALLY_EXTERN (decl)
++            && CLASS_TYPE_P (TREE_TYPE (DECL_NAME (decl)))
++            && !CLASSTYPE_VISIBILITY_SPECIFIED (TREE_TYPE (DECL_NAME (decl))))
++          targetm.cxx.determine_class_data_visibility (decl);
+       }
+       else if (use_template)
+       /* Template instantiations and specializations get visibility based
+--- a/gcc/cp/mangle.c
++++ b/gcc/cp/mangle.c
+@@ -1593,6 +1593,13 @@ write_type (tree type)
+         if (target_mangling)
+           {
+             write_string (target_mangling);
++            /* Add substitutions for types other than fundamental
++               types.  */
++            if (TREE_CODE (type) != VOID_TYPE
++                && TREE_CODE (type) != INTEGER_TYPE
++                && TREE_CODE (type) != REAL_TYPE
++                && TREE_CODE (type) != BOOLEAN_TYPE)
++              add_substitution (type);
+             return;
+           }
+--- a/gcc/cp/semantics.c
++++ b/gcc/cp/semantics.c
+@@ -3218,8 +3218,10 @@ expand_or_defer_fn (tree fn)
+       /* If the user wants us to keep all inline functions, then mark
+        this function as needed so that finish_file will make sure to
+-       output it later.  */
+-      if (flag_keep_inline_functions && DECL_DECLARED_INLINE_P (fn))
++       output it later.  Similarly, all dllexport'd functions must
++       be emitted; there may be callers in other DLLs.  */
++      if ((flag_keep_inline_functions && DECL_DECLARED_INLINE_P (fn))
++        || lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn)))
+       mark_needed (fn);
+     }
+--- a/gcc/cp/typeck.c
++++ b/gcc/cp/typeck.c
+@@ -1627,10 +1627,14 @@ decay_conversion (tree exp)
+ tree
+ default_conversion (tree exp)
+ {
++  /* Check for target-specific promotions.  */
++  tree promoted_type = targetm.promoted_type (TREE_TYPE (exp));
++  if (promoted_type)
++    exp = cp_convert (promoted_type, exp);
+   /* Perform the integral promotions first so that bitfield
+      expressions (which may promote to "int", even if the bitfield is
+      declared "unsigned") are promoted correctly.  */
+-  if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
++  else if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
+     exp = perform_integral_promotions (exp);
+   /* Perform the other conversions.  */
+   exp = decay_conversion (exp);
+@@ -4837,6 +4841,12 @@ build_compound_expr (tree lhs, tree rhs)
+       return rhs;
+     }
++  if (type_unknown_p (rhs))
++    {
++      error ("no context to resolve type of %qE", rhs);
++      return error_mark_node;
++    }
++  
+   return build2 (COMPOUND_EXPR, TREE_TYPE (rhs), lhs, rhs);
+ }
+@@ -6814,6 +6824,7 @@ static int
+ comp_ptr_ttypes_real (tree to, tree from, int constp)
+ {
+   bool to_more_cv_qualified = false;
++  bool is_opaque_pointer = false;
+   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
+     {
+@@ -6848,9 +6859,13 @@ comp_ptr_ttypes_real (tree to, tree from
+           constp &= TYPE_READONLY (to);
+       }
++      if (TREE_CODE (to) == VECTOR_TYPE)
++      is_opaque_pointer = vector_targets_convertible_p (to, from);
++
+       if (TREE_CODE (to) != POINTER_TYPE && !TYPE_PTRMEM_P (to))
+       return ((constp >= 0 || to_more_cv_qualified)
+-              && same_type_ignoring_top_level_qualifiers_p (to, from));
++              && (is_opaque_pointer
++                  || same_type_ignoring_top_level_qualifiers_p (to, from)));
+     }
+ }
+@@ -6911,6 +6926,8 @@ ptr_reasonably_similar (const_tree to, c
+ bool
+ comp_ptr_ttypes_const (tree to, tree from)
+ {
++  bool is_opaque_pointer = false;
++
+   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
+     {
+       if (TREE_CODE (to) != TREE_CODE (from))
+@@ -6921,8 +6938,12 @@ comp_ptr_ttypes_const (tree to, tree fro
+                         TYPE_OFFSET_BASETYPE (to)))
+         continue;
++      if (TREE_CODE (to) == VECTOR_TYPE)
++      is_opaque_pointer = vector_targets_convertible_p (to, from);
++
+       if (TREE_CODE (to) != POINTER_TYPE)
+-      return same_type_ignoring_top_level_qualifiers_p (to, from);
++      return (is_opaque_pointer
++              || same_type_ignoring_top_level_qualifiers_p (to, from));
+     }
+ }
+--- a/gcc/cse.c
++++ b/gcc/cse.c
+@@ -5776,6 +5776,11 @@ cse_process_notes_1 (rtx x, rtx object, 
+       validate_change (object, &XEXP (x, i),
+                      cse_process_notes (XEXP (x, i), object, changed), 0);
++  /* Rebuild a PLUS expression in canonical form if the first operand
++     ends up as a constant.  */
++  if (code == PLUS && GET_CODE (XEXP (x, 0)) == CONST_INT)
++    return plus_constant (XEXP(x, 1), INTVAL (XEXP (x, 0)));
++
+   return x;
+ }
+--- a/gcc/dbxout.c
++++ b/gcc/dbxout.c
+@@ -373,6 +373,7 @@ const struct gcc_debug_hooks dbx_debug_h
+   dbxout_handle_pch,                   /* handle_pch */
+   debug_nothing_rtx,                   /* var_location */
+   debug_nothing_void,                    /* switch_text_section */
++  debug_nothing_tree_tree,             /* set_name */
+   0                                      /* start_end_main_source_file */
+ };
+ #endif /* DBX_DEBUGGING_INFO  */
+--- a/gcc/debug.c
++++ b/gcc/debug.c
+@@ -49,6 +49,7 @@ const struct gcc_debug_hooks do_nothing_
+   debug_nothing_int,                   /* handle_pch */
+   debug_nothing_rtx,                   /* var_location */
+   debug_nothing_void,                    /* switch_text_section */
++  debug_nothing_tree_tree,             /* set_name */
+   0                                      /* start_end_main_source_file */
+ };
+--- a/gcc/debug.h
++++ b/gcc/debug.h
+@@ -124,6 +124,8 @@ struct gcc_debug_hooks
+      text sections.  */
+   void (* switch_text_section) (void);
++  void (* set_name) (tree, tree);
++
+   /* This is 1 if the debug writer wants to see start and end commands for the
+      main source files, and 0 otherwise.  */
+   int start_end_main_source_file;
+--- a/gcc/doc/extend.texi
++++ b/gcc/doc/extend.texi
+@@ -28,10 +28,10 @@ extensions, accepted by GCC in C89 mode 
+ * Local Labels::        Labels local to a block.
+ * Labels as Values::    Getting pointers to labels, and computed gotos.
+ * Nested Functions::    As in Algol and Pascal, lexical scoping of functions.
+-* Constructing Calls::        Dispatching a call to another function.
++* Constructing Calls::  Dispatching a call to another function.
+ * Typeof::              @code{typeof}: referring to the type of an expression.
+ * Conditionals::        Omitting the middle operand of a @samp{?:} expression.
+-* Long Long::         Double-word integers---@code{long long int}.
++* Long Long::           Double-word integers---@code{long long int}.
+ * Complex::             Data types for complex numbers.
+ * Floating Types::      Additional Floating Types.
+ * Decimal Float::       Decimal Floating Types. 
+@@ -40,41 +40,41 @@ extensions, accepted by GCC in C89 mode 
+ * Zero Length::         Zero-length arrays.
+ * Variable Length::     Arrays whose length is computed at run time.
+ * Empty Structures::    Structures with no members.
+-* Variadic Macros::   Macros with a variable number of arguments.
++* Variadic Macros::     Macros with a variable number of arguments.
+ * Escaped Newlines::    Slightly looser rules for escaped newlines.
+ * Subscripting::        Any array can be subscripted, even if not an lvalue.
+ * Pointer Arith::       Arithmetic on @code{void}-pointers and function pointers.
+ * Initializers::        Non-constant initializers.
+ * Compound Literals::   Compound literals give structures, unions
+-                         or arrays as values.
+-* Designated Inits::  Labeling elements of initializers.
++                        or arrays as values.
++* Designated Inits::    Labeling elements of initializers.
+ * Cast to Union::       Casting to union type from any member of the union.
+-* Case Ranges::               `case 1 ... 9' and such.
+-* Mixed Declarations::        Mixing declarations and code.
++* Case Ranges::         `case 1 ... 9' and such.
++* Mixed Declarations::  Mixing declarations and code.
+ * Function Attributes:: Declaring that functions have no side effects,
+-                         or that they can never return.
++                        or that they can never return.
+ * Attribute Syntax::    Formal syntax for attributes.
+ * Function Prototypes:: Prototype declarations and old-style definitions.
+ * C++ Comments::        C++ comments are recognized.
+ * Dollar Signs::        Dollar sign is allowed in identifiers.
+ * Character Escapes::   @samp{\e} stands for the character @key{ESC}.
+-* Variable Attributes::       Specifying attributes of variables.
+-* Type Attributes::   Specifying attributes of types.
++* Variable Attributes:: Specifying attributes of variables.
++* Type Attributes::     Specifying attributes of types.
+ * Alignment::           Inquiring about the alignment of a type or variable.
+ * Inline::              Defining inline functions (as fast as macros).
+ * Extended Asm::        Assembler instructions with C expressions as operands.
+-                         (With them you can define ``built-in'' functions.)
++                        (With them you can define ``built-in'' functions.)
+ * Constraints::         Constraints for asm operands
+ * Asm Labels::          Specifying the assembler name to use for a C symbol.
+ * Explicit Reg Vars::   Defining variables residing in specified registers.
+ * Alternate Keywords::  @code{__const__}, @code{__asm__}, etc., for header files.
+ * Incomplete Enums::    @code{enum foo;}, with details to follow.
+-* Function Names::    Printable strings which are the name of the current
+-                       function.
++* Function Names::      Printable strings which are the name of the current
++                        function.
+ * Return Address::      Getting the return or frame address of a function.
+ * Vector Extensions::   Using vector instructions through built-in functions.
+ * Offsetof::            Special syntax for implementing @code{offsetof}.
+-* Atomic Builtins::   Built-in functions for atomic memory access.
++* Atomic Builtins::     Built-in functions for atomic memory access.
+ * Object Size Checking:: Built-in functions for limited buffer overflow
+                         checking.
+ * Other Builtins::      Other built-in functions.
+@@ -2486,7 +2486,13 @@ defined by shared libraries.
+ @cindex function without a prologue/epilogue code
+ Use this attribute on the ARM, AVR, IP2K and SPU ports to indicate that
+ the specified function does not need prologue/epilogue sequences generated by
+-the compiler.  It is up to the programmer to provide these sequences.
++the compiler.  It is up to the programmer to provide these sequences. The 
++only statements that can be safely included in naked functions are 
++@code{asm} statements that do not have operands.  All other statements,
++including declarations of local variables, @code{if} statements, and so 
++forth, should be avoided.  Naked functions should be used to implement the 
++body of an assembly function, while allowing the compiler to construct
++the requisite function declaration for the assembler.
+ @item near
+ @cindex functions which do not handle memory bank switching on 68HC11/68HC12
+@@ -2539,7 +2545,7 @@ be non-null pointers.  For instance, the
+ @smallexample
+ extern void *
+ my_memcpy (void *dest, const void *src, size_t len)
+-      __attribute__((nonnull (1, 2)));
++        __attribute__((nonnull (1, 2)));
+ @end smallexample
+ @noindent
+@@ -2557,7 +2563,7 @@ following declaration is equivalent to t
+ @smallexample
+ extern void *
+ my_memcpy (void *dest, const void *src, size_t len)
+-      __attribute__((nonnull));
++        __attribute__((nonnull));
+ @end smallexample
+ @item noreturn
+@@ -3710,13 +3716,13 @@ targets.  You can use @code{__declspec (
+ compilers.
+ @item weak
+-The @code{weak} attribute is described in @xref{Function Attributes}.
++The @code{weak} attribute is described in @ref{Function Attributes}.
+ @item dllimport
+-The @code{dllimport} attribute is described in @xref{Function Attributes}.
++The @code{dllimport} attribute is described in @ref{Function Attributes}.
+ @item dllexport
+-The @code{dllexport} attribute is described in @xref{Function Attributes}.
++The @code{dllexport} attribute is described in @ref{Function Attributes}.
+ @end table
+@@ -3897,21 +3903,21 @@ Three attributes currently are defined f
+ @code{altivec}, @code{ms_struct} and @code{gcc_struct}.
+ For full documentation of the struct attributes please see the
+-documentation in the @xref{i386 Variable Attributes}, section.
++documentation in @ref{i386 Variable Attributes}.
+ For documentation of @code{altivec} attribute please see the
+-documentation in the @xref{PowerPC Type Attributes}, section.
++documentation in @ref{PowerPC Type Attributes}.
+ @subsection SPU Variable Attributes
+ The SPU supports the @code{spu_vector} attribute for variables.  For
+-documentation of this attribute please see the documentation in the
+-@xref{SPU Type Attributes}, section.
++documentation of this attribute please see the documentation in
++@ref{SPU Type Attributes}.
+ @subsection Xstormy16 Variable Attributes
+ One attribute is currently defined for xstormy16 configurations:
+-@code{below100}
++@code{below100}.
+ @table @code
+ @item below100
+@@ -4231,6 +4237,8 @@ and caught in another, the class must ha
+ Otherwise the two shared objects will be unable to use the same
+ typeinfo node and exception handling will break.
++@end table
++
+ @subsection ARM Type Attributes
+ On those ARM targets that support @code{dllimport} (such as Symbian
+@@ -4258,7 +4266,9 @@ most Symbian OS code uses @code{__declsp
+ @subsection i386 Type Attributes
+ Two attributes are currently defined for i386 configurations:
+-@code{ms_struct} and @code{gcc_struct}
++@code{ms_struct} and @code{gcc_struct}.
++
++@table @code
+ @item ms_struct
+ @itemx gcc_struct
+@@ -4286,8 +4296,8 @@ packed))}.
+ Three attributes currently are defined for PowerPC configurations:
+ @code{altivec}, @code{ms_struct} and @code{gcc_struct}.
+-For full documentation of the struct attributes please see the
+-documentation in the @xref{i386 Type Attributes}, section.
++For full documentation of the @code{ms_struct} and @code{gcc_struct} 
++attributes please see the documentation in @ref{i386 Type Attributes}.
+ The @code{altivec} attribute allows one to declare AltiVec vector data
+ types supported by the AltiVec Programming Interface Manual.  The
+@@ -5231,7 +5241,6 @@ GCC provides three magic variables which
+ function, as a string.  The first of these is @code{__func__}, which
+ is part of the C99 standard:
+-@display
+ The identifier @code{__func__} is implicitly declared by the translator
+ as if, immediately following the opening brace of each function
+ definition, the declaration
+@@ -5240,9 +5249,9 @@ definition, the declaration
+ static const char __func__[] = "function-name";
+ @end smallexample
++@noindent
+ appeared, where function-name is the name of the lexically-enclosing
+ function.  This name is the unadorned name of the function.
+-@end display
+ @code{__FUNCTION__} is another name for @code{__func__}.  Older
+ versions of GCC recognize only this name.  However, it is not
+@@ -5451,12 +5460,12 @@ the @code{offsetof} macro.
+ @smallexample
+ primary:
+-      "__builtin_offsetof" "(" @code{typename} "," offsetof_member_designator ")"
++        "__builtin_offsetof" "(" @code{typename} "," offsetof_member_designator ")"
+ offsetof_member_designator:
+-        @code{identifier}
+-      | offsetof_member_designator "." @code{identifier}
+-      | offsetof_member_designator "[" @code{expr} "]"
++          @code{identifier}
++        | offsetof_member_designator "." @code{identifier}
++        | offsetof_member_designator "[" @code{expr} "]"
+ @end smallexample
+ This extension is sufficient such that
+@@ -5649,7 +5658,7 @@ assert (__builtin_object_size (p, 0) == 
+ assert (__builtin_object_size (p, 1) == sizeof (var.buf1) - 1);
+ /* The object q points to is var.  */
+ assert (__builtin_object_size (q, 0)
+-      == (char *) (&var + 1) - (char *) &var.b);
++        == (char *) (&var + 1) - (char *) &var.b);
+ /* The subobject q points to is var.b.  */
+ assert (__builtin_object_size (q, 1) == sizeof (var.b));
+ @end smallexample
+@@ -5701,11 +5710,11 @@ There are also checking built-in functio
+ @smallexample
+ int __builtin___sprintf_chk (char *s, int flag, size_t os, const char *fmt, ...);
+ int __builtin___snprintf_chk (char *s, size_t maxlen, int flag, size_t os,
+-                            const char *fmt, ...);
++                              const char *fmt, ...);
+ int __builtin___vsprintf_chk (char *s, int flag, size_t os, const char *fmt,
+-                            va_list ap);
++                              va_list ap);
+ int __builtin___vsnprintf_chk (char *s, size_t maxlen, int flag, size_t os,
+-                             const char *fmt, va_list ap);
++                               const char *fmt, va_list ap);
+ @end smallexample
+ The added @var{flag} argument is passed unchanged to @code{__sprintf_chk}
+@@ -11518,7 +11527,7 @@ test specifically for GNU C++ (@pxref{Co
+ Predefined Macros,cpp,The GNU C Preprocessor}).
+ @menu
+-* Volatiles::         What constitutes an access to a volatile object.
++* Volatiles::           What constitutes an access to a volatile object.
+ * Restricted Pointers:: C99 restricted pointers and references.
+ * Vague Linkage::       Where G++ puts inlines, vtables and such.
+ * C++ Interface::       You can use a single C++ header file for both
+@@ -12039,7 +12048,7 @@ interface table mechanism, instead of re
+ @end table
+-See also @xref{Namespace Association}.
++See also @ref{Namespace Association}.
+ @node Namespace Association
+ @section Namespace Association
+@@ -12266,7 +12275,7 @@ should work just fine for standard-confo
+ Previously it was possible to use an empty prototype parameter list to
+ indicate an unspecified number of parameters (like C), rather than no
+ parameters, as C++ demands.  This feature has been removed, except where
+-it is required for backwards compatibility @xref{Backwards Compatibility}.
++it is required for backwards compatibility.   @xref{Backwards Compatibility}.
+ @end table
+ G++ allows a virtual function returning @samp{void *} to be overridden
+@@ -12317,7 +12326,7 @@ used to be acceptable in previous drafts
+ compilation of C++ written to such drafts, G++ contains some backwards
+ compatibilities.  @emph{All such backwards compatibility features are
+ liable to disappear in future versions of G++.} They should be considered
+-deprecated @xref{Deprecated Features}.
++deprecated.   @xref{Deprecated Features}.
+ @table @code
+ @item For scope
+--- a/gcc/doc/fragments.texi
++++ b/gcc/doc/fragments.texi
+@@ -143,6 +143,22 @@ options enabled.  Therefore @code{MULTIL
+ *mthumb/*mhard-float*
+ @end smallexample
++@findex MULTILIB_ALIASES
++@item MULTILIB_ALIASES
++Sometimes it is desirable to support a large set of multilib options, but
++only build libraries for a subset of those multilibs.  The remaining
++combinations use a sutiable alternative multilb.  In that case, set
++@code{MULTILIB_ALIASES} to a list of the form @samp{realname=aliasname}.
++
++For example, consider a little-endian ARM toolchain with big-endian and
++Thumb multilibs.  If a big-endian Thumb multilib is not wanted, then
++setting @code{MULTILIB_ALIASES} to @samp{mbig-endian=mbig-endian/mthumb} 
++makes this combination use the big-endian ARM libraries instead.
++
++If the multilib is instead excluded by setting @code{MULTILIB_EXCEPTIONS}
++then big-endian Thumb code uses the default multilib as none of the
++remaining multilibs match.
++
+ @findex MULTILIB_EXTRA_OPTS
+ @item MULTILIB_EXTRA_OPTS
+ Sometimes it is desirable that when building multiple versions of
+--- a/gcc/doc/gcc.texi
++++ b/gcc/doc/gcc.texi
+@@ -147,12 +147,12 @@ Introduction, gccint, GNU Compiler Colle
+ * GNU Project::     The GNU Project and GNU/Linux.
+ * Copying::         GNU General Public License says
+-                     how you can copy and share GCC.
++                    how you can copy and share GCC.
+ * GNU Free Documentation License:: How you can copy and share this manual.
+ * Contributors::    People who have contributed to GCC.
+ * Option Index::    Index to command line options.
+-* Keyword Index::    Index of concepts and symbol names.
++* Keyword Index::   Index of concepts and symbol names.
+ @end menu
+ @include frontends.texi
+--- a/gcc/doc/install.texi
++++ b/gcc/doc/install.texi
+@@ -671,7 +671,7 @@ internal data files of GCC@.  The defaul
+ @item --libexecdir=@var{dirname}
+ Specify the installation directory for internal executables of GCC@.
+-  The default is @file{@var{exec-prefix}/libexec}.
++The default is @file{@var{exec-prefix}/libexec}.
+ @item --with-slibdir=@var{dirname}
+ Specify the installation directory for the shared libgcc library.  The
+@@ -3513,15 +3513,17 @@ applications.  There are no standard Uni
+ @end html
+ @heading @anchor{m68k-x-x}m68k-*-*
+ By default, @samp{m68k-*-aout}, @samp{m68k-*-coff*},
+-@samp{m68k-*-elf*}, @samp{m68k-*-rtems} and @samp{m68k-*-uclinux}
++@samp{m68k-*-elf*}, @samp{m68k-*-rtems},  @samp{m68k-*-uclinux} and
++@samp{m68k-*-linux}
+ build libraries for both M680x0 and ColdFire processors.  If you only
+ need the M680x0 libraries, you can omit the ColdFire ones by passing
+ @option{--with-arch=m68k} to @command{configure}.  Alternatively, you
+ can omit the M680x0 libraries by passing @option{--with-arch=cf} to
+-@command{configure}.  These targets default to 5206 code when
++@command{configure}.  These targets default to 5206 or 5475 code as
++appropriate for the target system when
+ configured with @option{--with-arch=cf} and 68020 code otherwise.
+-The @samp{m68k-*-linux-gnu}, @samp{m68k-*-netbsd} and
++The @samp{m68k-*-netbsd} and
+ @samp{m68k-*-openbsd} targets also support the @option{--with-arch}
+ option.  They will generate ColdFire CFV4e code when configured with
+ @option{--with-arch=cf} and 68020 code otherwise.
+--- a/gcc/doc/invoke.texi
++++ b/gcc/doc/invoke.texi
+@@ -120,11 +120,11 @@ only one of these two forms, whichever o
+ @xref{Option Index}, for an index to GCC's options.
+ @menu
+-* Option Summary::    Brief list of all options, without explanations.
++* Option Summary::      Brief list of all options, without explanations.
+ * Overall Options::     Controlling the kind of output:
+                         an executable, object files, assembler files,
+                         or preprocessed source.
+-* Invoking G++::      Compiling C++ programs.
++* Invoking G++::        Compiling C++ programs.
+ * C Dialect Options::   Controlling the variant of C language compiled.
+ * C++ Dialect Options:: Variations on C++.
+ * Objective-C and Objective-C++ Dialect Options:: Variations on Objective-C
+@@ -248,6 +248,7 @@ Objective-C and Objective-C++ Dialects}.
+ -Wno-multichar  -Wnonnull  -Wno-overflow @gol
+ -Woverlength-strings  -Wpacked  -Wpadded @gol
+ -Wparentheses  -Wpointer-arith  -Wno-pointer-to-int-cast @gol
++-Wno-poison-system-directories @gol
+ -Wredundant-decls @gol
+ -Wreturn-type  -Wsequence-point  -Wshadow @gol
+ -Wsign-compare  -Wsign-conversion  -Wstack-protector @gol
+@@ -309,13 +310,13 @@ Objective-C and Objective-C++ Dialects}.
+ -p  -pg  -print-file-name=@var{library}  -print-libgcc-file-name @gol
+ -print-multi-directory  -print-multi-lib @gol
+ -print-prog-name=@var{program}  -print-search-dirs  -Q @gol
+--print-sysroot-headers-suffix @gol
++-print-sysroot -print-sysroot-headers-suffix @gol
+ -save-temps  -time}
+ @item Optimization Options
+ @xref{Optimize Options,,Options that Control Optimization}.
+ @gccoptlist{
+--falign-functions[=@var{n}] -falign-jumps[=@var{n}] @gol
++-falign-arrays -falign-functions[=@var{n}] -falign-jumps[=@var{n}] @gol
+ -falign-labels[=@var{n}] -falign-loops[=@var{n}] -fassociative-math @gol
+ -fauto-inc-dec -fbranch-probabilities -fbranch-target-load-optimize @gol
+ -fbranch-target-load-optimize2 -fbtr-bb-exclusive -fcaller-saves @gol
+@@ -388,7 +389,7 @@ Objective-C and Objective-C++ Dialects}.
+ @gccoptlist{@var{object-file-name}  -l@var{library} @gol
+ -nostartfiles  -nodefaultlibs  -nostdlib -pie -rdynamic @gol
+ -s  -static  -static-libgcc  -shared  -shared-libgcc  -symbolic @gol
+--Wl,@var{option}  -Xlinker @var{option} @gol
++-T @var{script}  -Wl,@var{option}  -Xlinker @var{option} @gol
+ -u @var{symbol}}
+ @item Directory Options
+@@ -421,8 +422,11 @@ Objective-C and Objective-C++ Dialects}.
+ -msched-prolog  -mno-sched-prolog @gol
+ -mlittle-endian  -mbig-endian  -mwords-little-endian @gol
+ -mfloat-abi=@var{name}  -msoft-float  -mhard-float  -mfpe @gol
++-mfp16-format=@var{name}
+ -mthumb-interwork  -mno-thumb-interwork @gol
++-mfix-janus-2cc @gol
+ -mcpu=@var{name}  -march=@var{name}  -mfpu=@var{name}  @gol
++-mmarvell-div @gol
+ -mstructure-size-boundary=@var{n} @gol
+ -mabort-on-noreturn @gol
+ -mlong-calls  -mno-long-calls @gol
+@@ -434,7 +438,9 @@ Objective-C and Objective-C++ Dialects}.
+ -mthumb  -marm @gol
+ -mtpcs-frame  -mtpcs-leaf-frame @gol
+ -mcaller-super-interworking  -mcallee-super-interworking @gol
+--mtp=@var{name}}
++-mtp=@var{name} @gol
++-mlow-irq-latency  -mword-relocations @gol
++-mfix-cortex-m3-ldrd}
+ @emph{AVR Options}
+ @gccoptlist{-mmcu=@var{mcu}  -msize  -minit-stack=@var{n}  -mno-interrupts @gol
+@@ -602,7 +608,8 @@ Objective-C and Objective-C++ Dialects}.
+ -mnobitfield  -mrtd  -mno-rtd  -mdiv  -mno-div  -mshort @gol
+ -mno-short  -mhard-float  -m68881  -msoft-float  -mpcrel @gol
+ -malign-int  -mstrict-align  -msep-data  -mno-sep-data @gol
+--mshared-library-id=n  -mid-shared-library  -mno-id-shared-library}
++-mshared-library-id=n  -mid-shared-library  -mno-id-shared-library @gol
++-mxgot -mno-xgot}
+ @emph{M68hc1x Options}
+ @gccoptlist{-m6811  -m6812  -m68hc11  -m68hc12   -m68hcs12 @gol
+@@ -619,7 +626,7 @@ Objective-C and Objective-C++ Dialects}.
+ @emph{MIPS Options}
+ @gccoptlist{-EL  -EB  -march=@var{arch}  -mtune=@var{arch} @gol
+ -mips1  -mips2  -mips3  -mips4  -mips32  -mips32r2  -mips64 @gol
+--mips16  -mno-mips16  -mflip-mips16 @gol
++-mips16   -mips16e -mno-mips16  -mflip-mips16 @gol
+ -minterlink-mips16  -mno-interlink-mips16 @gol
+ -mabi=@var{abi}  -mabicalls  -mno-abicalls @gol
+ -mshared  -mno-shared  -mxgot  -mno-xgot  -mgp32  -mgp64 @gol
+@@ -642,11 +649,12 @@ Objective-C and Objective-C++ Dialects}.
+ -mmad  -mno-mad  -mfused-madd  -mno-fused-madd  -nocpp @gol
+ -mfix-r4000  -mno-fix-r4000  -mfix-r4400  -mno-fix-r4400 @gol
+ -mfix-vr4120  -mno-fix-vr4120  -mfix-vr4130  -mno-fix-vr4130 @gol
+--mfix-sb1  -mno-fix-sb1 @gol
++-mfix-ice9a  -mno-fix-ice9a  -mfix-sb1  -mno-fix-sb1 @gol
+ -mflush-func=@var{func}  -mno-flush-func @gol
+ -mbranch-cost=@var{num}  -mbranch-likely  -mno-branch-likely @gol
+ -mfp-exceptions -mno-fp-exceptions @gol
+--mvr4130-align -mno-vr4130-align}
++-mvr4130-align -mno-vr4130-align @gol
++-mwarn-framesize=@var{framesize}}
+ @emph{MMIX Options}
+ @gccoptlist{-mlibfuncs  -mno-libfuncs  -mepsilon  -mno-epsilon  -mabi=gnu @gol
+@@ -746,7 +754,7 @@ See RS/6000 and PowerPC Options.
+ -mprefergot  -musermode -multcost=@var{number} -mdiv=@var{strategy} @gol
+ -mdivsi3_libfunc=@var{name}  @gol
+ -madjust-unroll -mindexed-addressing -mgettrcost=@var{number} -mpt-fixed @gol
+- -minvalid-symbols}
++-minvalid-symbols}
+ @emph{SPARC Options}
+ @gccoptlist{-mcpu=@var{cpu-type} @gol
+@@ -3377,6 +3385,14 @@ code.  However, note that using @option{
+ option will @emph{not} warn about unknown pragmas in system
+ headers---for that, @option{-Wunknown-pragmas} must also be used.
++@item -Wno-poison-system-directories
++@opindex Wno-poison-system-directories
++Do not warn for @option{-I} or @option{-L} options using system
++directories such as @file{/usr/include} when cross compiling.  This
++option is intended for use in chroot environments when such
++directories contain the correct headers and libraries for the target
++system rather than the host.
++
+ @item -Wfloat-equal
+ @opindex Wfloat-equal
+ @opindex Wno-float-equal
+@@ -5065,6 +5081,14 @@ variable @env{GCC_EXEC_PREFIX} to the di
+ Don't forget the trailing @samp{/}.
+ @xref{Environment Variables}.
++@item -print-sysroot
++@opindex print-sysroot
++Print the target sysroot directory that will be used during
++compilation.  This is the target sysroot specified either at configure
++time or or using the @option{--sysroot} option, possibly with an extra
++suffix that depends on compilation options.  If no target sysroot is
++specified, the options prints nothing.
++
+ @item -print-sysroot-headers-suffix
+ @opindex print-sysroot-headers-suffix
+ Print the suffix added to the target sysroot when searching for
+@@ -5128,7 +5152,13 @@ the compiler to use information gained f
+ compiling each of them.
+ Not all optimizations are controlled directly by a flag.  Only
+-optimizations that have a flag are listed.
++optimizations that have a flag are listed in this section.
++
++Depending on the target and how GCC was configured, a slightly different 
++set of optimizations may be enabled at each @option{-O} level than 
++those listed here.  You can invoke GCC with @samp{-Q --help=optimizers} 
++to find out the exact set of optimizations that are enabled at each level.
++@xref{Overall Options}, for examples.
+ @table @gcctabopt
+ @item -O
+@@ -5355,9 +5385,9 @@ as follows:
+ @table @gcctabopt
+ @item max-inline-insns-single
+- is set to @var{n}/2.
++is set to @var{n}/2.
+ @item max-inline-insns-auto
+- is set to @var{n}/2.
++is set to @var{n}/2.
+ @end table
+ See below for a documentation of the individual
+@@ -6207,6 +6237,14 @@ arithmetic on constants, the overflowed 
+ The @option{-fstrict-overflow} option is enabled at levels
+ @option{-O2}, @option{-O3}, @option{-Os}.
++@item -falign-arrays
++@opindex falign-arrays
++Set the minimum alignment for array variables to be the largest power
++of two less than or equal to their total storage size, or the biggest
++alignment used on the machine, whichever is smaller.  This option may be
++helpful when compiling legacy code that uses type punning on arrays that
++does not strictly conform to the C standard.
++
+ @item -falign-functions
+ @itemx -falign-functions=@var{n}
+ @opindex falign-functions
+@@ -6757,6 +6795,21 @@ int foo (void)
+ Not all targets support this option.
++@item -fremove-local-statics
++@opindex fremove-local-statics
++Converts function-local static variables to automatic variables when it
++is safe to do so.  This transformation can reduce the number of
++instructions executed due to automatic variables being cheaper to
++read/write than static variables.
++
++@item -fpromote-loop-indices
++@opindex fpromote-loop-indices
++Converts loop indices that have a type shorter than the word size to
++word-sized quantities.  This transformation can reduce the overhead
++associated with sign/zero-extension and truncation of such variables.
++Using @option{-funsafe-loop-optimizations} with this option may result
++in more effective optimization.
++
+ @item --param @var{name}=@var{value}
+ @opindex param
+ In some places, GCC uses various constants to control the amount of
+@@ -7582,23 +7635,42 @@ about any unresolved references (unless 
+ option @samp{-Xlinker -z -Xlinker defs}).  Only a few systems support
+ this option.
++@item -T @var{script}
++@opindex T
++@cindex linker script
++Use @var{script} as the linker script.  This option is supported by most
++systems using the GNU linker.  On some targets, such as bare-board
++targets without an operating system, the @option{-T} option may be required 
++when linking to avoid references to undefined symbols.
++
+ @item -Xlinker @var{option}
+ @opindex Xlinker
+ Pass @var{option} as an option to the linker.  You can use this to
+ supply system-specific linker options which GCC does not know how to
+ recognize.
+-If you want to pass an option that takes an argument, you must use
++If you want to pass an option that takes a separate argument, you must use
+ @option{-Xlinker} twice, once for the option and once for the argument.
+ For example, to pass @option{-assert definitions}, you must write
+ @samp{-Xlinker -assert -Xlinker definitions}.  It does not work to write
+ @option{-Xlinker "-assert definitions"}, because this passes the entire
+ string as a single argument, which is not what the linker expects.
++When using the GNU linker, it is usually more convenient to pass 
++arguments to linker options using the @option{@var{option}=@var{value}}
++syntax than as separate arguments.  For example, you can specify
++@samp{-Xlinker -Map=output.map} rather than
++@samp{-Xlinker -Map -Xlinker output.map}.  Other linkers may not support
++this syntax for command-line options.
++
+ @item -Wl,@var{option}
+ @opindex Wl
+ Pass @var{option} as an option to the linker.  If @var{option} contains
+-commas, it is split into multiple options at the commas.
++commas, it is split into multiple options at the commas.  You can use this
++syntax to pass an argument to the option.  
++For example, @samp{-Wl,-Map,output.map} passes @samp{-Map output.map} to the
++linker.  When using the GNU linker, you can also get the same effect with
++@samp{-Wl,-Map=output.map}.
+ @item -u @var{symbol}
+ @opindex u
+@@ -8500,35 +8572,30 @@ different function prologues), and this 
+ locate the start if functions inside an executable piece of code.  The
+ default is @option{-msched-prolog}.
++@item -mfloat-abi=@var{name}
++@opindex mfloat-abi
++Specifies which floating-point ABI to use.  Permissible values
++are: @samp{soft}, @samp{softfp} and @samp{hard}.
++
++Specifying @samp{soft} causes GCC to generate output containing 
++library calls for floating-point operations.
++@samp{softfp} allows the generation of code using hardware floating-point 
++instructions, but still uses the soft-float calling conventions.  
++@samp{hard} allows generation of floating-point instructions 
++and uses FPU-specific calling conventions.
++
++The default depends on the specific target configuration.  Note that
++the hard-float and soft-float ABIs are not link-compatible; you must
++compile your entire program with the same ABI, and link with a
++compatible set of libraries.
++
+ @item -mhard-float
+ @opindex mhard-float
+-Generate output containing floating point instructions.  This is the
+-default.
++Equivalent to @option{-mfloat-abi=hard}.
+ @item -msoft-float
+ @opindex msoft-float
+-Generate output containing library calls for floating point.
+-@strong{Warning:} the requisite libraries are not available for all ARM
+-targets.  Normally the facilities of the machine's usual C compiler are
+-used, but this cannot be done directly in cross-compilation.  You must make
+-your own arrangements to provide suitable library functions for
+-cross-compilation.
+-
+-@option{-msoft-float} changes the calling convention in the output file;
+-therefore, it is only useful if you compile @emph{all} of a program with
+-this option.  In particular, you need to compile @file{libgcc.a}, the
+-library that comes with GCC, with @option{-msoft-float} in order for
+-this to work.
+-
+-@item -mfloat-abi=@var{name}
+-@opindex mfloat-abi
+-Specifies which ABI to use for floating point values.  Permissible values
+-are: @samp{soft}, @samp{softfp} and @samp{hard}.
+-
+-@samp{soft} and @samp{hard} are equivalent to @option{-msoft-float}
+-and @option{-mhard-float} respectively.  @samp{softfp} allows the generation
+-of floating point instructions, but still uses the soft-float calling
+-conventions.
++Equivalent to @option{-mfloat-abi=soft}.
+ @item -mlittle-endian
+ @opindex mlittle-endian
+@@ -8567,8 +8634,9 @@ assembly code.  Permissible names are: @
+ @samp{arm10e}, @samp{arm1020e}, @samp{arm1022e},
+ @samp{arm1136j-s}, @samp{arm1136jf-s}, @samp{mpcore}, @samp{mpcorenovfp},
+ @samp{arm1156t2-s}, @samp{arm1176jz-s}, @samp{arm1176jzf-s},
+-@samp{cortex-a8}, @samp{cortex-r4}, @samp{cortex-m3},
+-@samp{xscale}, @samp{iwmmxt}, @samp{ep9312}.
++@samp{cortex-a8}, @samp{cortex-r4}, @samp{cortex-r4f}, @samp{cortex-m3},
++@samp{cortex-m1}, @samp{cortex-m0},
++@samp{xscale}, @samp{iwmmxt}, @samp{ep9312} @samp{marvell-f}.
+ @itemx -mtune=@var{name}
+ @opindex mtune
+@@ -8600,13 +8668,26 @@ of the @option{-mcpu=} option.  Permissi
+ @opindex mfp
+ This specifies what floating point hardware (or hardware emulation) is
+ available on the target.  Permissible names are: @samp{fpa}, @samp{fpe2},
+-@samp{fpe3}, @samp{maverick}, @samp{vfp}.  @option{-mfp} and @option{-mfpe}
++@samp{fpe3}, @samp{maverick}, @samp{vfp}, @samp{vfpv3}, @samp{vfpv3-d16},
++@samp{neon}, and @samp{neon-fp16}.  @option{-mfp} and @option{-mfpe}
+ are synonyms for @option{-mfpu}=@samp{fpe}@var{number}, for compatibility
+ with older versions of GCC@.
+ If @option{-msoft-float} is specified this specifies the format of
+ floating point values.
++@item -mfp16-format=@var{name}
++@opindex mfp16-format
++Specify the format of the @code{__fp16} half-precision floating-point type.
++Permissible names are @samp{none}, @samp{ieee}, and @samp{alternative}; 
++the default is @samp{none}, in which case the @code{__fp16} type is not 
++defined.  Refer to the ARM Half-precision Extensions documentation for 
++details of the formats.
++
++@item -mmarvell-div
++@opindex mmarvell-div
++Generate hardware integer division instructions supported by some Marvell cores.
++
+ @item -mstructure-size-boundary=@var{n}
+ @opindex mstructure-size-boundary
+ The size of all structures and unions will be rounded up to a multiple
+@@ -8714,6 +8795,10 @@ This option automatically enables either
+ mixed 16/32-bit Thumb-2 instructions based on the @option{-mcpu=@var{name}}
+ and @option{-march=@var{name}} options.
++@item -mfix-janus-2cc
++@opindex mfix-janus-2cc
++Work around hardware errata for Avalent Janus 2CC cores.
++
+ @item -mtpcs-frame
+ @opindex mtpcs-frame
+ Generate a stack frame that is compliant with the Thumb Procedure Call
+@@ -8749,6 +8834,25 @@ models are @option{soft}, which generate
+ best available method for the selected processor.  The default setting is
+ @option{auto}.
++@item -mlow-irq-latency
++@opindex mlow-irq-latency
++Avoid instructions with high interrupt latency when generating
++code.  This can increase code size and reduce performance.
++The option is off by default.
++
++@item -mword-relocations
++@opindex mword-relocations
++Only generate absolute relocations on word sized values (i.e. R_ARM_ABS32).
++This is enabled by default on targets (uClinux, SymbianOS) where the runtime
++loader imposes this restriction.
++
++@item -mfix-cortex-m3-ldrd
++@opindex mfix-cortex-m3-ldrd
++Some Cortex-M3 cores can cause data corruption when @code{ldrd} instructions
++with overlapping destination and base registers are used.  This option avoids
++generating these instructions.  This option is enabled by default when
++@option{-mcpu=cortex-m3} is specified.
++
+ @end table
+ @node AVR Options
+@@ -11402,7 +11506,7 @@ below, which also classifies the CPUs in
+ @multitable @columnfractions 0.20 0.80
+ @item @strong{Family} @tab @strong{@samp{-mcpu} arguments}
+-@item @samp{51qe} @tab @samp{51qe}
++@item @samp{51} @tab @samp{51} @samp{51ac} @samp{51cn} @samp{51em} @samp{51qe}
+ @item @samp{5206} @tab @samp{5202} @samp{5204} @samp{5206}
+ @item @samp{5206e} @tab @samp{5206e}
+ @item @samp{5208} @tab @samp{5207} @samp{5208}
+@@ -11411,6 +11515,7 @@ below, which also classifies the CPUs in
+ @item @samp{5216} @tab @samp{5214} @samp{5216}
+ @item @samp{52235} @tab @samp{52230} @samp{52231} @samp{52232} @samp{52233} @samp{52234} @samp{52235}
+ @item @samp{5225} @tab @samp{5224} @samp{5225}
++@item @samp{52259} @tab @samp{52252} @samp{52254} @samp{52255} @samp{52256} @samp{52258} @samp{52259}
+ @item @samp{5235} @tab @samp{5232} @samp{5233} @samp{5234} @samp{5235} @samp{523x}
+ @item @samp{5249} @tab @samp{5249}
+ @item @samp{5250} @tab @samp{5250}
+@@ -11418,6 +11523,7 @@ below, which also classifies the CPUs in
+ @item @samp{5272} @tab @samp{5272}
+ @item @samp{5275} @tab @samp{5274} @samp{5275}
+ @item @samp{5282} @tab @samp{5280} @samp{5281} @samp{5282} @samp{528x}
++@item @samp{53017} @tab @samp{53011} @samp{53012} @samp{53013} @samp{53014} @samp{53015} @samp{53016} @samp{53017}
+ @item @samp{5307} @tab @samp{5307}
+ @item @samp{5329} @tab @samp{5327} @samp{5328} @samp{5329} @samp{532x}
+ @item @samp{5373} @tab @samp{5372} @samp{5373} @samp{537x}
+@@ -11711,6 +11817,38 @@ compiled.  Specifying a value of 0 will 
+ other values will force the allocation of that number to the current
+ library but is no more space or time efficient than omitting this option.
++@item -mxgot
++@itemx -mno-xgot
++@opindex mxgot
++@opindex mno-xgot
++When generating position-independent code for ColdFire, generate code
++that works if the GOT has more than 8192 entries.  This code is
++larger and slower than code generated without this option.  On M680x0
++processors, this option is not needed; @option{-fPIC} suffices.
++
++GCC normally uses a single instruction to load values from the GOT@.
++While this is relatively efficient, it only works if the GOT
++is smaller than about 64k.  Anything larger causes the linker
++to report an error such as:
++
++@cindex relocation truncated to fit (ColdFire)
++@smallexample
++relocation truncated to fit: R_68K_GOT16O foobar
++@end smallexample
++
++If this happens, you should recompile your code with @option{-mxgot}.
++It should then work with very large GOTs.  However, code generated with
++@option{-mxgot} is less efficient, since it takes 4 instructions to fetch
++the value of a global symbol.
++
++Note that some linkers, including newer versions of the GNU linker,
++can create multiple GOTs and sort GOT entries.  If you have such a linker,
++you should only need to use @option{-mxgot} when compiling a single
++object file that accesses more than 8192 GOT entries.  Very few do.
++
++These options have no effect unless GCC is generating
++position-independent code.
++
+ @end table
+ @node M68hc1x Options
+@@ -11871,6 +12009,7 @@ The processor names are:
+ @samp{24kec}, @samp{24kef2_1}, @samp{24kef1_1},
+ @samp{34kc}, @samp{34kf2_1}, @samp{34kf1_1},
+ @samp{74kc}, @samp{74kf2_1}, @samp{74kf1_1}, @samp{74kf3_2},
++@samp{ice9},
+ @samp{m4k},
+ @samp{orion},
+ @samp{r2000}, @samp{r3000}, @samp{r3900}, @samp{r4000}, @samp{r4400},
+@@ -11879,7 +12018,8 @@ The processor names are:
+ @samp{sb1},
+ @samp{sr71000},
+ @samp{vr4100}, @samp{vr4111}, @samp{vr4120}, @samp{vr4130}, @samp{vr4300},
+-@samp{vr5000}, @samp{vr5400} and @samp{vr5500}.
++@samp{vr5000}, @samp{vr5400}, @samp{vr5500}
++and @samp{xlr}.
+ The special value @samp{from-abi} selects the
+ most compatible architecture for the selected ABI (that is,
+ @samp{mips1} for 32-bit ABIs and @samp{mips3} for 64-bit ABIs)@.
+@@ -11957,11 +12097,14 @@ Equivalent to @samp{-march=mips32r2}.
+ Equivalent to @samp{-march=mips64}.
+ @item -mips16
++@itemx -mips16e
+ @itemx -mno-mips16
+ @opindex mips16
++@opindex mips16e
+ @opindex mno-mips16
+ Generate (do not generate) MIPS16 code.  If GCC is targetting a
+ MIPS32 or MIPS64 architecture, it will make use of the MIPS16e ASE@.
++@option{-mips16e} is a deprecated alias for @option{-mips16}.
+ MIPS16 code generation can also be controlled on a per-function basis
+ by means of @code{mips16} and @code{nomips16} attributes.  
+@@ -12453,6 +12596,12 @@ although GCC will avoid using @code{mflo
+ VR4130 @code{macc}, @code{macchi}, @code{dmacc} and @code{dmacchi}
+ instructions are available instead.
++@item -mfix-ice9a
++@itemx -mno-fix-ice9a
++@opindex mfix-ice9a
++Work around ICE9A double floating-point multiplication
++errata.  When enabled, the preprocessor defines @code{_MIPS_FIX_ICE9A}.
++
+ @item -mfix-sb1
+ @itemx -mno-fix-sb1
+ @opindex mfix-sb1
+@@ -12512,6 +12661,13 @@ thinks should execute in parallel.
+ This option only has an effect when optimizing for the VR4130.
+ It normally makes code faster, but at the expense of making it bigger.
+ It is enabled by default at optimization level @option{-O3}.
++
++@item -mwarn-framesize=@var{framesize}
++@opindex mwarn-framesize
++Emit a compile-time warning if the current function exceeds the given
++frame size.  This is intended to help identify functions which
++may cause a stack overflow in run-time environments with limited or
++absent stack, e.g., BIOS. 
+ @end table
+ @node MMIX Options
+@@ -12943,11 +13099,12 @@ Supported values for @var{cpu_type} are 
+ @samp{601}, @samp{602}, @samp{603}, @samp{603e}, @samp{604},
+ @samp{604e}, @samp{620}, @samp{630}, @samp{740}, @samp{7400},
+ @samp{7450}, @samp{750}, @samp{801}, @samp{821}, @samp{823},
+-@samp{860}, @samp{970}, @samp{8540}, @samp{ec603e}, @samp{G3},
+-@samp{G4}, @samp{G5}, @samp{power}, @samp{power2}, @samp{power3},
+-@samp{power4}, @samp{power5}, @samp{power5+}, @samp{power6},
+-@samp{power6x}, @samp{common}, @samp{powerpc}, @samp{powerpc64},
+-@samp{rios}, @samp{rios1}, @samp{rios2}, @samp{rsc}, and @samp{rs64}.
++@samp{860}, @samp{970}, @samp{8540}, @samp{e300c2}, @samp{e300c3},
++@samp{e500mc}, @samp{ec603e}, @samp{G3}, @samp{G4}, @samp{G5},
++@samp{power}, @samp{power2}, @samp{power3}, @samp{power4},
++@samp{power5}, @samp{power5+}, @samp{power6}, @samp{power6x},
++@samp{common}, @samp{powerpc}, @samp{powerpc64}, @samp{rios},
++@samp{rios1}, @samp{rios2}, @samp{rsc}, and @samp{rs64}.
+ @option{-mcpu=common} selects a completely generic processor.  Code
+ generated under this option will run on any POWER or PowerPC processor.
+@@ -13482,12 +13639,11 @@ header to indicate that @samp{eabi} exte
+ On System V.4 and embedded PowerPC systems do (do not) adhere to the
+ Embedded Applications Binary Interface (eabi) which is a set of
+ modifications to the System V.4 specifications.  Selecting @option{-meabi}
+-means that the stack is aligned to an 8 byte boundary, a function
+-@code{__eabi} is called to from @code{main} to set up the eabi
+-environment, and the @option{-msdata} option can use both @code{r2} and
++means that the stack is aligned to an 8 byte boundary,
++and the @option{-msdata} option can use both @code{r2} and
+ @code{r13} to point to two separate small data areas.  Selecting
+ @option{-mno-eabi} means that the stack is aligned to a 16 byte boundary,
+-do not call an initialization function from @code{main}, and the
++and the
+ @option{-msdata} option will only use @code{r13} to point to a single
+ small data area.  The @option{-meabi} option is on by default if you
+ configured GCC using one of the @samp{powerpc*-*-eabi*} options.
+@@ -14916,12 +15072,25 @@ Use it to conform to a non-default appli
+ @item -fno-common
+ @opindex fno-common
+-In C, allocate even uninitialized global variables in the data section of the
+-object file, rather than generating them as common blocks.  This has the
+-effect that if the same variable is declared (without @code{extern}) in
+-two different compilations, you will get an error when you link them.
+-The only reason this might be useful is if you wish to verify that the
+-program will work on other systems which always work this way.
++In C code, controls the placement of uninitialized global variables.
++Unix C compilers have traditionally permitted multiple definitions of
++such variables in different compilation units by placing the variables
++in a common block.  
++This is the behavior specified by @option{-fcommon}, and is the default 
++for GCC on most targets.  
++On the other hand, this behavior is not required by ISO C, and on some
++targets may carry a speed or code size penalty on variable references.
++The @option{-fno-common} option specifies that the compiler should place 
++uninitialized global variables in the data section of the object file,
++rather than generating them as common blocks.
++This has the effect that if the same variable is declared 
++(without @code{extern}) in two different compilations,
++you will get a multiple-definition error when you link them.
++In this case, you must compile with @option{-fcommon} instead.  
++Compiling with @option{-fno-common} is useful on targets for which 
++it provides better performance, or if you wish to verify that the
++program will work on other systems which always treat uninitialized
++variable declarations this way.
+ @item -fno-ident
+ @opindex fno-ident
+--- a/gcc/doc/md.texi
++++ b/gcc/doc/md.texi
+@@ -25,11 +25,11 @@ See the next chapter for information on 
+ * Example::             An explained example of a @code{define_insn} pattern.
+ * RTL Template::        The RTL template defines what insns match a pattern.
+ * Output Template::     The output template says how to make assembler code
+-                          from such an insn.
++                        from such an insn.
+ * Output Statement::    For more generality, write C code to output
+-                          the assembler code.
++                        the assembler code.
+ * Predicates::          Controlling what kinds of operands can be used
+-                          for an insn.
++                        for an insn.
+ * Constraints::         Fine-tuning operand selection.
+ * Standard Names::      Names mark patterns to use for code generation.
+ * Pattern Ordering::    When the order of patterns makes a difference.
+@@ -38,13 +38,13 @@ See the next chapter for information on 
+ * Looping Patterns::    How to define patterns for special looping insns.
+ * Insn Canonicalizations::Canonicalization of Instructions
+ * Expander Definitions::Generating a sequence of several RTL insns
+-                          for a standard operation.
++                        for a standard operation.
+ * Insn Splitting::      Splitting Instructions into Multiple Instructions.
+-* Including Patterns::      Including Patterns in Machine Descriptions.
++* Including Patterns::  Including Patterns in Machine Descriptions.
+ * Peephole Definitions::Defining machine-specific peephole optimizations.
+ * Insn Attributes::     Specifying the value of attributes for generated insns.
+ * Conditional Execution::Generating @code{define_insn} patterns for
+-                           predication.
++                         predication.
+ * Constant Definitions::Defining symbolic constants that can be used in the
+                         md file.
+ * Iterators::           Using iterators to generate patterns from a template.
+@@ -1626,7 +1626,7 @@ it includes both constraints that are us
+ constraints that aren't.  The compiler source file mentioned in the
+ table heading for each architecture is the definitive reference for
+ the meanings of that architecture's constraints.
+- 
++
+ @table @emph
+ @item ARM family---@file{config/arm/arm.h}
+ @table @code
+@@ -2889,10 +2889,10 @@ Signed 16-bit constant (@minus{}32768--3
+ @item L
+ Value appropriate as displacement.
+ @table @code
+-       @item (0..4095)
+-       for short displacement
+-       @item (-524288..524287)
+-       for long displacement
++@item (0..4095)
++for short displacement
++@item (-524288..524287)
++for long displacement
+ @end table
+ @item M
+@@ -2901,14 +2901,14 @@ Constant integer with a value of 0x7ffff
+ @item N
+ Multiple letter constraint followed by 4 parameter letters.
+ @table @code
+-         @item 0..9:
+-         number of the part counting from most to least significant
+-         @item H,Q:
+-         mode of the part
+-         @item D,S,H:
+-         mode of the containing operand
+-         @item 0,F:
+-         value of the other parts (F---all bits set)
++@item 0..9:
++number of the part counting from most to least significant
++@item H,Q:
++mode of the part
++@item D,S,H:
++mode of the containing operand
++@item 0,F:
++value of the other parts (F---all bits set)
+ @end table
+ The constraint matches if the specified part of a constant
+ has a value different from its other parts.
+@@ -3345,8 +3345,8 @@ definition from the i386 machine descrip
+ (define_peephole2
+   [(match_scratch:SI 3 "r")
+    (set (match_operand:SI 0 "register_operand" "")
+-      (mult:SI (match_operand:SI 1 "memory_operand" "")
+-               (match_operand:SI 2 "immediate_operand" "")))]
++        (mult:SI (match_operand:SI 1 "memory_operand" "")
++                 (match_operand:SI 2 "immediate_operand" "")))]
+   "!satisfies_constraint_K (operands[2])"
+@@ -5378,15 +5378,15 @@ following for its @code{dbra} instructio
+ @group
+ (define_insn "decrement_and_branch_until_zero"
+   [(set (pc)
+-      (if_then_else
+-        (ge (plus:SI (match_operand:SI 0 "general_operand" "+d*am")
+-                     (const_int -1))
+-            (const_int 0))
+-        (label_ref (match_operand 1 "" ""))
+-        (pc)))
++        (if_then_else
++          (ge (plus:SI (match_operand:SI 0 "general_operand" "+d*am")
++                       (const_int -1))
++              (const_int 0))
++          (label_ref (match_operand 1 "" ""))
++          (pc)))
+    (set (match_dup 0)
+-      (plus:SI (match_dup 0)
+-               (const_int -1)))]
++        (plus:SI (match_dup 0)
++                 (const_int -1)))]
+   "find_reg_note (insn, REG_NONNEG, 0)"
+   "@dots{}")
+ @end group
+@@ -5404,14 +5404,14 @@ pattern will not be matched by the combi
+ @group
+ (define_insn "decrement_and_branch_until_zero"
+   [(set (pc)
+-      (if_then_else
+-        (ge (match_operand:SI 0 "general_operand" "+d*am")
+-            (const_int 1))
+-        (label_ref (match_operand 1 "" ""))
+-        (pc)))
++        (if_then_else
++          (ge (match_operand:SI 0 "general_operand" "+d*am")
++              (const_int 1))
++          (label_ref (match_operand 1 "" ""))
++          (pc)))
+    (set (match_dup 0)
+-      (plus:SI (match_dup 0)
+-               (const_int -1)))]
++        (plus:SI (match_dup 0)
++                 (const_int -1)))]
+   "find_reg_note (insn, REG_NONNEG, 0)"
+   "@dots{}")
+ @end group
+@@ -6033,7 +6033,7 @@ from i386.md:
+   "&& reload_completed"
+   [(parallel [(set (match_dup 0)
+                    (and:SI (match_dup 0) (const_int 65535)))
+-            (clobber (reg:CC 17))])]
++              (clobber (reg:CC 17))])]
+   ""
+   [(set_attr "type" "alu1")])
+@@ -7158,10 +7158,10 @@ the instruction issue is possible if the
+ automaton state to another one.  This algorithm is very fast, and
+ furthermore, its speed is not dependent on processor
+ complexity@footnote{However, the size of the automaton depends on
+-  processor complexity.  To limit this effect, machine descriptions
+-  can split orthogonal parts of the machine description among several
+-  automata: but then, since each of these must be stepped independently,
+-  this does cause a small decrease in the algorithm's performance.}.
++processor complexity.  To limit this effect, machine descriptions
++can split orthogonal parts of the machine description among several
++automata: but then, since each of these must be stepped independently,
++this does cause a small decrease in the algorithm's performance.}.
+ @cindex automaton based pipeline description
+ The rest of this section describes the directives that constitute
+@@ -7761,8 +7761,8 @@ rtx-based construct, such as a @code{def
+ @menu
+ * Defining Mode Iterators:: Defining a new mode iterator.
+-* Substitutions::         Combining mode iterators with substitutions
+-* Examples::              Examples
++* Substitutions::           Combining mode iterators with substitutions
++* Examples::                Examples
+ @end menu
+ @node Defining Mode Iterators
+--- a/gcc/doc/options.texi
++++ b/gcc/doc/options.texi
+@@ -29,13 +29,13 @@ The files can contain the following type
+ @itemize @bullet
+ @item
+-A language definition record. Â These records have two fields: the
+-string @samp{Language} and the name of the language. Â Once a language
++A language definition record.  These records have two fields: the
++string @samp{Language} and the name of the language.  Once a language
+ has been declared in this way, it can be used as an option property.
+ @xref{Option properties}.
+ @item
+-An option definition record. Â These records have the following fields:
++An option definition record.  These records have the following fields:
+ @enumerate
+ @item
+@@ -62,11 +62,11 @@ tab forms the help text.  This allows yo
+ of argument the option takes.
+ @item
+-A target mask record. Â These records have one field of the form
+-@samp{Mask(@var{x})}. Â The options-processing script will automatically
++A target mask record.  These records have one field of the form
++@samp{Mask(@var{x})}.  The options-processing script will automatically
+ allocate a bit in @code{target_flags} (@pxref{Run-time Target}) for
+ each mask name @var{x} and set the macro @code{MASK_@var{x}} to the
+-appropriate bitmask. Â It will also declare a @code{TARGET_@var{x}}
++appropriate bitmask.  It will also declare a @code{TARGET_@var{x}}
+ macro that has the value 1 when bit @code{MASK_@var{x}} is set and
+ 0 otherwise.
+--- a/gcc/doc/passes.texi
++++ b/gcc/doc/passes.texi
+@@ -20,7 +20,7 @@ where near complete.
+ @menu
+ * Parsing pass::         The language front end turns text into bits.
+ * Gimplification pass::  The bits are turned into something we can optimize.
+-* Pass manager::       Sequencing the optimization passes.
++* Pass manager::         Sequencing the optimization passes.
+ * Tree-SSA passes::      Optimizations on a high-level representation.
+ * RTL passes::           Optimizations on a low-level representation.
+ @end menu
+--- a/gcc/doc/rtl.texi
++++ b/gcc/doc/rtl.texi
+@@ -3019,11 +3019,9 @@ represents @var{x} before @var{x} is mod
+ @var{m} must be the machine mode for pointers on the machine in use.
+ The expression @var{y} must be one of three forms:
+-@table @code
+ @code{(plus:@var{m} @var{x} @var{z})},
+ @code{(minus:@var{m} @var{x} @var{z})}, or
+ @code{(plus:@var{m} @var{x} @var{i})},
+-@end table
+ where @var{z} is an index register and @var{i} is a constant.
+ Here is an example of its use:
+--- a/gcc/doc/sourcebuild.texi
++++ b/gcc/doc/sourcebuild.texi
+@@ -198,9 +198,7 @@ timestamp.
+ @itemize @bullet
+ @item The standard GNU @file{config.sub} and @file{config.guess}
+-files, kept in the top level directory, are used.  FIXME: when is the
+-@file{config.guess} file in the @file{gcc} directory (that just calls
+-the top level one) used?
++files, kept in the top level directory, are used.
+ @item The file @file{config.gcc} is used to handle configuration
+ specific to the particular target machine.  The file
+@@ -1021,7 +1019,11 @@ an empty @var{exclude-opts} list.
+ @item  @{ dg-xfail-if @var{comment} @{ @var{selector} @} @{ @var{include-opts} @} @{ @var{exclude-opts} @} @}
+ Expect the test to fail if the conditions (which are the same as for
+-@code{dg-skip-if}) are met.
++@code{dg-skip-if}) are met.  This does not affect the execute step.
++
++@item  @{ dg-xfail-run-if @var{comment} @{ @var{selector} @} @{ @var{include-opts} @} @{ @var{exclude-opts} @} @}
++Expect the execute step of a test to fail if the conditions (which are
++the same as for @code{dg-skip-if}) and @code{dg-xfail-if}) are met.
+ @item @{ dg-require-@var{support} args @}
+ Skip the test if the target does not provide the required support;
+--- a/gcc/doc/tm.texi
++++ b/gcc/doc/tm.texi
+@@ -35,7 +35,7 @@ through the macros defined in the @file{
+ * Register Classes::    Defining the classes of hardware registers.
+ * Old Constraints::     The old way to define machine-specific constraints.
+ * Stack and Calling::   Defining which way the stack grows and by how much.
+-* Varargs::           Defining the varargs macros.
++* Varargs::             Defining the varargs macros.
+ * Trampolines::         Code set up at run time to enter a nested function.
+ * Library Calls::       Controlling how library routines are implicitly called.
+ * Addressing Modes::    Defining addressing modes valid for memory operands.
+@@ -44,7 +44,7 @@ through the macros defined in the @file{
+ * Costs::               Defining relative costs of different operations.
+ * Scheduling::          Adjusting the behavior of the instruction scheduler.
+ * Sections::            Dividing storage into text, data, and other sections.
+-* PIC::                       Macros for position independent code.
++* PIC::                 Macros for position independent code.
+ * Assembler Format::    Defining how to write insns and pseudo-ops to output.
+ * Debugging Info::      Defining the format of debugging output.
+ * Floating Point::      Handling floating point for cross-compilers.
+@@ -1138,6 +1138,9 @@ macro is used instead of that alignment 
+ If this macro is not defined, then @var{basic-align} is used.
++This macro should never be used directly; use
++@code{calculate_global_alignment} instead.
++
+ @findex strcpy
+ One use of this macro is to increase alignment of medium-size data to
+ make it all fit in fewer cache lines.  Another is to cause character
+@@ -1169,6 +1172,9 @@ If this macro is not defined, then @var{
+ One use of this macro is to increase alignment of medium-size data to
+ make it all fit in fewer cache lines.
++
++This macro should never be used directly; use
++@code{calculate_local_alignment} instead.
+ @end defmac
+ @defmac EMPTY_FIELD_BOUNDARY
+@@ -1895,11 +1901,11 @@ For passing values in registers, see @re
+ For returning values in registers, see @ref{Scalar Return}.
+ @menu
+-* Register Basics::           Number and kinds of registers.
+-* Allocation Order::          Order in which registers are allocated.
+-* Values in Registers::               What kinds of values each reg can hold.
+-* Leaf Functions::            Renumbering registers for leaf functions.
+-* Stack Registers::           Handling a register stack such as 80387.
++* Register Basics::             Number and kinds of registers.
++* Allocation Order::            Order in which registers are allocated.
++* Values in Registers::         What kinds of values each reg can hold.
++* Leaf Functions::              Renumbering registers for leaf functions.
++* Stack Registers::             Handling a register stack such as 80387.
+ @end menu
+ @node Register Basics
+@@ -2064,6 +2070,15 @@ machines, define @code{REG_ALLOC_ORDER} 
+ the highest numbered allocable register first.
+ @end defmac
++@deftypefn {Target Hook} void TARGET_ADJUST_REG_ALLOC_ORDER (int *@var{order})
++If @code{REG_ALLOC_ORDER} has been defined, this hook is called after
++all command-line options have been processed.   It enables adjustment of
++the allocation order based on target-specific flags.  Any such adjustment
++should be performed by the hook directly on the elements of the
++array @code{order}.  On entry to the hook this array is an
++unmodified copy of @code{REG_ALLOC_ORDER}.
++@end deftypefn
++
+ @defmac ORDER_REGS_FOR_LOCAL_ALLOC
+ A C statement (sans semicolon) to choose the order in which to allocate
+ hard registers for pseudo-registers local to a basic block.
+@@ -2476,6 +2491,15 @@ address where its value is either multip
+ added to another register (as well as added to a displacement).
+ @end defmac
++@defmac MODE_INDEX_REG_CLASS (@var{mode})
++This is a variation of the @code{INDEX_REG_CLASS} macro which allows
++the selection of an index register in a mode dependent manner.  It can
++return @code{NO_REGS} for modes that do not support any form of index
++register.  If @var{mode} is @code{VOIDmode} then the macro should
++return a class of registers that is suitable for all addresses in
++which an index register of some form is allowed.
++@end defmac
++
+ @defmac REGNO_OK_FOR_BASE_P (@var{num})
+ A C expression which is nonzero if register number @var{num} is
+ suitable for use as a base register in operand addresses.  It may be
+@@ -2535,6 +2559,14 @@ looking for one that is valid, and will 
+ only if neither labeling works.
+ @end defmac
++@defmac REGNO_MODE_OK_FOR_INDEX_P (@var{num}, @var{mode})
++A C expression that is just like @code{REGNO_OK_FOR_INDEX_P}, except
++that the expression may examine the mode of the memory reference
++in @var{mode}.  If @var{mode} is @code{VOIDmode}, the macro should
++return true if @var{x} is suitable for all modes in which some
++form of index register is allowed.
++@end defmac
++
+ @defmac PREFERRED_RELOAD_CLASS (@var{x}, @var{class})
+ A C expression that places additional restrictions on the register class
+ to use when it is necessary to copy value @var{x} into a register in class
+@@ -2969,7 +3001,7 @@ be treated like memory constraints by th
+ It should return 1 if the operand type represented by the constraint
+ at the start of @var{str}, the first letter of which is the letter @var{c},
+- comprises a subset of all memory references including
++comprises a subset of all memory references including
+ all those whose address is simply a base register.  This allows the reload
+ pass to reload an operand, if it does not directly correspond to the operand
+ type of @var{c}, by copying its address into a base register.
+@@ -4272,6 +4304,18 @@ The definition of @code{LIBRARY_VALUE} n
+ data types, because none of the library functions returns such types.
+ @end defmac
++@deftypefn {Target Hook} rtx TARGET_LIBCALL_VALUE (enum machine_mode
++@var{mode}, rtx @var{fun})
++Define this hook if the back-end needs to know the name of the libcall
++function in order to determine where the result should be returned.  
++
++The mode of the result is given by @var{mode} and the name of the called
++library function is given by @var{fun}.  The hook should return an RTX 
++representing the place where the library function result will be returned.
++
++If this hook is not defined, then LIBCALL_VALUE will be used.
++@end deftypefn
++
+ @defmac FUNCTION_VALUE_REGNO_P (@var{regno})
+ A C expression that is nonzero if @var{regno} is the number of a hard
+ register in which the values of called function may come back.
+@@ -6741,10 +6785,10 @@ instructions do.
+ * Uninitialized Data::   Output of uninitialized variables.
+ * Label Output::         Output and generation of labels.
+ * Initialization::       General principles of initialization
+-                         and termination routines.
++                         and termination routines.
+ * Macros for Initialization::
+-                       Specific macros that control the handling of
+-                         initialization and termination routines.
++                         Specific macros that control the handling of
++                         initialization and termination routines.
+ * Instruction Output::   Output of actual instructions.
+ * Dispatch Tables::      Output of jump tables.
+ * Exception Region Output:: Output of exception region code.
+@@ -6873,7 +6917,7 @@ This is true on most ELF targets.
+ Choose a set of section attributes for use by @code{TARGET_ASM_NAMED_SECTION}
+ based on a variable or function decl, a section name, and whether or not the
+ declaration's initializer may contain runtime relocations.  @var{decl} may be
+- null, in which case read-write data should be assumed.
++null, in which case read-write data should be assumed.
+ The default version of this function handles choosing code vs data,
+ read-only vs read-write data, and @code{flag_pic}.  You should only
+@@ -7077,7 +7121,7 @@ assembler for grouping arithmetic expres
+ default to normal parentheses, which is correct for most assemblers.
+ @end deftypevr
+-  These macros are provided by @file{real.h} for writing the definitions
++These macros are provided by @file{real.h} for writing the definitions
+ of @code{ASM_OUTPUT_DOUBLE} and the like:
+ @defmac REAL_VALUE_TO_TARGET_SINGLE (@var{x}, @var{l})
+@@ -10355,6 +10399,36 @@ and @var{type2}, or @code{NULL} if valid
+ the front end.
+ @end deftypefn
++@deftypefn {Target Hook} {const char *} TARGET_INVALID_PARAMETER_TYPE (tree @var{type})
++If defined, this macro returns the diagnostic message when it is
++invalid for functions to include parameters of type @var{type}, 
++or @code{NULL} if validity should be determined by
++the front end.
++@end deftypefn
++
++@deftypefn {Target Hook} {const char *} TARGET_INVALID_RETURN_TYPE (tree @var{type})
++If defined, this macro returns the diagnostic message when it is
++invalid for functions to have return type @var{type}, 
++or @code{NULL} if validity should be determined by
++the front end.
++@end deftypefn
++
++@deftypefn {Target Hook} {tree} TARGET_PROMOTED_TYPE (tree @var{type})
++If defined, this target hook returns the type to which values of 
++@var{type} should be promoted when they appear in expressions, 
++analogous to the integer promotions, or @code{NULL_TREE} to use the
++front end's normal promotion rules.  This hook is useful when there are
++target-specific types with special promotion rules.
++@end deftypefn
++
++@deftypefn {Target Hook} {tree} TARGET_CONVERT_TO_TYPE (tree @var{type}, tree @var{expr})
++If defined, this hook returns the result of converting @var{expr} to 
++@var{type}.  It should return the converted expression, 
++or @code{NULL_TREE} to apply the front end's normal conversion rules.
++This hook is useful when there are target-specific types with special 
++conversion rules.
++@end deftypefn
++
+ @defmac TARGET_USE_JCR_SECTION
+ This macro determines whether to use the JCR section to register Java
+ classes. By default, TARGET_USE_JCR_SECTION is defined to 1 if both
+@@ -10372,3 +10446,14 @@ to the functions in @file{libgcc} that p
+ call stack unwinding.  It is used in declarations in @file{unwind-generic.h}
+ and the associated definitions of those functions.
+ @end defmac
++
++@deftypefn {Target Hook} {bool} TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS (void)
++When optimization is disabled, this hook indicates whether or not
++arguments should be allocated to stack slots.  Normally, GCC allocates
++stacks slots for arguments when not optimizing in order to make
++debugging easier.  However, when a function is declared with
++@code{__attribute__((naked))}, there is no stack frame, and the compiler
++cannot safely move arguments from the registers in which they are passed
++to the stack.  Therefore, this hook should return true in general, but
++false for naked functions.  The default implementation always returns true.
++@end deftypefn
+--- a/gcc/doc/tree-ssa.texi
++++ b/gcc/doc/tree-ssa.texi
+@@ -37,12 +37,12 @@ functions and programming constructs nee
+ passes for GIMPLE@.
+ @menu
+-* GENERIC::           A high-level language-independent representation.
++* GENERIC::             A high-level language-independent representation.
+ * GIMPLE::              A lower-level factored tree representation.
+-* Annotations::               Attributes for statements and variables.
+-* Statement Operands::        Variables referenced by GIMPLE statements.
+-* SSA::                       Static Single Assignment representation.
+-* Alias analysis::    Representing aliased loads and stores.
++* Annotations::         Attributes for statements and variables.
++* Statement Operands::  Variables referenced by GIMPLE statements.
++* SSA::                 Static Single Assignment representation.
++* Alias analysis::      Representing aliased loads and stores.
+ @end menu
+ @node GENERIC
+@@ -735,10 +735,10 @@ void f()
+                 | RELOP
+                         op0 -> val
+                         op1 -> val
+-              | COND_EXPR
+-                      op0 -> condition
+-                      op1 -> val
+-                      op2 -> val
++                | COND_EXPR
++                        op0 -> condition
++                        op1 -> val
++                        op2 -> val
+ @end smallexample
+ @node Annotations
+@@ -943,7 +943,7 @@ How to choose the appropriate iterator:
+ @enumerate
+ @item Determine whether you are need to see the operand pointers, or just the
+-    trees, and choose the appropriate macro:
++trees, and choose the appropriate macro:
+ @smallexample
+ Need            Macro:
+@@ -954,12 +954,12 @@ tree            FOR_EACH_SSA_TREE_OPERAN
+ @end smallexample
+ @item You need to declare a variable of the type you are interested
+-    in, and an ssa_op_iter structure which serves as the loop
+-    controlling variable.
++in, and an ssa_op_iter structure which serves as the loop controlling
++variable.
+ @item Determine which operands you wish to use, and specify the flags of
+-    those you are interested in.  They are documented in
+-    @file{tree-ssa-operands.h}:
++those you are interested in.  They are documented in
++@file{tree-ssa-operands.h}:
+ @smallexample
+ #define SSA_OP_USE              0x01    /* @r{Real USE operands.}  */
+@@ -1228,27 +1228,27 @@ which''.
+ The following macros can be used to examine PHI nodes
+-@defmac       PHI_RESULT (@var{phi})
++@defmac PHI_RESULT (@var{phi})
+ Returns the @code{SSA_NAME} created by PHI node @var{phi} (i.e.,
+ @var{phi}'s LHS)@.
+ @end defmac
+-@defmac       PHI_NUM_ARGS (@var{phi})
++@defmac PHI_NUM_ARGS (@var{phi})
+ Returns the number of arguments in @var{phi}.  This number is exactly
+ the number of incoming edges to the basic block holding @var{phi}@.
+ @end defmac
+-@defmac       PHI_ARG_ELT (@var{phi}, @var{i})
++@defmac PHI_ARG_ELT (@var{phi}, @var{i})
+ Returns a tuple representing the @var{i}th argument of @var{phi}@.
+ Each element of this tuple contains an @code{SSA_NAME} @var{var} and
+ the incoming edge through which @var{var} flows.
+ @end defmac
+-@defmac       PHI_ARG_EDGE (@var{phi}, @var{i})
++@defmac PHI_ARG_EDGE (@var{phi}, @var{i})
+ Returns the incoming edge for the @var{i}th argument of @var{phi}.
+ @end defmac
+-@defmac       PHI_ARG_DEF (@var{phi}, @var{i})
++@defmac PHI_ARG_DEF (@var{phi}, @var{i})
+ Returns the @code{SSA_NAME} for the @var{i}th argument of @var{phi}.
+ @end defmac
+@@ -1274,36 +1274,36 @@ the program@.
+ For instance, given the following code:
+ @smallexample
+-     1        L0:
+-     2        x_1 = PHI (0, x_5)
+-     3        if (x_1 < 10)
+-     4          if (x_1 > 7)
+-     5            y_2 = 0
+-     6          else
+-     7            y_3 = x_1 + x_7
+-     8          endif
+-     9          x_5 = x_1 + 1
++     1  L0:
++     2  x_1 = PHI (0, x_5)
++     3  if (x_1 < 10)
++     4    if (x_1 > 7)
++     5      y_2 = 0
++     6    else
++     7      y_3 = x_1 + x_7
++     8    endif
++     9    x_5 = x_1 + 1
+      10   goto L0;
+-     11       endif
++     11 endif
+ @end smallexample
+ Suppose that we insert new names @code{x_10} and @code{x_11} (lines
+ @code{4} and @code{8})@.
+ @smallexample
+-     1        L0:
+-     2        x_1 = PHI (0, x_5)
+-     3        if (x_1 < 10)
+-     4          x_10 = @dots{}
+-     5          if (x_1 > 7)
+-     6            y_2 = 0
+-     7          else
+-     8            x_11 = @dots{}
+-     9            y_3 = x_1 + x_7
+-     10         endif
+-     11         x_5 = x_1 + 1
+-     12         goto L0;
+-     13       endif
++     1  L0:
++     2  x_1 = PHI (0, x_5)
++     3  if (x_1 < 10)
++     4    x_10 = @dots{}
++     5    if (x_1 > 7)
++     6      y_2 = 0
++     7    else
++     8      x_11 = @dots{}
++     9      y_3 = x_1 + x_7
++     10   endif
++     11   x_5 = x_1 + 1
++     12   goto L0;
++     13 endif
+ @end smallexample
+ We want to replace all the uses of @code{x_1} with the new definitions
+@@ -1341,40 +1341,40 @@ There are several @code{TODO} flags that
+ @itemize @bullet
+ @item @code{TODO_update_ssa}.  Update the SSA form inserting PHI nodes
+-      for newly exposed symbols and virtual names marked for updating.
+-      When updating real names, only insert PHI nodes for a real name
+-      @code{O_j} in blocks reached by all the new and old definitions for
+-      @code{O_j}.  If the iterated dominance frontier for @code{O_j}
+-      is not pruned, we may end up inserting PHI nodes in blocks that
+-      have one or more edges with no incoming definition for
+-      @code{O_j}.  This would lead to uninitialized warnings for
+-      @code{O_j}'s symbol@.
++for newly exposed symbols and virtual names marked for updating.
++When updating real names, only insert PHI nodes for a real name
++@code{O_j} in blocks reached by all the new and old definitions for
++@code{O_j}.  If the iterated dominance frontier for @code{O_j}
++is not pruned, we may end up inserting PHI nodes in blocks that
++have one or more edges with no incoming definition for
++@code{O_j}.  This would lead to uninitialized warnings for
++@code{O_j}'s symbol@.
+ @item @code{TODO_update_ssa_no_phi}.  Update the SSA form without
+-      inserting any new PHI nodes at all.  This is used by passes that
+-      have either inserted all the PHI nodes themselves or passes that
+-      need only to patch use-def and def-def chains for virtuals
+-      (e.g., DCE)@.
++inserting any new PHI nodes at all.  This is used by passes that
++have either inserted all the PHI nodes themselves or passes that
++need only to patch use-def and def-def chains for virtuals
++(e.g., DCE)@.
+ @item @code{TODO_update_ssa_full_phi}.  Insert PHI nodes everywhere
+-      they are needed.  No pruning of the IDF is done.  This is used
+-      by passes that need the PHI nodes for @code{O_j} even if it
+-      means that some arguments will come from the default definition
+-      of @code{O_j}'s symbol (e.g., @code{pass_linear_transform})@.
+-
+-      WARNING: If you need to use this flag, chances are that your
+-      pass may be doing something wrong.  Inserting PHI nodes for an
+-      old name where not all edges carry a new replacement may lead to
+-      silent codegen errors or spurious uninitialized warnings@.
++they are needed.  No pruning of the IDF is done.  This is used
++by passes that need the PHI nodes for @code{O_j} even if it
++means that some arguments will come from the default definition
++of @code{O_j}'s symbol (e.g., @code{pass_linear_transform})@.
++
++WARNING: If you need to use this flag, chances are that your
++pass may be doing something wrong.  Inserting PHI nodes for an
++old name where not all edges carry a new replacement may lead to
++silent codegen errors or spurious uninitialized warnings@.
+ @item @code{TODO_update_ssa_only_virtuals}.  Passes that update the
+-      SSA form on their own may want to delegate the updating of
+-      virtual names to the generic updater.  Since FUD chains are
+-      easier to maintain, this simplifies the work they need to do.
+-      NOTE: If this flag is used, any OLD->NEW mappings for real names
+-      are explicitly destroyed and only the symbols marked for
+-      renaming are processed@.
++SSA form on their own may want to delegate the updating of
++virtual names to the generic updater.  Since FUD chains are
++easier to maintain, this simplifies the work they need to do.
++NOTE: If this flag is used, any OLD->NEW mappings for real names
++are explicitly destroyed and only the symbols marked for
++renaming are processed@.
+ @end itemize
+ @subsection Preserving the virtual SSA form
+@@ -1445,8 +1445,8 @@ slightly different.  For each argument @
+ function will:
+ @enumerate
+-@item Walk the use-def chains for @var{arg}.
+-@item Call @code{FN (@var{arg}, @var{phi}, @var{data})}.
++@item Walk the use-def chains for @var{arg}.
++@item Call @code{FN (@var{arg}, @var{phi}, @var{data})}.
+ @end enumerate
+ Note how the first argument to @var{fn} is no longer the original
+@@ -1466,26 +1466,26 @@ hooks to execute custom code at various 
+ @enumerate
+ @item Once to initialize any local data needed while processing
+-      @var{bb} and its children.  This local data is pushed into an
+-      internal stack which is automatically pushed and popped as the
+-      walker traverses the dominator tree.
++@var{bb} and its children.  This local data is pushed into an
++internal stack which is automatically pushed and popped as the
++walker traverses the dominator tree.
+ @item Once before traversing all the statements in the @var{bb}.
+ @item Once for every statement inside @var{bb}.
+ @item Once after traversing all the statements and before recursing
+-      into @var{bb}'s dominator children.
++into @var{bb}'s dominator children.
+ @item It then recurses into all the dominator children of @var{bb}.
+ @item After recursing into all the dominator children of @var{bb} it
+-      can, optionally, traverse every statement in @var{bb} again
+-      (i.e., repeating steps 2 and 3).
++can, optionally, traverse every statement in @var{bb} again
++(i.e., repeating steps 2 and 3).
+ @item Once after walking the statements in @var{bb} and @var{bb}'s
+-      dominator children.  At this stage, the block local data stack
+-      is popped.
++dominator children.  At this stage, the block local data stack
++is popped.
+ @end enumerate
+ @end deftypefn
+@@ -1535,16 +1535,16 @@ int bar (void)
+ If you copy the symbol tag for a variable for some reason, you probably
+ also want to copy the subvariables for that variable.
+-@item Points-to and escape analysis.
++@item Points-to and escape analysis.
+ This phase walks the use-def chains in the SSA web looking for
+ three things:
+-      @itemize @bullet
+-      @item   Assignments of the form @code{P_i = &VAR}
+-      @item   Assignments of the form P_i = malloc()
+-      @item   Pointers and ADDR_EXPR that escape the current function.
+-      @end itemize
++@itemize @bullet
++@item Assignments of the form @code{P_i = &VAR}
++@item Assignments of the form P_i = malloc()
++@item Pointers and ADDR_EXPR that escape the current function.
++@end itemize
+ The concept of `escaping' is the same one used in the Java world.
+ When a pointer or an ADDR_EXPR escapes, it means that it has been
+@@ -1562,7 +1562,7 @@ call-clobbered.  Simply put, if an ADDR_
+ variable is call-clobbered.  If a pointer P_i escapes, then all
+ the variables pointed-to by P_i (and its memory tag) also escape.
+-@item Compute flow-sensitive aliases
++@item Compute flow-sensitive aliases
+ We have two classes of memory tags.  Memory tags associated with
+ the pointed-to data type of the pointers in the program.  These
+@@ -1579,7 +1579,7 @@ associated with each pointer P_i.  If P_
+ call-clobbered the variables it points to and its tag.
+-@item Compute flow-insensitive aliases
++@item Compute flow-insensitive aliases
+ This pass will compare the alias set of every symbol memory tag and
+ every addressable variable found in the program.  Given a symbol
+--- a/gcc/doc/trouble.texi
++++ b/gcc/doc/trouble.texi
+@@ -19,21 +19,21 @@ missing features that are too much work 
+ where people's opinions differ as to what is best.
+ @menu
+-* Actual Bugs::                     Bugs we will fix later.
+-* Cross-Compiler Problems::   Common problems of cross compiling with GCC.
++* Actual Bugs::         Bugs we will fix later.
++* Cross-Compiler Problems:: Common problems of cross compiling with GCC.
+ * Interoperation::      Problems using GCC with other compilers,
+-                         and with certain linkers, assemblers and debuggers.
++                        and with certain linkers, assemblers and debuggers.
+ * Incompatibilities::   GCC is incompatible with traditional C.
+ * Fixed Headers::       GCC uses corrected versions of system header files.
+-                           This is necessary, but doesn't always work smoothly.
++                        This is necessary, but doesn't always work smoothly.
+ * Standard Libraries::  GCC uses the system C library, which might not be
+-                           compliant with the ISO C standard.
++                        compliant with the ISO C standard.
+ * Disappointments::     Regrettable things we can't change, but not quite bugs.
+-* C++ Misunderstandings::     Common misunderstandings with GNU C++.
++* C++ Misunderstandings:: Common misunderstandings with GNU C++.
+ * Protoize Caveats::    Things to watch out for when using @code{protoize}.
+-* Non-bugs::          Things we think are right, but some others disagree.
++* Non-bugs::            Things we think are right, but some others disagree.
+ * Warnings and Errors:: Which problems in your code get warnings,
+-                         and which get errors.
++                        and which get errors.
+ @end menu
+ @node Actual Bugs
+--- a/gcc/dse.c
++++ b/gcc/dse.c
+@@ -228,7 +228,7 @@ struct store_info 
+   /* An bitmask as wide as the number of bytes in the word that
+      contains a 1 if the byte may be needed.  The store is unused if
+      all of the bits are 0.  */
+-  long positions_needed;
++  unsigned HOST_WIDEST_INT positions_needed;
+   /* The next store info for this insn.  */
+   struct store_info *next;
+@@ -239,6 +239,15 @@ struct store_info 
+   rtx rhs;  
+ };
++/* Return a bitmask with the first N low bits set.  */
++
++static unsigned HOST_WIDEST_INT
++lowpart_bitmask (int n)
++{
++  unsigned HOST_WIDEST_INT mask = ~(unsigned HOST_WIDEST_INT) 0;
++  return mask >> (HOST_BITS_PER_WIDEST_INT - n);
++}
++
+ typedef struct store_info *store_info_t;
+ static alloc_pool cse_store_info_pool;
+ static alloc_pool rtx_store_info_pool;
+@@ -1153,6 +1162,39 @@ clear_rhs_from_active_local_stores (void
+     }
+ }
++/* Mark byte POS bytes from the beginning of store S_INFO as unneeded.  */
++
++static inline void
++set_position_unneeded (store_info_t s_info, int pos)
++{
++  s_info->positions_needed &= ~(((unsigned HOST_WIDEST_INT) 1) << pos);
++}
++
++/* Mark the whole store S_INFO as unneeded.  */
++
++static inline void
++set_all_positions_unneeded (store_info_t s_info)
++{
++  s_info->positions_needed = (unsigned HOST_WIDEST_INT) 0;
++}
++
++/* Return TRUE if any bytes from S_INFO store are needed.  */
++
++static inline bool
++any_positions_needed_p (store_info_t s_info)
++{
++  return (s_info->positions_needed != (unsigned HOST_WIDEST_INT) 0);
++}
++
++/* Return TRUE if all bytes START through START+WIDTH-1 from S_INFO
++   store are needed.  */
++
++static inline bool
++all_positions_needed_p (store_info_t s_info, int start, int width)
++{
++  unsigned HOST_WIDEST_INT mask = lowpart_bitmask (width) << start;
++  return (s_info->positions_needed & mask) == mask;
++}
+ /* BODY is an instruction pattern that belongs to INSN.  Return 1 if
+    there is a candidate store, after adding it to the appropriate
+@@ -1223,6 +1265,7 @@ record_store (rtx body, bb_info_t bb_inf
+     }
+   width = GET_MODE_SIZE (GET_MODE (mem));
++  gcc_assert ((unsigned) width <= HOST_BITS_PER_WIDEST_INT);
+   if (spill_alias_set)
+     {
+@@ -1308,7 +1351,7 @@ record_store (rtx body, bb_info_t bb_inf
+             && (GET_MODE (mem) == entry->mode))
+           {
+             delete = true;
+-            s_info->positions_needed = 0;
++            set_all_positions_unneeded (s_info);
+           }
+         if (dump_file)
+           fprintf (dump_file, "    trying spill store in insn=%d alias_set=%d\n",
+@@ -1322,9 +1365,10 @@ record_store (rtx body, bb_info_t bb_inf
+           fprintf (dump_file, "    trying store in insn=%d gid=%d[%d..%d)\n",
+                    INSN_UID (ptr->insn), s_info->group_id, 
+                    (int)s_info->begin, (int)s_info->end);
+-        for (i = offset; i < offset+width; i++)
+-          if (i >= s_info->begin && i < s_info->end)
+-            s_info->positions_needed &= ~(1L << (i - s_info->begin));
++        for (i = MAX (offset, s_info->begin);
++             i < offset + width && i < s_info->end;
++             i++)
++          set_position_unneeded (s_info, i - s_info->begin);
+       }
+       else if (s_info->rhs)
+       /* Need to see if it is possible for this store to overwrite
+@@ -1340,9 +1384,9 @@ record_store (rtx body, bb_info_t bb_inf
+       
+       /* An insn can be deleted if every position of every one of
+        its s_infos is zero.  */
+-      if (s_info->positions_needed != 0)
++      if (any_positions_needed_p (s_info))
+       delete = false;
+-      
++
+       if (delete)
+       {
+         insn_info_t insn_to_delete = ptr;
+@@ -1360,8 +1404,6 @@ record_store (rtx body, bb_info_t bb_inf
+       ptr = next;
+     }
+   
+-  gcc_assert ((unsigned) width < sizeof (store_info->positions_needed) * CHAR_BIT);
+-  
+   /* Finish filling in the store_info.  */
+   store_info->next = insn_info->store_rec;
+   insn_info->store_rec = store_info;
+@@ -1369,7 +1411,7 @@ record_store (rtx body, bb_info_t bb_inf
+   store_info->alias_set = spill_alias_set;
+   store_info->mem_addr = get_addr (XEXP (mem, 0));
+   store_info->cse_base = base;
+-  store_info->positions_needed = (1L << width) - 1;
++  store_info->positions_needed = lowpart_bitmask (width);
+   store_info->group_id = group_id;
+   store_info->begin = offset;
+   store_info->end = offset + width;
+@@ -1820,16 +1862,14 @@ check_mem_read_rtx (rtx *loc, void *data
+             else 
+               {
+                 if (store_info->rhs
+-                    && (offset >= store_info->begin)
+-                    && (offset + width <= store_info->end))
+-                  {
+-                    int mask = ((1L << width) - 1) << (offset - store_info->begin);
+-                    
+-                    if ((store_info->positions_needed & mask) == mask
+-                        && replace_read (store_info, i_ptr, 
+-                                         read_info, insn_info, loc))
+-                      return 0;
+-                  }
++                    && offset >= store_info->begin
++                    && offset + width <= store_info->end
++                    && all_positions_needed_p (store_info,
++                                               offset - store_info->begin,
++                                               width)
++                    && replace_read (store_info, i_ptr, read_info,
++                                     insn_info, loc))
++                  return 0;
+                 /* The bases are the same, just see if the offsets
+                    overlap.  */
+                 if ((offset < store_info->end) 
+@@ -1887,16 +1927,12 @@ check_mem_read_rtx (rtx *loc, void *data
+         if (store_info->rhs
+             && store_info->group_id == -1
+             && store_info->cse_base == base
+-            && (offset >= store_info->begin)
+-            && (offset + width <= store_info->end))
+-          {
+-            int mask = ((1L << width) - 1) << (offset - store_info->begin);
+-            
+-            if ((store_info->positions_needed & mask) == mask
+-                && replace_read (store_info, i_ptr, 
+-                                 read_info, insn_info, loc))
+-              return 0;
+-          }
++            && offset >= store_info->begin
++            && offset + width <= store_info->end
++            && all_positions_needed_p (store_info,
++                                       offset - store_info->begin, width)
++            && replace_read (store_info, i_ptr, read_info, insn_info, loc))
++          return 0;
+         if (!store_info->alias_set)
+           remove = canon_true_dependence (store_info->mem, 
+--- a/gcc/dwarf2out.c
++++ b/gcc/dwarf2out.c
+@@ -1705,7 +1705,7 @@ static dw_cfa_location cfa_temp;
+ static void
+ dwarf2out_frame_debug_expr (rtx expr, const char *label)
+ {
+-  rtx src, dest;
++  rtx src, dest, span;
+   HOST_WIDE_INT offset;
+   /* If RTX_FRAME_RELATED_P is set on a PARALLEL, process each member of
+@@ -2081,7 +2081,32 @@ dwarf2out_frame_debug_expr (rtx expr, co
+       }
+       def_cfa_1 (label, &cfa);
+-      queue_reg_save (label, src, NULL_RTX, offset);
++      {
++      span = targetm.dwarf_register_span (src);
++
++      if (!span)
++        queue_reg_save (label, src, NULL_RTX, offset);
++      else
++        {
++          /* We have a PARALLEL describing where the contents of SRC
++             live.  Queue register saves for each piece of the
++             PARALLEL.  */
++          int par_index;
++          int limit;
++          HOST_WIDE_INT span_offset = offset;
++
++          gcc_assert (GET_CODE (span) == PARALLEL);
++
++          limit = XVECLEN (span, 0);
++          for (par_index = 0; par_index < limit; par_index++)
++            {
++              rtx elem = XVECEXP (span, 0, par_index);
++
++              queue_reg_save (label, elem, NULL_RTX, span_offset);
++              span_offset += GET_MODE_SIZE (GET_MODE (elem));
++            }
++        }
++      }
+       break;
+     default:
+@@ -3914,6 +3939,7 @@ static void dwarf2out_imported_module_or
+ static void dwarf2out_abstract_function (tree);
+ static void dwarf2out_var_location (rtx);
+ static void dwarf2out_begin_function (tree);
++static void dwarf2out_set_name (tree, tree);
+ /* The debug hooks structure.  */
+@@ -3947,6 +3973,7 @@ const struct gcc_debug_hooks dwarf2_debu
+   debug_nothing_int,          /* handle_pch */
+   dwarf2out_var_location,
+   dwarf2out_switch_text_section,
++  dwarf2out_set_name,
+   1                             /* start_end_main_source_file */
+ };
+ #endif
+@@ -5334,12 +5361,9 @@ debug_str_eq (const void *x1, const void
+                (const char *)x2) == 0;
+ }
+-/* Add a string attribute value to a DIE.  */
+-
+-static inline void
+-add_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind, const char *str)
++static struct indirect_string_node *
++find_AT_string (const char *str)
+ {
+-  dw_attr_node attr;
+   struct indirect_string_node *node;
+   void **slot;
+@@ -5360,6 +5384,18 @@ add_AT_string (dw_die_ref die, enum dwar
+     node = (struct indirect_string_node *) *slot;
+   node->refcount++;
++  return node;
++}
++
++/* Add a string attribute value to a DIE.  */
++
++static inline void
++add_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind, const char *str)
++{
++  dw_attr_node attr;
++  struct indirect_string_node *node;
++
++  node = find_AT_string (str);
+   attr.dw_attr = attr_kind;
+   attr.dw_attr_val.val_class = dw_val_class_str;
+@@ -14538,6 +14574,31 @@ maybe_emit_file (struct dwarf_file_data 
+   return fd->emitted_number;
+ }
++/* Replace DW_AT_name for the decl with name.  */
++ 
++static void
++dwarf2out_set_name (tree decl, tree name)
++{
++  dw_die_ref die;
++  dw_attr_ref attr;
++
++  die = TYPE_SYMTAB_DIE (decl);
++  if (!die)
++    return;
++
++  attr = get_AT (die, DW_AT_name);
++  if (attr)
++    {
++      struct indirect_string_node *node;
++
++      node = find_AT_string (dwarf2_name (name, 0));
++      /* replace the string.  */
++      attr->dw_attr_val.v.val_str = node;
++    }
++
++  else
++    add_name_attribute (die, dwarf2_name (name, 0));
++}
+ /* Called by the final INSN scan whenever we see a var location.  We
+    use it to drop labels in the right places, and throw the location in
+    our lookup table.  */
+--- a/gcc/emit-rtl.c
++++ b/gcc/emit-rtl.c
+@@ -1909,6 +1909,7 @@ adjust_address_1 (rtx memref, enum machi
+   rtx memoffset = MEM_OFFSET (memref);
+   rtx size = 0;
+   unsigned int memalign = MEM_ALIGN (memref);
++  int pbits;
+   /* If there are no changes, just return the original memory reference.  */
+   if (mode == GET_MODE (memref) && !offset
+@@ -1920,6 +1921,16 @@ adjust_address_1 (rtx memref, enum machi
+      (plus (plus reg reg) const_int) -- so do this always.  */
+   addr = copy_rtx (addr);
++  /* Convert a possibly large offset to a signed value within the
++     range of the target address space.  */
++  pbits = GET_MODE_BITSIZE (Pmode);
++  if (HOST_BITS_PER_WIDE_INT > pbits)
++    {
++      int shift = HOST_BITS_PER_WIDE_INT - pbits;
++      offset = (((HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) offset << shift))
++              >> shift);
++    }
++
+   if (adjust)
+     {
+       /* If MEMREF is a LO_SUM and the offset is within the alignment of the
+--- a/gcc/explow.c
++++ b/gcc/explow.c
+@@ -489,6 +489,7 @@ memory_address (enum machine_mode mode, 
+  done:
++  gcc_assert (memory_address_p (mode, x));
+   /* If we didn't change the address, we are done.  Otherwise, mark
+      a reg as a pointer if we have REG or REG + CONST_INT.  */
+   if (oldx == x)
+@@ -1489,9 +1490,9 @@ hard_function_value (const_tree valtype,
+    in which a scalar value of mode MODE was returned by a library call.  */
+ rtx
+-hard_libcall_value (enum machine_mode mode)
++hard_libcall_value (enum machine_mode mode, rtx fun)
+ {
+-  return LIBCALL_VALUE (mode);
++  return targetm.calls.libcall_value (mode, fun);
+ }
+ /* Look up the tree code for a given rtx code
+--- a/gcc/expmed.c
++++ b/gcc/expmed.c
+@@ -103,7 +103,8 @@ static int add_cost[NUM_MACHINE_MODES];
+ static int neg_cost[NUM_MACHINE_MODES];
+ static int shift_cost[NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
+ static int shiftadd_cost[NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
+-static int shiftsub_cost[NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
++static int shiftsub0_cost[NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
++static int shiftsub1_cost[NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
+ static int mul_cost[NUM_MACHINE_MODES];
+ static int sdiv_cost[NUM_MACHINE_MODES];
+ static int udiv_cost[NUM_MACHINE_MODES];
+@@ -130,7 +131,8 @@ init_expmed (void)
+     struct rtx_def shift;     rtunion shift_fld1;
+     struct rtx_def shift_mult;        rtunion shift_mult_fld1;
+     struct rtx_def shift_add; rtunion shift_add_fld1;
+-    struct rtx_def shift_sub; rtunion shift_sub_fld1;
++    struct rtx_def shift_sub0;        rtunion shift_sub0_fld1;
++    struct rtx_def shift_sub1;        rtunion shift_sub1_fld1;
+   } all;
+   rtx pow2[MAX_BITS_PER_WORD];
+@@ -202,9 +204,13 @@ init_expmed (void)
+   XEXP (&all.shift_add, 0) = &all.shift_mult;
+   XEXP (&all.shift_add, 1) = &all.reg;
+-  PUT_CODE (&all.shift_sub, MINUS);
+-  XEXP (&all.shift_sub, 0) = &all.shift_mult;
+-  XEXP (&all.shift_sub, 1) = &all.reg;
++  PUT_CODE (&all.shift_sub0, MINUS);
++  XEXP (&all.shift_sub0, 0) = &all.shift_mult;
++  XEXP (&all.shift_sub0, 1) = &all.reg;
++
++  PUT_CODE (&all.shift_sub1, MINUS);
++  XEXP (&all.shift_sub1, 0) = &all.reg;
++  XEXP (&all.shift_sub1, 1) = &all.shift_mult;
+   for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
+        mode != VOIDmode;
+@@ -222,7 +228,8 @@ init_expmed (void)
+       PUT_MODE (&all.shift, mode);
+       PUT_MODE (&all.shift_mult, mode);
+       PUT_MODE (&all.shift_add, mode);
+-      PUT_MODE (&all.shift_sub, mode);
++      PUT_MODE (&all.shift_sub0, mode);
++      PUT_MODE (&all.shift_sub1, mode);
+       add_cost[mode] = rtx_cost (&all.plus, SET);
+       neg_cost[mode] = rtx_cost (&all.neg, SET);
+@@ -248,7 +255,7 @@ init_expmed (void)
+       }
+       shift_cost[mode][0] = 0;
+-      shiftadd_cost[mode][0] = shiftsub_cost[mode][0] = add_cost[mode];
++      shiftadd_cost[mode][0] = shiftsub0_cost[mode][0] = shiftsub1_cost[mode][0] = add_cost[mode];
+       n = MIN (MAX_BITS_PER_WORD, GET_MODE_BITSIZE (mode));
+       for (m = 1; m < n; m++)
+@@ -258,7 +265,8 @@ init_expmed (void)
+         shift_cost[mode][m] = rtx_cost (&all.shift, SET);
+         shiftadd_cost[mode][m] = rtx_cost (&all.shift_add, SET);
+-        shiftsub_cost[mode][m] = rtx_cost (&all.shift_sub, SET);
++        shiftsub0_cost[mode][m] = rtx_cost (&all.shift_sub0, SET);
++        shiftsub1_cost[mode][m] = rtx_cost (&all.shift_sub1, SET);
+       }
+     }
+ }
+@@ -976,7 +984,10 @@ store_fixed_bit_field (rtx op0, unsigned
+     }
+   if (op0 != temp)
+-    emit_move_insn (op0, temp);
++    {
++      op0 = copy_rtx (op0);
++      emit_move_insn (op0, temp);
++    }
+ }
\f
+ /* Store a bit field that is split across multiple accessible memory objects.
+@@ -2426,6 +2437,7 @@ synth_mult (struct algorithm *alg_out, u
+   struct mult_cost best_cost;
+   struct mult_cost new_limit;
+   int op_cost, op_latency;
++  unsigned HOST_WIDE_INT orig_t = t;
+   unsigned HOST_WIDE_INT q;
+   int maxm = MIN (BITS_PER_WORD, GET_MODE_BITSIZE (mode));
+   int hash_index;
+@@ -2568,6 +2580,38 @@ synth_mult (struct algorithm *alg_out, u
+             best_alg->log[best_alg->ops] = m;
+             best_alg->op[best_alg->ops] = alg_shift;
+           }
++
++        /* See if treating ORIG_T as a signed number yields a better
++           sequence.  Try this sequence only for a negative ORIG_T
++           as it would be useless for a non-negative ORIG_T.  */
++        if ((HOST_WIDE_INT) orig_t < 0)
++          {
++            /* Shift ORIG_T as follows because a right shift of a
++               negative-valued signed type is implementation
++               defined.  */
++            q = ~(~orig_t >> m);
++            /* The function expand_shift will choose between a shift
++               and a sequence of additions, so the observed cost is
++               given as MIN (m * add_cost[mode],
++               shift_cost[mode][m]).  */
++            op_cost = m * add_cost[mode];
++            if (shift_cost[mode][m] < op_cost)
++              op_cost = shift_cost[mode][m];
++            new_limit.cost = best_cost.cost - op_cost;
++            new_limit.latency = best_cost.latency - op_cost;
++            synth_mult (alg_in, q, &new_limit, mode);
++
++            alg_in->cost.cost += op_cost;
++            alg_in->cost.latency += op_cost;
++            if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
++              {
++                struct algorithm *x;
++                best_cost = alg_in->cost;
++                x = alg_in, alg_in = best_alg, best_alg = x;
++                best_alg->log[best_alg->ops] = m;
++                best_alg->op[best_alg->ops] = alg_shift;
++              }
++          }
+       }
+       if (cache_hit)
+       goto done;
+@@ -2630,6 +2674,29 @@ synth_mult (struct algorithm *alg_out, u
+             best_alg->op[best_alg->ops] = alg_add_t_m2;
+           }
+       }
++
++      /* We may be able to calculate a * -7, a * -15, a * -31, etc
++       quickly with a - a * n for some appropriate constant n.  */
++      m = exact_log2 (-orig_t + 1);
++      if (m >= 0 && m < maxm)
++      {
++        op_cost = shiftsub1_cost[mode][m];
++        new_limit.cost = best_cost.cost - op_cost;
++        new_limit.latency = best_cost.latency - op_cost;
++        synth_mult (alg_in, (unsigned HOST_WIDE_INT) (-orig_t + 1) >> m, &new_limit, mode);
++
++        alg_in->cost.cost += op_cost;
++        alg_in->cost.latency += op_cost;
++        if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
++          {
++            struct algorithm *x;
++            best_cost = alg_in->cost;
++            x = alg_in, alg_in = best_alg, best_alg = x;
++            best_alg->log[best_alg->ops] = m;
++            best_alg->op[best_alg->ops] = alg_sub_t_m2;
++          }
++      }
++
+       if (cache_hit)
+       goto done;
+     }
+@@ -2699,9 +2766,9 @@ synth_mult (struct algorithm *alg_out, u
+            hardware the shift may be executed concurrently with the
+            earlier steps in the algorithm.  */
+         op_cost = add_cost[mode] + shift_cost[mode][m];
+-        if (shiftsub_cost[mode][m] < op_cost)
++        if (shiftsub0_cost[mode][m] < op_cost)
+           {
+-            op_cost = shiftsub_cost[mode][m];
++            op_cost = shiftsub0_cost[mode][m];
+             op_latency = op_cost;
+           }
+         else
+@@ -2764,7 +2831,7 @@ synth_mult (struct algorithm *alg_out, u
+       m = exact_log2 (q);
+       if (m >= 0 && m < maxm)
+       {
+-        op_cost = shiftsub_cost[mode][m];
++        op_cost = shiftsub0_cost[mode][m];
+         new_limit.cost = best_cost.cost - op_cost;
+         new_limit.latency = best_cost.latency - op_cost;
+         synth_mult (alg_in, (t + 1) >> m, &new_limit, mode);
+--- a/gcc/expr.c
++++ b/gcc/expr.c
+@@ -2038,10 +2038,55 @@ emit_group_store (rtx orig_dst, rtx src,
+       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);
++      unsigned int adj_bytelen = bytelen;
+       rtx dest = dst;
+       /* Handle trailing fragments that run over the size of the struct.  */
+       if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
++      adj_bytelen = ssize - bytepos;
++
++      if (GET_CODE (dst) == CONCAT)
++      {
++        if (bytepos + adj_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
++          {
++            enum machine_mode dest_mode = GET_MODE (dest);
++            enum machine_mode tmp_mode = GET_MODE (tmps[i]);
++
++            gcc_assert (bytepos == 0 && XVECLEN (src, 0));
++
++            if (GET_MODE_ALIGNMENT (dest_mode)
++                >= GET_MODE_ALIGNMENT (tmp_mode))
++              {
++                dest = assign_stack_temp (dest_mode,
++                                          GET_MODE_SIZE (dest_mode),
++                                          0);
++                emit_move_insn (adjust_address (dest,
++                                                tmp_mode,
++                                                bytepos),
++                                tmps[i]);
++                dst = dest;
++              }
++            else
++              {
++                dest = assign_stack_temp (tmp_mode,
++                                          GET_MODE_SIZE (tmp_mode),
++                                          0);
++                emit_move_insn (dest, tmps[i]);
++                dst = adjust_address (dest, dest_mode, bytepos);
++              }
++            break;
++          }
++      }
++
++      if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
+       {
+         /* store_bit_field always takes its value from the lsb.
+            Move the fragment to the lsb if it's not already there.  */
+@@ -2059,28 +2104,7 @@ emit_group_store (rtx orig_dst, rtx src,
+                                     build_int_cst (NULL_TREE, shift),
+                                     tmps[i], 0);
+           }
+-        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
+-          {
+-            gcc_assert (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;
+-          }
++        bytelen = adj_bytelen;
+       }
+       /* Optimize the access just a bit.  */
+--- a/gcc/expr.h
++++ b/gcc/expr.h
+@@ -729,7 +729,7 @@ extern void probe_stack_range (HOST_WIDE
+ /* Return an rtx that refers to the value returned by a library call
+    in its original home.  This becomes invalid if any more code is emitted.  */
+-extern rtx hard_libcall_value (enum machine_mode);
++extern rtx hard_libcall_value (enum machine_mode, rtx);
+ /* Return the mode desired by operand N of a particular bitfield
+    insert/extract insn, or MAX_MACHINE_MODE if no such insn is
+--- a/gcc/final.c
++++ b/gcc/final.c
+@@ -893,6 +893,7 @@ shorten_branches (rtx first ATTRIBUTE_UN
+       if (LABEL_P (insn))
+       {
+         rtx next;
++        bool next_is_jumptable;
+         /* Merge in alignments computed by compute_alignments.  */
+         log = LABEL_TO_ALIGNMENT (insn);
+@@ -902,31 +903,30 @@ shorten_branches (rtx first ATTRIBUTE_UN
+             max_skip = LABEL_TO_MAX_SKIP (insn);
+           }
+-        log = LABEL_ALIGN (insn);
+-        if (max_log < log)
++        next = next_nonnote_insn (insn);
++        next_is_jumptable = next && JUMP_TABLE_DATA_P (next);
++        if (!next_is_jumptable)
+           {
+-            max_log = log;
+-            max_skip = LABEL_ALIGN_MAX_SKIP;
++            log = LABEL_ALIGN (insn);
++            if (max_log < log)
++              {
++                max_log = log;
++                max_skip = LABEL_ALIGN_MAX_SKIP;
++              }
+           }
+-        next = next_nonnote_insn (insn);
+         /* ADDR_VECs only take room if read-only data goes into the text
+            section.  */
+-        if (JUMP_TABLES_IN_TEXT_SECTION
+-            || readonly_data_section == text_section)
+-          if (next && JUMP_P (next))
+-            {
+-              rtx nextbody = PATTERN (next);
+-              if (GET_CODE (nextbody) == ADDR_VEC
+-                  || GET_CODE (nextbody) == ADDR_DIFF_VEC)
+-                {
+-                  log = ADDR_VEC_ALIGN (next);
+-                  if (max_log < log)
+-                    {
+-                      max_log = log;
+-                      max_skip = LABEL_ALIGN_MAX_SKIP;
+-                    }
+-                }
+-            }
++        if ((JUMP_TABLES_IN_TEXT_SECTION
++             || readonly_data_section == text_section)
++            && next_is_jumptable)
++          {
++            log = ADDR_VEC_ALIGN (next);
++            if (max_log < log)
++              {
++                max_log = log;
++                max_skip = LABEL_ALIGN_MAX_SKIP;
++              }
++          }
+         LABEL_TO_ALIGNMENT (insn) = max_log;
+         LABEL_TO_MAX_SKIP (insn) = max_skip;
+         max_log = 0;
+@@ -1390,6 +1390,9 @@ asm_insn_count (rtx body)
+   else
+     template = decode_asm_operands (body, NULL, NULL, NULL, NULL, NULL);
++  if (*template == '\0')
++    return 0;
++
+   for (; *template; template++)
+     if (IS_ASM_LOGICAL_LINE_SEPARATOR (*template, template)
+       || *template == '\n')
+@@ -2003,48 +2006,41 @@ final_scan_insn (rtx insn, FILE *file, i
+       }
+       next = next_nonnote_insn (insn);
+-      if (next != 0 && JUMP_P (next))
++      /* If this label is followed by a jump-table, make sure we put
++       the label in the read-only section.  Also possibly write the
++       label and jump table together.  */
++      if (next != 0 && JUMP_TABLE_DATA_P (next))
+       {
+-        rtx nextbody = PATTERN (next);
+-
+-        /* If this label is followed by a jump-table,
+-           make sure we put the label in the read-only section.  Also
+-           possibly write the label and jump table together.  */
+-
+-        if (GET_CODE (nextbody) == ADDR_VEC
+-            || GET_CODE (nextbody) == ADDR_DIFF_VEC)
+-          {
+ #if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
+-            /* In this case, the case vector is being moved by the
+-               target, so don't output the label at all.  Leave that
+-               to the back end macros.  */
++        /* In this case, the case vector is being moved by the
++           target, so don't output the label at all.  Leave that
++           to the back end macros.  */
+ #else
+-            if (! JUMP_TABLES_IN_TEXT_SECTION)
+-              {
+-                int log_align;
++        if (! JUMP_TABLES_IN_TEXT_SECTION)
++          {
++            int log_align;
+-                switch_to_section (targetm.asm_out.function_rodata_section
+-                                   (current_function_decl));
++            switch_to_section (targetm.asm_out.function_rodata_section
++                               (current_function_decl));
+ #ifdef ADDR_VEC_ALIGN
+-                log_align = ADDR_VEC_ALIGN (next);
++            log_align = ADDR_VEC_ALIGN (next);
+ #else
+-                log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
++            log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
+ #endif
+-                ASM_OUTPUT_ALIGN (file, log_align);
+-              }
+-            else
+-              switch_to_section (current_function_section ());
++            ASM_OUTPUT_ALIGN (file, log_align);
++          }
++        else
++          switch_to_section (current_function_section ());
+ #ifdef ASM_OUTPUT_CASE_LABEL
+-            ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
+-                                   next);
++        ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
++                               next);
+ #else
+-            targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
++        targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
+ #endif
+ #endif
+-            break;
+-          }
++        break;
+       }
+       if (LABEL_ALT_ENTRY_P (insn))
+       output_alternate_entry_point (file, insn);
+--- a/gcc/fold-const.c
++++ b/gcc/fold-const.c
+@@ -2290,7 +2290,24 @@ fold_convert_const_real_from_real (tree 
+   real_convert (&value, TYPE_MODE (type), &TREE_REAL_CST (arg1));
+   t = build_real (type, value);
+-  TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1);
++  /* If converting an infinity or NAN to a representation that doesn't
++     have one, set the overflow bit so that we can produce some kind of
++     error message at the appropriate point if necessary.  It's not the
++     most user-friendly message, but it's better than nothing.  */
++  if (REAL_VALUE_ISINF (TREE_REAL_CST (arg1))
++      && !MODE_HAS_INFINITIES (TYPE_MODE (type)))
++    TREE_OVERFLOW (t) = 1;
++  else if (REAL_VALUE_ISNAN (TREE_REAL_CST (arg1))
++         && !MODE_HAS_NANS (TYPE_MODE (type)))
++    TREE_OVERFLOW (t) = 1;
++  /* Regular overflow, conversion produced an infinity in a mode that
++     can't represent them.  */
++  else if (!MODE_HAS_INFINITIES (TYPE_MODE (type))
++         && REAL_VALUE_ISINF (value)
++         && !REAL_VALUE_ISINF (TREE_REAL_CST (arg1)))
++    TREE_OVERFLOW (t) = 1;
++  else
++    TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1);
+   return t;
+ }
+--- a/gcc/function.c
++++ b/gcc/function.c
+@@ -73,6 +73,10 @@ along with GCC; see the file COPYING3.  
+ #define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
+ #endif
++#ifndef DATA_ALIGNMENT
++#define DATA_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
++#endif
++
+ #ifndef STACK_ALIGNMENT_NEEDED
+ #define STACK_ALIGNMENT_NEEDED 1
+ #endif
+@@ -419,7 +423,7 @@ assign_stack_local_1 (enum machine_mode 
+        stack slot.  */
+       type = lang_hooks.types.type_for_mode (mode, 0);
+       if (type)
+-      alignment = LOCAL_ALIGNMENT (type, alignment);
++      alignment = calculate_local_alignment (type, alignment);
+       alignment /= BITS_PER_UNIT;
+     }
+@@ -625,7 +629,7 @@ assign_stack_temp_for_type (enum machine
+     type = lang_hooks.types.type_for_mode (mode, 0);
+   if (type)
+-    align = LOCAL_ALIGNMENT (type, align);
++    align = calculate_local_alignment (type, align);
+   /* Try to find an available, already-allocated temporary of the proper
+      mode which meets the size and alignment requirements.  Choose the
+@@ -1530,6 +1534,7 @@ instantiate_virtual_regs_in_insn (rtx in
+           }
+         x = simplify_gen_subreg (recog_data.operand_mode[i], new,
+                                  GET_MODE (new), SUBREG_BYTE (x));
++        gcc_assert (x);
+         break;
+       default:
+@@ -1845,6 +1850,9 @@ aggregate_value_p (const_tree exp, const
+ bool
+ use_register_for_decl (const_tree decl)
+ {
++  if (!targetm.calls.allocate_stack_slots_for_args())
++    return true;
++  
+   /* Honor volatile.  */
+   if (TREE_SIDE_EFFECTS (decl))
+     return false;
+@@ -2425,6 +2433,30 @@ assign_parm_adjust_entry_rtl (struct ass
+   data->entry_parm = entry_parm;
+ }
++/* A subroutine of assign_parms.  Reconstitute any values which were
++   passed in multiple registers and would fit in a single register.  */
++
++static void
++assign_parm_remove_parallels (struct assign_parm_data_one *data)
++{
++  rtx entry_parm = data->entry_parm;
++
++  /* Convert the PARALLEL to a REG of the same mode as the parallel.
++     This can be done with register operations rather than on the
++     stack, even if we will store the reconstituted parameter on the
++     stack later.  */
++  if (GET_CODE (entry_parm) == PARALLEL
++      && data->passed_mode != BLKmode)
++    {
++      rtx parmreg = gen_reg_rtx (GET_MODE (entry_parm));
++      emit_group_store (parmreg, entry_parm, NULL_TREE,
++                      GET_MODE_SIZE (GET_MODE (entry_parm)));
++      entry_parm = parmreg;
++    }
++
++  data->entry_parm = entry_parm;
++}
++
+ /* A subroutine of assign_parms.  Adjust DATA->STACK_RTL such that it's
+    always valid and properly aligned.  */
+@@ -2470,8 +2502,6 @@ assign_parm_setup_block_p (struct assign
+ {
+   if (data->nominal_mode == BLKmode)
+     return true;
+-  if (GET_CODE (data->entry_parm) == PARALLEL)
+-    return true;
+ #ifdef BLOCK_REG_PADDING
+   /* Only assign_parm_setup_block knows how to deal with register arguments
+@@ -2497,59 +2527,10 @@ assign_parm_setup_block (struct assign_p
+   rtx stack_parm = data->stack_parm;
+   HOST_WIDE_INT size;
+   HOST_WIDE_INT size_stored;
+-  rtx orig_entry_parm = entry_parm;
+   if (GET_CODE (entry_parm) == PARALLEL)
+     entry_parm = emit_group_move_into_temps (entry_parm);
+-  /* If we've a non-block object that's nevertheless passed in parts,
+-     reconstitute it in register operations rather than on the stack.  */
+-  if (GET_CODE (entry_parm) == PARALLEL
+-      && data->nominal_mode != BLKmode)
+-    {
+-      rtx elt0 = XEXP (XVECEXP (orig_entry_parm, 0, 0), 0);
+-
+-      if ((XVECLEN (entry_parm, 0) > 1
+-         || hard_regno_nregs[REGNO (elt0)][GET_MODE (elt0)] > 1)
+-        && use_register_for_decl (parm))
+-      {
+-        rtx parmreg = gen_reg_rtx (data->nominal_mode);
+-
+-        push_to_sequence2 (all->first_conversion_insn,
+-                           all->last_conversion_insn);
+-
+-        /* For values returned in multiple registers, handle possible
+-           incompatible calls to emit_group_store.
+-
+-           For example, the following would be invalid, and would have to
+-           be fixed by the conditional below:
+-
+-           emit_group_store ((reg:SF), (parallel:DF))
+-           emit_group_store ((reg:SI), (parallel:DI))
+-
+-           An example of this are doubles in e500 v2:
+-           (parallel:DF (expr_list (reg:SI) (const_int 0))
+-           (expr_list (reg:SI) (const_int 4))).  */
+-        if (data->nominal_mode != data->passed_mode)
+-          {
+-            rtx t = gen_reg_rtx (GET_MODE (entry_parm));
+-            emit_group_store (t, entry_parm, NULL_TREE,
+-                              GET_MODE_SIZE (GET_MODE (entry_parm)));
+-            convert_move (parmreg, t, 0);
+-          }
+-        else
+-          emit_group_store (parmreg, entry_parm, data->nominal_type,
+-                            int_size_in_bytes (data->nominal_type));
+-
+-        all->first_conversion_insn = get_insns ();
+-        all->last_conversion_insn = get_last_insn ();
+-        end_sequence ();
+-
+-        SET_DECL_RTL (parm, parmreg);
+-        return;
+-      }
+-    }
+-
+   size = int_size_in_bytes (data->passed_type);
+   size_stored = CEIL_ROUND (size, UNITS_PER_WORD);
+   if (stack_parm == 0)
+@@ -2714,6 +2695,8 @@ assign_parm_setup_reg (struct assign_par
+   else
+     SET_DECL_RTL (parm, parmreg);
++  assign_parm_remove_parallels (data);
++
+   /* Copy the value into the register.  */
+   if (data->nominal_mode != data->passed_mode
+       || promoted_nominal_mode != data->promoted_mode)
+@@ -2876,6 +2859,8 @@ assign_parm_setup_stack (struct assign_p
+      execution.  */
+   bool to_conversion = false;
++  assign_parm_remove_parallels (data);
++
+   if (data->promoted_mode != data->nominal_mode)
+     {
+       /* Conversion is required.  */
+@@ -5560,6 +5545,77 @@ current_function_assembler_name (void)
+ {
+   return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (cfun->decl));
+ }
++
++/* Helper function for below.  This function adjusts alignments as
++   appropriate according to the setting of -falign-arrays.  If that is
++   specified then the minimum alignment for array variables is set to be
++   the largest power of two less than or equal to their total storage size,
++   or the biggest alignment used on the machine, whichever is smaller.  */
++
++static unsigned int
++alignment_for_aligned_arrays (tree ty, unsigned int existing_alignment)
++{
++  unsigned int min_alignment;
++  tree size;
++
++  /* Return the existing alignment if not using -falign-arrays or if
++     the type is not an array type.  */
++  if (!flag_align_arrays || TREE_CODE (ty) != ARRAY_TYPE)
++    return existing_alignment;
++
++  /* Extract the total storage size of the array in bits.  */
++  size = TYPE_SIZE (ty);
++  gcc_assert (size);
++
++  /* At least for variable-length arrays, TREE_CODE (size) might not be an
++     integer constant; check it now.  If it is not, give the array at
++     least BIGGEST_ALIGNMENT just to be safe.   Furthermore, we assume that
++     alignments always fit into a host integer.  So if we can't fit the
++     size of the array in bits into a host integer, it must also be large
++     enough to deserve at least BIGGEST_ALIGNMENT (see below).  */
++  if (TREE_CODE (size) != INTEGER_CST || !host_integerp (size, 1))
++    min_alignment = BIGGEST_ALIGNMENT;
++  else
++    {
++      unsigned HOST_WIDE_INT bits = TREE_INT_CST_LOW (size);
++      bits = (bits ? bits : 1);
++
++      /* An array with size greater than BIGGEST_ALIGNMENT is assigned
++       at least that alignment.  In all other cases the minimum
++       alignment of the array is set to be the largest power of two
++       less than or equal to the total storage size of the array.
++       We assume that BIGGEST_ALIGNMENT fits in "unsigned int"; thus,
++       the shift below will not overflow.  */
++      if (bits >= BIGGEST_ALIGNMENT)
++      min_alignment = BIGGEST_ALIGNMENT;
++      else
++      min_alignment = 1 << (floor_log2 (bits));
++    }
++
++  /* Having computed the minimum permissible alignment, enlarge it
++     if EXISTING_ALIGNMENT is greater.  */
++  return MAX (min_alignment, existing_alignment); 
++}
++
++/* Return the alignment in bits to be used for a local variable
++   of type TY whose usual alignment would be EXISTING_ALIGNMENT.  */
++
++unsigned int
++calculate_local_alignment (tree ty, unsigned int existing_alignment)
++{
++  return alignment_for_aligned_arrays (ty,
++    LOCAL_ALIGNMENT (ty, existing_alignment));
++}
++
++/* Return the alignment in bits to be used for a global variable
++   of type TY whose usual alignment would be EXISTING_ALIGNMENT.  */
++
++unsigned int
++calculate_global_alignment (tree ty, unsigned int existing_alignment)
++{
++  return alignment_for_aligned_arrays (ty,
++    DATA_ALIGNMENT (ty, existing_alignment));
++}
\f
+ static unsigned int
+--- a/gcc/function.h
++++ b/gcc/function.h
+@@ -594,4 +594,10 @@ extern bool reference_callee_copied (CUM
+ extern void used_types_insert (tree);
+ extern int get_next_funcdef_no (void);
++
++extern unsigned int calculate_local_alignment (
++  tree ty, unsigned int existing_alignment);
++extern unsigned int calculate_global_alignment (
++  tree ty, unsigned int existing_alignment);
++
+ #endif  /* GCC_FUNCTION_H */
+--- a/gcc/gcc.c
++++ b/gcc/gcc.c
+@@ -155,6 +155,8 @@ static const char *print_prog_name = NUL
+ static int print_multi_directory;
++static int print_sysroot;
++
+ /* Flag saying to print the relative path we'd use to
+    find OS libraries given the current compiler flags.  */
+@@ -643,8 +645,32 @@ proper position among the other output f
+ /* config.h can define SWITCHES_NEED_SPACES to control which options
+    require spaces between the option and the argument.  */
++/* GCC Bugzilla PR11810 indicates that GCC does not correctly handle
++   "-ofoo.o", in that it records "-ofoo.o" as a temporary file to
++   delete, rather than "foo.o".  
++
++   Unfortunately, Eclipse's makefile generators use the "-ofoo.o"
++   form.  See also CS Issue #3433.  So, although most users probably
++   use "-o foo.o", the "-ofoo.o" form is used in practice.
++
++   See this email thread for additional information:
++
++     http://gcc.gnu.org/ml/gcc/2008-07/msg00395.html
++
++   Therefore, we define SWITCHES_NEED_SPACES to include "o" by
++   default.  This causes "-ofoo.o" to be split into "-o foo.o" during
++   the initial processing of the command-line, before being seen by
++   the specs machinery.
++ 
++   A risk of this change is that tools which *require* the "-ofoo.o"
++   form will no longer work.  However, we know of no such tools, and
++   they would not have worked with the "-o foo.o" form anyhow.  
++
++   If this general strategy is acceptable upstream, the best approach
++   might be simply to eliminate this macro, since the only definitions
++   in target files are also to the value "o".  */
+ #ifndef SWITCHES_NEED_SPACES
+-#define SWITCHES_NEED_SPACES ""
++#define SWITCHES_NEED_SPACES "o"
+ #endif
+ /* config.h can define ENDFILE_SPEC to override the default crtn files.  */
+@@ -720,6 +746,8 @@ proper position among the other output f
+ %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
+     %(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
+     %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
++    %{Wno-poison-system-directories:--no-poison-system-directories}\
++    %{Werror=poison-system-directories:--error-poison-system-directories}\
+     %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
+     %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)} %(mflib)\
+     %{fprofile-arcs|fprofile-generate|coverage:-lgcov}\
+@@ -874,7 +902,7 @@ static const char *const multilib_defaul
+ #endif
+ static const char *const driver_self_specs[] = {
+-  DRIVER_SELF_SPECS, GOMP_SELF_SPECS
++  DRIVER_SELF_SPECS, CONFIGURE_SPECS, GOMP_SELF_SPECS
+ };
+ #ifndef OPTION_DEFAULT_SPECS
+@@ -1150,6 +1178,7 @@ static const struct option_map option_ma
+    {"--print-multi-directory", "-print-multi-directory", 0},
+    {"--print-multi-os-directory", "-print-multi-os-directory", 0},
+    {"--print-prog-name", "-print-prog-name=", "aj"},
++   {"--print-sysroot", "-print-sysroot", 0},
+    {"--print-sysroot-headers-suffix", "-print-sysroot-headers-suffix", 0},
+    {"--profile", "-p", 0},
+    {"--profile-blocks", "-a", 0},
+@@ -3224,6 +3253,7 @@ display_help (void)
+   -print-multi-lib         Display the mapping between command line options and\n\
+                            multiple library search directories\n"), stdout);
+   fputs (_("  -print-multi-os-directory Display the relative path to OS libraries\n"), stdout);
++  fputs (_("  -print-sysroot           Display the target libraries directory\n"), stdout);
+   fputs (_("  -print-sysroot-headers-suffix Display the sysroot suffix used to find headers\n"), stdout);
+   fputs (_("  -Wa,<options>            Pass comma-separated <options> on to the assembler\n"), stdout);
+   fputs (_("  -Wp,<options>            Pass comma-separated <options> on to the preprocessor\n"), stdout);
+@@ -3668,6 +3698,8 @@ warranty; not even for MERCHANTABILITY o
+       print_multi_lib = 1;
+       else if (! strcmp (argv[i], "-print-multi-directory"))
+       print_multi_directory = 1;
++      else if (! strcmp (argv[i], "-print-sysroot"))
++      print_sysroot = 1;
+       else if (! strcmp (argv[i], "-print-multi-os-directory"))
+       print_multi_os_directory = 1;
+       else if (! strcmp (argv[i], "-print-sysroot-headers-suffix"))
+@@ -4099,6 +4131,8 @@ warranty; not even for MERCHANTABILITY o
+       ;
+       else if (! strcmp (argv[i], "-print-multi-directory"))
+       ;
++      else if (! strcmp (argv[i], "-print-sysroot"))
++      ;
+       else if (! strcmp (argv[i], "-print-multi-os-directory"))
+       ;
+       else if (! strcmp (argv[i], "-print-sysroot-headers-suffix"))
+@@ -4518,28 +4552,51 @@ do_self_spec (const char *spec)
+   if (argbuf_index > 0)
+     {
+-      int i, first;
++      int i, first, n;
+       first = n_switches;
+-      n_switches += argbuf_index;
+-      switches = xrealloc (switches,
+-                         sizeof (struct switchstr) * (n_switches + 1));
+-
+-      switches[n_switches] = switches[first];
++      n = n_switches + argbuf_index;
++      switches = xrealloc (switches, sizeof (struct switchstr) * (n + 1));
++      switches[n] = switches[first];
+       for (i = 0; i < argbuf_index; i++)
+       {
+         struct switchstr *sw;
++        const char *p = &argbuf[i][1];
++        int c = *p;
+         /* Each switch should start with '-'.  */
+         if (argbuf[i][0] != '-')
+           fatal ("switch '%s' does not start with '-'", argbuf[i]);
+-        sw = &switches[i + first];
++        sw = &switches[n_switches];
+         sw->part1 = &argbuf[i][1];
+         sw->args = 0;
+         sw->live_cond = 0;
+         sw->validated = 0;
+         sw->ordering = 0;
++
++        /* Deal with option arguments in separate argv elements.  */
++        if ((SWITCH_TAKES_ARG (c) > (p[1] != 0))
++            || WORD_SWITCH_TAKES_ARG (p))
++          {
++            int j = 0;
++            int n_args = WORD_SWITCH_TAKES_ARG (p);
++
++            if (n_args == 0)
++              {
++                /* Count only the option arguments in separate argv elements.  */
++                n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
++              }
++            if (i + n_args >= argbuf_index)
++              fatal ("argument to '-%s' is missing", p);
++            switches[n_switches].args
++              = XNEWVEC (const char *, n_args + 1);
++            while (j < n_args)
++              switches[n_switches].args[j++] = argbuf[++i];
++            /* Null-terminate the vector.  */
++            switches[n_switches].args[j] = 0;
++          }
++        n_switches++;
+       }
+     }
+ }
+@@ -6455,6 +6512,18 @@ main (int argc, char **argv)
+       return (0);
+     }
++  if (print_sysroot)
++    {
++      if (target_system_root)
++      {
++          if (target_sysroot_suffix)
++          printf ("%s%s\n", target_system_root, target_sysroot_suffix);
++          else
++          printf ("%s\n", target_system_root);
++      }
++      return (0);
++    }
++
+   if (print_multi_os_directory)
+     {
+       if (multilib_os_dir == NULL)
+@@ -7949,7 +8018,7 @@ include_spec_function (int argc, const c
+   if (argc != 1)
+     abort ();
+-  file = find_a_file (&startfile_prefixes, argv[0], R_OK, 0);
++  file = find_a_file (&startfile_prefixes, argv[0], R_OK, true);
+   read_specs (file ? file : argv[0], FALSE);
+   return NULL;
+--- a/gcc/gengtype-lex.c
++++ /dev/null
+@@ -1,2636 +0,0 @@
+-#line 2 "gengtype-lex.c"
+-
+-#line 4 "gengtype-lex.c"
+-
+-#define  YY_INT_ALIGNED short int
+-
+-/* A lexical scanner generated by flex */
+-
+-#define FLEX_SCANNER
+-#define YY_FLEX_MAJOR_VERSION 2
+-#define YY_FLEX_MINOR_VERSION 5
+-#define YY_FLEX_SUBMINOR_VERSION 35
+-#if YY_FLEX_SUBMINOR_VERSION > 0
+-#define FLEX_BETA
+-#endif
+-
+-/* First, we deal with  platform-specific or compiler-specific issues. */
+-
+-/* begin standard C headers. */
+-#include <stdio.h>
+-#include <string.h>
+-#include <errno.h>
+-#include <stdlib.h>
+-
+-/* end standard C headers. */
+-
+-/* flex integer type definitions */
+-
+-#ifndef FLEXINT_H
+-#define FLEXINT_H
+-
+-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+-
+-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+-
+-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+- * if you want the limit (max/min) macros for int types. 
+- */
+-#ifndef __STDC_LIMIT_MACROS
+-#define __STDC_LIMIT_MACROS 1
+-#endif
+-
+-#include <inttypes.h>
+-typedef int8_t flex_int8_t;
+-typedef uint8_t flex_uint8_t;
+-typedef int16_t flex_int16_t;
+-typedef uint16_t flex_uint16_t;
+-typedef int32_t flex_int32_t;
+-typedef uint32_t flex_uint32_t;
+-#else
+-typedef signed char flex_int8_t;
+-typedef short int flex_int16_t;
+-typedef int flex_int32_t;
+-typedef unsigned char flex_uint8_t; 
+-typedef unsigned short int flex_uint16_t;
+-typedef unsigned int flex_uint32_t;
+-#endif /* ! C99 */
+-
+-/* Limits of integral types. */
+-#ifndef INT8_MIN
+-#define INT8_MIN               (-128)
+-#endif
+-#ifndef INT16_MIN
+-#define INT16_MIN              (-32767-1)
+-#endif
+-#ifndef INT32_MIN
+-#define INT32_MIN              (-2147483647-1)
+-#endif
+-#ifndef INT8_MAX
+-#define INT8_MAX               (127)
+-#endif
+-#ifndef INT16_MAX
+-#define INT16_MAX              (32767)
+-#endif
+-#ifndef INT32_MAX
+-#define INT32_MAX              (2147483647)
+-#endif
+-#ifndef UINT8_MAX
+-#define UINT8_MAX              (255U)
+-#endif
+-#ifndef UINT16_MAX
+-#define UINT16_MAX             (65535U)
+-#endif
+-#ifndef UINT32_MAX
+-#define UINT32_MAX             (4294967295U)
+-#endif
+-
+-#endif /* ! FLEXINT_H */
+-
+-#ifdef __cplusplus
+-
+-/* The "const" storage-class-modifier is valid. */
+-#define YY_USE_CONST
+-
+-#else /* ! __cplusplus */
+-
+-/* C99 requires __STDC__ to be defined as 1. */
+-#if defined (__STDC__)
+-
+-#define YY_USE_CONST
+-
+-#endif        /* defined (__STDC__) */
+-#endif        /* ! __cplusplus */
+-
+-#ifdef YY_USE_CONST
+-#define yyconst const
+-#else
+-#define yyconst
+-#endif
+-
+-/* Returned upon end-of-file. */
+-#define YY_NULL 0
+-
+-/* Promotes a possibly negative, possibly signed char to an unsigned
+- * integer for use as an array index.  If the signed char is negative,
+- * we want to instead treat it as an 8-bit unsigned char, hence the
+- * double cast.
+- */
+-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+-
+-/* Enter a start condition.  This macro really ought to take a parameter,
+- * but we do it the disgusting crufty way forced on us by the ()-less
+- * definition of BEGIN.
+- */
+-#define BEGIN (yy_start) = 1 + 2 *
+-
+-/* Translate the current start state into a value that can be later handed
+- * to BEGIN to return to the state.  The YYSTATE alias is for lex
+- * compatibility.
+- */
+-#define YY_START (((yy_start) - 1) / 2)
+-#define YYSTATE YY_START
+-
+-/* Action number for EOF rule of a given start state. */
+-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+-
+-/* Special action meaning "start processing a new file". */
+-#define YY_NEW_FILE yyrestart(yyin  )
+-
+-#define YY_END_OF_BUFFER_CHAR 0
+-
+-/* Size of default input buffer. */
+-#ifndef YY_BUF_SIZE
+-#define YY_BUF_SIZE 16384
+-#endif
+-
+-/* The state buf must be large enough to hold one state per character in the main buffer.
+- */
+-#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+-
+-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+-#define YY_TYPEDEF_YY_BUFFER_STATE
+-typedef struct yy_buffer_state *YY_BUFFER_STATE;
+-#endif
+-
+-extern int yyleng;
+-
+-extern FILE *yyin, *yyout;
+-
+-#define EOB_ACT_CONTINUE_SCAN 0
+-#define EOB_ACT_END_OF_FILE 1
+-#define EOB_ACT_LAST_MATCH 2
+-
+-    #define YY_LESS_LINENO(n)
+-    
+-/* Return all but the first "n" matched characters back to the input stream. */
+-#define yyless(n) \
+-      do \
+-              { \
+-              /* Undo effects of setting up yytext. */ \
+-        int yyless_macro_arg = (n); \
+-        YY_LESS_LINENO(yyless_macro_arg);\
+-              *yy_cp = (yy_hold_char); \
+-              YY_RESTORE_YY_MORE_OFFSET \
+-              (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+-              YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+-              } \
+-      while ( 0 )
+-
+-#define unput(c) yyunput( c, (yytext_ptr)  )
+-
+-#ifndef YY_TYPEDEF_YY_SIZE_T
+-#define YY_TYPEDEF_YY_SIZE_T
+-typedef size_t yy_size_t;
+-#endif
+-
+-#ifndef YY_STRUCT_YY_BUFFER_STATE
+-#define YY_STRUCT_YY_BUFFER_STATE
+-struct yy_buffer_state
+-      {
+-      FILE *yy_input_file;
+-
+-      char *yy_ch_buf;                /* input buffer */
+-      char *yy_buf_pos;               /* current position in input buffer */
+-
+-      /* Size of input buffer in bytes, not including room for EOB
+-       * characters.
+-       */
+-      yy_size_t yy_buf_size;
+-
+-      /* Number of characters read into yy_ch_buf, not including EOB
+-       * characters.
+-       */
+-      int yy_n_chars;
+-
+-      /* Whether we "own" the buffer - i.e., we know we created it,
+-       * and can realloc() it to grow it, and should free() it to
+-       * delete it.
+-       */
+-      int yy_is_our_buffer;
+-
+-      /* Whether this is an "interactive" input source; if so, and
+-       * if we're using stdio for input, then we want to use getc()
+-       * instead of fread(), to make sure we stop fetching input after
+-       * each newline.
+-       */
+-      int yy_is_interactive;
+-
+-      /* Whether we're considered to be at the beginning of a line.
+-       * If so, '^' rules will be active on the next match, otherwise
+-       * not.
+-       */
+-      int yy_at_bol;
+-
+-    int yy_bs_lineno; /**< The line count. */
+-    int yy_bs_column; /**< The column count. */
+-    
+-      /* Whether to try to fill the input buffer when we reach the
+-       * end of it.
+-       */
+-      int yy_fill_buffer;
+-
+-      int yy_buffer_status;
+-
+-#define YY_BUFFER_NEW 0
+-#define YY_BUFFER_NORMAL 1
+-      /* When an EOF's been seen but there's still some text to process
+-       * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+-       * shouldn't try reading from the input source any more.  We might
+-       * still have a bunch of tokens to match, though, because of
+-       * possible backing-up.
+-       *
+-       * When we actually see the EOF, we change the status to "new"
+-       * (via yyrestart()), so that the user can continue scanning by
+-       * just pointing yyin at a new input file.
+-       */
+-#define YY_BUFFER_EOF_PENDING 2
+-
+-      };
+-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+-
+-/* Stack of input buffers. */
+-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+-
+-/* We provide macros for accessing buffer states in case in the
+- * future we want to put the buffer states in a more general
+- * "scanner state".
+- *
+- * Returns the top of the stack, or NULL.
+- */
+-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+-                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+-                          : NULL)
+-
+-/* Same as previous macro, but useful when we know that the buffer stack is not
+- * NULL or when we need an lvalue. For internal use only.
+- */
+-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+-
+-/* yy_hold_char holds the character lost when yytext is formed. */
+-static char yy_hold_char;
+-static int yy_n_chars;                /* number of characters read into yy_ch_buf */
+-int yyleng;
+-
+-/* Points to current character in buffer. */
+-static char *yy_c_buf_p = (char *) 0;
+-static int yy_init = 0;               /* whether we need to initialize */
+-static int yy_start = 0;      /* start state number */
+-
+-/* Flag which is used to allow yywrap()'s to do buffer switches
+- * instead of setting up a fresh yyin.  A bit of a hack ...
+- */
+-static int yy_did_buffer_switch_on_eof;
+-
+-void yyrestart (FILE *input_file  );
+-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
+-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
+-void yy_delete_buffer (YY_BUFFER_STATE b  );
+-void yy_flush_buffer (YY_BUFFER_STATE b  );
+-void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
+-void yypop_buffer_state (void );
+-
+-static void yyensure_buffer_stack (void );
+-static void yy_load_buffer_state (void );
+-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+-
+-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+-
+-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
+-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
+-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
+-
+-void *yyalloc (yy_size_t  );
+-void *yyrealloc (void *,yy_size_t  );
+-void yyfree (void *  );
+-
+-#define yy_new_buffer yy_create_buffer
+-
+-#define yy_set_interactive(is_interactive) \
+-      { \
+-      if ( ! YY_CURRENT_BUFFER ){ \
+-        yyensure_buffer_stack (); \
+-              YY_CURRENT_BUFFER_LVALUE =    \
+-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
+-      } \
+-      YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+-      }
+-
+-#define yy_set_bol(at_bol) \
+-      { \
+-      if ( ! YY_CURRENT_BUFFER ){\
+-        yyensure_buffer_stack (); \
+-              YY_CURRENT_BUFFER_LVALUE =    \
+-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
+-      } \
+-      YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+-      }
+-
+-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+-
+-/* Begin user sect3 */
+-
+-#define yywrap(n) 1
+-#define YY_SKIP_YYWRAP
+-
+-typedef unsigned char YY_CHAR;
+-
+-FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+-
+-typedef int yy_state_type;
+-
+-extern int yylineno;
+-
+-int yylineno = 1;
+-
+-extern char *yytext;
+-#define yytext_ptr yytext
+-
+-static yy_state_type yy_get_previous_state (void );
+-static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
+-static int yy_get_next_buffer (void );
+-static void yy_fatal_error (yyconst char msg[]  );
+-
+-/* Done after the current pattern has been matched and before the
+- * corresponding action - sets up yytext.
+- */
+-#define YY_DO_BEFORE_ACTION \
+-      (yytext_ptr) = yy_bp; \
+-      yyleng = (size_t) (yy_cp - yy_bp); \
+-      (yy_hold_char) = *yy_cp; \
+-      *yy_cp = '\0'; \
+-      (yy_c_buf_p) = yy_cp;
+-
+-#define YY_NUM_RULES 49
+-#define YY_END_OF_BUFFER 50
+-/* This struct is not used in this scanner,
+-   but its presence is necessary. */
+-struct yy_trans_info
+-      {
+-      flex_int32_t yy_verify;
+-      flex_int32_t yy_nxt;
+-      };
+-static yyconst flex_int16_t yy_accept[445] =
+-    {   0,
+-        0,    0,    0,    0,    0,    0,    0,    0,   50,   36,
+-       36,   33,   45,   36,   45,   34,   36,   36,   34,   34,
+-       34,   34,   34,   31,   10,   10,   31,   29,   31,   31,
+-       31,   20,   31,   31,   31,   31,   31,   31,   31,   31,
+-       31,   31,   31,   31,   31,   31,   31,   31,   31,   31,
+-       31,   10,   31,   41,   39,   46,   46,    0,    0,    0,
+-       37,    0,    0,    0,   38,   32,   34,    0,    0,    0,
+-        0,    0,    0,    0,    0,    0,   34,   34,   34,   34,
+-       34,   10,    0,   25,    0,    0,    0,    0,    9,   20,
+-       24,    0,    0,    0,    0,    0,    0,    0,    0,   26,
+-
+-       11,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+-        0,    0,    0,    0,    0,   10,    0,    0,    0,    0,
+-       42,   44,   43,    0,   35,    0,    0,    0,    0,    0,
+-        0,   34,   34,   34,   34,   34,   34,   27,   28,    0,
+-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+-        0,    0,    0,   30,    0,    0,    0,    0,    0,    0,
+-        0,    0,    0,    0,   34,   34,   34,   34,   34,   34,
+-        0,    0,    0,   13,    0,   14,    0,    0,    0,    0,
+-       22,   22,    0,    0,    0,    0,    0,    0,    0,    0,
+-
+-        0,    0,    0,   48,    0,    0,    0,    0,    0,    0,
+-        0,   34,   34,   34,   34,   34,   34,    0,    0,    0,
+-        0,    0,   17,    0,    0,    0,    0,    0,    0,    0,
+-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+-        0,    0,    0,    0,    0,    0,    0,    0,    0,   34,
+-       34,   34,   34,   34,    3,    0,    0,    0,    0,   12,
+-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+-        0,    0,    0,    0,    0,    0,   15,    0,    0,    0,
+-        0,    0,    0,    0,   34,    4,    5,    2,   34,    0,
+-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+-
+-        0,    0,    0,    0,    0,    0,    0,    0,    0,   16,
+-        0,    0,    0,    0,   34,    1,    0,    0,    0,    0,
+-        0,    0,    0,    0,    0,   22,   22,    0,    0,    0,
+-        0,    0,    0,    0,    0,    0,    0,   34,   34,   34,
+-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+-       21,    0,    0,    0,    0,    0,    0,   34,    7,    6,
+-        0,    0,    0,    0,    0,    0,    0,    0,    0,   18,
+-        0,    0,    0,   34,    0,    0,    0,    0,    0,    0,
+-        0,    0,   19,    0,    0,   47,   34,    0,    0,    0,
+-        0,    0,    0,    0,    0,    0,    0,   34,    0,    0,
+-
+-        0,    0,    0,    0,    0,    0,   34,    0,   24,   24,
+-        0,    0,    0,    0,    0,    0,    0,   34,    0,    0,
+-        0,    0,    0,    0,    0,    0,    0,    0,    0,    8,
+-        0,   23,    0,    0,    0,    0,    0,   40,    0,    0,
+-        0,    0,    0,    0
+-    } ;
+-
+-static yyconst flex_int32_t yy_ec[256] =
+-    {   0,
+-        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+-        2,    2,    2,    1,    1,    1,    1,    1,    1,    1,
+-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+-        1,    2,    1,    4,    5,    1,    6,    1,    7,    8,
+-        9,   10,    1,    6,    6,   11,   12,   13,   13,   13,
+-       13,   13,   13,   13,   13,   13,   13,    6,    6,    6,
+-        6,    6,    1,    1,   14,   15,   16,   17,   18,   19,
+-       20,   21,   22,   23,   23,   24,   25,   26,   27,   28,
+-       23,   29,   30,   31,   32,   33,   34,   23,   35,   23,
+-       36,   37,   38,    1,   39,    1,   40,   41,   42,   43,
+-
+-       44,   45,   46,   47,   48,   49,   49,   50,   51,   52,
+-       53,   54,   49,   55,   56,   57,   58,   59,   49,   60,
+-       61,   62,    6,    6,    6,    1,    1,    1,    1,    1,
+-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+-
+-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+-        1,    1,    1,    1,    1
+-    } ;
+-
+-static yyconst flex_int32_t yy_meta[63] =
+-    {   0,
+-        1,    2,    3,    1,    1,    1,    1,    1,    4,    5,
+-        1,    1,    6,    7,    7,    7,    7,    7,    7,    7,
+-        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
+-        7,    7,    7,    7,    7,    8,    1,    1,    9,    9,
+-        9,    9,    9,    9,    9,    9,    9,    9,    9,    9,
+-        9,    9,    9,    9,    9,    9,    9,    9,    9,    9,
+-        9,    9
+-    } ;
+-
+-static yyconst flex_int16_t yy_base[483] =
+-    {   0,
+-        0,   38,   96,   12,   12,   13,   15,   16, 1028, 1444,
+-       32,   51,   20,  990, 1016,    0,  157,   18, 1007,  964,
+-      966,  961,  969, 1444,   25,   27,   27, 1444,  983, 1008,
+-     1008, 1004,  215,  253,    5,   32,   29,  974,   45,  962,
+-      996,   35,   38,   39,   40,   41,  134,   42,  136,  137,
+-      138,   75,  996,    0, 1444,  985,  984,  166,  964,  162,
+-     1444,    0,  987,  990, 1444, 1444,    0,  186,  165,  974,
+-      931,  933,  928,  936,  168,  943,  967,  928,  140,  930,
+-      935,   87,  167, 1444,  979,  974,  977,  968, 1444,  950,
+-     1444,  935,  934,  145,   52,   46,  148,  165,  922, 1444,
+-
+-     1444,  152,  156,  155,  170,  173,  175,  182,  183,  185,
+-      211,  214,  222,  218,  221,  269,  957,  956,  291,    0,
+-     1444, 1444, 1444,  922, 1444,  937,  898,  195,  900,  905,
+-      907,  912,  906,  892,  890,  903,  893, 1444, 1444,  209,
+-      254,  251,  353,  248,  391,  354,  350,  351,  340,  355,
+-      341,  429,  339,  356,  344,  347,  360,  390,   43,  361,
+-      391,  395,  429, 1444,    0,    0,  280,  906,  900,  886,
+-      884,  897,  872,  876,  890,  867,  873,  878,  876,  866,
+-      381,  348,  382, 1444,  384, 1444,  389,  397,  491,  398,
+-     1444,  528,  418,  399,  420,  477,  478,  422,  421,  480,
+-
+-      479,    0,  449, 1444,  884,  861,  867,  872,  870,  860,
+-      859,  892,  857,  866,  850,  862,  586,  493,  496,  494,
+-      484,  624, 1444,    0,  878,  876,  876,  834,  839,  841,
+-      832,  830,  199,  830,  490,  499,  486,  492,  488,  489,
+-      662,    0,  863,  828,  837,  821,  833,    0,  832,  859,
+-      700,  738,  776,  829, 1444,  431,  258,  437,  515, 1444,
+-      846,  844,  841,  817,  829,  809,  319,  815,  813,  478,
+-      809,  512,  528,  520,  525,  814, 1444,    0,  833,    0,
+-        0,    0,  803,  551,  808, 1444, 1444, 1444,  852,  383,
+-      521,  530,  539,  822,  829,  813,  793,  787,  802,  801,
+-
+-      556,  793,  783,  785,  792,  787,  523,  545,  535, 1444,
+-        0,  795,    0,  561,  585, 1444,  555,  343,  581,  584,
+-      794,  811,  792,  773,  772, 1444,    0,  771,  783,  772,
+-      764,  552,  890,  558,    0,  623,  778,  784,  928,  966,
+-      583,  593,  594,  613,  792,  792,  771,  761,  746,  591,
+-     1444, 1004,    0,  778,    0,    0,  766,  776, 1444, 1444,
+-      620,  621,  626,  627,  653,  777,  769,  775, 1042, 1444,
+-        0,  772,  787,  767,  556,  577,  615,  649,  629,  762,
+-      753,  774, 1444,    0,  763, 1444,  773,  632,  659,  662,
+-      656,  654,  754,  742,  753,    0,  754,  729,  665,  688,
+-
+-      667,  744,  742,  683,    0,  695,  692,  689,  715,  722,
+-      699,  711,  701,  666,  673,    0,  705, 1080,  704,  749,
+-      751,  753,  756,  663,  658,  618,  593,    0,    0, 1444,
+-      758, 1444,  760,  600,  588,  543,  483, 1444,  439,  386,
+-      247,  206,  167, 1444, 1118, 1127, 1136, 1145, 1154, 1158,
+-     1167, 1176, 1185, 1194, 1202, 1211, 1220, 1229, 1238, 1247,
+-     1256, 1265, 1273, 1282, 1290, 1298, 1306, 1314, 1323, 1331,
+-     1340, 1349, 1357, 1365, 1374, 1383, 1392, 1400, 1409, 1417,
+-     1426, 1435
+-    } ;
+-
+-static yyconst flex_int16_t yy_def[483] =
+-    {   0,
+-      445,  445,  444,    3,  446,  446,  446,  446,  444,  444,
+-      444,  444,  447,  448,  449,  450,  444,  444,  450,  450,
+-      450,  450,  450,  444,  444,  444,  451,  444,  452,  444,
+-      444,  444,  453,  453,   34,   34,   34,   34,   34,  454,
+-      444,   34,   34,   34,   34,   34,   34,   34,   34,   34,
+-       34,  444,  455,  456,  444,  457,  457,  444,  444,  447,
+-      444,  447,  444,  448,  444,  444,  450,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  450,  450,  450,  450,
+-      450,  444,  451,  444,  451,  444,  452,  444,  444,  444,
+-      444,   34,   34,   34,   34,   34,   34,   34,  454,  444,
+-
+-      444,   34,   34,   34,   34,   34,   34,   34,   34,   34,
+-       34,   34,   34,   34,   34,  444,  455,  455,  444,  458,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,  450,  450,  450,  450,  450,  450,  444,  444,   34,
+-       34,   34,  453,   34,  453,   34,   34,   34,   34,   34,
+-       34,  453,   34,   34,   34,   34,   34,   34,   34,   34,
+-       34,   34,  119,  444,  119,  459,  444,  444,  444,  444,
+-      444,  444,  444,  444,  450,  450,  450,  450,  450,  450,
+-       34,   34,   34,  444,   34,  444,   34,   34,  453,   34,
+-      444,  444,   34,   34,   34,   34,   34,   34,   34,   34,
+-
+-       34,  460,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,  450,  450,  450,  450,  450,  450,   34,   34,   34,
+-       34,  453,  444,  192,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,   34,   34,   34,   34,   34,   34,
+-      453,  461,  444,  444,  444,  444,  444,  462,  444,  450,
+-      450,  450,  450,  450,  444,   34,   34,   34,   34,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,   34,   34,   34,   34,  453,  444,  463,  444,  464,
+-      465,  466,  444,  444,  450,  444,  444,  444,  450,   34,
+-       34,   34,   34,  444,  444,  444,  444,  444,  444,  444,
+-
+-      467,  444,  444,  444,  444,  444,   34,   34,   34,  444,
+-      468,  444,  469,  444,  450,  444,   34,   34,   34,   34,
+-      444,  444,  444,  444,  444,  444,  192,  444,  444,  444,
+-      444,   34,  453,   34,  470,  444,  444,  450,  450,  450,
+-       34,   34,   34,   34,  444,  444,  444,  444,  444,   34,
+-      444,  453,  471,  444,  472,  473,  444,  450,  444,  444,
+-       34,   34,   34,   34,   34,  444,  444,  444,  453,  444,
+-      474,  444,  444,  450,   34,   34,   34,   34,   34,  444,
+-      444,  444,  444,  475,  444,  444,  450,   34,   34,   34,
+-       34,   34,  444,  444,  444,  476,  444,  450,   34,   34,
+-
+-       34,  444,  444,  444,  477,  444,  450,   34,  444,  478,
+-       34,  444,  444,  444,  444,  479,  444,  450,   34,  444,
+-      478,  478,  480,  444,  444,  444,  444,  481,  482,  444,
+-      444,  444,  480,  444,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,    0,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,  444
+-    } ;
+-
+-static yyconst flex_int16_t yy_nxt[1507] =
+-    {   0,
+-       10,   11,   12,   13,   10,   10,   14,   10,   10,   10,
+-       10,   15,   10,   52,   55,   55,   53,   55,   55,   75,
+-      444,   56,   56,   61,   57,   57,   82,   82,   82,   82,
+-       84,   92,   94,   58,   58,   10,   10,   10,   10,   17,
+-       12,   13,   18,   10,   14,   10,   10,   10,   10,   15,
+-       10,   59,   58,   58,   19,   92,   62,   95,   92,   96,
+-       76,   92,   98,   85,   92,   92,   92,   92,   92,   92,
+-       59,   92,   92,   10,   10,   10,  116,   82,   92,  117,
+-      143,   20,  105,  142,  103,  109,  198,  102,   82,   82,
+-      104,  106,  107,   21,   22,   23,   24,   25,   26,   27,
+-
+-       24,   28,   29,   28,   28,   28,   30,   31,   32,   33,
+-       34,   35,   33,   36,   33,   37,   38,   33,   33,   33,
+-       33,   33,   33,   33,   33,   33,   33,   33,   39,   33,
+-       33,   40,   41,   24,   33,   33,   42,   43,   44,   45,
+-       33,   33,   33,   46,   33,   47,   33,   48,   33,   49,
+-       33,   50,   33,   51,   33,   33,   33,   33,   68,   58,
+-       92,   69,   92,   92,   92,   61,   75,   58,   58,   75,
+-       84,   92,  141,   70,   92,  110,   59,  144,   92,  134,
+-      145,   92,   92,  112,  113,   59,  108,   68,   58,  115,
+-       69,   92,  111,  114,  135,  147,   92,  301,   62,   92,
+-
+-       71,   92,   70,   85,  146,   59,  148,   76,   92,   92,
+-       76,   92,   72,   73,   74,   91,   91,   91,   91,   91,
+-       91,   91,   91,   91,   91,   91,   91,  151,  149,   71,
+-      150,  152,  181,  153,  170,   92,  301,   92,  154,  155,
+-       92,   72,   73,   74,   92,  269,  270,   92,   92,  171,
+-       91,   91,   91,   91,   91,   91,   91,   91,   91,   91,
+-       91,   91,   91,   91,   91,  156,  157,  158,  161,  182,
+-      116,   82,  160,  117,   92,  183,  162,   92,  185,   93,
+-       92,  203,  203,  159,   92,  443,  291,  204,   91,   91,
+-       91,  163,  163,  164,  163,  163,  163,  163,  163,  163,
+-
+-      163,  163,  163,  163,  163,  163,  163,  163,  163,  163,
+-      163,  163,  163,  163,  163,  163,  163,  163,  163,  163,
+-      163,  163,  163,  163,  163,  163,  163,  163,  163,  165,
+-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
+-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
+-      165,  165,  165,  184,  184,  184,  184,  184,  184,  184,
+-      184,  184,  184,  184,  184,   92,   92,   92,  219,   92,
+-       92,  300,  342,   92,   92,  301,   92,   92,  188,  190,
+-       92,   92,   92,  194,  152,  195,   92,   92,  184,  184,
+-      184,  186,  186,  186,  186,  186,  186,  186,  186,  186,
+-
+-      186,  186,  186,  152,  152,  189,  187,   92,   92,   92,
+-       92,  442,  193,  317,  196,   92,   92,   92,  199,  218,
+-      220,   92,  221,   92,   92,   92,  186,  186,  186,  191,
+-      192,  192,  191,  191,  191,  191,  191,  191,  191,  191,
+-      191,  197,  201,  200,   92,  222,   92,   92,   92,  236,
+-      203,  203,  290,  152,  152,  441,  204,   92,  292,  237,
+-      239,  235,  240,   92,  191,  191,  191,  163,  163,  163,
+-      163,  163,  163,  163,  163,  163,  163,  163,  163,  163,
+-      163,  163,  163,  163,  163,  163,  163,  163,  163,  163,
+-      163,  223,  223,  223,  223,  223,  223,  223,  223,  223,
+-
+-      223,  223,  223,   92,   92,   92,   92,  256,  258,  257,
+-       92,  273,   92,  301,   92,   92,   92,  259,   92,   92,
+-       92,  238,   92,  304,  158,   92,  223,  223,  223,  224,
+-      224,  241,  272,  152,  152,  275,  293,  274,   92,  305,
+-      273,   92,  225,  226,  152,  276,   92,   92,  227,   92,
+-      307,   92,  314,  314,   92,  320,   92,  327,  327,  318,
+-      319,   92,  314,  314,  440,   92,  274,  308,  228,  229,
+-      230,   92,  309,  341,  334,  231,  332,  232,   92,  388,
+-      337,   92,   92,  233,   92,  234,  255,  255,  255,  255,
+-      255,  255,  255,  255,  255,  255,  255,  255,  338,  343,
+-
+-      333,  344,  389,   92,  361,  439,  339,   92,  350,   92,
+-       92,  340,  340,  352,  362,  363,  301,   92,  437,   92,
+-       92,  255,  255,  255,  260,  260,  260,  260,  260,  260,
+-      260,  260,  260,  260,  260,  260,  354,  375,  390,   92,
+-      376,   92,  364,  377,  355,  369,   92,   92,  152,  356,
+-      356,  365,   92,   92,  392,   92,  436,  378,   92,  260,
+-      260,  260,  277,  277,  277,  277,  277,  277,  277,  277,
+-      277,  277,  277,  277,  379,   92,  399,  401,  400,   92,
+-       92,  408,   92,  435,  152,   92,  434,  391,   92,  409,
+-      409,   92,  411,   92,  427,  410,  426,  277,  277,  277,
+-
+-      286,  286,  286,  286,  286,  286,  286,  286,  286,  286,
+-      286,  286,  414,  418,   92,   92,  420,  420,  418,  418,
+-      425,  415,  421,  422,  422,   92,  429,  419,  424,  152,
+-       92,  429,  429,  417,  152,  286,  286,  286,  287,  287,
+-      287,  287,  287,  287,  287,  287,  287,  287,  287,  287,
+-      420,  420,  422,  422,  422,  422,  421,  431,  431,  431,
+-      431,  431,  431,  413,  432,  412,  432,  407,  432,  406,
+-      404,  403,  402,  287,  287,  287,  288,  288,  288,  288,
+-      288,  288,  288,  288,  288,  288,  288,  288,  398,  397,
+-      395,  394,  393,  387,  386,  385,  382,  381,  380,  374,
+-
+-      373,  372,  301,  301,  368,  367,  366,  358,  357,  304,
+-      349,  288,  288,  288,  310,  310,  310,  310,  310,  310,
+-      310,  310,  310,  310,  310,  310,  348,  301,  301,  301,
+-      347,  346,  345,  336,  331,  330,  329,  328,  301,  325,
+-      324,  301,  301,  323,  322,  321,  315,  313,  312,  310,
+-      310,  310,  316,  316,  316,  316,  316,  316,  316,  316,
+-      316,  316,  316,  316,  306,  303,  302,  299,  298,  297,
+-      296,  295,  294,  289,  285,  284,  283,  282,  281,  280,
+-      279,  271,  268,  267,  266,  265,  264,  316,  316,  316,
+-      351,  351,  351,  351,  351,  351,  351,  351,  351,  351,
+-
+-      351,  351,  263,  262,  261,  254,  253,  252,  251,  250,
+-      249,  248,  247,  246,  245,  244,  243,  217,  216,  215,
+-      214,  213,  212,  211,  210,  351,  351,  351,  359,  359,
+-      359,  359,  359,  359,  359,  359,  359,  359,  359,  359,
+-      209,  208,  207,  206,  205,  180,  179,  178,  177,  176,
+-      175,  174,  173,  172,  169,  168,  167,  118,  118,  100,
+-      140,   92,   90,  359,  359,  359,  360,  360,  360,  360,
+-      360,  360,  360,  360,  360,  360,  360,  360,  139,  444,
+-      138,  444,  137,  136,  133,  132,  131,  130,  129,  128,
+-      127,  126,  444,  125,  124,  123,  122,  118,  101,  100,
+-
+-       97,  360,  360,  360,  370,  370,  370,  370,  370,  370,
+-      370,  370,  370,  370,  370,  370,   90,   89,   88,   87,
+-       81,   80,   79,   78,   77,   66,   64,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  370,
+-      370,  370,  383,  383,  383,  383,  383,  383,  383,  383,
+-      383,  383,  383,  383,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  383,  383,  383,
+-      430,  430,  430,  430,  430,  430,  430,  430,  430,  430,
+-      430,  430,  444,  444,  444,  444,  444,  444,  444,  444,
+-
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  430,  430,  430,   16,   16,
+-       16,   16,   16,   16,   16,   16,   16,   54,   54,   54,
+-       54,   54,   54,   54,   54,   54,   60,   60,   60,   60,
+-       60,   60,   60,   60,   60,   63,   63,   63,   63,   63,
+-       63,   63,   63,   63,   65,   65,   65,   65,   65,   65,
+-       65,   65,   65,   67,   67,  444,   67,   83,   83,   83,
+-       83,   83,   83,   83,   83,   83,   86,   86,   86,   86,
+-       86,   86,   86,   86,   86,   92,   92,   92,   92,   92,
+-       92,   92,   92,   92,   99,   99,   99,   99,   99,   99,
+-
+-       99,  444,   99,  119,  444,  444,  444,  444,  444,  444,
+-      119,  120,  120,  444,  120,  444,  120,  120,  120,  120,
+-      121,  121,  121,  121,  121,  121,  121,  121,  121,  166,
+-      166,  444,  166,  444,  166,  166,  166,  166,  202,  202,
+-      444,  202,  444,  202,  202,  202,  202,  242,  242,  444,
+-      242,  444,  242,  242,  242,  242,  278,  278,  444,  278,
+-      444,  278,  278,  278,  278,  255,  255,  255,  255,  255,
+-      444,  444,  255,  311,  311,  444,  311,  444,  311,  311,
+-      311,  311,  286,  286,  286,  286,  286,  444,  444,  286,
+-      287,  287,  287,  287,  287,  444,  444,  287,  288,  288,
+-
+-      288,  288,  288,  444,  444,  288,  326,  326,  326,  326,
+-      326,  444,  444,  326,  335,  335,  444,  335,  444,  335,
+-      335,  335,  335,  316,  316,  316,  316,  316,  444,  444,
+-      316,  353,  353,  444,  353,  444,  353,  353,  353,  353,
+-      371,  371,  444,  371,  444,  371,  371,  371,  371,  359,
+-      359,  359,  359,  359,  444,  444,  359,  360,  360,  360,
+-      360,  360,  444,  444,  360,  384,  384,  444,  384,  444,
+-      384,  384,  384,  384,  396,  396,  444,  396,  444,  396,
+-      396,  396,  396,  405,  405,  444,  405,  444,  405,  405,
+-      405,  405,  416,  416,  444,  416,  444,  416,  416,  416,
+-
+-      416,  423,  423,  444,  444,  444,  423,  444,  423,  428,
+-      428,  444,  428,  444,  428,  428,  428,  428,  433,  433,
+-      433,  444,  433,  433,  444,  433,  438,  438,  444,  438,
+-      444,  438,  438,  438,  438,  430,  430,  430,  430,  430,
+-      444,  444,  430,    9,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-
+-      444,  444,  444,  444,  444,  444
+-    } ;
+-
+-static yyconst flex_int16_t yy_chk[1507] =
+-    {   0,
+-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+-        1,    1,    1,    4,    5,    6,    4,    7,    8,   18,
+-        0,    5,    6,   13,    7,    8,   25,   25,   26,   26,
+-       27,   35,   35,   11,   11,    1,    1,    1,    2,    2,
+-        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+-        2,   11,   12,   12,    2,   37,   13,   36,   36,   37,
+-       18,   42,   39,   27,   43,   44,   45,   46,   48,  159,
+-       12,   39,   96,    2,    2,    2,   52,   52,   95,   52,
+-       96,    2,   44,   95,   43,   48,  159,   42,   82,   82,
+-       43,   45,   46,    2,    2,    2,    3,    3,    3,    3,
+-
+-        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+-        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+-        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+-        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+-        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+-        3,    3,    3,    3,    3,    3,    3,    3,   17,   17,
+-       47,   17,   49,   50,   51,   60,   69,   58,   58,   75,
+-       83,   94,   94,   17,   97,   49,   17,   97,  102,   79,
+-       98,  104,  103,   50,   50,   58,   47,   68,   68,   51,
+-       68,   98,   49,   50,   79,  103,  105,  443,   60,  106,
+-
+-       17,  107,   68,   83,  102,   68,  104,   69,  108,  109,
+-       75,  110,   17,   17,   17,   33,   33,   33,   33,   33,
+-       33,   33,   33,   33,   33,   33,   33,  107,  105,   68,
+-      106,  107,  140,  108,  128,  140,  442,  111,  109,  110,
+-      112,   68,   68,   68,  114,  233,  233,  115,  113,  128,
+-       33,   33,   33,   34,   34,   34,   34,   34,   34,   34,
+-       34,   34,   34,   34,   34,  111,  112,  113,  115,  141,
+-      116,  116,  114,  116,  144,  142,  115,  142,  144,   34,
+-      141,  167,  167,  113,  257,  441,  257,  167,   34,   34,
+-       34,  119,  119,  119,  119,  119,  119,  119,  119,  119,
+-
+-      119,  119,  119,  119,  119,  119,  119,  119,  119,  119,
+-      119,  119,  119,  119,  119,  119,  119,  119,  119,  119,
+-      119,  119,  119,  119,  119,  119,  119,  119,  119,  119,
+-      119,  119,  119,  119,  119,  119,  119,  119,  119,  119,
+-      119,  119,  119,  119,  119,  119,  119,  119,  119,  119,
+-      119,  119,  119,  143,  143,  143,  143,  143,  143,  143,
+-      143,  143,  143,  143,  143,  153,  149,  151,  182,  318,
+-      155,  267,  318,  156,  182,  267,  147,  148,  149,  151,
+-      146,  150,  154,  155,  153,  156,  157,  160,  143,  143,
+-      143,  145,  145,  145,  145,  145,  145,  145,  145,  145,
+-
+-      145,  145,  145,  146,  147,  150,  148,  181,  183,  290,
+-      185,  440,  154,  290,  157,  187,  158,  161,  160,  181,
+-      183,  162,  185,  188,  190,  194,  145,  145,  145,  152,
+-      152,  152,  152,  152,  152,  152,  152,  152,  152,  152,
+-      152,  158,  162,  161,  193,  187,  195,  199,  198,  194,
+-      203,  203,  256,  188,  190,  439,  203,  256,  258,  195,
+-      198,  193,  199,  258,  152,  152,  152,  163,  163,  163,
+-      163,  163,  163,  163,  163,  163,  163,  163,  163,  163,
+-      163,  163,  163,  163,  163,  163,  163,  163,  163,  163,
+-      163,  189,  189,  189,  189,  189,  189,  189,  189,  189,
+-
+-      189,  189,  189,  196,  197,  201,  200,  218,  220,  219,
+-      221,  236,  237,  437,  239,  240,  235,  221,  238,  218,
+-      220,  197,  219,  270,  201,  236,  189,  189,  189,  192,
+-      192,  200,  235,  196,  238,  237,  259,  236,  272,  270,
+-      273,  259,  192,  192,  239,  240,  274,  291,  192,  307,
+-      272,  275,  284,  284,  273,  293,  292,  301,  301,  291,
+-      292,  309,  314,  314,  436,  293,  273,  274,  192,  192,
+-      192,  308,  275,  317,  309,  192,  307,  192,  332,  375,
+-      314,  317,  375,  192,  334,  192,  217,  217,  217,  217,
+-      217,  217,  217,  217,  217,  217,  217,  217,  315,  319,
+-
+-      308,  320,  376,  376,  341,  435,  315,  319,  332,  341,
+-      320,  315,  315,  334,  342,  343,  434,  350,  427,  342,
+-      343,  217,  217,  217,  222,  222,  222,  222,  222,  222,
+-      222,  222,  222,  222,  222,  222,  336,  361,  377,  344,
+-      362,  377,  344,  363,  336,  350,  361,  362,  388,  336,
+-      336,  344,  363,  364,  379,  379,  426,  364,  388,  222,
+-      222,  222,  241,  241,  241,  241,  241,  241,  241,  241,
+-      241,  241,  241,  241,  365,  378,  389,  391,  390,  365,
+-      392,  399,  391,  425,  392,  389,  424,  378,  390,  400,
+-      400,  399,  401,  401,  415,  400,  414,  241,  241,  241,
+-
+-      251,  251,  251,  251,  251,  251,  251,  251,  251,  251,
+-      251,  251,  404,  407,  400,  408,  409,  409,  407,  407,
+-      413,  404,  409,  410,  410,  411,  417,  408,  412,  411,
+-      419,  417,  417,  406,  419,  251,  251,  251,  252,  252,
+-      252,  252,  252,  252,  252,  252,  252,  252,  252,  252,
+-      420,  420,  421,  421,  422,  422,  420,  423,  423,  431,
+-      431,  433,  433,  403,  423,  402,  431,  398,  433,  397,
+-      395,  394,  393,  252,  252,  252,  253,  253,  253,  253,
+-      253,  253,  253,  253,  253,  253,  253,  253,  387,  385,
+-      382,  381,  380,  374,  373,  372,  368,  367,  366,  358,
+-
+-      357,  354,  349,  348,  347,  346,  345,  338,  337,  331,
+-      330,  253,  253,  253,  276,  276,  276,  276,  276,  276,
+-      276,  276,  276,  276,  276,  276,  329,  328,  325,  324,
+-      323,  322,  321,  312,  306,  305,  304,  303,  302,  300,
+-      299,  298,  297,  296,  295,  294,  285,  283,  279,  276,
+-      276,  276,  289,  289,  289,  289,  289,  289,  289,  289,
+-      289,  289,  289,  289,  271,  269,  268,  266,  265,  264,
+-      263,  262,  261,  254,  250,  249,  247,  246,  245,  244,
+-      243,  234,  232,  231,  230,  229,  228,  289,  289,  289,
+-      333,  333,  333,  333,  333,  333,  333,  333,  333,  333,
+-
+-      333,  333,  227,  226,  225,  216,  215,  214,  213,  212,
+-      211,  210,  209,  208,  207,  206,  205,  180,  179,  178,
+-      177,  176,  175,  174,  173,  333,  333,  333,  339,  339,
+-      339,  339,  339,  339,  339,  339,  339,  339,  339,  339,
+-      172,  171,  170,  169,  168,  137,  136,  135,  134,  133,
+-      132,  131,  130,  129,  127,  126,  124,  118,  117,   99,
+-       93,   92,   90,  339,  339,  339,  340,  340,  340,  340,
+-      340,  340,  340,  340,  340,  340,  340,  340,   88,   87,
+-       86,   85,   81,   80,   78,   77,   76,   74,   73,   72,
+-       71,   70,   64,   63,   59,   57,   56,   53,   41,   40,
+-
+-       38,  340,  340,  340,  352,  352,  352,  352,  352,  352,
+-      352,  352,  352,  352,  352,  352,   32,   31,   30,   29,
+-       23,   22,   21,   20,   19,   15,   14,    9,    0,    0,
+-        0,    0,    0,    0,    0,    0,    0,    0,    0,  352,
+-      352,  352,  369,  369,  369,  369,  369,  369,  369,  369,
+-      369,  369,  369,  369,    0,    0,    0,    0,    0,    0,
+-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+-        0,    0,    0,    0,    0,    0,    0,  369,  369,  369,
+-      418,  418,  418,  418,  418,  418,  418,  418,  418,  418,
+-      418,  418,    0,    0,    0,    0,    0,    0,    0,    0,
+-
+-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+-        0,    0,    0,    0,    0,  418,  418,  418,  445,  445,
+-      445,  445,  445,  445,  445,  445,  445,  446,  446,  446,
+-      446,  446,  446,  446,  446,  446,  447,  447,  447,  447,
+-      447,  447,  447,  447,  447,  448,  448,  448,  448,  448,
+-      448,  448,  448,  448,  449,  449,  449,  449,  449,  449,
+-      449,  449,  449,  450,  450,    0,  450,  451,  451,  451,
+-      451,  451,  451,  451,  451,  451,  452,  452,  452,  452,
+-      452,  452,  452,  452,  452,  453,  453,  453,  453,  453,
+-      453,  453,  453,  453,  454,  454,  454,  454,  454,  454,
+-
+-      454,    0,  454,  455,    0,    0,    0,    0,    0,    0,
+-      455,  456,  456,    0,  456,    0,  456,  456,  456,  456,
+-      457,  457,  457,  457,  457,  457,  457,  457,  457,  458,
+-      458,    0,  458,    0,  458,  458,  458,  458,  459,  459,
+-        0,  459,    0,  459,  459,  459,  459,  460,  460,    0,
+-      460,    0,  460,  460,  460,  460,  461,  461,    0,  461,
+-        0,  461,  461,  461,  461,  462,  462,  462,  462,  462,
+-        0,    0,  462,  463,  463,    0,  463,    0,  463,  463,
+-      463,  463,  464,  464,  464,  464,  464,    0,    0,  464,
+-      465,  465,  465,  465,  465,    0,    0,  465,  466,  466,
+-
+-      466,  466,  466,    0,    0,  466,  467,  467,  467,  467,
+-      467,    0,    0,  467,  468,  468,    0,  468,    0,  468,
+-      468,  468,  468,  469,  469,  469,  469,  469,    0,    0,
+-      469,  470,  470,    0,  470,    0,  470,  470,  470,  470,
+-      471,  471,    0,  471,    0,  471,  471,  471,  471,  472,
+-      472,  472,  472,  472,    0,    0,  472,  473,  473,  473,
+-      473,  473,    0,    0,  473,  474,  474,    0,  474,    0,
+-      474,  474,  474,  474,  475,  475,    0,  475,    0,  475,
+-      475,  475,  475,  476,  476,    0,  476,    0,  476,  476,
+-      476,  476,  477,  477,    0,  477,    0,  477,  477,  477,
+-
+-      477,  478,  478,    0,    0,    0,  478,    0,  478,  479,
+-      479,    0,  479,    0,  479,  479,  479,  479,  480,  480,
+-      480,    0,  480,  480,    0,  480,  481,  481,    0,  481,
+-        0,  481,  481,  481,  481,  482,  482,  482,  482,  482,
+-        0,    0,  482,  444,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-      444,  444,  444,  444,  444,  444,  444,  444,  444,  444,
+-
+-      444,  444,  444,  444,  444,  444
+-    } ;
+-
+-static yy_state_type yy_last_accepting_state;
+-static char *yy_last_accepting_cpos;
+-
+-extern int yy_flex_debug;
+-int yy_flex_debug = 0;
+-
+-/* The intent behind this definition is that it'll catch
+- * any uses of REJECT which flex missed.
+- */
+-#define REJECT reject_used_but_not_detected
+-#define yymore() yymore_used_but_not_detected
+-#define YY_MORE_ADJ 0
+-#define YY_RESTORE_YY_MORE_OFFSET
+-char *yytext;
+-#line 1 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-/* -*- indented-text -*- */
+-/* Process source files and output type information.
+-   Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+-
+-This file is part of GCC.
+-
+-GCC is free software; you can redistribute it and/or modify it under
+-the terms of the GNU General Public License as published by the Free
+-Software Foundation; either version 3, or (at your option) any later
+-version.
+-
+-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+-WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+-for more details.
+-
+-You should have received a copy of the GNU General Public License
+-along with GCC; see the file COPYING3.  If not see
+-<http://www.gnu.org/licenses/>.  */
+-#line 22 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-#include "bconfig.h"
+-#include "system.h"
+-
+-#define malloc xmalloc
+-#define realloc xrealloc
+-
+-#include "gengtype.h"
+-
+-#define YY_DECL int yylex (const char **yylval)
+-#define yyterminate() return EOF_TOKEN
+-
+-struct fileloc lexer_line;
+-int lexer_toplevel_done;
+-
+-static void 
+-update_lineno (const char *l, size_t len)
+-{
+-  while (len-- > 0)
+-    if (*l++ == '\n')
+-      lexer_line.line++;
+-}
+-
+-
+-#line 984 "gengtype-lex.c"
+-
+-#define INITIAL 0
+-#define in_struct 1
+-#define in_struct_comment 2
+-#define in_comment 3
+-
+-#ifndef YY_NO_UNISTD_H
+-/* Special case for "unistd.h", since it is non-ANSI. We include it way
+- * down here because we want the user's section 1 to have been scanned first.
+- * The user has a chance to override it with an option.
+- */
+-#include <unistd.h>
+-#endif
+-
+-#ifndef YY_EXTRA_TYPE
+-#define YY_EXTRA_TYPE void *
+-#endif
+-
+-static int yy_init_globals (void );
+-
+-/* Accessor methods to globals.
+-   These are made visible to non-reentrant scanners for convenience. */
+-
+-int yylex_destroy (void );
+-
+-int yyget_debug (void );
+-
+-void yyset_debug (int debug_flag  );
+-
+-YY_EXTRA_TYPE yyget_extra (void );
+-
+-void yyset_extra (YY_EXTRA_TYPE user_defined  );
+-
+-FILE *yyget_in (void );
+-
+-void yyset_in  (FILE * in_str  );
+-
+-FILE *yyget_out (void );
+-
+-void yyset_out  (FILE * out_str  );
+-
+-int yyget_leng (void );
+-
+-char *yyget_text (void );
+-
+-int yyget_lineno (void );
+-
+-void yyset_lineno (int line_number  );
+-
+-/* Macros after this point can all be overridden by user definitions in
+- * section 1.
+- */
+-
+-#ifndef YY_SKIP_YYWRAP
+-#ifdef __cplusplus
+-extern "C" int yywrap (void );
+-#else
+-extern int yywrap (void );
+-#endif
+-#endif
+-
+-#ifndef yytext_ptr
+-static void yy_flex_strncpy (char *,yyconst char *,int );
+-#endif
+-
+-#ifdef YY_NEED_STRLEN
+-static int yy_flex_strlen (yyconst char * );
+-#endif
+-
+-#ifndef YY_NO_INPUT
+-
+-#ifdef __cplusplus
+-static int yyinput (void );
+-#else
+-static int input (void );
+-#endif
+-
+-#endif
+-
+-/* Amount of stuff to slurp up with each read. */
+-#ifndef YY_READ_BUF_SIZE
+-#define YY_READ_BUF_SIZE 8192
+-#endif
+-
+-/* Copy whatever the last rule matched to the standard output. */
+-#ifndef ECHO
+-/* This used to be an fputs(), but since the string might contain NUL's,
+- * we now use fwrite().
+- */
+-#define ECHO fwrite( yytext, yyleng, 1, yyout )
+-#endif
+-
+-/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+- * is returned in "result".
+- */
+-#ifndef YY_INPUT
+-#define YY_INPUT(buf,result,max_size) \
+-      if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+-              { \
+-              int c = '*'; \
+-              int n; \
+-              for ( n = 0; n < max_size && \
+-                           (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+-                      buf[n] = (char) c; \
+-              if ( c == '\n' ) \
+-                      buf[n++] = (char) c; \
+-              if ( c == EOF && ferror( yyin ) ) \
+-                      YY_FATAL_ERROR( "input in flex scanner failed" ); \
+-              result = n; \
+-              } \
+-      else \
+-              { \
+-              errno=0; \
+-              while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+-                      { \
+-                      if( errno != EINTR) \
+-                              { \
+-                              YY_FATAL_ERROR( "input in flex scanner failed" ); \
+-                              break; \
+-                              } \
+-                      errno=0; \
+-                      clearerr(yyin); \
+-                      } \
+-              }\
+-\
+-
+-#endif
+-
+-/* No semi-colon after return; correct usage is to write "yyterminate();" -
+- * we don't want an extra ';' after the "return" because that will cause
+- * some compilers to complain about unreachable statements.
+- */
+-#ifndef yyterminate
+-#define yyterminate() return YY_NULL
+-#endif
+-
+-/* Number of entries by which start-condition stack grows. */
+-#ifndef YY_START_STACK_INCR
+-#define YY_START_STACK_INCR 25
+-#endif
+-
+-/* Report a fatal error. */
+-#ifndef YY_FATAL_ERROR
+-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+-#endif
+-
+-/* end tables serialization structures and prototypes */
+-
+-/* Default declaration of generated scanner - a define so the user can
+- * easily add parameters.
+- */
+-#ifndef YY_DECL
+-#define YY_DECL_IS_OURS 1
+-
+-extern int yylex (void);
+-
+-#define YY_DECL int yylex (void)
+-#endif /* !YY_DECL */
+-
+-/* Code executed at the beginning of each rule, after yytext and yyleng
+- * have been set up.
+- */
+-#ifndef YY_USER_ACTION
+-#define YY_USER_ACTION
+-#endif
+-
+-/* Code executed at the end of each rule. */
+-#ifndef YY_BREAK
+-#define YY_BREAK break;
+-#endif
+-
+-#define YY_RULE_SETUP \
+-      if ( yyleng > 0 ) \
+-              YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
+-                              (yytext[yyleng - 1] == '\n'); \
+-      YY_USER_ACTION
+-
+-/** The main scanner function which does all the work.
+- */
+-YY_DECL
+-{
+-      register yy_state_type yy_current_state;
+-      register char *yy_cp, *yy_bp;
+-      register int yy_act;
+-    
+-#line 56 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-
+-  /* Do this on entry to yylex():  */
+-  *yylval = 0;
+-  if (lexer_toplevel_done)
+-    {
+-      BEGIN(INITIAL);
+-      lexer_toplevel_done = 0;
+-    }
+-
+-  /* Things we look for in skipping mode: */
+-#line 1181 "gengtype-lex.c"
+-
+-      if ( !(yy_init) )
+-              {
+-              (yy_init) = 1;
+-
+-#ifdef YY_USER_INIT
+-              YY_USER_INIT;
+-#endif
+-
+-              if ( ! (yy_start) )
+-                      (yy_start) = 1; /* first start state */
+-
+-              if ( ! yyin )
+-                      yyin = stdin;
+-
+-              if ( ! yyout )
+-                      yyout = stdout;
+-
+-              if ( ! YY_CURRENT_BUFFER ) {
+-                      yyensure_buffer_stack ();
+-                      YY_CURRENT_BUFFER_LVALUE =
+-                              yy_create_buffer(yyin,YY_BUF_SIZE );
+-              }
+-
+-              yy_load_buffer_state( );
+-              }
+-
+-      while ( 1 )             /* loops until end-of-file is reached */
+-              {
+-              yy_cp = (yy_c_buf_p);
+-
+-              /* Support of yytext. */
+-              *yy_cp = (yy_hold_char);
+-
+-              /* yy_bp points to the position in yy_ch_buf of the start of
+-               * the current run.
+-               */
+-              yy_bp = yy_cp;
+-
+-              yy_current_state = (yy_start);
+-              yy_current_state += YY_AT_BOL();
+-yy_match:
+-              do
+-                      {
+-                      register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+-                      if ( yy_accept[yy_current_state] )
+-                              {
+-                              (yy_last_accepting_state) = yy_current_state;
+-                              (yy_last_accepting_cpos) = yy_cp;
+-                              }
+-                      while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+-                              {
+-                              yy_current_state = (int) yy_def[yy_current_state];
+-                              if ( yy_current_state >= 445 )
+-                                      yy_c = yy_meta[(unsigned int) yy_c];
+-                              }
+-                      yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+-                      ++yy_cp;
+-                      }
+-              while ( yy_current_state != 444 );
+-              yy_cp = (yy_last_accepting_cpos);
+-              yy_current_state = (yy_last_accepting_state);
+-
+-yy_find_action:
+-              yy_act = yy_accept[yy_current_state];
+-
+-              YY_DO_BEFORE_ACTION;
+-
+-do_action:    /* This label is used only to access EOF actions. */
+-
+-              switch ( yy_act )
+-      { /* beginning of action switch */
+-                      case 0: /* must back up */
+-                      /* undo the effects of YY_DO_BEFORE_ACTION */
+-                      *yy_cp = (yy_hold_char);
+-                      yy_cp = (yy_last_accepting_cpos);
+-                      yy_current_state = (yy_last_accepting_state);
+-                      goto yy_find_action;
+-
+-case 1:
+-/* rule 1 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp -= 1;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 67 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  BEGIN(in_struct);
+-  return TYPEDEF;
+-}
+-      YY_BREAK
+-case 2:
+-/* rule 2 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp -= 1;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 71 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  BEGIN(in_struct);
+-  return STRUCT;
+-}
+-      YY_BREAK
+-case 3:
+-/* rule 3 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp -= 1;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 75 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  BEGIN(in_struct);
+-  return UNION;
+-}
+-      YY_BREAK
+-case 4:
+-/* rule 4 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp -= 1;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 79 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  BEGIN(in_struct);
+-  return EXTERN;
+-}
+-      YY_BREAK
+-case 5:
+-/* rule 5 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp -= 1;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 83 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  BEGIN(in_struct);
+-  return STATIC;
+-}
+-      YY_BREAK
+-case 6:
+-/* rule 6 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp -= 1;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 88 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  BEGIN(in_struct);
+-  return DEFVEC_OP;
+-}
+-      YY_BREAK
+-case 7:
+-/* rule 7 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp -= 1;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 92 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  BEGIN(in_struct);
+-  return DEFVEC_I;
+-}
+-      YY_BREAK
+-case 8:
+-/* rule 8 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp -= 1;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 96 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  BEGIN(in_struct);
+-  return DEFVEC_ALLOC;
+-}
+-      YY_BREAK
+-
+-
+-case 9:
+-YY_RULE_SETUP
+-#line 104 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ BEGIN(in_struct_comment); }
+-      YY_BREAK
+-case 10:
+-/* rule 10 can match eol */
+-YY_RULE_SETUP
+-#line 106 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ update_lineno (yytext, yyleng); }
+-      YY_BREAK
+-case 11:
+-/* rule 11 can match eol */
+-YY_RULE_SETUP
+-#line 107 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ lexer_line.line++; }
+-      YY_BREAK
+-case 12:
+-/* rule 12 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp = yy_bp + 5;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 109 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-/* don't care */
+-      YY_BREAK
+-case 13:
+-/* rule 13 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp = yy_bp + 3;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 110 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ return GTY_TOKEN; }
+-      YY_BREAK
+-case 14:
+-/* rule 14 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp = yy_bp + 3;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 111 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ return VEC_TOKEN; }
+-      YY_BREAK
+-case 15:
+-/* rule 15 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp = yy_bp + 5;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 112 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ return UNION; }
+-      YY_BREAK
+-case 16:
+-/* rule 16 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp = yy_bp + 6;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 113 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ return STRUCT; }
+-      YY_BREAK
+-case 17:
+-/* rule 17 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp = yy_bp + 4;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 114 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ return ENUM; }
+-      YY_BREAK
+-case 18:
+-/* rule 18 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp = yy_bp + 9;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 115 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ return PTR_ALIAS; }
+-      YY_BREAK
+-case 19:
+-/* rule 19 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp = yy_bp + 10;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 116 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ return NESTED_PTR; }
+-      YY_BREAK
+-case 20:
+-YY_RULE_SETUP
+-#line 117 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ return NUM; }
+-      YY_BREAK
+-case 21:
+-/* rule 21 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp -= 1;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 118 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  *yylval = xmemdup (yytext, yyleng, yyleng+1);
+-  return PARAM_IS;
+-}
+-      YY_BREAK
+-case 22:
+-/* rule 22 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp -= 1;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-#line 124 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-case 23:
+-/* rule 23 can match eol */
+-YY_RULE_SETUP
+-#line 124 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  size_t len;
+-
+-  for (len = yyleng; ISSPACE (yytext[len-1]); len--)
+-    ;
+-
+-  *yylval = xmemdup (yytext, len, len+1);
+-  update_lineno (yytext, yyleng);
+-  return SCALAR;
+-}
+-      YY_BREAK
+-case 24:
+-/* rule 24 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp -= 1;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 136 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  *yylval = xmemdup (yytext, yyleng, yyleng+1);
+-  return ID;
+-}
+-      YY_BREAK
+-case 25:
+-/* rule 25 can match eol */
+-YY_RULE_SETUP
+-#line 141 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  *yylval = xmemdup (yytext+1, yyleng-2, yyleng-1);
+-  return STRING;
+-}
+-      YY_BREAK
+-/* This "terminal" avoids having to parse integer constant expressions.  */
+-case 26:
+-/* rule 26 can match eol */
+-YY_RULE_SETUP
+-#line 146 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  *yylval = xmemdup (yytext+1, yyleng-2, yyleng-1);
+-  return ARRAY;
+-}
+-      YY_BREAK
+-case 27:
+-/* rule 27 can match eol */
+-YY_RULE_SETUP
+-#line 150 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  *yylval = xmemdup (yytext+1, yyleng-2, yyleng);
+-  return CHAR;
+-}
+-      YY_BREAK
+-case 28:
+-YY_RULE_SETUP
+-#line 155 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ return ELLIPSIS; }
+-      YY_BREAK
+-case 29:
+-YY_RULE_SETUP
+-#line 156 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ return yytext[0]; }
+-      YY_BREAK
+-/* ignore pp-directives */
+-case 30:
+-/* rule 30 can match eol */
+-YY_RULE_SETUP
+-#line 159 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{lexer_line.line++;}
+-      YY_BREAK
+-case 31:
+-YY_RULE_SETUP
+-#line 161 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  error_at_line (&lexer_line, "unexpected character `%s'", yytext);
+-}
+-      YY_BREAK
+-
+-case 32:
+-YY_RULE_SETUP
+-#line 166 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ BEGIN(in_comment); }
+-      YY_BREAK
+-case 33:
+-/* rule 33 can match eol */
+-YY_RULE_SETUP
+-#line 167 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ lexer_line.line++; }
+-      YY_BREAK
+-case 34:
+-#line 169 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-case 35:
+-/* rule 35 can match eol */
+-#line 170 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-case 36:
+-/* rule 36 can match eol */
+-YY_RULE_SETUP
+-#line 170 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-/* do nothing */
+-      YY_BREAK
+-case 37:
+-/* rule 37 can match eol */
+-YY_RULE_SETUP
+-#line 171 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ update_lineno (yytext, yyleng); }
+-      YY_BREAK
+-case 38:
+-/* rule 38 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp = yy_bp + 1;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 172 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-/* do nothing */
+-      YY_BREAK
+-
+-case 39:
+-/* rule 39 can match eol */
+-YY_RULE_SETUP
+-#line 175 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ lexer_line.line++; }
+-      YY_BREAK
+-case 40:
+-#line 177 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-case 41:
+-YY_RULE_SETUP
+-#line 177 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-/* do nothing */
+-      YY_BREAK
+-case 42:
+-/* rule 42 can match eol */
+-*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+-(yy_c_buf_p) = yy_cp = yy_bp + 1;
+-YY_DO_BEFORE_ACTION; /* set up yytext again */
+-YY_RULE_SETUP
+-#line 178 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-/* do nothing */
+-      YY_BREAK
+-
+-case 43:
+-YY_RULE_SETUP
+-#line 180 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ BEGIN(INITIAL); } 
+-      YY_BREAK
+-case 44:
+-YY_RULE_SETUP
+-#line 181 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{ BEGIN(in_struct); }
+-      YY_BREAK
+-case 45:
+-#line 184 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-case 46:
+-YY_RULE_SETUP
+-#line 184 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  error_at_line (&lexer_line, 
+-               "unterminated comment or string; unexpected EOF");
+-}
+-      YY_BREAK
+-case 47:
+-/* rule 47 can match eol */
+-YY_RULE_SETUP
+-#line 189 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-/* do nothing */
+-      YY_BREAK
+-case 48:
+-/* rule 48 can match eol */
+-YY_RULE_SETUP
+-#line 190 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-{
+-  error_at_line (&lexer_line, "stray GTY marker");
+-}
+-      YY_BREAK
+-case 49:
+-YY_RULE_SETUP
+-#line 194 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-YY_FATAL_ERROR( "flex scanner jammed" );
+-      YY_BREAK
+-#line 1651 "gengtype-lex.c"
+-case YY_STATE_EOF(INITIAL):
+-case YY_STATE_EOF(in_struct):
+-case YY_STATE_EOF(in_struct_comment):
+-case YY_STATE_EOF(in_comment):
+-      yyterminate();
+-
+-      case YY_END_OF_BUFFER:
+-              {
+-              /* Amount of text matched not including the EOB char. */
+-              int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+-
+-              /* Undo the effects of YY_DO_BEFORE_ACTION. */
+-              *yy_cp = (yy_hold_char);
+-              YY_RESTORE_YY_MORE_OFFSET
+-
+-              if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+-                      {
+-                      /* We're scanning a new file or input source.  It's
+-                       * possible that this happened because the user
+-                       * just pointed yyin at a new source and called
+-                       * yylex().  If so, then we have to assure
+-                       * consistency between YY_CURRENT_BUFFER and our
+-                       * globals.  Here is the right place to do so, because
+-                       * this is the first action (other than possibly a
+-                       * back-up) that will match for the new input source.
+-                       */
+-                      (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+-                      YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+-                      YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+-                      }
+-
+-              /* Note that here we test for yy_c_buf_p "<=" to the position
+-               * of the first EOB in the buffer, since yy_c_buf_p will
+-               * already have been incremented past the NUL character
+-               * (since all states make transitions on EOB to the
+-               * end-of-buffer state).  Contrast this with the test
+-               * in input().
+-               */
+-              if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+-                      { /* This was really a NUL. */
+-                      yy_state_type yy_next_state;
+-
+-                      (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+-
+-                      yy_current_state = yy_get_previous_state(  );
+-
+-                      /* Okay, we're now positioned to make the NUL
+-                       * transition.  We couldn't have
+-                       * yy_get_previous_state() go ahead and do it
+-                       * for us because it doesn't know how to deal
+-                       * with the possibility of jamming (and we don't
+-                       * want to build jamming into it because then it
+-                       * will run more slowly).
+-                       */
+-
+-                      yy_next_state = yy_try_NUL_trans( yy_current_state );
+-
+-                      yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+-
+-                      if ( yy_next_state )
+-                              {
+-                              /* Consume the NUL. */
+-                              yy_cp = ++(yy_c_buf_p);
+-                              yy_current_state = yy_next_state;
+-                              goto yy_match;
+-                              }
+-
+-                      else
+-                              {
+-                              yy_cp = (yy_last_accepting_cpos);
+-                              yy_current_state = (yy_last_accepting_state);
+-                              goto yy_find_action;
+-                              }
+-                      }
+-
+-              else switch ( yy_get_next_buffer(  ) )
+-                      {
+-                      case EOB_ACT_END_OF_FILE:
+-                              {
+-                              (yy_did_buffer_switch_on_eof) = 0;
+-
+-                              if ( yywrap( ) )
+-                                      {
+-                                      /* Note: because we've taken care in
+-                                       * yy_get_next_buffer() to have set up
+-                                       * yytext, we can now set up
+-                                       * yy_c_buf_p so that if some total
+-                                       * hoser (like flex itself) wants to
+-                                       * call the scanner after we return the
+-                                       * YY_NULL, it'll still work - another
+-                                       * YY_NULL will get returned.
+-                                       */
+-                                      (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+-
+-                                      yy_act = YY_STATE_EOF(YY_START);
+-                                      goto do_action;
+-                                      }
+-
+-                              else
+-                                      {
+-                                      if ( ! (yy_did_buffer_switch_on_eof) )
+-                                              YY_NEW_FILE;
+-                                      }
+-                              break;
+-                              }
+-
+-                      case EOB_ACT_CONTINUE_SCAN:
+-                              (yy_c_buf_p) =
+-                                      (yytext_ptr) + yy_amount_of_matched_text;
+-
+-                              yy_current_state = yy_get_previous_state(  );
+-
+-                              yy_cp = (yy_c_buf_p);
+-                              yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+-                              goto yy_match;
+-
+-                      case EOB_ACT_LAST_MATCH:
+-                              (yy_c_buf_p) =
+-                              &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+-
+-                              yy_current_state = yy_get_previous_state(  );
+-
+-                              yy_cp = (yy_c_buf_p);
+-                              yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+-                              goto yy_find_action;
+-                      }
+-              break;
+-              }
+-
+-      default:
+-              YY_FATAL_ERROR(
+-                      "fatal flex scanner internal error--no action found" );
+-      } /* end of action switch */
+-              } /* end of scanning one token */
+-} /* end of yylex */
+-
+-/* yy_get_next_buffer - try to read in a new buffer
+- *
+- * Returns a code representing an action:
+- *    EOB_ACT_LAST_MATCH -
+- *    EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+- *    EOB_ACT_END_OF_FILE - end of file
+- */
+-static int yy_get_next_buffer (void)
+-{
+-      register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+-      register char *source = (yytext_ptr);
+-      register int number_to_move, i;
+-      int ret_val;
+-
+-      if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+-              YY_FATAL_ERROR(
+-              "fatal flex scanner internal error--end of buffer missed" );
+-
+-      if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+-              { /* Don't try to fill the buffer, so this is an EOF. */
+-              if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+-                      {
+-                      /* We matched a single character, the EOB, so
+-                       * treat this as a final EOF.
+-                       */
+-                      return EOB_ACT_END_OF_FILE;
+-                      }
+-
+-              else
+-                      {
+-                      /* We matched some text prior to the EOB, first
+-                       * process it.
+-                       */
+-                      return EOB_ACT_LAST_MATCH;
+-                      }
+-              }
+-
+-      /* Try to read more data. */
+-
+-      /* First move last chars to start of buffer. */
+-      number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+-
+-      for ( i = 0; i < number_to_move; ++i )
+-              *(dest++) = *(source++);
+-
+-      if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+-              /* don't do the read, it's not guaranteed to return an EOF,
+-               * just force an EOF
+-               */
+-              YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+-
+-      else
+-              {
+-                      int num_to_read =
+-                      YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+-
+-              while ( num_to_read <= 0 )
+-                      { /* Not enough room in the buffer - grow it. */
+-
+-                      /* just a shorter name for the current buffer */
+-                      YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+-
+-                      int yy_c_buf_p_offset =
+-                              (int) ((yy_c_buf_p) - b->yy_ch_buf);
+-
+-                      if ( b->yy_is_our_buffer )
+-                              {
+-                              int new_size = b->yy_buf_size * 2;
+-
+-                              if ( new_size <= 0 )
+-                                      b->yy_buf_size += b->yy_buf_size / 8;
+-                              else
+-                                      b->yy_buf_size *= 2;
+-
+-                              b->yy_ch_buf = (char *)
+-                                      /* Include room in for 2 EOB chars. */
+-                                      yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+-                              }
+-                      else
+-                              /* Can't grow it, we don't own it. */
+-                              b->yy_ch_buf = 0;
+-
+-                      if ( ! b->yy_ch_buf )
+-                              YY_FATAL_ERROR(
+-                              "fatal error - scanner input buffer overflow" );
+-
+-                      (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+-
+-                      num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+-                                              number_to_move - 1;
+-
+-                      }
+-
+-              if ( num_to_read > YY_READ_BUF_SIZE )
+-                      num_to_read = YY_READ_BUF_SIZE;
+-
+-              /* Read in more data. */
+-              YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+-                      (yy_n_chars), (size_t) num_to_read );
+-
+-              YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+-              }
+-
+-      if ( (yy_n_chars) == 0 )
+-              {
+-              if ( number_to_move == YY_MORE_ADJ )
+-                      {
+-                      ret_val = EOB_ACT_END_OF_FILE;
+-                      yyrestart(yyin  );
+-                      }
+-
+-              else
+-                      {
+-                      ret_val = EOB_ACT_LAST_MATCH;
+-                      YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+-                              YY_BUFFER_EOF_PENDING;
+-                      }
+-              }
+-
+-      else
+-              ret_val = EOB_ACT_CONTINUE_SCAN;
+-
+-      if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+-              /* Extend the array by 50%, plus the number we really need. */
+-              yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+-              YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+-              if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+-                      YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+-      }
+-
+-      (yy_n_chars) += number_to_move;
+-      YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+-      YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+-
+-      (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+-
+-      return ret_val;
+-}
+-
+-/* yy_get_previous_state - get the state just before the EOB char was reached */
+-
+-    static yy_state_type yy_get_previous_state (void)
+-{
+-      register yy_state_type yy_current_state;
+-      register char *yy_cp;
+-    
+-      yy_current_state = (yy_start);
+-      yy_current_state += YY_AT_BOL();
+-
+-      for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+-              {
+-              register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+-              if ( yy_accept[yy_current_state] )
+-                      {
+-                      (yy_last_accepting_state) = yy_current_state;
+-                      (yy_last_accepting_cpos) = yy_cp;
+-                      }
+-              while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+-                      {
+-                      yy_current_state = (int) yy_def[yy_current_state];
+-                      if ( yy_current_state >= 445 )
+-                              yy_c = yy_meta[(unsigned int) yy_c];
+-                      }
+-              yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+-              }
+-
+-      return yy_current_state;
+-}
+-
+-/* yy_try_NUL_trans - try to make a transition on the NUL character
+- *
+- * synopsis
+- *    next_state = yy_try_NUL_trans( current_state );
+- */
+-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+-{
+-      register int yy_is_jam;
+-      register char *yy_cp = (yy_c_buf_p);
+-
+-      register YY_CHAR yy_c = 1;
+-      if ( yy_accept[yy_current_state] )
+-              {
+-              (yy_last_accepting_state) = yy_current_state;
+-              (yy_last_accepting_cpos) = yy_cp;
+-              }
+-      while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+-              {
+-              yy_current_state = (int) yy_def[yy_current_state];
+-              if ( yy_current_state >= 445 )
+-                      yy_c = yy_meta[(unsigned int) yy_c];
+-              }
+-      yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+-      yy_is_jam = (yy_current_state == 444);
+-
+-      return yy_is_jam ? 0 : yy_current_state;
+-}
+-
+-#ifndef YY_NO_INPUT
+-#ifdef __cplusplus
+-    static int yyinput (void)
+-#else
+-    static int input  (void)
+-#endif
+-
+-{
+-      int c;
+-    
+-      *(yy_c_buf_p) = (yy_hold_char);
+-
+-      if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+-              {
+-              /* yy_c_buf_p now points to the character we want to return.
+-               * If this occurs *before* the EOB characters, then it's a
+-               * valid NUL; if not, then we've hit the end of the buffer.
+-               */
+-              if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+-                      /* This was really a NUL. */
+-                      *(yy_c_buf_p) = '\0';
+-
+-              else
+-                      { /* need more input */
+-                      int offset = (yy_c_buf_p) - (yytext_ptr);
+-                      ++(yy_c_buf_p);
+-
+-                      switch ( yy_get_next_buffer(  ) )
+-                              {
+-                              case EOB_ACT_LAST_MATCH:
+-                                      /* This happens because yy_g_n_b()
+-                                       * sees that we've accumulated a
+-                                       * token and flags that we need to
+-                                       * try matching the token before
+-                                       * proceeding.  But for input(),
+-                                       * there's no matching to consider.
+-                                       * So convert the EOB_ACT_LAST_MATCH
+-                                       * to EOB_ACT_END_OF_FILE.
+-                                       */
+-
+-                                      /* Reset buffer status. */
+-                                      yyrestart(yyin );
+-
+-                                      /*FALLTHROUGH*/
+-
+-                              case EOB_ACT_END_OF_FILE:
+-                                      {
+-                                      if ( yywrap( ) )
+-                                              return EOF;
+-
+-                                      if ( ! (yy_did_buffer_switch_on_eof) )
+-                                              YY_NEW_FILE;
+-#ifdef __cplusplus
+-                                      return yyinput();
+-#else
+-                                      return input();
+-#endif
+-                                      }
+-
+-                              case EOB_ACT_CONTINUE_SCAN:
+-                                      (yy_c_buf_p) = (yytext_ptr) + offset;
+-                                      break;
+-                              }
+-                      }
+-              }
+-
+-      c = *(unsigned char *) (yy_c_buf_p);    /* cast for 8-bit char's */
+-      *(yy_c_buf_p) = '\0';   /* preserve yytext */
+-      (yy_hold_char) = *++(yy_c_buf_p);
+-
+-      YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
+-
+-      return c;
+-}
+-#endif        /* ifndef YY_NO_INPUT */
+-
+-/** Immediately switch to a different input stream.
+- * @param input_file A readable stream.
+- * 
+- * @note This function does not reset the start condition to @c INITIAL .
+- */
+-    void yyrestart  (FILE * input_file )
+-{
+-    
+-      if ( ! YY_CURRENT_BUFFER ){
+-        yyensure_buffer_stack ();
+-              YY_CURRENT_BUFFER_LVALUE =
+-            yy_create_buffer(yyin,YY_BUF_SIZE );
+-      }
+-
+-      yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+-      yy_load_buffer_state( );
+-}
+-
+-/** Switch to a different input buffer.
+- * @param new_buffer The new input buffer.
+- * 
+- */
+-    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+-{
+-    
+-      /* TODO. We should be able to replace this entire function body
+-       * with
+-       *              yypop_buffer_state();
+-       *              yypush_buffer_state(new_buffer);
+-     */
+-      yyensure_buffer_stack ();
+-      if ( YY_CURRENT_BUFFER == new_buffer )
+-              return;
+-
+-      if ( YY_CURRENT_BUFFER )
+-              {
+-              /* Flush out information for old buffer. */
+-              *(yy_c_buf_p) = (yy_hold_char);
+-              YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+-              YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+-              }
+-
+-      YY_CURRENT_BUFFER_LVALUE = new_buffer;
+-      yy_load_buffer_state( );
+-
+-      /* We don't actually know whether we did this switch during
+-       * EOF (yywrap()) processing, but the only time this flag
+-       * is looked at is after yywrap() is called, so it's safe
+-       * to go ahead and always set it.
+-       */
+-      (yy_did_buffer_switch_on_eof) = 1;
+-}
+-
+-static void yy_load_buffer_state  (void)
+-{
+-      (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+-      (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+-      yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+-      (yy_hold_char) = *(yy_c_buf_p);
+-}
+-
+-/** Allocate and initialize an input buffer state.
+- * @param file A readable stream.
+- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+- * 
+- * @return the allocated buffer state.
+- */
+-    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
+-{
+-      YY_BUFFER_STATE b;
+-    
+-      b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+-      if ( ! b )
+-              YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+-
+-      b->yy_buf_size = size;
+-
+-      /* yy_ch_buf has to be 2 characters longer than the size given because
+-       * we need to put in 2 end-of-buffer characters.
+-       */
+-      b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
+-      if ( ! b->yy_ch_buf )
+-              YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+-
+-      b->yy_is_our_buffer = 1;
+-
+-      yy_init_buffer(b,file );
+-
+-      return b;
+-}
+-
+-/** Destroy the buffer.
+- * @param b a buffer created with yy_create_buffer()
+- * 
+- */
+-    void yy_delete_buffer (YY_BUFFER_STATE  b )
+-{
+-    
+-      if ( ! b )
+-              return;
+-
+-      if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+-              YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+-
+-      if ( b->yy_is_our_buffer )
+-              yyfree((void *) b->yy_ch_buf  );
+-
+-      yyfree((void *) b  );
+-}
+-
+-/* Initializes or reinitializes a buffer.
+- * This function is sometimes called more than once on the same buffer,
+- * such as during a yyrestart() or at EOF.
+- */
+-    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+-
+-{
+-      int oerrno = errno;
+-    
+-      yy_flush_buffer(b );
+-
+-      b->yy_input_file = file;
+-      b->yy_fill_buffer = 1;
+-
+-    /* If b is the current buffer, then yy_init_buffer was _probably_
+-     * called from yyrestart() or through yy_get_next_buffer.
+-     * In that case, we don't want to reset the lineno or column.
+-     */
+-    if (b != YY_CURRENT_BUFFER){
+-        b->yy_bs_lineno = 1;
+-        b->yy_bs_column = 0;
+-    }
+-
+-        b->yy_is_interactive = 0;
+-    
+-      errno = oerrno;
+-}
+-
+-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+- * 
+- */
+-    void yy_flush_buffer (YY_BUFFER_STATE  b )
+-{
+-      if ( ! b )
+-              return;
+-
+-      b->yy_n_chars = 0;
+-
+-      /* We always need two end-of-buffer characters.  The first causes
+-       * a transition to the end-of-buffer state.  The second causes
+-       * a jam in that state.
+-       */
+-      b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+-      b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+-
+-      b->yy_buf_pos = &b->yy_ch_buf[0];
+-
+-      b->yy_at_bol = 1;
+-      b->yy_buffer_status = YY_BUFFER_NEW;
+-
+-      if ( b == YY_CURRENT_BUFFER )
+-              yy_load_buffer_state( );
+-}
+-
+-/** Pushes the new state onto the stack. The new state becomes
+- *  the current state. This function will allocate the stack
+- *  if necessary.
+- *  @param new_buffer The new state.
+- *  
+- */
+-void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+-{
+-      if (new_buffer == NULL)
+-              return;
+-
+-      yyensure_buffer_stack();
+-
+-      /* This block is copied from yy_switch_to_buffer. */
+-      if ( YY_CURRENT_BUFFER )
+-              {
+-              /* Flush out information for old buffer. */
+-              *(yy_c_buf_p) = (yy_hold_char);
+-              YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+-              YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+-              }
+-
+-      /* Only push if top exists. Otherwise, replace top. */
+-      if (YY_CURRENT_BUFFER)
+-              (yy_buffer_stack_top)++;
+-      YY_CURRENT_BUFFER_LVALUE = new_buffer;
+-
+-      /* copied from yy_switch_to_buffer. */
+-      yy_load_buffer_state( );
+-      (yy_did_buffer_switch_on_eof) = 1;
+-}
+-
+-/** Removes and deletes the top of the stack, if present.
+- *  The next element becomes the new top.
+- *  
+- */
+-void yypop_buffer_state (void)
+-{
+-      if (!YY_CURRENT_BUFFER)
+-              return;
+-
+-      yy_delete_buffer(YY_CURRENT_BUFFER );
+-      YY_CURRENT_BUFFER_LVALUE = NULL;
+-      if ((yy_buffer_stack_top) > 0)
+-              --(yy_buffer_stack_top);
+-
+-      if (YY_CURRENT_BUFFER) {
+-              yy_load_buffer_state( );
+-              (yy_did_buffer_switch_on_eof) = 1;
+-      }
+-}
+-
+-/* Allocates the stack if it does not exist.
+- *  Guarantees space for at least one push.
+- */
+-static void yyensure_buffer_stack (void)
+-{
+-      int num_to_alloc;
+-    
+-      if (!(yy_buffer_stack)) {
+-
+-              /* First allocation is just for 2 elements, since we don't know if this
+-               * scanner will even need a stack. We use 2 instead of 1 to avoid an
+-               * immediate realloc on the next call.
+-         */
+-              num_to_alloc = 1;
+-              (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+-                                                              (num_to_alloc * sizeof(struct yy_buffer_state*)
+-                                                              );
+-              if ( ! (yy_buffer_stack) )
+-                      YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+-                                                                
+-              memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+-                              
+-              (yy_buffer_stack_max) = num_to_alloc;
+-              (yy_buffer_stack_top) = 0;
+-              return;
+-      }
+-
+-      if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+-
+-              /* Increase the buffer to prepare for a possible push. */
+-              int grow_size = 8 /* arbitrary grow size */;
+-
+-              num_to_alloc = (yy_buffer_stack_max) + grow_size;
+-              (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+-                                                              ((yy_buffer_stack),
+-                                                              num_to_alloc * sizeof(struct yy_buffer_state*)
+-                                                              );
+-              if ( ! (yy_buffer_stack) )
+-                      YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+-
+-              /* zero only the new slots.*/
+-              memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+-              (yy_buffer_stack_max) = num_to_alloc;
+-      }
+-}
+-
+-/** Setup the input buffer state to scan directly from a user-specified character buffer.
+- * @param base the character buffer
+- * @param size the size in bytes of the character buffer
+- * 
+- * @return the newly allocated buffer state object. 
+- */
+-YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
+-{
+-      YY_BUFFER_STATE b;
+-    
+-      if ( size < 2 ||
+-           base[size-2] != YY_END_OF_BUFFER_CHAR ||
+-           base[size-1] != YY_END_OF_BUFFER_CHAR )
+-              /* They forgot to leave room for the EOB's. */
+-              return 0;
+-
+-      b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+-      if ( ! b )
+-              YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+-
+-      b->yy_buf_size = size - 2;      /* "- 2" to take care of EOB's */
+-      b->yy_buf_pos = b->yy_ch_buf = base;
+-      b->yy_is_our_buffer = 0;
+-      b->yy_input_file = 0;
+-      b->yy_n_chars = b->yy_buf_size;
+-      b->yy_is_interactive = 0;
+-      b->yy_at_bol = 1;
+-      b->yy_fill_buffer = 0;
+-      b->yy_buffer_status = YY_BUFFER_NEW;
+-
+-      yy_switch_to_buffer(b  );
+-
+-      return b;
+-}
+-
+-/** Setup the input buffer state to scan a string. The next call to yylex() will
+- * scan from a @e copy of @a str.
+- * @param yystr a NUL-terminated string to scan
+- * 
+- * @return the newly allocated buffer state object.
+- * @note If you want to scan bytes that may contain NUL values, then use
+- *       yy_scan_bytes() instead.
+- */
+-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+-{
+-    
+-      return yy_scan_bytes(yystr,strlen(yystr) );
+-}
+-
+-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+- * scan from a @e copy of @a bytes.
+- * @param bytes the byte buffer to scan
+- * @param len the number of bytes in the buffer pointed to by @a bytes.
+- * 
+- * @return the newly allocated buffer state object.
+- */
+-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+-{
+-      YY_BUFFER_STATE b;
+-      char *buf;
+-      yy_size_t n;
+-      int i;
+-    
+-      /* Get memory for full buffer, including space for trailing EOB's. */
+-      n = _yybytes_len + 2;
+-      buf = (char *) yyalloc(n  );
+-      if ( ! buf )
+-              YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+-
+-      for ( i = 0; i < _yybytes_len; ++i )
+-              buf[i] = yybytes[i];
+-
+-      buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+-
+-      b = yy_scan_buffer(buf,n );
+-      if ( ! b )
+-              YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+-
+-      /* It's okay to grow etc. this buffer, and we should throw it
+-       * away when we're done.
+-       */
+-      b->yy_is_our_buffer = 1;
+-
+-      return b;
+-}
+-
+-#ifndef YY_EXIT_FAILURE
+-#define YY_EXIT_FAILURE 2
+-#endif
+-
+-static void yy_fatal_error (yyconst char* msg )
+-{
+-      (void) fprintf( stderr, "%s\n", msg );
+-      exit( YY_EXIT_FAILURE );
+-}
+-
+-/* Redefine yyless() so it works in section 3 code. */
+-
+-#undef yyless
+-#define yyless(n) \
+-      do \
+-              { \
+-              /* Undo effects of setting up yytext. */ \
+-        int yyless_macro_arg = (n); \
+-        YY_LESS_LINENO(yyless_macro_arg);\
+-              yytext[yyleng] = (yy_hold_char); \
+-              (yy_c_buf_p) = yytext + yyless_macro_arg; \
+-              (yy_hold_char) = *(yy_c_buf_p); \
+-              *(yy_c_buf_p) = '\0'; \
+-              yyleng = yyless_macro_arg; \
+-              } \
+-      while ( 0 )
+-
+-/* Accessor  methods (get/set functions) to struct members. */
+-
+-/** Get the current line number.
+- * 
+- */
+-int yyget_lineno  (void)
+-{
+-        
+-    return yylineno;
+-}
+-
+-/** Get the input stream.
+- * 
+- */
+-FILE *yyget_in  (void)
+-{
+-        return yyin;
+-}
+-
+-/** Get the output stream.
+- * 
+- */
+-FILE *yyget_out  (void)
+-{
+-        return yyout;
+-}
+-
+-/** Get the length of the current token.
+- * 
+- */
+-int yyget_leng  (void)
+-{
+-        return yyleng;
+-}
+-
+-/** Get the current token.
+- * 
+- */
+-
+-char *yyget_text  (void)
+-{
+-        return yytext;
+-}
+-
+-/** Set the current line number.
+- * @param line_number
+- * 
+- */
+-void yyset_lineno (int  line_number )
+-{
+-    
+-    yylineno = line_number;
+-}
+-
+-/** Set the input stream. This does not discard the current
+- * input buffer.
+- * @param in_str A readable stream.
+- * 
+- * @see yy_switch_to_buffer
+- */
+-void yyset_in (FILE *  in_str )
+-{
+-        yyin = in_str ;
+-}
+-
+-void yyset_out (FILE *  out_str )
+-{
+-        yyout = out_str ;
+-}
+-
+-int yyget_debug  (void)
+-{
+-        return yy_flex_debug;
+-}
+-
+-void yyset_debug (int  bdebug )
+-{
+-        yy_flex_debug = bdebug ;
+-}
+-
+-static int yy_init_globals (void)
+-{
+-        /* Initialization is the same as for the non-reentrant scanner.
+-     * This function is called from yylex_destroy(), so don't allocate here.
+-     */
+-
+-    (yy_buffer_stack) = 0;
+-    (yy_buffer_stack_top) = 0;
+-    (yy_buffer_stack_max) = 0;
+-    (yy_c_buf_p) = (char *) 0;
+-    (yy_init) = 0;
+-    (yy_start) = 0;
+-
+-/* Defined in main.c */
+-#ifdef YY_STDINIT
+-    yyin = stdin;
+-    yyout = stdout;
+-#else
+-    yyin = (FILE *) 0;
+-    yyout = (FILE *) 0;
+-#endif
+-
+-    /* For future reference: Set errno on error, since we are called by
+-     * yylex_init()
+-     */
+-    return 0;
+-}
+-
+-/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+-int yylex_destroy  (void)
+-{
+-    
+-    /* Pop the buffer stack, destroying each element. */
+-      while(YY_CURRENT_BUFFER){
+-              yy_delete_buffer(YY_CURRENT_BUFFER  );
+-              YY_CURRENT_BUFFER_LVALUE = NULL;
+-              yypop_buffer_state();
+-      }
+-
+-      /* Destroy the stack itself. */
+-      yyfree((yy_buffer_stack) );
+-      (yy_buffer_stack) = NULL;
+-
+-    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+-     * yylex() is called, initialization will occur. */
+-    yy_init_globals( );
+-
+-    return 0;
+-}
+-
+-/*
+- * Internal utility routines.
+- */
+-
+-#ifndef yytext_ptr
+-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+-{
+-      register int i;
+-      for ( i = 0; i < n; ++i )
+-              s1[i] = s2[i];
+-}
+-#endif
+-
+-#ifdef YY_NEED_STRLEN
+-static int yy_flex_strlen (yyconst char * s )
+-{
+-      register int n;
+-      for ( n = 0; s[n]; ++n )
+-              ;
+-
+-      return n;
+-}
+-#endif
+-
+-void *yyalloc (yy_size_t  size )
+-{
+-      return (void *) malloc( size );
+-}
+-
+-void *yyrealloc  (void * ptr, yy_size_t  size )
+-{
+-      /* The cast to (char *) in the following accommodates both
+-       * implementations that use char* generic pointers, and those
+-       * that use void* generic pointers.  It works with the latter
+-       * because both ANSI C and C++ allow castless assignment from
+-       * any pointer type to void*, and deal with argument conversions
+-       * as though doing an assignment.
+-       */
+-      return (void *) realloc( (char *) ptr, size );
+-}
+-
+-void yyfree (void * ptr )
+-{
+-      free( (char *) ptr );   /* see yyrealloc() for (char *) cast */
+-}
+-
+-#define YYTABLES_NAME "yytables"
+-
+-#line 194 "/abuild/rguenther/tmp/gcc-4.3.3/gcc-4.3.3/gcc/gengtype-lex.l"
+-
+-
+-
+-void
+-yybegin (const char *fname)
+-{
+-  yyin = fopen (fname, "r");
+-  if (yyin == NULL)
+-    {
+-      perror (fname);
+-      exit (1);
+-    }
+-  lexer_line.file = fname;
+-  lexer_line.line = 1;
+-}
+-
+-void
+-yyend (void)
+-{
+-  fclose (yyin);
+-}
+-
+--- a/gcc/genmultilib
++++ b/gcc/genmultilib
+@@ -73,6 +73,20 @@
+ # the os directory names are used exclusively.  Use the mapping when
+ # there is no one-to-one equivalence between GCC levels and the OS.
++# The optional eighth option is a list of multilib aliases.  This takes the
++# same form as the third argument.  It specifies that the second multilib is
++# a synonym for the first.  This allows a suitable multilib to be selected
++# for all option combinations while only building a subset of all possible
++# multilibs.
++# For example:
++#   genmultilib "mbig-endian mthumb" "eb thumb" "" "" "" "" "" \
++#             "mbig-endian=mbig-endian/mthumb" yes
++# This produces:
++#   ". !mbig-endian !mthumb;",
++#   "be mbig-endian !mthumb;",
++#   "be mbig-endian mthumb;",
++#   "thumb !mbig-endian mthumb;",
++
+ # The last option should be "yes" if multilibs are enabled.  If it is not
+ # "yes", all GCC multilib dir names will be ".".
+@@ -121,7 +135,8 @@ exceptions=$4
+ extra=$5
+ exclusions=$6
+ osdirnames=$7
+-enable_multilib=$8
++aliases=$8
++enable_multilib=$9
+ echo "static const char *const multilib_raw[] = {"
+@@ -129,6 +144,23 @@ mkdir tmpmultilib.$$ || exit 1
+ # Use cd ./foo to avoid CDPATH output.
+ cd ./tmpmultilib.$$ || exit 1
++# Handle aliases
++cat >tmpmultilib3 <<\EOF
++#!/bin/sh
++# Output a list of aliases (including the original name) for a multilib.
++
++echo $1
++EOF
++for a in ${aliases}; do
++  l=`echo $a | sed -e 's/=.*$//' -e 's/?/=/g'`
++  r=`echo $a | sed -e 's/^.*=//' -e 's/?/=/g'`
++  echo "[ \$1 == /$l/ ] && echo /$r/" >>tmpmultilib3
++  
++  # Also add the alias to the exclusion list
++  exceptions="${exceptions} $r"
++done
++chmod +x tmpmultilib3
++
+ # What we want to do is select all combinations of the sets in
+ # options.  Each combination which includes a set of mutually
+ # exclusive options must then be output multiple times, once for each
+@@ -195,6 +227,21 @@ EOF
+   combinations=`./tmpmultilib2 ${combinations}`
+ fi
++# Check that all the aliases actually exist
++for a in ${aliases}; do
++  l=`echo $a | sed -e 's/=.*$//' -e 's/?/=/g'`
++  for c in ${combinations}; do
++    if [ "/$l/" = "$c" ]; then
++      l=""
++      break;
++    fi
++  done
++  if [ -n "$l" ] ;then
++    echo "Missing multilib $l for alias $a" 1>&2
++    exit 1
++  fi
++done
++
+ # Construct a sed pattern which will convert option names to directory
+ # names.
+ todirnames=
+@@ -343,23 +390,25 @@ for combo in ${combinations}; do
+     fi
+   fi
+-  # Look through the options.  We must output each option that is
+-  # present, and negate each option that is not present.
+-  optout=
+-  for set in ${options}; do
+-    setopts=`echo ${set} | sed -e 's_[/|]_ _g'`
+-    for opt in ${setopts}; do
+-      if expr "${combo} " : ".*/${opt}/.*" > /dev/null; then
+-      optout="${optout} ${opt}"
+-      else
+-      optout="${optout} !${opt}"
+-      fi
++  for optcombo in `./tmpmultilib3 ${combo}`; do
++    # Look through the options.  We must output each option that is
++    # present, and negate each option that is not present.
++    optout=
++    for set in ${options}; do
++      setopts=`echo ${set} | sed -e 's_[/|]_ _g'`
++      for opt in ${setopts}; do
++      if expr "${optcombo} " : ".*/${opt}/.*" > /dev/null; then
++        optout="${optout} ${opt}"
++      else
++        optout="${optout} !${opt}"
++      fi
++      done
+     done
+-  done
+-  optout=`echo ${optout} | sed -e 's/^ //'`
++    optout=`echo ${optout} | sed -e 's/^ //'`
+-  # Output the line with all appropriate matches.
+-  dirout="${dirout}" optout="${optout}" ./tmpmultilib2
++    # Output the line with all appropriate matches.
++    dirout="${dirout}" optout="${optout}" ./tmpmultilib2
++  done
+ done
+ # Terminate the list of string.
+--- a/gcc/haifa-sched.c
++++ b/gcc/haifa-sched.c
+@@ -1846,6 +1846,23 @@ move_insn (rtx insn)
+   SCHED_GROUP_P (insn) = 0;  
+ }
++/* Return true if scheduling INSN will finish current clock cycle.  */
++static bool
++insn_finishes_cycle_p (rtx insn)
++{
++  if (SCHED_GROUP_P (insn))
++    /* After issuing INSN, rest of the sched_group will be forced to issue
++       in order.  Don't make any plans for the rest of cycle.  */
++    return true;
++
++  /* Finishing the block will, apparently, finish the cycle.  */
++  if (current_sched_info->insn_finishes_block_p
++      && current_sched_info->insn_finishes_block_p (insn))
++    return true;
++
++  return false;
++}
++
+ /* The following structure describe an entry of the stack of choices.  */
+ struct choice_entry
+ {
+@@ -1902,13 +1919,15 @@ static int
+ max_issue (struct ready_list *ready, int *index, int max_points)
+ {
+   int n, i, all, n_ready, best, delay, tries_num, points = -1;
++  int rest;
+   struct choice_entry *top;
+   rtx insn;
+   best = 0;
+   memcpy (choice_stack->state, curr_state, dfa_state_size);
+   top = choice_stack;
+-  top->rest = cached_first_cycle_multipass_dfa_lookahead;
++  /* Add +1 to account the empty initial state.  */
++  top->rest = cached_first_cycle_multipass_dfa_lookahead + 1;
+   top->n = 0;
+   n_ready = ready->n_ready;
+   for (all = i = 0; i < n_ready; i++)
+@@ -1918,7 +1937,10 @@ max_issue (struct ready_list *ready, int
+   tries_num = 0;
+   for (;;)
+     {
+-      if (top->rest == 0 || i >= n_ready)
++      if (/* Enough instructions are issued (or we won't issue more).  */
++        top->rest == 0
++        /* Or there's nothing left to try.  */
++        || i >= n_ready)
+       {
+         if (top == choice_stack)
+           break;
+@@ -1942,17 +1964,27 @@ max_issue (struct ready_list *ready, int
+           break;
+         insn = ready_element (ready, i);
+         delay = state_transition (curr_state, insn);
++
+         if (delay < 0)
+           {
+-            if (state_dead_lock_p (curr_state))
+-              top->rest = 0;
++            rest = top->rest;
++            if (state_dead_lock_p (curr_state)
++                || insn_finishes_cycle_p (insn))
++              /* We won't issue any more instructions in the next
++                 choice_state.  */
++              rest = 0;
+             else
+-              top->rest--;
++              rest--;
++
+             n = top->n;
+             if (memcmp (top->state, curr_state, dfa_state_size) != 0)
+               n += ISSUE_POINTS (insn);
++
++            /* Go to next choice_state.  */
+             top++;
+-            top->rest = cached_first_cycle_multipass_dfa_lookahead;
++
++            /* Initialize it.  */
++            top->rest = rest;
+             top->index = i;
+             top->n = n;
+             memcpy (top->state, curr_state, dfa_state_size);
+--- a/gcc/hooks.c
++++ b/gcc/hooks.c
+@@ -34,6 +34,12 @@ hook_void_void (void)
+ {
+ }
++/* Generic hook that receives an int * and does nothing.  */
++void
++hook_intp_void (int *p ATTRIBUTE_UNUSED)
++{
++}
++
+ /* Generic hook that takes no arguments and returns false.  */
+ bool
+ hook_bool_void_false (void)
+@@ -319,3 +325,10 @@ hook_constcharptr_int_const_tree_const_t
+ {
+   return NULL;
+ }
++
++/* Generic hook that takes a const_tree and returns NULL_TREE.  */
++tree
++hook_tree_const_tree_null (const_tree t ATTRIBUTE_UNUSED)
++{
++  return NULL;
++}
+--- a/gcc/hooks.h
++++ b/gcc/hooks.h
+@@ -51,6 +51,7 @@ extern bool hook_bool_tree_tree_false (t
+ extern bool hook_bool_tree_bool_false (tree, bool);
+ extern void hook_void_void (void);
++extern void hook_intp_void (int *);
+ extern void hook_void_constcharptr (const char *);
+ extern void hook_void_FILEptr_constcharptr (FILE *, const char *);
+ extern void hook_void_tree (tree);
+@@ -62,6 +63,8 @@ extern int hook_int_rtx_0 (rtx);
+ extern int hook_int_size_t_constcharptr_int_0 (size_t, const char *, int);
+ extern int hook_int_void_no_regs (void);
++extern tree hook_tree_const_tree_null (const_tree);
++
+ extern tree hook_tree_tree_tree_null (tree, tree);
+ extern tree hook_tree_tree_tree_tree_3rd_identity (tree, tree, tree);
+ extern tree hook_tree_tree_tree_bool_null (tree, tree, bool);
+--- a/gcc/integrate.c
++++ b/gcc/integrate.c
+@@ -81,8 +81,9 @@ function_attribute_inlinable_p (const_tr
+         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);
++          if (is_attribute_p (targetm.attribute_table[i].name, name)
++              && !targetm.function_attribute_inlinable_p (fndecl))
++            return false;
+       }
+     }
+--- a/gcc/java/Make-lang.in
++++ b/gcc/java/Make-lang.in
+@@ -303,11 +303,13 @@ java/jcf-io.o: java/jcf-io.c $(CONFIG_H)
+       $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(ZLIBINC) \
+               $(srcdir)/java/jcf-io.c $(OUTPUT_OPTION)
++# This must match the setting in libjava/Makefile.am.
++jardir = $(prefix)/$(target_noncanonical)/share/java
+ # jcf-path.o needs a -D.
+ java/jcf-path.o: java/jcf-path.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+   java/jcf.h
+       $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+-        -DLIBGCJ_ZIP_FILE='"$(datadir)/java/libgcj-$(version).jar"' \
++        -DLIBGCJ_ZIP_FILE='"$(jardir)/libgcj-$(version).jar"' \
+         -DDEFAULT_TARGET_VERSION=\"$(version)\" \
+         $(srcdir)/java/jcf-path.c $(OUTPUT_OPTION)
+--- a/gcc/jump.c
++++ b/gcc/jump.c
+@@ -1551,12 +1551,22 @@ rtx_renumbered_equal_p (const_rtx x, con
+         if (reg_renumber[reg_x] >= 0)
+           {
++            if (!subreg_offset_representable_p (reg_renumber[reg_x],
++                                                GET_MODE (SUBREG_REG (x)),
++                                                byte_x,
++                                                GET_MODE (x)))
++              return 0;
+             reg_x = subreg_regno_offset (reg_renumber[reg_x],
+                                          GET_MODE (SUBREG_REG (x)),
+                                          byte_x,
+                                          GET_MODE (x));
+             byte_x = 0;
+           }
++        else if (!subreg_offset_representable_p (reg_x,
++                                                 GET_MODE (SUBREG_REG (x)),
++                                                 byte_x,
++                                                 GET_MODE (x)))
++          return 0;
+       }
+       else
+       {
+@@ -1572,12 +1582,22 @@ rtx_renumbered_equal_p (const_rtx x, con
+         if (reg_renumber[reg_y] >= 0)
+           {
++            if (!subreg_offset_representable_p (reg_renumber[reg_y],
++                                                GET_MODE (SUBREG_REG (y)),
++                                                byte_y,
++                                                GET_MODE (y)))
++              return 0;
+             reg_y = subreg_regno_offset (reg_renumber[reg_y],
+                                          GET_MODE (SUBREG_REG (y)),
+                                          byte_y,
+                                          GET_MODE (y));
+             byte_y = 0;
+           }
++        else if (!subreg_offset_representable_p (reg_y,
++                                                 GET_MODE (SUBREG_REG (y)),
++                                                 byte_y,
++                                                 GET_MODE (y)))
++          return 0;
+       }
+       else
+       {
+--- a/gcc/libgcc2.c
++++ b/gcc/libgcc2.c
+@@ -1830,6 +1830,7 @@ CTYPE
+ CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
+ {
+   MTYPE ac, bd, ad, bc, x, y;
++  CTYPE res;
+   ac = a * c;
+   bd = b * d;
+@@ -1886,7 +1887,9 @@ CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b,
+       }
+     }
+-  return x + I * y;
++  __real__ res = x;
++  __imag__ res = y;
++  return res;
+ }
+ #endif /* complex multiply */
+@@ -1897,6 +1900,7 @@ CTYPE
+ CONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
+ {
+   MTYPE denom, ratio, x, y;
++  CTYPE res;
+   /* ??? We can get better behavior from logarithmic scaling instead of
+      the division.  But that would mean starting to link libgcc against
+@@ -1942,7 +1946,9 @@ CONCAT3(__div,MODE,3) (MTYPE a, MTYPE b,
+       }
+     }
+-  return x + I * y;
++  __real__ res = x;
++  __imag__ res = y;
++  return res;
+ }
+ #endif /* complex divide */
+@@ -2137,7 +2143,8 @@ __do_global_dtors (void)
+       (*(p-1)) ();
+     }
+ #endif
+-#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
++#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION) \
++  && !defined (__MINGW32__)
+   {
+     static int completed = 0;
+     if (! completed)
+@@ -2156,14 +2163,14 @@ __do_global_dtors (void)
+ void
+ __do_global_ctors (void)
+ {
+-#ifdef EH_FRAME_SECTION_NAME
++  atexit (__do_global_dtors);
++#if defined (EH_FRAME_SECTION_NAME) && !defined (__MINGW32__)
+   {
+     static struct object object;
+     __register_frame_info (__EH_FRAME_BEGIN__, &object);
+   }
+ #endif
+   DO_GLOBAL_CTORS_BODY;
+-  atexit (__do_global_dtors);
+ }
+ #endif /* no HAS_INIT_SECTION */
+--- a/gcc/modulo-sched.c
++++ b/gcc/modulo-sched.c
+@@ -268,6 +268,7 @@ static struct sched_info sms_sched_info 
+   sms_print_insn,
+   NULL,
+   compute_jump_reg_dependencies,
++  NULL, /* insn_finishes_block_p */
+   NULL, NULL,
+   NULL, NULL,
+   0, 0, 0,
+--- a/gcc/optabs.c
++++ b/gcc/optabs.c
+@@ -2140,6 +2140,10 @@ expand_binop (enum machine_mode mode, op
+         && GET_MODE (op0) != mode)
+       op0 = convert_to_mode (mode, op0, unsignedp);
++      /* Force things into registers so subreg handling comes out right.  */
++      op0 = force_reg (mode, op0);
++      op1x = force_reg (op1_mode, op1x);
++
+       /* 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 (libfunc,
+@@ -3281,7 +3285,8 @@ expand_unop (enum machine_mode mode, opt
+       if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
+         || unoptab == popcount_optab || unoptab == parity_optab)
+       outmode
+-          = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node)));
++        = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
++                                        optab_libfunc (unoptab, mode)));
+       start_sequence ();
+@@ -4508,10 +4513,12 @@ prepare_float_lib_cmp (rtx *px, rtx *py,
+        mode != VOIDmode;
+        mode = GET_MODE_WIDER_MODE (mode))
+     {
+-      if ((libfunc = optab_libfunc (code_to_optab[comparison], mode)))
++      if (code_to_optab[comparison]
++        && (libfunc = optab_libfunc (code_to_optab[comparison], mode)))
+       break;
+-      if ((libfunc = optab_libfunc (code_to_optab[swapped] , mode)))
++      if (code_to_optab[swapped]
++        && (libfunc = optab_libfunc (code_to_optab[swapped], mode)))
+       {
+         rtx tmp;
+         tmp = x; x = y; y = tmp;
+@@ -4519,7 +4526,8 @@ prepare_float_lib_cmp (rtx *px, rtx *py,
+         break;
+       }
+-      if ((libfunc = optab_libfunc (code_to_optab[reversed], mode))
++      if (code_to_optab[reversed]
++        && (libfunc = optab_libfunc (code_to_optab[reversed], mode))
+         && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
+       {
+         comparison = reversed;
+--- a/gcc/opts.c
++++ b/gcc/opts.c
+@@ -1787,6 +1787,10 @@ common_handle_option (size_t scode, cons
+       /* These are no-ops, preserved for backward compatibility.  */
+       break;
++    case OPT_feglibc_:
++      /* This is a no-op at the moment.  */
++      break;
++
+     default:
+       /* If the flag was handled in a standard way, assume the lack of
+        processing here is intentional.  */
+--- a/gcc/passes.c
++++ b/gcc/passes.c
+@@ -522,6 +522,7 @@ init_optimization_passes (void)
+         NEXT_PASS (pass_cleanup_cfg);
+         NEXT_PASS (pass_rename_ssa_copies);
+         NEXT_PASS (pass_ccp);
++        NEXT_PASS (pass_promote_short_indices);
+         NEXT_PASS (pass_forwprop);
+         NEXT_PASS (pass_update_address_taken);
+         NEXT_PASS (pass_simple_dse);
+@@ -561,6 +562,7 @@ init_optimization_passes (void)
+        execute TODO_rebuild_alias at this point even if
+        pass_create_structure_vars was disabled.  */
+       NEXT_PASS (pass_build_alias);
++      NEXT_PASS (pass_remove_local_statics);
+       NEXT_PASS (pass_return_slot);
+       NEXT_PASS (pass_rename_ssa_copies);
+--- a/gcc/pointer-set.c
++++ b/gcc/pointer-set.c
+@@ -181,6 +181,23 @@ void pointer_set_traverse (const struct 
+       break;
+ }
++/* Return the number of elements in PSET.  */
++
++size_t
++pointer_set_n_elements (struct pointer_set_t *pset)
++{
++  return pset->n_elements;
++}
++
++/* Remove all entries from PSET.  */
++
++void
++pointer_set_clear (struct pointer_set_t *pset)
++{
++  pset->n_elements = 0;
++  memset (pset->slots, 0, sizeof (pset->slots[0]) * pset->n_slots);
++}
++
\f
+ /* A pointer map is represented the same way as a pointer_set, so
+    the hash code is based on the address of the key, rather than
+@@ -301,3 +318,20 @@ void pointer_map_traverse (const struct 
+     if (pmap->keys[i] && !fn (pmap->keys[i], &pmap->values[i], data))
+       break;
+ }
++
++/* Return the number of elements in PMAP.  */
++
++size_t
++pointer_map_n_elements (struct pointer_map_t *pmap)
++{
++  return pmap->n_elements;
++}
++
++/* Remove all entries from PMAP.  */
++
++void pointer_map_clear (struct pointer_map_t *pmap)
++{
++  pmap->n_elements = 0;
++  memset (pmap->keys, 0, sizeof (pmap->keys[0]) * pmap->n_slots);
++  memset (pmap->values, 0, sizeof (pmap->values[0]) * pmap->n_slots);
++}
+--- a/gcc/pointer-set.h
++++ b/gcc/pointer-set.h
+@@ -29,6 +29,8 @@ int pointer_set_insert (struct pointer_s
+ void pointer_set_traverse (const struct pointer_set_t *,
+                          bool (*) (const void *, void *),
+                          void *);
++size_t pointer_set_n_elements (struct pointer_set_t *);
++void pointer_set_clear (struct pointer_set_t *);
+ struct pointer_map_t;
+ struct pointer_map_t *pointer_map_create (void);
+@@ -38,5 +40,7 @@ void **pointer_map_contains (const struc
+ void **pointer_map_insert (struct pointer_map_t *pmap, const void *p);
+ void pointer_map_traverse (const struct pointer_map_t *,
+                          bool (*) (const void *, void **, void *), void *);
++size_t pointer_map_n_elements (struct pointer_map_t *);
++void pointer_map_clear (struct pointer_map_t *);
+ #endif  /* POINTER_SET_H  */
+--- a/gcc/postreload.c
++++ b/gcc/postreload.c
+@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  
+ #include "tree.h"
+ #include "timevar.h"
+ #include "tree-pass.h"
++#include "addresses.h"
+ #include "df.h"
+ #include "dbgcnt.h"
+@@ -705,17 +706,19 @@ reload_combine (void)
+   int last_label_ruid;
+   int min_labelno, n_labels;
+   HARD_REG_SET ever_live_at_start, *label_live;
++  enum reg_class index_regs;
+   /* If reg+reg can be used in offsetable memory addresses, the main chunk of
+      reload has already used it where appropriate, so there is no use in
+      trying to generate it now.  */
+-  if (double_reg_address_ok && INDEX_REG_CLASS != NO_REGS)
++  index_regs = index_reg_class (VOIDmode);
++  if (double_reg_address_ok && index_regs != NO_REGS)
+     return;
+   /* To avoid wasting too much time later searching for an index register,
+      determine the minimum and maximum index register numbers.  */
+   for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
+-    if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], r))
++    if (TEST_HARD_REG_BIT (reg_class_contents[index_regs], r))
+       {
+       if (first_index_reg == -1)
+         first_index_reg = r;
+@@ -823,8 +826,8 @@ reload_combine (void)
+            substitute uses of REG (typically in MEMs) with.
+            First check REG and BASE for being index registers;
+            we can use them even if they are not dead.  */
+-        if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], regno)
+-            || TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS],
++        if (TEST_HARD_REG_BIT (reg_class_contents[index_regs], regno)
++            || TEST_HARD_REG_BIT (reg_class_contents[index_regs],
+                                   REGNO (base)))
+           {
+             const_reg = reg;
+@@ -838,8 +841,7 @@ reload_combine (void)
+                two registers.  */
+             for (i = first_index_reg; i <= last_index_reg; i++)
+               {
+-                if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS],
+-                                       i)
++                if (TEST_HARD_REG_BIT (reg_class_contents[index_regs], i)
+                     && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES
+                     && reg_state[i].store_ruid <= reg_state[regno].use_ruid
+                     && hard_regno_nregs[i][GET_MODE (reg)] == 1)
+--- a/gcc/real.c
++++ b/gcc/real.c
+@@ -4379,6 +4379,165 @@ const struct real_format decimal_quad_fo
+     false
+   };
\f
++/* Encode half-precision floats.  This routine is used both for the IEEE
++   ARM alternative encodings.  */
++static void
++encode_ieee_half (const struct real_format *fmt, long *buf,
++                const REAL_VALUE_TYPE *r)
++{
++  unsigned long image, sig, exp;
++  unsigned long sign = r->sign;
++  bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
++
++  image = sign << 15;
++  sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 11)) & 0x3ff;
++
++  switch (r->cl)
++    {
++    case rvc_zero:
++      break;
++
++    case rvc_inf:
++      if (fmt->has_inf)
++      image |= 31 << 10;
++      else
++      image |= 0x7fff;
++      break;
++
++    case rvc_nan:
++      if (fmt->has_nans)
++      {
++        if (r->canonical)
++          sig = (fmt->canonical_nan_lsbs_set ? (1 << 9) - 1 : 0);
++        if (r->signalling == fmt->qnan_msb_set)
++          sig &= ~(1 << 9);
++        else
++          sig |= 1 << 9;
++        if (sig == 0)
++          sig = 1 << 8;
++
++        image |= 31 << 10;
++        image |= sig;
++      }
++      else
++      image |= 0x3ff;
++      break;
++
++    case rvc_normal:
++      /* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
++       whereas the intermediate representation is 0.F x 2**exp.
++       Which means we're off by one.  */
++      if (denormal)
++      exp = 0;
++      else
++      exp = REAL_EXP (r) + 15 - 1;
++      image |= exp << 10;
++      image |= sig;
++      break;
++
++    default:
++      gcc_unreachable ();
++    }
++
++  buf[0] = image;
++}
++
++/* Decode half-precision floats.  This routine is used both for the IEEE
++   ARM alternative encodings.  */
++static void
++decode_ieee_half (const struct real_format *fmt, REAL_VALUE_TYPE *r,
++                const long *buf)
++{
++  unsigned long image = buf[0] & 0xffff;
++  bool sign = (image >> 15) & 1;
++  int exp = (image >> 10) & 0x1f;
++
++  memset (r, 0, sizeof (*r));
++  image <<= HOST_BITS_PER_LONG - 11;
++  image &= ~SIG_MSB;
++
++  if (exp == 0)
++    {
++      if (image && fmt->has_denorm)
++      {
++        r->cl = rvc_normal;
++        r->sign = sign;
++        SET_REAL_EXP (r, -14);
++        r->sig[SIGSZ-1] = image << 1;
++        normalize (r);
++      }
++      else if (fmt->has_signed_zero)
++      r->sign = sign;
++    }
++  else if (exp == 31 && (fmt->has_nans || fmt->has_inf))
++    {
++      if (image)
++      {
++        r->cl = rvc_nan;
++        r->sign = sign;
++        r->signalling = (((image >> (HOST_BITS_PER_LONG - 2)) & 1)
++                         ^ fmt->qnan_msb_set);
++        r->sig[SIGSZ-1] = image;
++      }
++      else
++      {
++        r->cl = rvc_inf;
++        r->sign = sign;
++      }
++    }
++  else
++    {
++      r->cl = rvc_normal;
++      r->sign = sign;
++      SET_REAL_EXP (r, exp - 15 + 1);
++      r->sig[SIGSZ-1] = image | SIG_MSB;
++    }
++}
++
++/* Half-precision format, as specified in IEEE 754R.  */
++const struct real_format ieee_half_format =
++  {
++    encode_ieee_half,
++    decode_ieee_half,
++    2,
++    11,
++    11,
++    -13,
++    16,
++    15,
++    15,
++    false,
++    true,
++    true,
++    true,
++    true,
++    true,
++    false
++  };
++
++/* ARM's alternative half-precision format, similar to IEEE but with
++   no reserved exponent value for NaNs and infinities; rather, it just
++   extends the range of exponents by one.  */
++const struct real_format arm_half_format =
++  {
++    encode_ieee_half,
++    decode_ieee_half,
++    2,
++    11,
++    11,
++    -13,
++    17,
++    15,
++    15,
++    false,
++    false,
++    false,
++    true,
++    true,
++    false,
++    false
++  };
++\f
+ /* A synthetic "format" for internal arithmetic.  It's the size of the
+    internal significand minus the two bits needed for proper rounding.
+    The encode and decode routines exist only to satisfy our paranoia
+--- a/gcc/real.h
++++ b/gcc/real.h
+@@ -286,6 +286,8 @@ extern const struct real_format real_int
+ extern const struct real_format decimal_single_format;
+ extern const struct real_format decimal_double_format;
+ extern const struct real_format decimal_quad_format;
++extern const struct real_format ieee_half_format;
++extern const struct real_format arm_half_format;
+ /* ====================================================================== */
+--- a/gcc/recog.c
++++ b/gcc/recog.c
+@@ -587,6 +587,7 @@ validate_replace_rtx_1 (rtx *loc, rtx fr
+      simplifications, as it is not our job.  */
+   if (SWAPPABLE_OPERANDS_P (x)
++      && !reload_in_progress
+       && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
+     {
+       validate_unshare_change (object, loc,
+--- a/gcc/regclass.c
++++ b/gcc/regclass.c
+@@ -468,6 +468,24 @@ init_reg_sets_1 (void)
+     inv_reg_alloc_order[reg_alloc_order[i]] = i;
+ #endif
++#ifdef REG_ALLOC_ORDER
++  /* Allow the target to change the allocation order based on
++     supplied flags.  */
++  targetm.adjust_reg_alloc_order (reg_alloc_order);
++
++  /* Now the contents of reg_alloc_order are fixed, calculate the
++     inverse map.  */
++  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
++    inv_reg_alloc_order[reg_alloc_order[i]] = i;
++#endif
++
++  restore_register_info ();
++
++#ifdef REG_ALLOC_ORDER
++  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
++    inv_reg_alloc_order[reg_alloc_order[i]] = i;
++#endif
++
+   /* This macro allows the fixed or call-used registers
+      and the register classes to depend on target flags.  */
+@@ -995,10 +1013,10 @@ static void reg_scan_mark_refs (rtx, rtx
+ /* Wrapper around REGNO_OK_FOR_INDEX_P, to allow pseudo registers.  */
+ static inline bool
+-ok_for_index_p_nonstrict (rtx reg)
++ok_for_index_p_nonstrict (rtx reg, enum machine_mode mode)
+ {
+   unsigned regno = REGNO (reg);
+-  return regno >= FIRST_PSEUDO_REGISTER || REGNO_OK_FOR_INDEX_P (regno);
++  return regno >= FIRST_PSEUDO_REGISTER || ok_for_index_p_1 (regno, mode);
+ }
+ /* A version of regno_ok_for_base_p for use during regclass, when all pseudos
+@@ -2073,7 +2091,7 @@ record_address_regs (enum machine_mode m
+   enum reg_class class;
+   if (context == 1)
+-    class = INDEX_REG_CLASS;
++    class = index_reg_class (mode);
+   else
+     class = base_reg_class (mode, outer_code, index_code);
+@@ -2123,7 +2141,8 @@ record_address_regs (enum machine_mode m
+          as well as in the tests below, that all addresses are in
+          canonical form.  */
+-      else if (INDEX_REG_CLASS == base_reg_class (VOIDmode, PLUS, SCRATCH))
++      else if (index_reg_class (mode)
++               == base_reg_class (mode, PLUS, SCRATCH))
+         {
+           record_address_regs (mode, arg0, context, PLUS, code1, scale);
+           if (! CONSTANT_P (arg1))
+@@ -2149,7 +2168,7 @@ record_address_regs (enum machine_mode m
+       else if (code0 == REG && code1 == REG
+                && REGNO (arg0) < FIRST_PSEUDO_REGISTER
+                && (ok_for_base_p_nonstrict (arg0, mode, PLUS, REG)
+-                   || ok_for_index_p_nonstrict (arg0)))
++                   || ok_for_index_p_nonstrict (arg0, mode)))
+         record_address_regs (mode, arg1,
+                              ok_for_base_p_nonstrict (arg0, mode, PLUS, REG)
+                              ? 1 : 0,
+@@ -2157,7 +2176,7 @@ record_address_regs (enum machine_mode m
+       else if (code0 == REG && code1 == REG
+                && REGNO (arg1) < FIRST_PSEUDO_REGISTER
+                && (ok_for_base_p_nonstrict (arg1, mode, PLUS, REG)
+-                   || ok_for_index_p_nonstrict (arg1)))
++                   || ok_for_index_p_nonstrict (arg1, mode)))
+         record_address_regs (mode, arg0,
+                              ok_for_base_p_nonstrict (arg1, mode, PLUS, REG)
+                              ? 1 : 0,
+--- a/gcc/regrename.c
++++ b/gcc/regrename.c
+@@ -566,14 +566,14 @@ scan_rtx_address (rtx insn, rtx *loc, en
+           int index_op;
+           unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
+-          if (REGNO_OK_FOR_INDEX_P (regno1)
++          if (regno_ok_for_index_p (regno1, mode)
+               && regno_ok_for_base_p (regno0, mode, PLUS, REG))
+             index_op = 1;
+-          else if (REGNO_OK_FOR_INDEX_P (regno0)
++          else if (regno_ok_for_index_p (regno0, mode)
+                    && regno_ok_for_base_p (regno1, mode, PLUS, REG))
+             index_op = 0;
+           else if (regno_ok_for_base_p (regno0, mode, PLUS, REG)
+-                   || REGNO_OK_FOR_INDEX_P (regno1))
++                   || regno_ok_for_index_p (regno1, mode))
+             index_op = 1;
+           else if (regno_ok_for_base_p (regno1, mode, PLUS, REG))
+             index_op = 0;
+@@ -598,7 +598,7 @@ scan_rtx_address (rtx insn, rtx *loc, en
+         }
+       if (locI)
+-        scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode);
++        scan_rtx_address (insn, locI, index_reg_class (mode), action, mode);
+       if (locB)
+         scan_rtx_address (insn, locB, base_reg_class (mode, PLUS, index_code),
+                           action, mode);
+@@ -820,7 +820,7 @@ build_def_use (basic_block bb)
+                   OP_IN, 0);
+         for (i = 0; i < recog_data.n_dups; i++)
+-          *recog_data.dup_loc[i] = copy_rtx (old_dups[i]);
++          *recog_data.dup_loc[i] = old_dups[i];
+         for (i = 0; i < n_ops; i++)
+           *recog_data.operand_loc[i] = old_operands[i];
+         if (recog_data.n_dups)
+@@ -1486,14 +1486,14 @@ replace_oldest_value_addr (rtx *loc, enu
+           int index_op;
+           unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
+-          if (REGNO_OK_FOR_INDEX_P (regno1)
++          if (regno_ok_for_index_p (regno1, mode)
+               && regno_ok_for_base_p (regno0, mode, PLUS, REG))
+             index_op = 1;
+-          else if (REGNO_OK_FOR_INDEX_P (regno0)
++          else if (regno_ok_for_index_p (regno0, mode)
+                    && regno_ok_for_base_p (regno1, mode, PLUS, REG))
+             index_op = 0;
+           else if (regno_ok_for_base_p (regno0, mode, PLUS, REG)
+-                   || REGNO_OK_FOR_INDEX_P (regno1))
++                   || regno_ok_for_index_p (regno1, mode))
+             index_op = 1;
+           else if (regno_ok_for_base_p (regno1, mode, PLUS, REG))
+             index_op = 0;
+@@ -1518,8 +1518,8 @@ replace_oldest_value_addr (rtx *loc, enu
+         }
+       if (locI)
+-        changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS, mode,
+-                                              insn, vd);
++        changed |= replace_oldest_value_addr (locI, index_reg_class (mode),
++                                              mode, insn, vd);
+       if (locB)
+         changed |= replace_oldest_value_addr (locB,
+                                               base_reg_class (mode, PLUS,
+--- a/gcc/reload.c
++++ b/gcc/reload.c
+@@ -5034,7 +5034,7 @@ find_reloads_address (enum machine_mode 
+           loc = &XEXP (*loc, 0);
+       }
+-      if (double_reg_address_ok)
++      if (double_reg_address_ok && index_reg_class (mode) != NO_REGS)
+       {
+         /* Unshare the sum as well.  */
+         *loc = ad = copy_rtx (ad);
+@@ -5042,8 +5042,8 @@ find_reloads_address (enum machine_mode 
+         /* Reload the displacement into an index reg.
+            We assume the frame pointer or arg pointer is a base reg.  */
+         find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1),
+-                                   INDEX_REG_CLASS, GET_MODE (ad), opnum,
+-                                   type, ind_levels);
++                                   index_reg_class (mode), GET_MODE (ad),
++                                   opnum, type, ind_levels);
+         return 0;
+       }
+       else
+@@ -5436,13 +5436,13 @@ find_reloads_address_1 (enum machine_mod
+ #define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE, OUTER, INDEX)                \
+   ((CONTEXT) == 0                                                     \
+    ? regno_ok_for_base_p (REGNO, MODE, OUTER, INDEX)                  \
+-   : REGNO_OK_FOR_INDEX_P (REGNO))                                    
++   : regno_ok_for_index_p (REGNO, MODE))
+   enum reg_class context_reg_class;
+   RTX_CODE code = GET_CODE (x);
+   if (context == 1)
+-    context_reg_class = INDEX_REG_CLASS;
++    context_reg_class = index_reg_class (mode);
+   else
+     context_reg_class = base_reg_class (mode, outer_code, index_code);
+@@ -5534,17 +5534,17 @@ find_reloads_address_1 (enum machine_mod
+       else if (code0 == REG && code1 == REG)
+         {
+-          if (REGNO_OK_FOR_INDEX_P (REGNO (op1))
++          if (regno_ok_for_index_p (REGNO (op1), mode)
+               && regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG))
+             return 0;
+-          else if (REGNO_OK_FOR_INDEX_P (REGNO (op0))
++          else if (regno_ok_for_index_p (REGNO (op0), mode)
+                    && regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG))
+             return 0;
+           else if (regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG))
+             find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
+                                     &XEXP (x, 1), opnum, type, ind_levels,
+                                     insn);
+-          else if (REGNO_OK_FOR_INDEX_P (REGNO (op1)))
++          else if (regno_ok_for_index_p (REGNO (op1), mode))
+             find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG,
+                                     &XEXP (x, 0), opnum, type, ind_levels,
+                                     insn);
+@@ -5552,7 +5552,7 @@ find_reloads_address_1 (enum machine_mod
+             find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
+                                     &XEXP (x, 0), opnum, type, ind_levels,
+                                     insn);
+-          else if (REGNO_OK_FOR_INDEX_P (REGNO (op0)))
++          else if (regno_ok_for_index_p (REGNO (op0), mode))
+             find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG,
+                                     &XEXP (x, 1), opnum, type, ind_levels,
+                                     insn);
+@@ -5622,7 +5622,7 @@ find_reloads_address_1 (enum machine_mod
+          need to live longer than a TYPE reload normally would, so be
+          conservative and class it as RELOAD_OTHER.  */
+       if ((REG_P (XEXP (op1, 1))
+-           && !REGNO_OK_FOR_INDEX_P (REGNO (XEXP (op1, 1))))
++           && !regno_ok_for_index_p (REGNO (XEXP (op1, 1)), mode))
+           || GET_CODE (XEXP (op1, 1)) == PLUS)
+         find_reloads_address_1 (mode, XEXP (op1, 1), 1, code, SCRATCH,
+                                 &XEXP (op1, 1), opnum, RELOAD_OTHER,
+--- a/gcc/reload1.c
++++ b/gcc/reload1.c
+@@ -7677,6 +7677,9 @@ emit_reload_insns (struct insn_chain *ch
+           }
+       }
++      if (i < 0 && rld[r].in != NULL_RTX && rld[r].reg_rtx != NULL_RTX)
++       forget_old_reloads_1 (rld[r].reg_rtx, NULL_RTX, NULL);
++
+       /* The following if-statement was #if 0'd in 1.34 (or before...).
+        It's reenabled in 1.35 because supposedly nothing else
+        deals with this problem.  */
+--- a/gcc/rtl-factoring.c
++++ b/gcc/rtl-factoring.c
+@@ -444,15 +444,17 @@ collect_pattern_seqs (void)
+   htab_iterator hti0, hti1, hti2;
+   p_hash_bucket hash_bucket;
+   p_hash_elem e0, e1;
+-#ifdef STACK_REGS
++#if defined STACK_REGS || defined HAVE_cc0
+   basic_block bb;
+-  bitmap_head stack_reg_live;
++  bitmap_head dont_collect;
+   /* Extra initialization step to ensure that no stack registers (if present)
+-     are live across abnormal edges. Set a flag in STACK_REG_LIVE for an insn
+-     if a stack register is live after the insn.  */
+-  bitmap_initialize (&stack_reg_live, NULL);
++     or cc0 code (if present) are live across abnormal edges.
++     Set a flag in DONT_COLLECT for an insn if a stack register is live
++     after the insn or the insn is cc0 setter or user.  */
++  bitmap_initialize (&dont_collect, NULL);
++#ifdef STACK_REGS
+   FOR_EACH_BB (bb)
+   {
+     regset_head live;
+@@ -476,7 +478,7 @@ collect_pattern_seqs (void)
+             {
+               if (REGNO_REG_SET_P (&live, reg))
+                 {
+-                  bitmap_set_bit (&stack_reg_live, INSN_UID (insn));
++                  bitmap_set_bit (&dont_collect, INSN_UID (insn));
+                   break;
+                 }
+             }
+@@ -493,6 +495,28 @@ collect_pattern_seqs (void)
+   }
+ #endif
++#ifdef HAVE_cc0
++  /* Mark CC0 setters and users as ineligible for collection into sequences.
++     This is an over-conservative fix, since it is OK to include
++     a cc0_setter, but only if we also include the corresponding cc0_user,
++     and vice versa.  */
++  FOR_EACH_BB (bb)
++  {
++    rtx insn;
++    rtx next_tail;
++
++    next_tail = NEXT_INSN (BB_END (bb));
++
++    for (insn = BB_HEAD (bb); insn != next_tail; insn = NEXT_INSN (insn))
++      {
++      if (INSN_P (insn) && reg_mentioned_p (cc0_rtx, PATTERN (insn)))
++        bitmap_set_bit (&dont_collect, INSN_UID (insn));
++      }
++  }
++#endif
++
++#endif /* defined STACK_REGS || defined HAVE_cc0 */
++
+   /* Initialize PATTERN_SEQS to empty.  */
+   pattern_seqs = 0;
+@@ -505,15 +529,15 @@ collect_pattern_seqs (void)
+         FOR_EACH_HTAB_ELEMENT (hash_bucket->seq_candidates, e1, p_hash_elem,
+                                hti2)
+           if (e0 != e1
+-#ifdef STACK_REGS
+-              && !bitmap_bit_p (&stack_reg_live, INSN_UID (e0->insn))
+-              && !bitmap_bit_p (&stack_reg_live, INSN_UID (e1->insn))
++#if defined STACK_REGS || defined HAVE_cc0
++              && !bitmap_bit_p (&dont_collect, INSN_UID (e0->insn))
++              && !bitmap_bit_p (&dont_collect, INSN_UID (e1->insn))
+ #endif
+              )
+             match_seqs (e0, e1);
+-#ifdef STACK_REGS
++#if defined STACK_REGS || defined HAVE_cc0
+   /* Free unused data.  */
+-  bitmap_clear (&stack_reg_live);
++  bitmap_clear (&dont_collect);
+ #endif
+ }
+--- a/gcc/sched-ebb.c
++++ b/gcc/sched-ebb.c
+@@ -271,6 +271,7 @@ static struct sched_info ebb_sched_info 
+   ebb_print_insn,
+   contributes_to_priority,
+   compute_jump_reg_dependencies,
++  NULL, /* insn_finishes_block_p */
+   NULL, NULL,
+   NULL, NULL,
+--- a/gcc/sched-int.h
++++ b/gcc/sched-int.h
+@@ -376,6 +376,10 @@ struct sched_info
+      the jump in the regset.  */
+   void (*compute_jump_reg_dependencies) (rtx, regset, regset, regset);
++  /* Return true if scheduling insn (passed as the parameter) will trigger
++     finish of scheduling current block.  */
++  bool (*insn_finishes_block_p) (rtx);
++
+   /* The boundaries of the set of insns to be scheduled.  */
+   rtx prev_head, next_tail;
+--- a/gcc/sched-rgn.c
++++ b/gcc/sched-rgn.c
+@@ -2210,6 +2210,19 @@ compute_jump_reg_dependencies (rtx insn 
+      add_branch_dependences.  */
+ }
++/* Return true if scheduling INSN will trigger finish of scheduling
++   current block.  */
++static bool
++rgn_insn_finishes_block_p (rtx insn)
++{
++  if (INSN_BB (insn) == target_bb
++      && sched_target_n_insns + 1 == target_n_insns)
++    /* INSN is the last not-scheduled instruction in the current block.  */
++    return true;
++
++  return false;
++}
++
+ /* Used in schedule_insns to initialize current_sched_info for scheduling
+    regions (or single basic blocks).  */
+@@ -2223,6 +2236,7 @@ static struct sched_info region_sched_in
+   rgn_print_insn,
+   contributes_to_priority,
+   compute_jump_reg_dependencies,
++  rgn_insn_finishes_block_p,
+   NULL, NULL,
+   NULL, NULL,
+--- a/gcc/sdbout.c
++++ b/gcc/sdbout.c
+@@ -336,6 +336,7 @@ const struct gcc_debug_hooks sdb_debug_h
+   debug_nothing_int,                   /* handle_pch */
+   debug_nothing_rtx,                   /* var_location */
+   debug_nothing_void,                    /* switch_text_section */
++  debug_nothing_tree_tree,             /* set_name */
+   0                                      /* start_end_main_source_file */
+ };
+--- a/gcc/target-def.h
++++ b/gcc/target-def.h
+@@ -461,6 +461,7 @@
+ #define TARGET_CANNOT_MODIFY_JUMPS_P hook_bool_void_false
+ #define TARGET_BRANCH_TARGET_REGISTER_CLASS hook_int_void_no_regs
+ #define TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED hook_bool_bool_false
++#define TARGET_ADJUST_REG_ALLOC_ORDER hook_intp_void
+ #define TARGET_CANNOT_FORCE_CONST_MEM hook_bool_rtx_false
+ #define TARGET_CANNOT_COPY_INSN_P NULL
+ #define TARGET_COMMUTATIVE_P hook_bool_const_rtx_commutative_p
+@@ -512,6 +513,10 @@
+ #define TARGET_INVALID_CONVERSION hook_constcharptr_const_tree_const_tree_null
+ #define TARGET_INVALID_UNARY_OP hook_constcharptr_int_const_tree_null
+ #define TARGET_INVALID_BINARY_OP hook_constcharptr_int_const_tree_const_tree_null
++#define TARGET_INVALID_PARAMETER_TYPE hook_constcharptr_const_tree_null
++#define TARGET_INVALID_RETURN_TYPE hook_constcharptr_const_tree_null
++#define TARGET_PROMOTED_TYPE hook_tree_const_tree_null
++#define TARGET_CONVERT_TO_TYPE hook_tree_tree_tree_null
+ #define TARGET_FIXED_CONDITION_CODE_REGS hook_bool_uintp_uintp_false
+@@ -568,7 +573,9 @@
+ #define TARGET_ARG_PARTIAL_BYTES hook_int_CUMULATIVE_ARGS_mode_tree_bool_0
+ #define TARGET_FUNCTION_VALUE default_function_value
++#define TARGET_LIBCALL_VALUE default_libcall_value
+ #define TARGET_INTERNAL_ARG_POINTER default_internal_arg_pointer
++#define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS hook_bool_void_true
+ #define TARGET_CALLS {                                                \
+    TARGET_PROMOTE_FUNCTION_ARGS,                              \
+@@ -588,7 +595,9 @@
+    TARGET_ARG_PARTIAL_BYTES,                                  \
+    TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN,                    \
+    TARGET_FUNCTION_VALUE,                                     \
+-   TARGET_INTERNAL_ARG_POINTER                                        \
++   TARGET_LIBCALL_VALUE,                                      \
++   TARGET_INTERNAL_ARG_POINTER,                                       \
++   TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS                               \
+    }
+ #ifndef TARGET_UNWIND_TABLES_DEFAULT
+@@ -731,6 +740,7 @@
+   TARGET_CANNOT_MODIFY_JUMPS_P,                       \
+   TARGET_BRANCH_TARGET_REGISTER_CLASS,                \
+   TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED, \
++  TARGET_ADJUST_REG_ALLOC_ORDER,                \
+   TARGET_CANNOT_FORCE_CONST_MEM,              \
+   TARGET_CANNOT_COPY_INSN_P,                  \
+   TARGET_COMMUTATIVE_P,                               \
+@@ -782,6 +792,10 @@
+   TARGET_INVALID_CONVERSION,                  \
+   TARGET_INVALID_UNARY_OP,                    \
+   TARGET_INVALID_BINARY_OP,                   \
++  TARGET_INVALID_PARAMETER_TYPE,              \
++  TARGET_INVALID_RETURN_TYPE,                 \
++  TARGET_PROMOTED_TYPE,                               \
++  TARGET_CONVERT_TO_TYPE,                     \
+   TARGET_SECONDARY_RELOAD,                    \
+   TARGET_EXPAND_TO_RTL_HOOK,                  \
+   TARGET_INSTANTIATE_DECLS,                   \
+--- a/gcc/target.h
++++ b/gcc/target.h
+@@ -555,6 +555,11 @@ struct gcc_target
+      already been generated.  */
+   bool (* branch_target_register_callee_saved) (bool after_pe_gen);
++  /* Called only if REG_ALLOC_ORDER is defined.  Given an array that has
++     been initialized from REG_ALLOC_ORDER, make any target-specific
++     adjustments that cannot be expressed in the definition of that macro.  */
++  void (* adjust_reg_alloc_order) (int *);
++
+   /* True if the constant X cannot be placed in the constant pool.  */
+   bool (* cannot_force_const_mem) (rtx);
+@@ -830,9 +835,18 @@ struct gcc_target
+     rtx (*function_value) (const_tree ret_type, const_tree fn_decl_or_type,
+                          bool outgoing);
++    /* Return the rtx for the result of a libcall of mode MODE,
++       calling the function FN_NAME.  */
++    rtx (*libcall_value) (enum machine_mode, rtx);
++
+     /* Return an rtx for the argument pointer incoming to the
+        current function.  */
+     rtx (*internal_arg_pointer) (void);
++
++    /* Return true if all function parameters should be spilled to the
++       stack.  */
++    bool (*allocate_stack_slots_for_args) (void);
++    
+   } calls;
+   /* Return the diagnostic message string if conversion from FROMTYPE
+@@ -847,6 +861,24 @@ struct gcc_target
+      is not permitted on TYPE1 and TYPE2, NULL otherwise.  */
+   const char *(*invalid_binary_op) (int op, const_tree type1, const_tree type2);
++  /* Return the diagnostic message string if TYPE is not valid as a
++     function parameter type, NULL otherwise.  */
++  const char *(*invalid_parameter_type) (const_tree type);
++
++  /* Return the diagnostic message string if TYPE is not valid as a
++     function return type, NULL otherwise.  */
++  const char *(*invalid_return_type) (const_tree type);
++
++  /* If values of TYPE are promoted to some other type when used in
++     expressions (analogous to the integer promotions), return that type,
++     or NULL_TREE otherwise.  */
++  tree (*promoted_type) (const_tree type);
++
++  /* Convert EXPR to TYPE, if target-specific types with special conversion
++     rules are involved.  Return the converted expression, or NULL to apply
++     the standard conversion rules.  */
++  tree (*convert_to_type) (tree type, tree expr);
++
+   /* Return the class for a secondary reload, and fill in extra information.  */
+   enum reg_class (*secondary_reload) (bool, rtx, enum reg_class,
+                                     enum machine_mode,
+--- a/gcc/targhooks.c
++++ b/gcc/targhooks.c
+@@ -565,6 +565,12 @@ default_function_value (const_tree ret_t
+ }
+ rtx
++default_libcall_value (enum machine_mode mode, rtx fun ATTRIBUTE_UNUSED)
++{
++  return LIBCALL_VALUE (mode);
++}
++
++rtx
+ default_internal_arg_pointer (void)
+ {
+   /* If the reg that the virtual arg pointer will be translated into is
+--- a/gcc/targhooks.h
++++ b/gcc/targhooks.h
+@@ -87,6 +87,7 @@ extern const char *hook_invalid_arg_for_
+   (const_tree, const_tree, const_tree);
+ extern bool hook_bool_const_rtx_commutative_p (const_rtx, int);
+ extern rtx default_function_value (const_tree, const_tree, bool);
++extern rtx default_libcall_value (enum machine_mode, rtx);
+ extern rtx default_internal_arg_pointer (void);
+ extern enum reg_class default_secondary_reload (bool, rtx, enum reg_class,
+                                               enum machine_mode,
+--- a/gcc/timevar.def
++++ b/gcc/timevar.def
+@@ -129,6 +129,7 @@ DEFTIMEVAR (TV_TREE_LOOP_IVOPTS         , "
+ DEFTIMEVAR (TV_PREDCOM                     , "predictive commoning")
+ DEFTIMEVAR (TV_TREE_LOOP_INIT      , "tree loop init")
+ DEFTIMEVAR (TV_TREE_LOOP_FINI      , "tree loop fini")
++DEFTIMEVAR (TV_TREE_LOOP_PROMOTE     , "tree loop index promotion")
+ DEFTIMEVAR (TV_TREE_CH                     , "tree copy headers")
+ DEFTIMEVAR (TV_TREE_SSA_UNCPROP            , "tree SSA uncprop")
+ DEFTIMEVAR (TV_TREE_SSA_TO_NORMAL    , "tree SSA to normal")
+@@ -136,6 +137,7 @@ DEFTIMEVAR (TV_TREE_NRV                 , "tree NR
+ DEFTIMEVAR (TV_TREE_COPY_RENAME            , "tree rename SSA copies")
+ DEFTIMEVAR (TV_TREE_SSA_VERIFY       , "tree SSA verifier")
+ DEFTIMEVAR (TV_TREE_STMT_VERIFY      , "tree STMT verifier")
++DEFTIMEVAR (TV_TREE_RLS              , "tree local static removal")
+ DEFTIMEVAR (TV_CGRAPH_VERIFY         , "callgraph verifier")
+ DEFTIMEVAR (TV_DOM_FRONTIERS         , "dominance frontiers")
+ DEFTIMEVAR (TV_DOMINANCE             , "dominance computation")
+--- a/gcc/toplev.h
++++ b/gcc/toplev.h
+@@ -131,6 +131,7 @@ extern int flag_unroll_loops;
+ extern int flag_unroll_all_loops;
+ extern int flag_unswitch_loops;
+ extern int flag_cprop_registers;
++extern int flag_remove_local_statics;
+ extern int time_report;
+ /* Things to do with target switches.  */
+--- a/gcc/tree-pass.h
++++ b/gcc/tree-pass.h
+@@ -264,6 +264,7 @@ extern struct tree_opt_pass pass_iv_cano
+ extern struct tree_opt_pass pass_scev_cprop;
+ extern struct tree_opt_pass pass_empty_loop;
+ extern struct tree_opt_pass pass_record_bounds;
++extern struct tree_opt_pass pass_promote_short_indices;
+ extern struct tree_opt_pass pass_if_conversion;
+ extern struct tree_opt_pass pass_vectorize;
+ extern struct tree_opt_pass pass_complete_unroll;
+@@ -328,6 +329,7 @@ extern struct tree_opt_pass pass_reassoc
+ extern struct tree_opt_pass pass_rebuild_cgraph_edges;
+ extern struct tree_opt_pass pass_build_cgraph_edges;
+ extern struct tree_opt_pass pass_reset_cc_flags;
++extern struct tree_opt_pass pass_remove_local_statics;
+ /* IPA Passes */
+ extern struct tree_opt_pass pass_ipa_matrix_reorg;
+--- a/gcc/tree-predcom.c
++++ b/gcc/tree-predcom.c
+@@ -1294,6 +1294,7 @@ ref_at_iteration (struct loop *loop, tre
+ {
+   tree idx, *idx_p, type, val, op0 = NULL_TREE, ret;
+   affine_iv iv;
++  tree fs;
+   bool ok;
+   if (handled_component_p (ref))
+@@ -1341,7 +1342,10 @@ ref_at_iteration (struct loop *loop, tre
+   else
+     return NULL_TREE;
+-  ok = simple_iv (loop, first_stmt (loop->header), idx, &iv, true);
++  fs = first_stmt (loop->header);
++  if (!fs)
++    return NULL_TREE;
++  ok = simple_iv (loop, fs, idx, &iv, true);
+   if (!ok)
+     return NULL_TREE;
+   iv.base = expand_simple_operations (iv.base);
+--- a/gcc/tree-ssa-loop-ivopts.c
++++ b/gcc/tree-ssa-loop-ivopts.c
+@@ -1391,10 +1391,75 @@ idx_record_use (tree base, tree *idx,
+   return true;
+ }
+-/* Returns true if memory reference REF may be unaligned.  */
++/* If we can prove that TOP = cst * BOT for some constant cst,
++   store cst to MUL and return true.  Otherwise return false.
++   The returned value is always sign-extended, regardless of the
++   signedness of TOP and BOT.  */
+ static bool
+-may_be_unaligned_p (tree ref)
++constant_multiple_of (tree top, tree bot, double_int *mul)
++{
++  tree mby;
++  enum tree_code code;
++  double_int res, p0, p1;
++  unsigned precision = TYPE_PRECISION (TREE_TYPE (top));
++
++  STRIP_NOPS (top);
++  STRIP_NOPS (bot);
++
++  if (operand_equal_p (top, bot, 0))
++    {
++      *mul = double_int_one;
++      return true;
++    }
++
++  code = TREE_CODE (top);
++  switch (code)
++    {
++    case MULT_EXPR:
++      mby = TREE_OPERAND (top, 1);
++      if (TREE_CODE (mby) != INTEGER_CST)
++      return false;
++
++      if (!constant_multiple_of (TREE_OPERAND (top, 0), bot, &res))
++      return false;
++
++      *mul = double_int_sext (double_int_mul (res, tree_to_double_int (mby)),
++                            precision);
++      return true;
++
++    case PLUS_EXPR:
++    case MINUS_EXPR:
++      if (!constant_multiple_of (TREE_OPERAND (top, 0), bot, &p0)
++        || !constant_multiple_of (TREE_OPERAND (top, 1), bot, &p1))
++      return false;
++
++      if (code == MINUS_EXPR)
++      p1 = double_int_neg (p1);
++      *mul = double_int_sext (double_int_add (p0, p1), precision);
++      return true;
++
++    case INTEGER_CST:
++      if (TREE_CODE (bot) != INTEGER_CST)
++      return false;
++
++      p0 = double_int_sext (tree_to_double_int (top), precision);
++      p1 = double_int_sext (tree_to_double_int (bot), precision);
++      if (double_int_zero_p (p1))
++      return false;
++      *mul = double_int_sext (double_int_sdivmod (p0, p1, FLOOR_DIV_EXPR, &res),
++                            precision);
++      return double_int_zero_p (res);
++
++    default:
++      return false;
++    }
++}
++
++/* Returns true if memory reference REF with step STEP may be unaligned.  */
++
++static bool
++may_be_unaligned_p (tree ref, tree step)
+ {
+   tree base;
+   tree base_type;
+@@ -1418,11 +1483,20 @@ may_be_unaligned_p (tree ref)
+   base_type = TREE_TYPE (base);
+   base_align = TYPE_ALIGN (base_type);
+-  if (mode != BLKmode
+-      && (base_align < GET_MODE_ALIGNMENT (mode)
++  if (mode != BLKmode)
++    {
++      double_int mul;
++      tree al = build_int_cst (TREE_TYPE (step),
++                             GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT);
++
++      if (base_align < GET_MODE_ALIGNMENT (mode)
+         || bitpos % GET_MODE_ALIGNMENT (mode) != 0
+-        || bitpos % BITS_PER_UNIT != 0))
+-    return true;
++        || bitpos % BITS_PER_UNIT != 0)
++      return true;
++    
++      if (! constant_multiple_of (step, al, &mul))
++      return true;
++    }
+   return false;
+ }
+@@ -1549,7 +1623,7 @@ find_interesting_uses_address (struct iv
+       /* Moreover, on strict alignment platforms, check that it is
+        sufficiently aligned.  */
+-      if (STRICT_ALIGNMENT && may_be_unaligned_p (base))
++      if (STRICT_ALIGNMENT && may_be_unaligned_p (base, step))
+       goto fail;
+       base = build_fold_addr_expr (base);
+@@ -2585,71 +2659,6 @@ tree_int_cst_sign_bit (const_tree t)
+   return (w >> bitno) & 1;
+ }
+-/* If we can prove that TOP = cst * BOT for some constant cst,
+-   store cst to MUL and return true.  Otherwise return false.
+-   The returned value is always sign-extended, regardless of the
+-   signedness of TOP and BOT.  */
+-
+-static bool
+-constant_multiple_of (tree top, tree bot, double_int *mul)
+-{
+-  tree mby;
+-  enum tree_code code;
+-  double_int res, p0, p1;
+-  unsigned precision = TYPE_PRECISION (TREE_TYPE (top));
+-
+-  STRIP_NOPS (top);
+-  STRIP_NOPS (bot);
+-
+-  if (operand_equal_p (top, bot, 0))
+-    {
+-      *mul = double_int_one;
+-      return true;
+-    }
+-
+-  code = TREE_CODE (top);
+-  switch (code)
+-    {
+-    case MULT_EXPR:
+-      mby = TREE_OPERAND (top, 1);
+-      if (TREE_CODE (mby) != INTEGER_CST)
+-      return false;
+-
+-      if (!constant_multiple_of (TREE_OPERAND (top, 0), bot, &res))
+-      return false;
+-
+-      *mul = double_int_sext (double_int_mul (res, tree_to_double_int (mby)),
+-                            precision);
+-      return true;
+-
+-    case PLUS_EXPR:
+-    case MINUS_EXPR:
+-      if (!constant_multiple_of (TREE_OPERAND (top, 0), bot, &p0)
+-        || !constant_multiple_of (TREE_OPERAND (top, 1), bot, &p1))
+-      return false;
+-
+-      if (code == MINUS_EXPR)
+-      p1 = double_int_neg (p1);
+-      *mul = double_int_sext (double_int_add (p0, p1), precision);
+-      return true;
+-
+-    case INTEGER_CST:
+-      if (TREE_CODE (bot) != INTEGER_CST)
+-      return false;
+-
+-      p0 = double_int_sext (tree_to_double_int (top), precision);
+-      p1 = double_int_sext (tree_to_double_int (bot), precision);
+-      if (double_int_zero_p (p1))
+-      return false;
+-      *mul = double_int_sext (double_int_sdivmod (p0, p1, FLOOR_DIV_EXPR, &res),
+-                            precision);
+-      return double_int_zero_p (res);
+-
+-    default:
+-      return false;
+-    }
+-}
+-
+ /* If A is (TYPE) BA and B is (TYPE) BB, and the types of BA and BB have the
+    same precision that is at least as wide as the precision of TYPE, stores
+    BA to A and BB to B, and returns the type of BA.  Otherwise, returns the
+--- /dev/null
++++ b/gcc/tree-ssa-loop-promote.c
+@@ -0,0 +1,1555 @@
++/* Promotion of shorter-than-word-size loop indices.
++   Copyright (C) 2009 Free Software Foundation, Inc.
++   
++This file is part of GCC.
++   
++GCC is free software; you can redistribute it and/or modify it
++under the terms of the GNU General Public License as published by the
++Free Software Foundation; either version 3, or (at your option) any
++later version.
++   
++GCC is distributed in the hope that it will be useful, but WITHOUT
++ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++for more details.
++   
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++/* This pass finds loop indices that are declared as
++   shorter-than-word-size and replaces them with word-sized loop
++   indices.  (It assumes that word-sized quantities are the most
++   efficient type on which to do arithmetic.)  The loop optimization
++   machinery has a difficult time seeing through the casts required to
++   promote such indices to word-sized quantities for memory addressing
++   and/or preserving the semantics of the source language (such as C).
++   The transformation also helps eliminate unnecessary
++   {sign,zero}-extensions required for the same.
++
++   Although this is most naturally expressed as a loop optimization
++   pass, we choose to place this pass some ways before the loop
++   optimization passes proper, so that other scalar optimizations will
++   run on our "cleaned-up" code.  This decision has the negative of
++   requiring us to build and destroy all the loop optimization
++   infrastructure.
++
++   The algorithm is relatively simple.  For each single-exit loop, we
++   identify the loop index variable.  If the loop index variable is
++   shorter than the word size, then we have a candidate for promotion.
++   We determine whether the scalar evolution of the loop index fits a
++   particular pattern (incremented by 1, compared against a
++   similarly-typed loop bound, and only modified by a single increment
++   within the loop), as well as examining the uses of the loop index to
++   ensure we are able to safely promote those uses (e.g. the loop index
++   must not be stored to memory or passed to function calls).  If these
++   conditions are satisfied, we create an appropriate word-sized type
++   and replace all uses and defs of the loop index variable with the new
++   variable.  */
++
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++
++#include "toplev.h"
++#include "rtl.h"
++#include "tm_p.h"
++#include "hard-reg-set.h"
++#include "obstack.h"
++#include "basic-block.h"
++#include "pointer-set.h"
++#include "intl.h"
++
++#include "tree.h"
++#include "tree-gimple.h"
++#include "hashtab.h"
++#include "diagnostic.h"
++#include "tree-flow.h"
++#include "tree-dump.h"
++#include "cfgloop.h"
++#include "flags.h"
++#include "timevar.h"
++#include "tree-pass.h"
++#include "tree-chrec.h"
++#include "tree-scalar-evolution.h"
++#include "tree-inline.h"
++
++struct promote_info {
++  /* The loop being analyzed.  */
++  struct loop *loop;
++
++  /* The COND_EXPR controlling exit from the loop.  */
++  tree exit_expr;
++
++  /* The loop index variable's SSA_NAME that is defined in a phi node in
++     LOOP->HEADER.  Note that this SSA_NAME may be different than the
++     one appearing in EXIT_EXPR.  */
++  tree loop_index_name;
++
++  /* The bound of the loop.  */
++  tree loop_limit;
++
++  /* Whether we've warned about things with
++     warn_unsafe_loop_optimizations.  */
++  bool warned;
++
++  /* LOOP_INDEX_NAME's underlying VAR_DECL.  */
++  tree var_decl;
++
++  /* The types to which defs/uses of LOOP_INDEX_NAME are cast via
++     NOP_EXPRs.  */
++  VEC(tree, heap) *cast_types;
++
++  /* The number of times we have seen a cast to the corresponding type
++     (as determined by types_compatible_p) in CAST_TYPES.  */
++  VEC(int, heap) *cast_counts;
++
++  /* Whether LOOP_INDEX_NAME is suitable for promotion.  */
++  bool can_be_promoted_p;
++
++  /* If CAN_BE_PROMOTED_P, the promoted type.  */
++  tree promoted_type;
++
++  /* If CAN_BE_PROMOTED_P, the promoted VAR_DECL.  */
++  tree promoted_var;
++};
++
++/* A set of `struct promote_info'.  */
++
++static struct pointer_set_t *promotion_info;
++
++/* A set of all potentially promotable SSA_NAMEs, used for quick
++decision-making during analysis.  */
++
++static struct pointer_set_t *promotable_names;
++
++/* A map from SSA_NAMEs to the VAR_DECL to which they will be
++   promoted.  */
++
++static struct pointer_map_t *variable_map;
++
++/* A set of the stmts that we have already rebuilt with promoted variables.  */
++
++static struct pointer_set_t *promoted_stmts;
++
++\f
++/* Add CASTED to PI->CAST_TYPES if we haven't seen CASTED before.  */
++
++static void
++add_casted_type (struct promote_info *pi, tree casted)
++{
++  int i;
++  tree type;
++
++  /* For this information to be useful later, CASTED must be wider than
++     the type of the variable.  */
++  if (TYPE_PRECISION (casted) <= TYPE_PRECISION (TREE_TYPE (pi->var_decl)))
++    return;
++
++  for (i = 0; VEC_iterate (tree, pi->cast_types, i, type); i++)
++    if (types_compatible_p (casted, type))
++      {
++      int c = VEC_index(int, pi->cast_counts, i);
++      VEC_replace(int, pi->cast_counts, i, ++c);
++      return;
++      }
++
++  /* Haven't see the type before.  */
++  VEC_safe_push (tree, heap, pi->cast_types, casted);
++  VEC_safe_push (int, heap, pi->cast_counts, 1);
++}
++
++/* Return the most-casted-to type in PI->CAST_TYPES.  Return an
++   appropriately signed variant of size_type_node if the variable wasn't
++   cast in some fashion.  */
++
++static tree
++choose_profitable_promoted_type (struct promote_info *pi)
++{
++  int i;
++  int count;
++  tree type = NULL_TREE;
++  int maxuse = -1;
++
++  for (i = 0; VEC_iterate (int, pi->cast_counts, i, count); i++)
++    if (count > maxuse)
++      {
++      maxuse = count;
++      type = VEC_index (tree, pi->cast_types, i);
++      }
++
++  if (type == NULL_TREE)
++    {
++      if (dump_file)
++      {
++        fprintf (dump_file, "Warning, failed to find upcast type for ");
++        print_generic_expr (dump_file, pi->loop_index_name, 0);
++        fprintf (dump_file, "\n");
++      }
++      return (TYPE_UNSIGNED (TREE_TYPE (pi->var_decl))
++            ? size_type_node
++            : signed_type_for (size_type_node));
++    }
++  else
++    return signed_type_for (type);
++}
++
++/* Intuit the loop index for LOOP from PHI.  There must be a path that
++   only goes through NOP_EXPRs or CONVERT_EXPRs from the result of PHI
++   to one of the operands of COND.  If such a path cannot be found,
++   return NULL_TREE.  If LIMIT is not NULL and a path can be found,
++   store the other operand of COND into LIMIT.  */
++
++static tree
++find_promotion_candidate_from_phi (struct loop *loop, tree cond,
++                                 tree phi, tree *limit)
++{
++  tree op0, op1;
++  tree result, candidate;
++
++  result = candidate = PHI_RESULT (phi);
++  /* Must be an integer variable.  */
++  if (TREE_CODE (TREE_TYPE (candidate)) != INTEGER_TYPE)
++    return NULL_TREE;
++
++  op0 = TREE_OPERAND (cond, 0);
++  op1 = TREE_OPERAND (cond, 1);
++
++  /* See if there's a path from CANDIDATE to an operand of COND.  */
++  while (true)
++    {
++      use_operand_p use;
++      imm_use_iterator iui;
++      tree use_stmt = NULL_TREE;
++
++      if (candidate == op0)
++      {
++        if (limit) *limit = op1;
++        break;
++      }
++      if (candidate == op1)
++      {
++        if (limit) *limit = op0;
++        break;
++      }
++
++      /* Find a single use in the loop header.  Give up if there's
++       multiple ones.  */
++      FOR_EACH_IMM_USE_FAST (use, iui, candidate)
++      {
++        tree stmt = USE_STMT (use);
++
++        if (bb_for_stmt (stmt) == loop->header)
++          {
++            if (use_stmt)
++              {
++                if (dump_file)
++                  {
++                    fprintf (dump_file, "Rejecting ");
++                    print_generic_expr (dump_file, candidate, 0);
++                    fprintf (dump_file, " because it has multiple uses in the loop header (bb #%d).\n",
++                             loop->header->index);
++                    fprintf (dump_file, "first use: ");
++                    print_generic_expr (dump_file, use_stmt, 0);
++                    fprintf (dump_file, "\nsecond use: ");
++                    print_generic_expr (dump_file, stmt, 0);
++                    fprintf (dump_file, "\n(possibly more, but unanalyzed)\n");
++                  }
++                return NULL_TREE;
++              }
++            else
++              use_stmt = stmt;
++          }
++      }
++
++      /* No uses in the loop header, bail.  */
++      if (use_stmt == NULL_TREE)
++      return NULL_TREE;
++
++      if (TREE_CODE (use_stmt) != GIMPLE_MODIFY_STMT
++        || TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 0)) != SSA_NAME
++        || (TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) != NOP_EXPR
++            && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) != CONVERT_EXPR))
++      {
++        if (dump_file)
++          {
++            fprintf (dump_file, "Rejecting ");
++            print_generic_expr (dump_file, candidate, 0);
++            fprintf (dump_file, " because of use in ");
++            print_generic_expr (dump_file, use_stmt, 0);
++            fprintf (dump_file, "\n");
++          }
++        return NULL_TREE;
++      }
++
++      candidate = GIMPLE_STMT_OPERAND (use_stmt, 0);
++    }
++
++  /* CANDIDATE is now what we believe to be the loop index variable.  There
++     are two possibilities:
++
++     - CANDIDATE is not the "true" loop index variable, but rather is a
++       promoted version of RESULT, done for purposes of satisfying a
++       language's semantics;
++
++     - CANDIDATE is the "true" loop index variable.  */
++  if (!types_compatible_p (TREE_TYPE (result), TREE_TYPE (candidate)))
++    candidate = result;
++
++  /* The type of candidate must be "short" to consider promoting it.  */
++  if (TREE_CODE (TREE_TYPE (candidate)) != INTEGER_TYPE
++      || TYPE_PRECISION (TREE_TYPE (candidate)) >= TYPE_PRECISION (size_type_node))
++    return NULL_TREE;
++
++  return candidate;
++}
++
++/* Find the loop index variable of LOOP.  LOOP's exit is controlled by
++   the COND_EXPR EXPR.  IF we can't determine what the loop index
++   variable is, or EXPR does not appear to be analyzable, then return
++   NULL_TREE.  */
++
++static tree
++find_promotion_candidate (struct loop *loop, tree expr, tree *limit)
++{
++  tree cond = COND_EXPR_COND (expr);
++  tree phi;
++  tree candidate = NULL_TREE;
++
++  switch (TREE_CODE (cond))
++    {
++    case GT_EXPR:
++    case GE_EXPR:
++    case NE_EXPR:
++    case LT_EXPR:
++    case LE_EXPR:
++      break;
++
++    default:
++      return NULL_TREE;
++    }
++
++  /* We'd like to examine COND and intuit the loop index variable from
++     there.  Instead, we're going to start from the phi nodes in BB and
++     attempt to work our way forwards to one of the operands of COND,
++     since starting from COND might yield an upcast loop index.  If we
++     find multiple phi nodes whose results reach COND, then give up.  */
++  for (phi = phi_nodes (loop->header); phi != NULL_TREE; phi = PHI_CHAIN (phi))
++    {
++      tree t = find_promotion_candidate_from_phi (loop, cond, phi, limit);
++
++      if (t == NULL_TREE)
++      continue;
++      else if (candidate == NULL_TREE)
++      candidate = t;
++      else
++      {
++        if (dump_file)
++          {
++            fprintf (dump_file, "Can't find a candidate from ");
++            print_generic_expr (dump_file, expr, 0);
++            fprintf (dump_file, "\n  because too many phi node results reach the condition.\n");
++          }
++        return NULL_TREE;
++      }
++    }
++
++  return candidate;
++}
++
++/* Return true if X is something that could be promoted.  */
++
++static bool
++could_be_promoted (tree x)
++{
++  return (TREE_CODE (x) == INTEGER_CST
++        || (TREE_CODE (x) == SSA_NAME
++            && pointer_set_contains (promotable_names, x)));
++}
++
++/* Examine EXPR's suitability with respect to being able to promote VAR.
++   ASSIGNED_TO is true if EXPR is being assigned to VAR; otherwise, EXPR
++   contains a use of VAR.  */
++
++static bool
++check_expr_for_promotability (struct promote_info *pi, tree var,
++                            tree expr, bool assigning_to)
++{
++  tree type = TREE_TYPE (expr);
++  bool ok = true;
++
++  switch (TREE_CODE (expr))
++    {
++    case PLUS_EXPR:
++    case MINUS_EXPR:
++    case MULT_EXPR:
++    case EQ_EXPR:
++    case NE_EXPR:
++    case LT_EXPR:
++    case LE_EXPR:
++    case GT_EXPR:
++    case GE_EXPR:
++      {
++      tree op0 = TREE_OPERAND (expr, 0);
++      tree op1 = TREE_OPERAND (expr, 1);
++
++      ok = ((op0 == var && could_be_promoted (op1))
++            || (op1 == var && could_be_promoted (op0)));
++      break;
++      }
++    case COND_EXPR:
++      if (TREE_TYPE (expr) == NULL
++        || TREE_TYPE (expr) == void_type_node)
++      ok = true;
++      else
++      /* This is conservative; it's possible that these sorts of nodes
++         could be promoted, but we'd have to be very careful about
++         checking in which parts of the COND_EXPR the promotable
++         variable(s) are.  */
++      ok = false;
++      break;
++    case SSA_NAME:
++      ok = (expr == var || could_be_promoted (expr));
++      break;
++    case NOP_EXPR:
++    case CONVERT_EXPR:
++      if (!assigning_to)
++      {
++        add_casted_type (pi, type);
++        break;
++      }
++      /* Fallthrough.  */
++    default:
++      ok = false;
++    }
++
++  return ok;
++}
++
++/* Analyze the loop index VAR for promotability.  The rules for
++   promotability are:
++
++   For uses:
++
++   - The underlying variable may be used in NOP_EXPRs.
++
++   - The underlying variable may be used in simple arithmmetic
++     expressions so long as the other parts are potentially promotable
++     variables or constants (so we don't go willy-nilly on promoting
++     things).
++
++   - The underlying variable may not be stored to memory.
++
++   - All uses must occur inside the loop.
++
++   For defs:
++
++   - The underlying variable may not be loaded from memory; and
++
++   - The underlying variable may only be formed from expressions
++     involving potentially promotable varibles or constants.
++
++   Note that defs may occur outside of the loop; we do this to handle
++   initial conditions before entering the loop.  */
++
++static void
++analyze_loop_index_uses (tree var, struct promote_info *pi)
++{
++  imm_use_iterator iui;
++  use_operand_p use;
++  tree rhs;
++  tree bad_stmt = NULL_TREE;
++  const char *reason = NULL;
++
++  FOR_EACH_IMM_USE_FAST (use, iui, var)
++    {
++      basic_block bb;
++      tree use_stmt = USE_STMT (use);
++
++      /* Uses must exist only within the loop.  */
++      bb = bb_for_stmt (use_stmt);
++
++      if (dump_file)
++      {
++        fprintf (dump_file, "Checking ");
++        print_generic_expr (dump_file, use_stmt, 0);
++        fprintf (dump_file, "\n");
++      }
++
++      if (!flow_bb_inside_loop_p (pi->loop, bb))
++      {
++        bad_stmt = use_stmt;
++        reason = " is involved in stmt outside loop ";
++        break;
++      }
++
++      /* We cannot store the index to memory.  */
++      if (stmt_references_memory_p (use_stmt))
++      {
++        bad_stmt = use_stmt;
++        reason = " is stored to memory in ";
++        break;
++      }
++
++      /* We cannot pass the variable to a function.  */
++      if (get_call_expr_in (use_stmt))
++      {
++        bad_stmt = use_stmt;
++        reason = " is passed to function in ";
++        break;
++      }
++
++      if (TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT) 
++      {
++        tree lhs = GIMPLE_STMT_OPERAND (use_stmt, 0);
++        rhs = GIMPLE_STMT_OPERAND (use_stmt, 1);
++
++        if (!check_expr_for_promotability (pi, var, rhs,
++                                           /*is_assign=*/false))
++          {
++            bad_stmt = rhs;
++            reason = " is involved in non-promotable expression ";
++            break;
++          }
++        else if ((TREE_CODE_CLASS (TREE_CODE (rhs)) == tcc_binary
++                  || TREE_CODE (rhs) == SSA_NAME)
++                 && !check_expr_for_promotability (pi, var, lhs,
++                                                   /*is_assign=*/true))
++          {
++            bad_stmt = lhs;
++            reason = " is being assigned to non-promotable variable ";
++            break;
++          }
++      }
++      else if (TREE_CODE (use_stmt) != COND_EXPR
++             && TREE_CODE (use_stmt) != PHI_NODE)
++      {
++        /* Use of the variable in some statement we don't know how to
++           analyze.  */
++        bad_stmt = use_stmt;
++        reason = " is used in unanalyzable expression in ";
++        break;
++      }
++    }
++
++  if (bad_stmt && reason)
++    {
++      if (dump_file)
++      {
++        fprintf (dump_file, "Loop index ");
++        print_generic_expr (dump_file, var, 0);
++        fprintf (dump_file, "%s", reason);
++        print_generic_expr (dump_file, bad_stmt, 0);
++        fprintf (dump_file, "\n");
++      }
++      pi->can_be_promoted_p = false;
++    }
++}
++
++/* Check that the uses and def of VAR, defined in STMT, conform to the
++   rules given above.  */
++
++static bool
++analyze_loop_index (tree var, tree stmt, void *data)
++{
++  struct promote_info *pi = data;
++  tree t;
++
++  if (dump_file)
++    {
++      fprintf (dump_file, "Analyzing loop index ");
++      print_generic_expr (dump_file, var, 0);
++      fprintf (dump_file, " defined in ");
++      print_generic_expr (dump_file, stmt, 0);
++      fprintf (dump_file, "\n");
++    }
++
++  /* Check the definition.  */
++  switch (TREE_CODE (stmt))
++    {
++    case PHI_NODE:
++      /* Phi nodes are OK.  */
++      break;
++
++    case GIMPLE_MODIFY_STMT:
++      t = GIMPLE_STMT_OPERAND (stmt, 1);
++      if (!check_expr_for_promotability (pi, var, t,
++                                       /*is_assign=*/true))
++      break;
++      /* Fallthrough.  */
++
++    default:
++      /* Something we can't handle or the variable is being loaded from
++       memory.  */
++      pi->can_be_promoted_p = false;
++      goto done;
++    }
++
++  if (TREE_CODE (stmt) == PHI_NODE)
++    {
++      int i;
++
++      for (i = 0; i < PHI_NUM_ARGS (stmt); i++)
++      {
++        tree arg = PHI_ARG_DEF (stmt, i);
++
++        if (TREE_CODE (arg) == SSA_NAME)
++          pointer_set_insert (promotable_names, arg);
++      }
++
++      analyze_loop_index_uses (PHI_RESULT (stmt), pi);
++    }
++  else
++    analyze_loop_index_uses (var, pi);
++
++  /* Only worth continuing if we think the loop index can be
++     promoted.  */
++ done:
++  if (dump_file)
++    {
++      fprintf (dump_file, "Done analyzing ");
++      print_generic_expr (dump_file, var, 0);
++      fprintf (dump_file, " defined in ");
++      print_generic_expr (dump_file, stmt, 0);
++      fprintf (dump_file, "...%s to analyze\n\n",
++             pi->can_be_promoted_p ? "continuing" : "not continuing");
++    }
++  return !pi->can_be_promoted_p;
++}
++
++/* Check for the idiom:
++
++     short x, y;
++     unsigned short x.2, y.2, tmp;
++     ...
++     x.2 = (unsigned short) x;
++     y.2 = (unsigned short) y;
++     tmp = x.2 + y.2;
++     x = (short) tmp;
++
++   which is generated by convert for avoiding signed arithmetic
++   overflow.  RHS is "(short) tmp" in the above statement.  If RHS is
++   defined via such an idiom, store x and y into OP0 and OP1,
++   respectively.  We permit y.2 to be a constant if necessary.  */
++
++static tree
++upcast_operand_p (tree t)
++{
++  tree def, nop;
++
++  if (TREE_CODE (t) == INTEGER_CST)
++    return t;
++
++  if (TREE_CODE (t) != SSA_NAME
++      || !has_single_use (t))
++    return NULL_TREE;
++
++  def = SSA_NAME_DEF_STMT (t);
++  if (TREE_CODE (def) != GIMPLE_MODIFY_STMT)
++    return NULL_TREE;
++
++  nop = GIMPLE_STMT_OPERAND (def, 1);
++  if (TREE_CODE (nop) != CONVERT_EXPR
++      && TREE_CODE (nop) != NOP_EXPR)
++    return NULL_TREE;
++
++  return TREE_OPERAND (nop, 0);
++}
++
++static bool
++signed_arithmetic_overflow_idiom_p (tree rhs, tree *op0, tree *op1)
++{
++  tree tmp = TREE_OPERAND (rhs, 0);
++  tree op_stmt = SSA_NAME_DEF_STMT (tmp);
++  tree expr, x2, y2;
++  bool yes = false;
++  enum tree_code code;
++
++  if (!has_single_use (tmp)
++      || TREE_CODE (op_stmt) != GIMPLE_MODIFY_STMT)
++    goto done;
++  expr = GIMPLE_STMT_OPERAND (op_stmt, 1);
++
++  /* This could probably profitably be expanded to consider
++     MINUS_EXPR, MULT_EXPR, etc.  */
++  code = TREE_CODE (expr);
++  if (code != PLUS_EXPR)
++    goto done;
++  x2 = TREE_OPERAND (expr, 0);
++  y2 = TREE_OPERAND (expr, 1);
++
++  x2 = upcast_operand_p (x2);
++  if (x2 == NULL_TREE)
++    goto done;
++  y2 = upcast_operand_p (y2);
++  if (y2 == NULL_TREE)
++    goto done;
++
++  *op0 = x2;
++  *op1 = y2;
++  yes = true;
++
++ done:
++  return yes;
++}
++
++/* The loop index should have a specific usage pattern:
++
++   - It should be defined in a phi node with two incoming values:
++
++     LI_phi = PHI (LI_out, LI_in)
++
++   - One incoming value, LI_out, should be from outside the loop.
++
++   - The other incoming value, LI_in, should be defined thusly:
++
++     LI_in = LI_phi + increment
++
++   - increment should be 1.  We permit other increments with
++     -funsafe-loop-optimizations.
++
++   - Finally, in the comparison to exit the loop, the loop index must be
++     compared against a variable that has a type at least as precise as
++     the loop index's type.  For instance, something like:
++
++       char limit;
++       short i;
++
++       for (i = 0; i < limit; i++) ... 
++
++     would not be permitted.  */
++
++static bool
++stmt_in_loop_p (tree t, struct loop *loop)
++{
++  basic_block bb;
++
++  if (t == NULL_TREE)
++    return false;
++
++  bb = bb_for_stmt (t);
++  if (bb == NULL)
++    return false;
++
++  return flow_bb_inside_loop_p (loop, bb);
++}
++
++static bool
++analyze_loop_index_definition_pattern (struct promote_info *pi)
++{
++  tree phi = SSA_NAME_DEF_STMT (pi->loop_index_name);
++  bool ok = false, warn = false;
++  tree in0, in1;
++  bool inside0, inside1;
++  tree def0, def1, rhs, op0, op1, increment = NULL_TREE;
++
++  if (TREE_CODE (phi) != PHI_NODE
++      || PHI_NUM_ARGS (phi) != 2)
++    goto done;
++
++  in0 = PHI_ARG_DEF (phi, 0);
++  in1 = PHI_ARG_DEF (phi, 1);
++
++  /* Figure out which value comes from outside the loop.  */
++  def0 = SSA_NAME_DEF_STMT (in0);
++  def1 = SSA_NAME_DEF_STMT (in1);
++
++  inside0 = stmt_in_loop_p (def0, pi->loop);
++  inside1 = stmt_in_loop_p (def1, pi->loop);
++
++  if (inside0 && inside1)
++    goto done;
++  else if (inside0)
++    {
++      tree t = in0;
++      in0 = in1;
++      in1 = t;
++      t = def0;
++      def0 = def1;
++      def1 = t;
++    }
++  else if (!inside1)
++    goto done;
++
++  /* IN0 comes from outside the loop, IN1 from inside.  Analyze IN1.  */
++  if (TREE_CODE (def1) != GIMPLE_MODIFY_STMT)
++    goto done;
++
++  rhs = GIMPLE_STMT_OPERAND (def1, 1);
++
++  switch (TREE_CODE (rhs))
++    {
++    case CONVERT_EXPR:
++    case NOP_EXPR:
++      if (!signed_arithmetic_overflow_idiom_p (rhs, &op0, &op1))
++      goto done;
++      goto plus;
++    case PLUS_EXPR:
++      op0 = TREE_OPERAND (rhs, 0);
++      op1 = TREE_OPERAND (rhs, 1);
++    plus:
++      {
++      bool op0_li = op0 == PHI_RESULT (phi);
++      bool op1_li = op1 == PHI_RESULT (phi);
++      if (op0_li && op1_li)
++        /* This is weird, and definitely is not a case we can support
++           for promotion.  */
++        goto done;
++      else if (op0_li)
++        increment = op1;
++      else if (op1_li)
++        increment = op0;
++      else
++        goto done;
++      break;
++      }
++    default:
++      break;
++    }
++
++
++  /* Check that the exit condition for the loop is OK.  */
++  {
++    tree cond = COND_EXPR_COND (pi->exit_expr);
++    enum tree_code code = TREE_CODE (cond);
++
++    op0 = TREE_OPERAND (cond, 0);
++    op1 = TREE_OPERAND (cond, 1);
++
++    if (op0 == pi->loop_limit)
++      {
++      tree t = op0;
++      op0 = op1;
++      op1 = t;
++      code = swap_tree_comparison (code);
++      }
++
++    if (code != LT_EXPR && code != LE_EXPR)
++      goto done;
++
++    if (!types_compatible_p (TREE_TYPE (pi->loop_index_name),
++                           TREE_TYPE (pi->loop_limit)))
++      {
++      switch (TREE_CODE (pi->loop_limit))
++        {
++        case INTEGER_CST:
++          if (!int_fits_type_p (pi->loop_limit,
++                                TREE_TYPE (pi->loop_index_name)))
++            goto done;
++          break;
++        case SSA_NAME:
++          {
++            tree v = pi->loop_limit;
++            tree def = SSA_NAME_DEF_STMT (v);
++
++            /* Backtrack through CONVERT_EXPRs and/or NOP_EXPRs to
++               determine if the variables "started out" as the same
++               type.  */
++            while (TREE_CODE (def) == GIMPLE_MODIFY_STMT)
++              {
++                tree rhs = GIMPLE_STMT_OPERAND (def, 1);
++
++                if (TREE_CODE (rhs) != NOP_EXPR
++                    && TREE_CODE (rhs) != CONVERT_EXPR)
++                  break;
++
++                v = TREE_OPERAND (rhs, 0);
++                def = SSA_NAME_DEF_STMT (v);
++              }
++            /* Permit comparisons between non-compatible types with
++               flag_unsafe_loop_optimizations, since we can assume the
++               loop index does not overflow.  */
++            if (types_compatible_p (TREE_TYPE (pi->loop_index_name),
++                                     TREE_TYPE (v))
++                || flag_unsafe_loop_optimizations)
++              break;
++            /* Fallthrough.  */
++          default:
++            goto done;
++          }
++        }
++      }
++  }
++
++  if (increment == NULL_TREE)
++    goto done;
++  if (TREE_CODE (increment) != INTEGER_CST
++      || compare_tree_int (increment, 1) != 0)
++    {
++      warn = true;
++      if (!flag_unsafe_loop_optimizations)
++      goto done;
++    }
++
++  ok = true;
++ done:
++  if (warn && !pi->warned)
++    {
++      pi->warned = true;
++      /* We can promote unsigned indices only if -funsafe-loop-optimizations
++       is in effect, since the user might be depending on the modulo
++       wraparound behavior of unsigned types.  */
++      if (warn_unsafe_loop_optimizations)
++      {
++        const char *wording;
++
++        wording = (flag_unsafe_loop_optimizations
++                   ? N_("assuming that the loop counter does not overflow")
++                   : N_("cannot optimize loop, the loop counter may overflow"));
++        warning (OPT_Wunsafe_loop_optimizations, "%s", gettext (wording));
++      }
++    }
++
++  return ok;
++}
++
++/* Analyze the loop associated with PI_ to see if its loop index can be
++   promoted.  */
++
++static bool
++analyze_loop (const void *pi_, void *data)
++{
++  struct promote_info *pi = CONST_CAST (struct promote_info *,
++                                      (const struct promote_info *) pi_);
++  bool *changed = data;
++
++  /* We previously determined we can't promote this; go ahead and
++     continue iterating.  */
++  if (pi->loop_index_name == NULL_TREE)
++    return true;
++
++  /* Assume we can always promote the loop index, even if it doesn't
++     exist.  */
++  pi->can_be_promoted_p = true;
++
++  if (dump_file)
++    {
++      fprintf (dump_file, "Analyzing ");
++      print_generic_expr (dump_file, pi->loop_index_name, 0);
++      fprintf (dump_file, "\n");
++    }
++
++  if (pi->loop_index_name
++      && analyze_loop_index_definition_pattern (pi))
++    {
++      /* Clear any previously gathered information.  */
++      VEC_truncate (tree, pi->cast_types, 0);
++      VEC_truncate (int, pi->cast_counts, 0);
++
++      walk_use_def_chains (pi->loop_index_name, analyze_loop_index, pi, false);
++    }
++  else
++    pi->can_be_promoted_p = false;
++
++  /* If we determined the loop index is used in strange ways, clear it
++     so we don't examine it again.  */
++  if (!pi->can_be_promoted_p)
++    pi->loop_index_name = NULL_TREE;
++
++  /* Let our caller know whether to re-do the analysis.  */
++  *changed = *changed || !pi->can_be_promoted_p;
++  /* Continue if PI is promotable.  */
++  return pi->can_be_promoted_p;
++}
++
++/* Add PI_->LOOP_INDEX_NAME to the set of variables, DATA, that we are
++   considering for promotion.  */
++
++static bool
++add_variable (const void *pi_, void *data ATTRIBUTE_UNUSED)
++{
++  const struct promote_info *pi = (const struct promote_info *) pi_;
++  struct pointer_set_t *pset = (struct pointer_set_t *) data;
++  int presentp;
++
++  if (pi->loop_index_name != NULL_TREE)
++    {
++      presentp = pointer_set_insert (pset, pi->loop_index_name);
++      gcc_assert (!presentp);
++    }
++
++  /* Continue traversal.  */
++  return true;
++}
++
++/* For each promotable variable:
++
++   - create a new, promoted VAR_DECL;
++
++   - walk through all the uses and defs and create new statements using
++     the promoted variables.  We don't create new phi nodes; post-pass
++     SSA update will handle those for us.  */
++
++/* Make dump files readable.  */
++#define PROMOTED_VAR_SUFFIX ".promoted"
++
++/* Create a variable NAME with TYPE and do the necessary work to inform
++   the SSA machinery about it.  */
++
++static tree
++create_pli_var (tree type, char *name)
++{
++  tree var = create_tmp_var (type, name);
++  create_var_ann (var);
++  mark_sym_for_renaming (var);
++  add_referenced_var (var);
++  return var;
++}
++
++/* Associate the SSA_NAME VAR with the promoted variable DATA.  */
++
++static bool
++associate_name_with_var (tree var, tree def_stmt, void *data)
++{
++  tree promoted_var = (tree) data;
++  void **p;
++
++  gcc_assert (promoted_var != NULL_TREE);
++
++  if (TREE_CODE (def_stmt) == PHI_NODE)
++    var = PHI_RESULT (def_stmt);
++
++  p = pointer_map_insert (variable_map, var);
++
++  if (!*p)
++    {
++      if (dump_file)
++      {
++        fprintf (dump_file, "Associating ");
++        print_generic_expr (dump_file, var, 0);
++        fprintf (dump_file, " with ");
++        print_generic_expr (dump_file, promoted_var, 0);
++        fprintf (dump_file, "\n\n");
++      }
++      *(tree *)p = promoted_var;
++    }
++
++  /* Continue traversal.  */
++  return false;
++}
++
++/* Create a promoted variable for the variable from PI_.  */
++
++static bool
++create_promoted_variable (const void *pi_, void *data ATTRIBUTE_UNUSED)
++{
++  struct promote_info *pi = CONST_CAST (struct promote_info *,
++                                      (const struct promote_info *) pi_);
++
++  if (pi->can_be_promoted_p)
++    {
++      tree type = choose_profitable_promoted_type (pi);
++      tree orig_name = DECL_NAME (pi->var_decl);
++      size_t id_len = IDENTIFIER_LENGTH (orig_name);
++      size_t name_len = id_len + strlen (PROMOTED_VAR_SUFFIX) + 1;
++      char *name;
++
++      name = alloca (name_len);
++      strcpy (name, IDENTIFIER_POINTER (orig_name));
++      strcpy (name + id_len, PROMOTED_VAR_SUFFIX);
++
++      pi->promoted_type = type;
++      pi->promoted_var = create_pli_var (type, name);
++
++      if (dump_file)
++      {
++        fprintf (dump_file, "Created new variable ");
++        print_generic_expr (dump_file, pi->promoted_var, 0);
++        fprintf (dump_file, " to stand in for ");
++        print_generic_expr (dump_file, pi->loop_index_name, 0);
++        fprintf (dump_file, "\n\n");
++      }
++
++      walk_use_def_chains (pi->loop_index_name,
++                         associate_name_with_var,
++                         pi->promoted_var, false);
++    }
++
++  /* Continue traversal.  */
++  return true;
++}
++
++/* Rebuild T with newly promoted variables; STMT is the original
++   statement in which T appeared and may be equivalent to T.  TYPE is
++   non-null when rebuilding the rhs of a GIMPLE_MODIFY_STMT and
++   indicates the type of the lhs.  */
++
++static tree
++rebuild_with_promotion_1 (tree t, tree stmt, tree type,
++                        block_stmt_iterator bsi,
++                        struct promote_info *pi)
++{
++  tree op0, op1;
++
++  switch (TREE_CODE (t))
++    {
++    case GIMPLE_MODIFY_STMT:
++      {
++      tree orig_op0 = GIMPLE_STMT_OPERAND (t, 0);
++      tree orig_op1 = GIMPLE_STMT_OPERAND (t, 1);
++      tree x, y;
++      void **v;
++
++      /* If we are defining a promotable variable, check for special
++         idioms.  */
++      v = pointer_map_contains (variable_map, orig_op0);
++      if (v != NULL
++          && *(tree *)v == pi->promoted_var
++          && (TREE_CODE (orig_op1) == NOP_EXPR
++              || TREE_CODE (orig_op1) == CONVERT_EXPR)
++          && signed_arithmetic_overflow_idiom_p (orig_op1, &x, &y))
++        {
++          tree tmp = TREE_OPERAND (orig_op1, 0);
++          void **xp;
++          void **yp;
++
++          if (TYPE_PRECISION (TREE_TYPE (tmp))
++              >= TYPE_PRECISION (pi->promoted_type))
++            goto done;
++
++          /* It's possible that we've already promoted the operands of
++             one or both of the NOP_EXPRs.  In that case, we can
++             bypass the logic below and go straight to rebuilding the
++             rhs that we really want to transform.  */
++          if (TREE_CODE (x) == VAR_DECL
++              || TREE_CODE (y) == VAR_DECL)
++            goto build_fake;
++          xp = pointer_map_contains (variable_map, x);
++          yp = pointer_map_contains (variable_map, y);
++
++          /* Nothing to see here.  */
++          if (!types_compatible_p (TREE_TYPE (x),
++                                   TREE_TYPE (y))
++              || (xp == NULL && yp == NULL))
++            goto done;
++          x = (xp == NULL ? NULL_TREE : *(tree *)xp);
++          y = (yp == NULL ? NULL_TREE : *(tree *)yp);
++
++          if (x != pi->promoted_var && y != pi->promoted_var)
++            goto done;
++
++
++        build_fake:
++          orig_op1 = build2 (PLUS_EXPR, TREE_TYPE (x), x, y);
++          if (dump_file)
++            {
++              fprintf (dump_file, "Substituting ");
++              print_generic_expr (dump_file, orig_op1, 0);
++              fprintf (dump_file, " for rhs of original statement\n");
++            }
++        done:
++          ;
++        }
++
++      op0 = rebuild_with_promotion_1 (orig_op0, stmt, type, bsi, pi);
++      op1 = rebuild_with_promotion_1 (orig_op1, stmt, TREE_TYPE (op0), bsi, pi);
++      /* Something must have been rebuilt.  */
++      gcc_assert ((op0 != orig_op0) || (op1 != orig_op1));
++      if (op0 != orig_op0)
++        GIMPLE_STMT_OPERAND (t, 0) = op0;
++      if (op1 != orig_op1)
++        GIMPLE_STMT_OPERAND (t, 1) = op1;
++      return t;
++      }
++    case NOP_EXPR:
++    case CONVERT_EXPR:
++      {
++      tree pvar = rebuild_with_promotion_1 (TREE_OPERAND (t, 0), stmt, type, bsi, pi);
++
++      if (types_compatible_p (type, TREE_TYPE (pvar)))
++        return pvar;
++      else
++        return build1 (TREE_CODE (t), type, pvar);
++      }
++    case INTEGER_CST:
++      {
++      return build_int_cst_wide (pi->promoted_type,
++                                 TREE_INT_CST_LOW (t),
++                                 TREE_INT_CST_HIGH (t));
++      }
++    case COND_EXPR:
++      {
++      tree orig_op0 = TREE_OPERAND (t, 0);
++      op0 = rebuild_with_promotion_1 (orig_op0, stmt, type, bsi, pi);
++      gcc_assert (orig_op0 != op0);
++      TREE_OPERAND (t, 0) = op0;
++      return t;
++      }
++    case PLUS_EXPR:
++    case MINUS_EXPR:
++    case MULT_EXPR:
++      type = pi->promoted_type;
++      goto binary_expr;
++    case EQ_EXPR:
++    case NE_EXPR:
++    case LT_EXPR:
++    case LE_EXPR:
++    case GT_EXPR:
++    case GE_EXPR:
++      type = TREE_TYPE (t);
++    binary_expr:
++      op0 = TREE_OPERAND (t, 0);
++      op1 = TREE_OPERAND (t, 1);
++      op0 = rebuild_with_promotion_1 (op0, stmt, type, bsi, pi);
++      op1 = rebuild_with_promotion_1 (op1, stmt, type, bsi, pi);
++      return build2 (TREE_CODE (t), type, op0, op1);
++    case SSA_NAME:
++      {
++      void **p = pointer_map_contains (variable_map, t);
++
++      if (p == NULL)
++        {
++          /* This is unexpected, but it does happen if we were dealing
++             with COND_EXPRs and such.  Just go ahead and create a
++             temporary for it.  */
++          if (types_compatible_p (TREE_TYPE (t), pi->promoted_type)
++              || SSA_NAME_DEF_STMT (t) == stmt)
++            return t;
++          else
++            goto insert_cast;
++        }
++      else
++        return *(tree *)p;
++      }
++    case VAR_DECL:
++      return t;
++    default:
++    insert_cast:
++      {
++      tree tmp, nop, cast;
++      tree to_upcast = t;
++
++      /* If we are dealing with a memory reference, then we can't have
++         wrap it in a NOP_EXPR; we need to load the value from memory
++         first, then convert it.  */
++      if (!is_gimple_reg (to_upcast))
++        {
++          tree tmp = create_pli_var (TREE_TYPE (to_upcast),
++                                     CONST_CAST (char *, "loadtmp"));
++          tree stmt = build_gimple_modify_stmt (tmp, to_upcast);
++          bsi_insert_before (&bsi, stmt, BSI_SAME_STMT);
++          to_upcast = tmp;
++        }
++
++      tmp = create_pli_var (pi->promoted_type,
++                            CONST_CAST (char *, "promotetmp"));
++      nop = build1 (NOP_EXPR, pi->promoted_type, to_upcast);
++      cast = build_gimple_modify_stmt (tmp, nop);
++      if (dump_file)
++        {
++          fprintf (dump_file, "Inserting cast ");
++          print_generic_expr (dump_file, cast, 0);
++          fprintf (dump_file, " prior to ");
++          print_generic_expr (dump_file, stmt, 0);
++          fprintf (dump_file, "\n");
++        }
++      bsi_insert_before (&bsi, cast, BSI_SAME_STMT);
++      return tmp;
++      }
++    }
++}
++
++/* Rebuild STMT, which contains uses or a def of the promotable variable
++   associated with PI.  */
++
++static void
++rebuild_with_promotion (tree stmt, struct promote_info *pi)
++{
++  tree rebuilt;
++  block_stmt_iterator bsi;
++
++  if (pointer_set_insert (promoted_stmts, stmt))
++    return;
++
++  if (dump_file)
++    {
++      fprintf (dump_file, "Rebuilding stmt ");
++      print_generic_expr (dump_file, stmt, 0);
++      fprintf (dump_file, "\n");
++    }
++
++  bsi = bsi_for_stmt (stmt);
++  rebuilt = rebuild_with_promotion_1 (stmt, stmt, NULL, bsi, pi);
++  if (dump_file)
++    {
++      fprintf (dump_file, "Converted stmt ");
++      print_generic_expr (dump_file, rebuilt, 0);
++      fprintf (dump_file, "\n\n");
++    }
++  update_stmt (rebuilt);
++}
++
++/* Helper function for promote_variable that walks over use/def
++   chains.  */
++
++static bool
++promote_variable_1 (tree var, tree stmt, void *data)
++{
++  struct promote_info *pi = (struct promote_info *) data;
++  imm_use_iterator imi;
++  tree use_stmt;
++
++  /* Due to the way walk_use_def_chains works, when STMT is a PHI_NODE,
++     VAR is actually an argument to the phi node, not the result of it.
++     Rebuild uses of the phi node's result after handle integer constant
++     inputs to the phi node.  */
++  if (TREE_CODE (stmt) == PHI_NODE)
++    {
++      if (TREE_CODE (var) == INTEGER_CST)
++      {
++        edge e = loop_preheader_edge (pi->loop);
++        basic_block preheader = e->src;
++        block_stmt_iterator bsi = bsi_last (preheader);
++        tree cst = build_int_cst_wide (pi->promoted_type,
++                                       TREE_INT_CST_LOW (var),
++                                       TREE_INT_CST_HIGH (var));
++        tree assign = build_gimple_modify_stmt (pi->promoted_var, cst);
++        bsi_insert_after (&bsi, assign, BSI_NEW_STMT);
++      }
++      var = PHI_RESULT (stmt);
++    }
++  else
++    rebuild_with_promotion (stmt, pi);
++
++  FOR_EACH_IMM_USE_STMT (use_stmt, imi, var)
++    {
++      if (TREE_CODE (use_stmt) != PHI_NODE)
++      rebuild_with_promotion (use_stmt, pi);
++    }
++
++  return false;
++}
++
++/* Convert all uses and defs of PI_->LOOP_INDEX_NAME as linked by
++   use-def chains to uses and defs of PI_->PROMOTED_VAR.  */
++
++static bool
++promote_variable (const void *pi_, void *data ATTRIBUTE_UNUSED)
++{
++  const struct promote_info *pi = (const struct promote_info *) pi_;
++
++  if (pi->can_be_promoted_p)
++    {
++      walk_use_def_chains (pi->loop_index_name, promote_variable_1,
++                         CONST_CAST (struct promote_info *, pi), false);
++    }
++
++  /* Continue traversal.  */
++  return true;
++}
++
++/* Free PI_ and its associated data.  */
++
++static bool
++free_pi_entries (const void *pi_, void *data ATTRIBUTE_UNUSED)
++{
++  struct promote_info *pi = CONST_CAST (struct promote_info *,
++                                      (const struct promote_info *) pi_);
++
++  VEC_free (tree, heap, pi->cast_types);
++  VEC_free (int, heap, pi->cast_counts);
++  free (pi);
++
++  /* Continue traversal.  */
++  return true;
++}
++
++/* Collect information about variables that we believe to be loop
++   indices in PROMOTION_INFO.  */
++
++static void
++collect_promotion_candidates (void)
++{
++  loop_iterator li;
++  struct loop *loop;
++
++  FOR_EACH_LOOP (li, loop, 0)
++    {
++      basic_block header = loop->header;
++      tree exit_cond = last_stmt (header);
++      
++      if (exit_cond && TREE_CODE (exit_cond) == COND_EXPR)
++      {
++        tree loop_index;
++        tree limit;
++        struct promote_info *pi;
++
++        loop_index = find_promotion_candidate (loop, exit_cond, &limit);
++        if (loop_index == NULL_TREE)
++          continue;
++
++        if (dump_file)
++          {
++            fprintf (dump_file, "Found loop index ");
++            print_generic_expr (dump_file, loop_index, 0);
++            fprintf (dump_file, " involved in ");
++            print_generic_expr (dump_file, exit_cond, 0);
++            fprintf (dump_file, "\n\n");
++          }
++
++        pi = XCNEW (struct promote_info);
++        pi->loop = loop;
++        pi->exit_expr = exit_cond;
++        pi->loop_index_name = loop_index;
++        pi->loop_limit = limit;
++        pi->var_decl = SSA_NAME_VAR (loop_index);
++        /* We think so, anyway...  */
++        pi->can_be_promoted_p = true;
++        pointer_set_insert (promotion_info, pi);
++      }
++      else if (dump_file)
++      {
++        fprintf (dump_file, "\nSkipping analysis of loop %d (header bb #%d)\n",
++                 loop->num, loop->header->index);
++        if (exit_cond)
++          {
++            fprintf (dump_file, "Exit condition was ");
++            print_generic_expr (dump_file, exit_cond, 0);
++            fprintf (dump_file, "\n");
++          }
++      }
++    }
++}
++
++/* Free memory associated with global variables that we used.  */
++
++static void
++pli_cleanup (void)
++{
++  if (promoted_stmts)
++    {
++      pointer_set_destroy (promoted_stmts);
++      promoted_stmts = NULL;
++    }
++  if (variable_map)
++    {
++      pointer_map_destroy (variable_map);
++      variable_map = NULL;
++    }
++  if (promotable_names)
++    {
++      pointer_set_destroy (promotable_names);
++      promotable_names = NULL;
++    }
++  if (promotion_info)
++    {
++      pointer_set_traverse (promotion_info, free_pi_entries, NULL);
++      pointer_set_destroy (promotion_info);
++      promotion_info = NULL;
++    }
++}
++
++/* The guts of the pass.  */
++
++static unsigned int
++promote_short_indices (void)
++{
++  bool did_something = false;
++  bool changed;
++  size_t max_iterations, i, n_promoted;
++
++  promotion_info = pointer_set_create ();
++  collect_promotion_candidates ();
++
++  if (dump_file)
++    fprintf (dump_file, "Found %d candidates for promotion\n",
++           (int) pointer_set_n_elements (promotion_info));
++
++  /* Nothing to do.  */
++  if (pointer_set_n_elements (promotion_info) == 0)
++    goto cleanup;
++
++  /* We have information about which variables are loop index variables.
++     We now need to determine the promotability of the loop indices.
++     Since the promotability of loop indices may depend on other loop
++     indices, we need to repeat this until we reach a fixed point.  */
++  changed = true;
++  max_iterations = pointer_set_n_elements (promotion_info);
++  i = 0;
++
++  promotable_names = pointer_set_create ();
++
++  while (changed)
++    {
++      changed = false;
++      pointer_set_clear (promotable_names);
++      pointer_set_traverse (promotion_info, add_variable,
++                          promotable_names);
++      n_promoted = pointer_set_n_elements (promotable_names);
++
++      if (dump_file)
++      fprintf (dump_file, "\nIteration %d, have %d variables to consider\n",
++               (int) i, (int) n_promoted);
++
++      if (n_promoted == 0)
++      break;
++      gcc_assert (i < max_iterations);
++      pointer_set_traverse (promotion_info, analyze_loop, &changed);
++      i++;
++    }
++
++  if (dump_file)
++    fprintf (dump_file, "Promoting %d variables\n",
++           (int) n_promoted);
++
++  if (n_promoted != 0)
++    {
++      did_something = true;
++      variable_map = pointer_map_create ();
++      promoted_stmts = pointer_set_create ();
++      pointer_set_traverse (promotion_info, create_promoted_variable, NULL);
++      pointer_set_traverse (promotion_info, promote_variable, NULL);
++    }
++
++ cleanup:
++  pli_cleanup ();
++  return did_something ? TODO_update_ssa : 0;
++}
++
++/* Entry point for the short loop index promotion pass.  */
++
++static unsigned int
++tree_short_index_promotion (void)
++{
++  unsigned int changed = 0;
++
++  /* Initialize all the necessary loop infrastructure.  */
++  loop_optimizer_init (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES | LOOPS_HAVE_RECORDED_EXITS);
++  add_noreturn_fake_exit_edges ();
++  connect_infinite_loops_to_exit ();
++
++  if (number_of_loops () > 1)
++    changed = promote_short_indices ();
++
++  /* Tear down loop optimization infrastructure.  */
++  remove_fake_exit_edges ();
++  free_numbers_of_iterations_estimates ();
++  loop_optimizer_finalize ();
++
++  return changed;
++}
++
++static bool
++gate_short_index_promotion (void)
++{
++  return flag_promote_loop_indices;
++}
++
++struct tree_opt_pass pass_promote_short_indices =
++{
++  "promoteshort",                     /* name */
++  gate_short_index_promotion,         /* gate */
++  tree_short_index_promotion,         /* execute */
++  NULL,                                       /* sub */
++  NULL,                                       /* next */
++  0,                                  /* static_pass_number */
++  TV_TREE_LOOP_PROMOTE,                       /* tv_id */
++  PROP_cfg | PROP_ssa,                        /* properties_required */
++  0,                                  /* properties_provided */
++  0,                                  /* properties_destroyed */
++  0,                                  /* todo_flags_start */
++  TODO_dump_func | TODO_verify_loops 
++    | TODO_ggc_collect,                       /* todo_flags_finish */
++  0                                   /* letter */
++};
+--- a/gcc/tree-ssa-pre.c
++++ b/gcc/tree-ssa-pre.c
+@@ -2006,7 +2006,7 @@ compute_antic (void)
+       fprintf (dump_file, "Starting iteration %d\n", num_iterations);
+       num_iterations++;
+       changed = false;
+-      for (i = 0; i < last_basic_block - NUM_FIXED_BLOCKS; i++)
++      for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
+       {
+         if (TEST_BIT (changed_blocks, postorder[i]))
+           {
+@@ -2038,7 +2038,7 @@ compute_antic (void)
+           fprintf (dump_file, "Starting iteration %d\n", num_iterations);
+         num_iterations++;
+         changed = false;
+-        for (i = 0; i < last_basic_block - NUM_FIXED_BLOCKS; i++)
++        for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
+           {
+             if (TEST_BIT (changed_blocks, postorder[i]))
+               {
+@@ -2345,6 +2345,10 @@ create_expression_by_pieces (basic_block
+       tree op2 = TREE_OPERAND (expr, 1);
+       tree genop1 = find_or_generate_expression (block, op1, stmts);
+       tree genop2 = find_or_generate_expression (block, op2, stmts);
++      /* Ensure op2 is a sizetype for POINTER_PLUS_EXPR.  It
++         may be a constant with the wrong type.  */
++      if (TREE_CODE(expr) == POINTER_PLUS_EXPR)
++        genop2 = fold_convert (sizetype, genop2);
+       folded = fold_build2 (TREE_CODE (expr), TREE_TYPE (expr),
+                             genop1, genop2);
+       break;
+--- /dev/null
++++ b/gcc/tree-ssa-remove-local-statics.c
+@@ -0,0 +1,813 @@
++/* Local static variable elimination pass.
++   Copyright (C) 2007 Free Software Foundation, Inc.
++   Contributed by Nathan Froyd <froydnj@codesourcery.com>
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify it
++under the terms of the GNU General Public License as published by the
++Free Software Foundation; either version 3, or (at your option) any
++later version.
++
++GCC is distributed in the hope that it will be useful, but WITHOUT
++ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++/* Converting static function-local variables to automatic variables.
++
++   The motivating example is a function like:
++
++   void
++   foo (unsigned n)
++   {
++     static int var;
++     unsigned i;
++
++     for (i = 0; i != n; i++)
++       {
++         var = ...
++
++         do other things with var...
++       }
++   }
++
++   Because VAR is static, doing things like code motion to loads and
++   stores of VAR is difficult.  Furthermore, accesses to VAR are
++   inefficient.  This pass aims to recognize the cases where it is not
++   necessary for VAR to be static and modify the code so that later
++   passes will do the appropriate optimizations.
++
++   The criteria for a static function-local variable V in a function F
++   being converted to an automatic variable are:
++
++   1. F does not call setjmp; and
++   2. V's address is never taken; and
++   3. V is not declared volatile; and
++   4. V is not used in any nested function;
++   5. V is not an aggregate value (union, struct, array, etc.); and
++   6. Every use of V is defined along all paths leading to the use.
++
++   NOTE: For ease of implementation, we currently treat a function call
++   as killing all previous definitions of static variables, since we
++   could have:
++
++   static void
++   foo (...)
++   {
++     static int x;
++
++     x = ...;       (1)
++
++    f (...);        (2)
++
++     ... = x;       (3)
++   }
++
++   The use at (3) needs to pick up a possible definition made by the
++   call at (2).  If the call at (2) does not call back into 'foo',
++   then the call is not a killing call.  We currently treat it as
++   though it is.  */
++
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++
++#include "rtl.h"
++#include "tm_p.h"
++#include "hard-reg-set.h"
++#include "obstack.h"
++#include "basic-block.h"
++
++#include "tree.h"
++#include "tree-gimple.h"
++#include "hashtab.h"
++#include "diagnostic.h"
++#include "tree-flow.h"
++#include "tree-dump.h"
++#include "flags.h"
++#include "timevar.h"
++#include "tree-pass.h"
++
++struct rls_decl_info
++{
++  /* The variable declaration.  */
++  tree orig_var;
++
++  /* Its index in rls_block_local_data.  */
++  int index;
++
++  /* Whether we can optimize this variable.  */
++  bool optimizable_p;
++
++  /* The new variable declaration, if we can optimize away the staticness
++     of 'orig_var'.  */
++  tree new_var;
++};
++
++/* Filled with 'struct rls_decl_info'; keyed off ORIG_VAR.  */
++static htab_t static_variables;
++
++struct rls_stmt_info
++{
++  /* The variable declaration.  */
++  tree var;
++
++  /* The statement in which we found a def or a use of the variable.  */
++  tree stmt;
++
++  /* Whether STMT represents a use of VAR.  */
++  bool use_p;
++
++  /* A bitmap whose entries denote what variables have been defined
++     when execution arrives at STMT.  This field is only used when
++     USE_P is true.  */
++  sbitmap defined;
++};
++
++/* Filled with 'struct rls_stmt_info'; keyed off STMT.  */
++static htab_t defuse_statements;
++
++static struct
++{
++  /* The number of static variables we found.  */
++  size_t n_statics;
++
++  /* The number of optimizable variables we found.  */
++  size_t n_optimizable;
++} stats;
++
++struct rls_block_dataflow_data {
++  /* A bitmap whose entries denote what variables have been defined on
++     entry to this block.  */
++  sbitmap defined_in;
++
++  /* A bitmap whose entries denote what variables have been defined on
++     exit from this block.  */
++  sbitmap defined_out;
++};
++
++/* Parameters for the 'static_variables' hash table.  */
++
++static hashval_t
++rls_hash_decl_info (const void *x)
++{
++  return htab_hash_pointer
++    ((const void *) ((const struct rls_decl_info *) x)->orig_var);
++}
++
++static int
++rls_eq_decl_info (const void *x, const void *y)
++{
++  const struct rls_decl_info *a = x;
++  const struct rls_decl_info *b = y;
++
++  return a->orig_var == b->orig_var;
++}
++
++static void
++rls_free_decl_info (void *info)
++{
++  free (info);
++}
++
++/* Parameters for the 'defuse_statements' hash table.  */
++
++static hashval_t
++rls_hash_use_info (const void *x)
++{
++  return htab_hash_pointer
++    ((const void *) ((const struct rls_stmt_info *) x)->stmt);
++}
++
++static int
++rls_eq_use_info (const void *x, const void *y)
++{
++  const struct rls_stmt_info *a = x;
++  const struct rls_stmt_info *b = y;
++
++  return a->stmt == b->stmt;
++}
++
++static void
++rls_free_use_info (void *info)
++{
++  struct rls_stmt_info *stmt_info = info;
++
++  if (stmt_info->defined)
++    sbitmap_free (stmt_info->defined);
++
++  free (stmt_info);
++}
++
++/* Initialize data structures and statistics.  */
++
++static void
++rls_init (void)
++{
++  basic_block bb;
++
++  /* We expect relatively few static variables, hence the small
++     initial size for the hash table.  */
++  static_variables = htab_create (8, rls_hash_decl_info,
++                                  rls_eq_decl_info, rls_free_decl_info);
++
++  /* We expect quite a few statements.  */
++  defuse_statements = htab_create (128, rls_hash_use_info,
++                                   rls_eq_use_info, rls_free_use_info);
++
++  FOR_ALL_BB (bb)
++    {
++      struct rls_block_dataflow_data *data;
++
++      data = XNEW (struct rls_block_dataflow_data);
++      memset (data, 0, sizeof (*data));
++      bb->aux = data;
++    }
++
++  stats.n_statics = 0;
++  stats.n_optimizable = 0;
++}
++
++/* Free data structures.  */
++
++static void
++rls_done (void)
++{
++  basic_block bb;
++
++  htab_delete (static_variables);
++  htab_delete (defuse_statements);
++
++  FOR_ALL_BB (bb)
++    {
++      struct rls_block_dataflow_data *data = bb->aux;
++
++      gcc_assert (data);
++
++      if (data->defined_in)
++      sbitmap_free (data->defined_in);
++      if (data->defined_out)
++      sbitmap_free (data->defined_out);
++      free (data);
++      bb->aux = NULL;
++    }
++}
++
++\f
++/* Doing the initial work to find static variables.  */
++
++/* Examine the defining statement for VAR and determine whether it is a
++   static variable we could potentially optimize.  If so, stick in it
++   in the 'static_variables' hashtable.
++
++   STMT is the statement in which a definition or use of VAR occurs.
++   USE_P indicates whether VAR is used or defined in STMT.  Enter STMT
++   into 'defuse_statements' as well for use during dataflow
++   analysis.  */
++
++static void
++maybe_discover_new_declaration (tree var, tree stmt, bool use_p)
++{
++  tree def_stmt = SSA_NAME_VAR (var);
++
++  if (TREE_CODE (def_stmt) == VAR_DECL
++      && DECL_CONTEXT (def_stmt) != NULL_TREE
++      && TREE_CODE (DECL_CONTEXT (def_stmt)) == FUNCTION_DECL
++      && TREE_STATIC (def_stmt)
++      /* We cannot optimize away aggregate statics, as we would have to
++       prove that definitions of every field of the aggregate dominate
++       uses.  */
++      && !AGGREGATE_TYPE_P (TREE_TYPE (def_stmt))
++      /* GCC doesn't normally treat vectors as aggregates; we need to,
++       though, since a user could use intrinsics to read/write
++       particular fields of the vector, thereby treating it as an
++       array.  */
++      && TREE_CODE (TREE_TYPE (def_stmt)) != VECTOR_TYPE
++      && !TREE_ADDRESSABLE (def_stmt)
++      && !TREE_THIS_VOLATILE (def_stmt))
++    {
++      struct rls_decl_info dummy;
++      void **slot;
++
++      dummy.orig_var = def_stmt;
++      slot = htab_find_slot (static_variables, &dummy, INSERT);
++
++      if (*slot == NULL)
++        {
++          /* Found a use or a def of a new declaration.  */
++          struct rls_decl_info *info = XNEW (struct rls_decl_info);
++
++          info->orig_var = def_stmt;
++          info->index = stats.n_statics++;
++          /* Optimistically assume that we can optimize.  */
++          info->optimizable_p = true;
++          info->new_var = NULL_TREE;
++          *slot = (void *) info;
++        }
++
++      /* Enter the statement into DEFUSE_STATEMENTS.  */
++      {
++        struct rls_stmt_info dummy;
++        struct rls_stmt_info *info;
++
++        dummy.stmt = stmt;
++        slot = htab_find_slot (defuse_statements, &dummy, INSERT);
++
++        /* We should never insert the same statement into the
++           hashtable twice.  */
++        gcc_assert (*slot == NULL);
++
++        info = XNEW (struct rls_stmt_info);
++        info->var = def_stmt;
++        info->stmt = stmt;
++        if (dump_file)
++          {
++            fprintf (dump_file, "entering as %s ", use_p ? "use" : "def");
++            print_generic_stmt (dump_file, stmt, TDF_DETAILS);
++          }
++        info->use_p = use_p;
++        /* We don't know how big to make the bitmap yet.  */
++        info->defined = NULL;
++        *slot = (void *) info;
++      }
++    }
++}
++
++/* Grovel through all the statements in the program, looking for
++   SSA_NAMEs whose SSA_NAME_VAR is a VAR_DECL.  We look at both use and
++   def SSA_NAMEs.  */
++
++static void
++find_static_nonvolatile_declarations (void)
++{
++  basic_block bb;
++
++  FOR_EACH_BB (bb)
++    {
++      block_stmt_iterator i;
++
++      for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
++        {
++          tree var;
++          ssa_op_iter iter;
++          tree stmt = bsi_stmt (i);
++
++        /* If there's a call expression in STMT, then previous passes
++           will have determined if the call transitively defines some
++           static variable.  However, we need more precise
++           information--we need to know whether static variables are
++           live out after the call.
++
++           Since we'll never see something like:
++
++             staticvar = foo (bar, baz);
++
++           in GIMPLE (the result of the call will be assigned to a
++           normal, non-static local variable which is then assigned to
++           STATICVAR in a subsequent statement), don't bother finding
++           new declarations if we see a CALL_EXPR.  */
++        if (get_call_expr_in (stmt) == NULL_TREE)
++          FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_VDEF)
++            {
++              maybe_discover_new_declaration (var, stmt, false);
++            }
++
++          FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_VUSE)
++            {
++              maybe_discover_new_declaration (var, stmt, true);
++            }
++        }
++    }
++}
++
++\f
++/* Determining if we have anything to optimize.  */
++
++/* Examine *SLOT (which is a 'struct rls_decl_info *') to see whether
++   the associated variable is optimizable.  If it is, create a new,
++   non-static declaration for the variable; this new variable will be
++   used during a subsequent rewrite of the function.  */
++
++#define NEW_VAR_PREFIX ".unstatic"
++
++static int
++maybe_create_new_variable (void **slot, void *data ATTRIBUTE_UNUSED)
++{
++  struct rls_decl_info *info = *slot;
++  tree id_node = DECL_NAME (info->orig_var);
++  size_t id_len = IDENTIFIER_LENGTH (id_node);
++  size_t name_len = id_len + strlen (NEW_VAR_PREFIX) + 1;
++  char *name;
++
++  /* Don't create a new variable multiple times.  */
++  gcc_assert (!info->new_var);
++
++  /* Tie the new name to the old one to aid debugging dumps.  */
++  name = alloca (name_len);
++  strcpy (name, IDENTIFIER_POINTER (id_node));
++  strcpy (name + id_len, NEW_VAR_PREFIX);
++  info->new_var = create_tmp_var (TREE_TYPE (info->orig_var), name);
++
++  if (dump_file)
++    {
++      fprintf (dump_file, "new variable ");
++      print_generic_stmt (dump_file, info->new_var, TDF_DETAILS);
++    }
++
++  /* Inform SSA about this new variable.  */
++  create_var_ann (info->new_var);
++  mark_sym_for_renaming (info->new_var);
++  add_referenced_var (info->new_var);
++
++  /* Always continue scanning.  */
++  return 1;
++}
++
++#undef NEW_VAR_PREFIX
++
++/* Traverse the 'defuse_statements' hash table.  For every use,
++   determine if the associated variable is defined along all paths
++   leading to said use.  Remove the associated variable from
++   'static_variables' if it is not.  */
++
++static int
++check_definedness (void **slot, void *data ATTRIBUTE_UNUSED)
++{
++  struct rls_stmt_info *info = *slot;
++  struct rls_decl_info dummy;
++
++  /* We don't need to look at definitions.  Continue scanning.  */
++  if (!info->use_p)
++    return 1;
++
++  dummy.orig_var = info->var;
++  slot = htab_find_slot (static_variables, &dummy, INSERT);
++
++  /* Might not be there because we deleted it already.  */
++  if (*slot)
++    {
++      struct rls_decl_info *decl = *slot;
++
++      if (!TEST_BIT (info->defined, decl->index))
++        {
++          if (dump_file)
++            {
++              fprintf (dump_file, "not optimizing ");
++              print_generic_stmt (dump_file, decl->orig_var, TDF_DETAILS);
++              fprintf (dump_file, "due to uncovered use in ");
++              print_generic_stmt (dump_file, info->stmt, TDF_DETAILS);
++              fprintf (dump_file, "\n");
++            }
++
++          htab_clear_slot (static_variables, slot);
++          stats.n_optimizable--;
++        }
++    }
++
++  /* Continue scan.  */
++  return 1;
++}
++
++/* Check all statements in 'defuse_statements' to see if all the
++   statements that use a static variable have that variable defined
++   along all paths leading to the statement.  Once that's done, go
++   through and create new, non-static variables for any static variables
++   that can be optimized.  */
++
++static size_t
++determine_optimizable_statics (void)
++{
++  htab_traverse (defuse_statements, check_definedness, NULL);
++
++  htab_traverse (static_variables, maybe_create_new_variable, NULL);
++
++  return stats.n_optimizable;
++}
++
++/* Look at STMT to see if we have uses or defs of a static variable.
++   STMT is passed in DATA.  Definitions of a static variable are found
++   by the presence of a V_MUST_DEF, while uses are found by the presence
++   of a VUSE.  */
++
++static int
++unstaticize_variable (void **slot, void *data)
++{
++  struct rls_decl_info *info = *slot;
++  tree stmt = (tree) data;
++  tree vdef;
++  tree vuse;
++
++  /* We should have removed unoptimizable variables during an earlier
++     traversal.  */
++  gcc_assert (info->optimizable_p);
++
++  /* Check for virtual definitions first.  */
++  vdef = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_VDEF);
++
++  if (vdef != NULL
++      && ZERO_SSA_OPERANDS (stmt, SSA_OP_DEF)
++      && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
++      && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == VAR_DECL
++      && GIMPLE_STMT_OPERAND (stmt, 0) == info->orig_var)
++    {
++      /* Make the statement define the new name.  The new name has
++         already been marked for renaming, so no need to do that
++         here.  */
++      GIMPLE_STMT_OPERAND (stmt, 0) = info->new_var;
++
++      update_stmt (stmt);
++
++      /* None of the other optimizable static variables can occur
++         in this statement.  Stop the scan.  */
++      return 0;
++    }
++
++  /* Check for virtual uses.  */
++  vuse = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_VUSE);
++
++  if (vuse != NULL
++      && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
++      && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == VAR_DECL
++      && GIMPLE_STMT_OPERAND (stmt, 1) == info->orig_var)
++    {
++      /* Make the statement use the new name.  */
++      GIMPLE_STMT_OPERAND (stmt, 1) = info->new_var;
++
++      update_stmt (stmt);
++
++      /* None of the other optimizable static variables can occur
++         in this statement.  Stop the scan.  */
++      return 0;
++    }
++
++  /* Continue scanning.  */
++  return 1;
++}
++
++/* Determine if we have any static variables we can optimize.  If so,
++   replace any defs or uses of those variables in their defining/using
++   statements.  */
++
++static void
++maybe_remove_static_from_declarations (void)
++{
++  size_t n_optimizable = determine_optimizable_statics ();
++  basic_block bb;
++
++  if (n_optimizable)
++    /* Replace any optimizable variables with new, non-static variables.  */
++    FOR_EACH_BB (bb)
++      {
++        block_stmt_iterator bsi;
++
++        for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
++          {
++            tree stmt = bsi_stmt (bsi);
++
++            htab_traverse (static_variables, unstaticize_variable, stmt);
++          }
++      }
++}
++
++/* Callback for htab_traverse to initialize the bitmap for *SLOT, which
++   is a 'struct rls_stmt_info'.  */
++
++static int
++initialize_statement_dataflow (void **slot, void *data ATTRIBUTE_UNUSED)
++{
++  struct rls_stmt_info *info = *slot;
++
++  gcc_assert (!info->defined);
++
++  if (info->use_p)
++    {
++      info->defined = sbitmap_alloc (stats.n_statics);
++      /* Assume defined along all paths until otherwise informed.  */
++      sbitmap_ones (info->defined);
++    }
++
++  /* Continue traversal.  */
++  return 1;
++}
++
++/* We have N_STATICS static variables to consider.  Go through all the
++   blocks and all the use statements to initialize their bitmaps.  */
++
++static void
++initialize_block_and_statement_dataflow (size_t n_statics)
++{
++  basic_block bb;
++
++  FOR_ALL_BB (bb)
++    {
++      struct rls_block_dataflow_data *data = bb->aux;
++
++      gcc_assert (data);
++
++      data->defined_in = sbitmap_alloc (n_statics);
++      sbitmap_zero (data->defined_in);
++      data->defined_out = sbitmap_alloc (n_statics);
++      sbitmap_zero (data->defined_out);
++    }
++
++  htab_traverse (defuse_statements, initialize_statement_dataflow, NULL);
++}
++
++/* Apply the individual effects of the stmts in BB to update the
++   dataflow analysis information for BB.  */
++
++static void
++compute_definedness_for_block (basic_block bb)
++{
++  bool changed_p = false;
++  struct rls_block_dataflow_data *data = bb->aux;
++  block_stmt_iterator bsi;
++
++  sbitmap_copy (data->defined_out, data->defined_in);
++
++  for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
++    {
++      tree stmt = bsi_stmt (bsi);
++      struct rls_stmt_info dummy;
++      void **slot;
++
++      /* First see if this statement uses or defines a static variable.  */
++      dummy.stmt = stmt;
++      slot = htab_find_slot (defuse_statements, &dummy, INSERT);
++
++      /* Check for uses.  */
++      if (*slot != NULL)
++      {
++        struct rls_stmt_info *info = *slot;
++
++        gcc_assert (get_call_expr_in (stmt) == NULL_TREE);
++
++        if (info->use_p)
++          {
++            gcc_assert (info->defined);
++
++            /* Found a statement that uses a function-local static
++               variable.  Copy the current state of definedness.  */
++            sbitmap_copy (info->defined, data->defined_out);
++          }
++        else
++          {
++            struct rls_decl_info dummy;
++            struct rls_decl_info *decl;
++
++            gcc_assert (!info->defined);
++
++            /* Found a statement that defines a function-local static
++               variable.  Look up the associated variable's information
++               and mark it as defined in the block.  */
++            dummy.orig_var = info->var;
++            slot = htab_find_slot (static_variables, &dummy, INSERT);
++
++            gcc_assert (*slot);
++
++            decl = (struct rls_decl_info *) *slot;
++
++            SET_BIT (data->defined_out, decl->index);
++            changed_p |= true;
++          }
++      }
++      else if (get_call_expr_in (stmt) != NULL_TREE)
++      /* If there's a call expression in STMT, then previous passes
++         will have determined if the call transitively defines some
++         static variable.  However, we need more precise
++         information--we need to know whether static variables are
++         live out after the call.  In the absence of such information,
++         simply declare that all static variables are clobbered by the
++         call.  A better analysis would be interprocedural and compute
++         the liveness information we require, but for now, we're being
++         pessimistic.  */
++      sbitmap_zero (data->defined_out);
++    }
++}
++
++/* Solve the dataflow equations:
++
++   DEFINED_IN(b) = intersect DEFINED_OUT(p) for p in preds(b)
++   DEFINED_OUT(b) = VARIABLES_DEFINED (b, DEFINED_IN (b))
++
++   via a simple iterative solver.  VARIABLES_DEFINED is computed by
++   'compute_definedness_for_block'.  */
++
++static void
++compute_definedness (void)
++{
++  basic_block bb;
++  bool changed_p;
++  sbitmap tmp_bitmap = sbitmap_alloc (stats.n_statics);
++
++  /* Compute initial sets.  */
++  FOR_EACH_BB (bb)
++    {
++      compute_definedness_for_block (bb);
++    }
++
++  /* Iterate.  */
++  do {
++    changed_p = false;
++
++    FOR_EACH_BB (bb)
++      {
++        edge e;
++        edge_iterator ei;
++        struct rls_block_dataflow_data *data = bb->aux;
++        bool bitmap_changed_p = false;
++
++        sbitmap_ones (tmp_bitmap);
++
++        gcc_assert (data);
++
++        /* We require information about whether a variable was defined
++           over all paths leading to a particular use.  Therefore, we
++           intersect the DEFINED sets of all predecessors.  */
++        FOR_EACH_EDGE (e, ei, bb->preds)
++          {
++            struct rls_block_dataflow_data *pred_data = e->src->aux;
++
++            gcc_assert (pred_data);
++
++            sbitmap_a_and_b (tmp_bitmap, tmp_bitmap, pred_data->defined_out);
++          }
++
++        bitmap_changed_p = !sbitmap_equal (tmp_bitmap, data->defined_in);
++
++        if (bitmap_changed_p)
++          {
++            sbitmap_copy (data->defined_in, tmp_bitmap);
++            compute_definedness_for_block (bb);
++          }
++
++        changed_p |= bitmap_changed_p;
++      }
++  } while (changed_p);
++
++  sbitmap_free (tmp_bitmap);
++}
++
++static unsigned int
++execute_rls (void)
++{
++  rls_init ();
++
++  find_static_nonvolatile_declarations ();
++
++  /* Can we optimize anything?  */
++  if (stats.n_statics != 0)
++    {
++      stats.n_optimizable = stats.n_statics;
++
++      if (dump_file)
++        fprintf (dump_file, "found %d static variables to consider\n",
++                 stats.n_statics);
++
++      initialize_block_and_statement_dataflow (stats.n_statics);
++
++      compute_definedness ();
++
++      maybe_remove_static_from_declarations ();
++
++      if (dump_file)
++        fprintf (dump_file, "removed %d static variables\n",
++                 stats.n_optimizable);
++    }
++
++  rls_done ();
++
++  return 0;
++}
++
++static bool
++gate_rls (void)
++{
++  return (flag_remove_local_statics != 0
++          && !current_function_calls_setjmp
++          && !cgraph_node (current_function_decl)->ever_was_nested);
++}
++
++struct tree_opt_pass pass_remove_local_statics =
++{
++  "remlocstatic",               /* name */
++  gate_rls,                     /* gate */
++  execute_rls,                  /* execute */
++  NULL,                         /* sub */
++  NULL,                         /* next */
++  0,                            /* static_pass_number */
++  TV_TREE_RLS,                  /* tv_id */
++  PROP_cfg | PROP_ssa,          /* properties_required */
++  0,                            /* properties_provided */
++  0,                            /* properties_destroyed */
++  0,                            /* todo_flags_start */
++  TODO_dump_func | TODO_verify_ssa | TODO_verify_stmts
++  | TODO_update_ssa,                /* todo_flags_finish */
++  0                                 /* letter */
++};
+--- a/gcc/tree-ssa-sink.c
++++ b/gcc/tree-ssa-sink.c
+@@ -458,6 +458,46 @@ sink_code_in_bb (basic_block bb)
+         last = false;
+         continue;
+       }      
++
++      /* We cannot move statements that contain references to block-scope
++       variables out of that block, as this may lead to incorrect aliasing
++       when we lay out the stack frame in cfgexpand.c.
++       In lieu of more sophisticated analysis, be very conservative here
++       and prohibit moving any statement that references memory out of a
++       block with variables.  */
++      if (stmt_references_memory_p (stmt))
++      {
++        tree fromblock = TREE_BLOCK (stmt);
++        while (fromblock
++               && fromblock != current_function_decl
++               && !BLOCK_VARS (fromblock))
++          fromblock = BLOCK_SUPERCONTEXT (fromblock);
++        if (fromblock && fromblock != current_function_decl)
++          {
++            tree tostmt;
++            tree toblock;
++            if (bsi_end_p (tobsi))
++              tostmt = last_stmt (tobb);
++            else
++              tostmt = bsi_stmt (tobsi);
++            if (tostmt)
++              toblock = TREE_BLOCK (tostmt);
++            else
++              toblock = NULL;
++            while (toblock
++                   && toblock != current_function_decl
++                   && toblock != fromblock)
++              toblock = BLOCK_SUPERCONTEXT (toblock);
++            if (!toblock || toblock != fromblock)
++              {
++                if (!bsi_end_p (bsi))
++                  bsi_prev (&bsi);
++                last = false;
++                continue;
++              }
++          }
++      }
++
+       if (dump_file)
+       {
+         fprintf (dump_file, "Sinking ");
+--- a/gcc/tree-vect-transform.c
++++ b/gcc/tree-vect-transform.c
+@@ -1366,22 +1366,41 @@ vect_get_constant_vectors (slp_tree slp_
+   tree stmt = VEC_index (tree, stmts, 0);
+   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
+   tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
+-  int nunits = TYPE_VECTOR_SUBPARTS (vectype);
++  int nunits;
+   tree vec_cst;
+   tree t = NULL_TREE;
+   int j, number_of_places_left_in_vector;
+   tree vector_type;
+-  tree op, vop, operation;
++  tree op, vop;
+   int group_size = VEC_length (tree, stmts);
+   unsigned int vec_num, i;
+   int number_of_copies = 1;
+-  bool is_store = false;
+   unsigned int number_of_vectors = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
+   VEC (tree, heap) *voprnds = VEC_alloc (tree, heap, number_of_vectors);
+-  bool constant_p;
++  bool constant_p, is_store;
++  op = GIMPLE_STMT_OPERAND (stmt, 1);
+   if (STMT_VINFO_DATA_REF (stmt_vinfo))
+     is_store = true;
++  else
++    {
++      is_store = false;
++      op = TREE_OPERAND (op, op_num);
++    }
++
++  if (CONSTANT_CLASS_P (op))
++    {
++      vector_type = vectype;
++      constant_p = true;
++    }
++  else
++    {
++      vector_type = get_vectype_for_scalar_type (TREE_TYPE (op)); 
++      gcc_assert (vector_type);
++      constant_p = false;
++    }
++
++  nunits = TYPE_VECTOR_SUBPARTS (vector_type);
+   /* NUMBER_OF_COPIES is the number of times we need to use the same values in
+      created vectors. It is greater than 1 if unrolling is performed. 
+@@ -1402,18 +1421,13 @@ vect_get_constant_vectors (slp_tree slp_
+   number_of_copies = least_common_multiple (nunits, group_size) / group_size;
+   number_of_places_left_in_vector = nunits;
+-  constant_p = true;
+   for (j = 0; j < number_of_copies; j++)
+     {
+       for (i = group_size - 1; VEC_iterate (tree, stmts, i, stmt); i--)
+         {
+-          operation = GIMPLE_STMT_OPERAND (stmt, 1);
+-        if (is_store)
+-          op = operation;
+-        else
+-          op = TREE_OPERAND (operation, op_num);
+-        if (!CONSTANT_CLASS_P (op))
+-          constant_p = false;
++        op = GIMPLE_STMT_OPERAND (stmt, 1);
++        if (!STMT_VINFO_DATA_REF (stmt_vinfo))
++          op = TREE_OPERAND (op, op_num);
+           /* Create 'vect_ = {op0,op1,...,opn}'.  */
+           t = tree_cons (NULL_TREE, op, t);
+@@ -1424,16 +1438,12 @@ vect_get_constant_vectors (slp_tree slp_
+             {
+               number_of_places_left_in_vector = nunits;
+-            vector_type = get_vectype_for_scalar_type (TREE_TYPE (op));
+-              gcc_assert (vector_type);
+             if (constant_p)
+               vec_cst = build_vector (vector_type, t);
+             else
+               vec_cst = build_constructor_from_list (vector_type, t);
+-            constant_p = true;
+               VEC_quick_push (tree, voprnds,
+-                              vect_init_vector (stmt, vec_cst, vector_type,
+-                                              NULL));
++                              vect_init_vector (stmt, vec_cst, vector_type, NULL));
+               t = NULL_TREE;
+             }
+         }
+@@ -1829,7 +1839,7 @@ vect_get_vec_def_for_operand (tree op, t
+   stmt_vec_info def_stmt_info = NULL;
+   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
+   tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
+-  int nunits = TYPE_VECTOR_SUBPARTS (vectype);
++  unsigned int nunits = TYPE_VECTOR_SUBPARTS (vectype);
+   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
+   tree vec_inv;
+   tree vec_cst;
+@@ -1878,16 +1888,17 @@ vect_get_vec_def_for_operand (tree op, t
+           {
+             t = tree_cons (NULL_TREE, op, t);
+           }
+-        vector_type = get_vectype_for_scalar_type (TREE_TYPE (op));
+-        gcc_assert (vector_type);
+-        vec_cst = build_vector (vector_type, t);
+-
+-        return vect_init_vector (stmt, vec_cst, vector_type, NULL);
++        vec_cst = build_vector (vectype, t);
++        return vect_init_vector (stmt, vec_cst, vectype, NULL);
+       }
+     /* Case 2: operand is defined outside the loop - loop invariant.  */
+     case vect_invariant_def:
+       {
++      vector_type = get_vectype_for_scalar_type (TREE_TYPE (def));
++      gcc_assert (vector_type);
++      nunits = TYPE_VECTOR_SUBPARTS (vector_type);
++
+       if (scalar_def) 
+         *scalar_def = def;
+@@ -1901,8 +1912,6 @@ vect_get_vec_def_for_operand (tree op, t
+           }
+       /* FIXME: use build_constructor directly.  */
+-      vector_type = get_vectype_for_scalar_type (TREE_TYPE (def));
+-        gcc_assert (vector_type);
+         vec_inv = build_constructor_from_list (vector_type, t);
+         return vect_init_vector (stmt, vec_inv, vector_type, NULL);
+       }
+@@ -2167,6 +2176,7 @@ get_initial_def_for_reduction (tree stmt
+   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+   tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
+   int nunits =  TYPE_VECTOR_SUBPARTS (vectype);
++  tree scalar_type = TREE_TYPE (vectype);
+   enum tree_code code = TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1));
+   tree type = TREE_TYPE (init_val);
+   tree vecdef;
+@@ -2174,7 +2184,6 @@ get_initial_def_for_reduction (tree stmt
+   tree init_def;
+   tree t = NULL_TREE;
+   int i;
+-  tree vector_type;
+   bool nested_in_vect_loop = false; 
+   gcc_assert (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type) || SCALAR_FLOAT_TYPE_P (type));
+@@ -2195,15 +2204,14 @@ get_initial_def_for_reduction (tree stmt
+     else
+       *adjustment_def = init_val;
+     /* Create a vector of zeros for init_def.  */
+-    if (SCALAR_FLOAT_TYPE_P (type))
+-      def_for_init = build_real (type, dconst0);
++    if (SCALAR_FLOAT_TYPE_P (scalar_type))
++      def_for_init = build_real (scalar_type, dconst0);
+     else
+-      def_for_init = build_int_cst (type, 0);
++      def_for_init = build_int_cst (scalar_type, 0);
++      
+     for (i = nunits - 1; i >= 0; --i)
+       t = tree_cons (NULL_TREE, def_for_init, t);
+-    vector_type = get_vectype_for_scalar_type (TREE_TYPE (def_for_init));
+-    gcc_assert (vector_type);
+-    init_def = build_vector (vector_type, t);
++    init_def = build_vector (vectype, t);
+     break;
+   case MIN_EXPR:
+--- a/gcc/tree.c
++++ b/gcc/tree.c
+@@ -4031,6 +4031,7 @@ handle_dll_attribute (tree * pnode, tree
+                     bool *no_add_attrs)
+ {
+   tree node = *pnode;
++  bool is_dllimport;
+   /* These attributes may apply to structure and union types being created,
+      but otherwise should pass to the declaration involved.  */
+@@ -4078,9 +4079,11 @@ handle_dll_attribute (tree * pnode, tree
+       return NULL_TREE;
+     }
++  is_dllimport = is_attribute_p ("dllimport", name);
++
+   /* Report error on dllimport ambiguities seen now before they cause
+      any damage.  */
+-  else if (is_attribute_p ("dllimport", name))
++  if (is_dllimport)
+     {
+       /* Honor any target-specific overrides. */ 
+       if (!targetm.valid_dllimport_attribute_p (node))
+@@ -4122,6 +4125,9 @@ handle_dll_attribute (tree * pnode, tree
+       if (*no_add_attrs == false)
+         DECL_DLLIMPORT_P (node) = 1;
+     }
++  else if (DECL_DECLARED_INLINE_P (node))
++    /* An exported function, even if inline, must be emitted.  */
++    DECL_EXTERNAL (node) = 0;
+   /*  Report error if symbol is not accessible at global scope.  */
+   if (!TREE_PUBLIC (node)
+--- a/gcc/tree.h
++++ b/gcc/tree.h
+@@ -399,7 +399,10 @@ struct tree_base GTY(())
+   unsigned lang_flag_6 : 1;
+   unsigned visited : 1;
+-  unsigned spare : 23;
++  /* For tree_type.  */
++  unsigned packed_flag : 1;
++
++  unsigned spare : 22;
+   /* FIXME tuples: Eventually, we need to move this somewhere external to
+      the trees.  */
+@@ -2287,7 +2290,7 @@ struct tree_block GTY(())
+ /* Indicated that objects of this type should be laid out in as
+    compact a way as possible.  */
+-#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->type.packed_flag)
++#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->common.base.packed_flag)
+ /* Used by type_contains_placeholder_p to avoid recomputation.
+    Values are: 0 (unknown), 1 (false), 2 (true).  Never access
+@@ -2306,17 +2309,16 @@ struct tree_type GTY(())
+   tree attributes;
+   unsigned int uid;
+-  unsigned int precision : 9;
+-  ENUM_BITFIELD(machine_mode) mode : 7;
+-
+-  unsigned string_flag : 1;
++  unsigned int precision : 10;
+   unsigned no_force_blk_flag : 1;
+   unsigned needs_constructing_flag : 1;
+   unsigned transparent_union_flag : 1;
+-  unsigned packed_flag : 1;
+   unsigned restrict_flag : 1;
+   unsigned contains_placeholder_bits : 2;
++  ENUM_BITFIELD(machine_mode) mode : 7;
++  unsigned string_flag : 1;
++
+   unsigned lang_flag_0 : 1;
+   unsigned lang_flag_1 : 1;
+   unsigned lang_flag_2 : 1;
+--- a/gcc/unwind-dw2.c
++++ b/gcc/unwind-dw2.c
+@@ -1402,16 +1402,12 @@ uw_advance_context (struct _Unwind_Conte
+ /* Fill in CONTEXT for top-of-stack.  The only valid registers at this
+    level will be the return address and the CFA.  */
+-#define uw_init_context(CONTEXT)                                         \
+-  do                                                                     \
+-    {                                                                    \
+-      /* Do any necessary initialization to access arbitrary stack frames. \
+-       On the SPARC, this means flushing the register windows.  */       \
+-      __builtin_unwind_init ();                                                  \
+-      uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (),                \
+-                       __builtin_return_address (0));                    \
+-    }                                                                    \
+-  while (0)
++#define uw_init_context(CONTEXT)                                      \
++  /* Do any necessary initialization to access arbitrary stack frames.        \
++     On the SPARC, this means flushing the register windows.  */      \
++  (__builtin_unwind_init (),                                          \
++   uw_init_context_1 ((CONTEXT), __builtin_dwarf_cfa (),              \
++                    __builtin_return_address (0)))
+ static inline void
+ init_dwarf_reg_size_table (void)
+@@ -1419,7 +1415,7 @@ init_dwarf_reg_size_table (void)
+   __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
+ }
+-static void
++static _Unwind_Reason_Code
+ uw_init_context_1 (struct _Unwind_Context *context,
+                  void *outer_cfa, void *outer_ra)
+ {
+@@ -1433,7 +1429,8 @@ uw_init_context_1 (struct _Unwind_Contex
+   context->flags = EXTENDED_CONTEXT_BIT;
+   code = uw_frame_state_for (context, &fs);
+-  gcc_assert (code == _URC_NO_REASON);
++  if (code != _URC_NO_REASON)
++    return code;
+ #if __GTHREADS
+   {
+@@ -1459,6 +1456,8 @@ uw_init_context_1 (struct _Unwind_Contex
+      initialization context, then we can't see it in the given
+      call frame data.  So have the initialization context tell us.  */
+   context->ra = __builtin_extract_return_addr (outer_ra);
++
++  return _URC_NO_REASON;
+ }
+--- a/gcc/unwind-sjlj.c
++++ b/gcc/unwind-sjlj.c
+@@ -297,10 +297,11 @@ uw_advance_context (struct _Unwind_Conte
+   uw_update_context (context, fs);
+ }
+-static inline void
++static inline _Unwind_Reason_Code
+ uw_init_context (struct _Unwind_Context *context)
+ {
+   context->fc = _Unwind_SjLj_GetContext ();
++  return _URC_NO_REASON;
+ }
+ static void __attribute__((noreturn))
+--- a/gcc/unwind.inc
++++ b/gcc/unwind.inc
+@@ -90,7 +90,8 @@ _Unwind_RaiseException(struct _Unwind_Ex
+   _Unwind_Reason_Code code;
+   /* Set up this_context to describe the current stack frame.  */
+-  uw_init_context (&this_context);
++  code = uw_init_context (&this_context);
++  gcc_assert (code == _URC_NO_REASON);
+   cur_context = this_context;
+   /* Phase 1: Search.  Unwind the stack, calling the personality routine
+@@ -203,7 +204,8 @@ _Unwind_ForcedUnwind (struct _Unwind_Exc
+   struct _Unwind_Context this_context, cur_context;
+   _Unwind_Reason_Code code;
+-  uw_init_context (&this_context);
++  code = uw_init_context (&this_context);
++  gcc_assert (code == _URC_NO_REASON);
+   cur_context = this_context;
+   exc->private_1 = (_Unwind_Ptr) stop;
+@@ -226,7 +228,8 @@ _Unwind_Resume (struct _Unwind_Exception
+   struct _Unwind_Context this_context, cur_context;
+   _Unwind_Reason_Code code;
+-  uw_init_context (&this_context);
++  code = uw_init_context (&this_context);
++  gcc_assert (code == _URC_NO_REASON);
+   cur_context = this_context;
+   /* Choose between continuing to process _Unwind_RaiseException
+@@ -256,7 +259,8 @@ _Unwind_Resume_or_Rethrow (struct _Unwin
+   if (exc->private_1 == 0)
+     return _Unwind_RaiseException (exc);
+-  uw_init_context (&this_context);
++  code = uw_init_context (&this_context);
++  gcc_assert (code == _URC_NO_REASON);
+   cur_context = this_context;
+   code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
+@@ -285,7 +289,9 @@ _Unwind_Backtrace(_Unwind_Trace_Fn trace
+   struct _Unwind_Context context;
+   _Unwind_Reason_Code code;
+-  uw_init_context (&context);
++  code = uw_init_context (&context);
++  if (code != _URC_NO_REASON)
++    return _URC_FATAL_PHASE1_ERROR;
+   while (1)
+     {
+--- a/gcc/varasm.c
++++ b/gcc/varasm.c
+@@ -555,7 +555,7 @@ get_section (const char *name, unsigned 
+ static bool
+ use_object_blocks_p (void)
+ {
+-  return flag_section_anchors;
++  return flag_section_anchors && flag_toplevel_reorder;
+ }
+ /* Return the object_block structure for section SECT.  Create a new
+@@ -1095,13 +1095,12 @@ align_variable (tree decl, bool dont_out
+   /* On some machines, it is good to increase alignment sometimes.  */
+   if (! DECL_USER_ALIGN (decl))
+     {
+-#ifdef DATA_ALIGNMENT
+-      unsigned int data_align = DATA_ALIGNMENT (TREE_TYPE (decl), align);
++      unsigned int data_align =
++      calculate_global_alignment (TREE_TYPE (decl), align);
+       /* Don't increase alignment too much for TLS variables - TLS space
+        is too precious.  */
+       if (! DECL_THREAD_LOCAL_P (decl) || data_align <= BITS_PER_WORD)
+       align = data_align;
+-#endif
+ #ifdef CONSTANT_ALIGNMENT
+       if (DECL_INITIAL (decl) != 0 && DECL_INITIAL (decl) != error_mark_node)
+       {
+--- a/gcc/vmsdbgout.c
++++ b/gcc/vmsdbgout.c
+@@ -211,6 +211,7 @@ const struct gcc_debug_hooks vmsdbg_debu
+    debug_nothing_int,           /* handle_pch */
+    debug_nothing_rtx,           /* var_location */
+    debug_nothing_void,            /* switch_text_section */
++   debug_nothing_tree_tree,     /* set_name */
+    0                              /* start_end_main_source_file */
+ };
+--- a/include/libiberty.h
++++ b/include/libiberty.h
+@@ -583,6 +583,10 @@ extern int pexecute (const char *, char 
+ extern int pwait (int, int *, int);
++/* Convert a Cygwin path to a Windows path.  */
++
++extern int cygpath (const char *, char []);
++
+ #if !HAVE_DECL_ASPRINTF
+ /* Like sprintf but provides a pointer to malloc'd storage, which must
+    be freed by the caller.  */
+--- a/libcpp/Makefile.in
++++ b/libcpp/Makefile.in
+@@ -119,7 +119,7 @@ stamp-h1: $(srcdir)/config.in config.sta
+       -rm -f stamp-h1
+       $(SHELL) ./config.status config.h
+-$(srcdir)/config.in: @MAINT@ $(srcdir)/configure
++$(srcdir)/config.in: @MAINT@ $(srcdir)/configure.ac
+       cd $(srcdir) && $(AUTOHEADER)
+       -rm -f stamp-h1
+--- a/libcpp/configure
++++ b/libcpp/configure
+@@ -8311,6 +8311,7 @@ case $target in
+       sparc64*-*-* | ultrasparc-*-freebsd* | \
+       sparcv9-*-solaris2* | \
+       sparc-*-solaris2.[789] | sparc-*-solaris2.1[0-9]* | \
++      sparc-wrs-linux-gnu | \
+       spu-*-* | \
+       sh[123456789l]*-*-*)
+               need_64bit_hwint=yes ;;
+--- a/libcpp/configure.ac
++++ b/libcpp/configure.ac
+@@ -129,6 +129,7 @@ case $target in
+       sparc64*-*-* | ultrasparc-*-freebsd* | \
+       sparcv9-*-solaris2* | \
+       sparc-*-solaris2.[789] | sparc-*-solaris2.1[0-9]* | \
++      sparc-wrs-linux-gnu | \
+       spu-*-* | \
+       sh[123456789l]*-*-*)
+               need_64bit_hwint=yes ;;
+--- a/libcpp/lex.c
++++ b/libcpp/lex.c
+@@ -1240,7 +1240,7 @@ cpp_token_len (const cpp_token *token)
+   switch (TOKEN_SPELL (token))
+     {
+-    default:          len = 4;                                break;
++    default:          len = 6;                                break;
+     case SPELL_LITERAL:       len = token->val.str.len;               break;
+     case SPELL_IDENT: len = NODE_LEN (token->val.node) * 10;  break;
+     }
+--- a/libffi/Makefile.am
++++ b/libffi/Makefile.am
+@@ -156,7 +156,9 @@ nodist_libffi_convenience_la_SOURCES = $
+ AM_CFLAGS = -Wall -g -fexceptions
+-libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version`
++LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
++
++libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS)
+ AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
+ AM_CCASFLAGS = $(AM_CPPFLAGS)
+--- a/libffi/Makefile.in
++++ b/libffi/Makefile.in
+@@ -439,7 +439,8 @@ nodist_libffi_la_SOURCES = $(am__append_
+ libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
+ nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
+ AM_CFLAGS = -Wall -g -fexceptions
+-libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version`
++LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
++libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS)
+ AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
+ AM_CCASFLAGS = $(AM_CPPFLAGS)
+ all: fficonfig.h
+--- a/libgcc/Makefile.in
++++ b/libgcc/Makefile.in
+@@ -388,18 +388,24 @@ libgcc-s-objects += $(patsubst %,%_s$(ob
+ endif
+ endif
++ifeq ($(LIB2_DIVMOD_EXCEPTION_FLAGS),)
++# Provide default flags for compiling divmod functions, if they haven't been
++# set already by a target-specific Makefile fragment.
++LIB2_DIVMOD_EXCEPTION_FLAGS := -fexceptions -fnon-call-exceptions
++endif
++
+ # Build LIB2_DIVMOD_FUNCS.
+ lib2-divmod-o = $(patsubst %,%$(objext),$(LIB2_DIVMOD_FUNCS))
+ $(lib2-divmod-o): %$(objext): $(gcc_srcdir)/libgcc2.c
+       $(gcc_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \
+-        -fexceptions -fnon-call-exceptions $(vis_hide)
++        $(LIB2_DIVMOD_EXCEPTION_FLAGS) $(vis_hide)
+ libgcc-objects += $(lib2-divmod-o)
+ ifeq ($(enable_shared),yes)
+ lib2-divmod-s-o = $(patsubst %,%_s$(objext),$(LIB2_DIVMOD_FUNCS))
+ $(lib2-divmod-s-o): %_s$(objext): $(gcc_srcdir)/libgcc2.c
+       $(gcc_s_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \
+-        -fexceptions -fnon-call-exceptions
++        $(LIB2_DIVMOD_EXCEPTION_FLAGS)
+ libgcc-s-objects += $(lib2-divmod-s-o)
+ endif
+--- a/libgcc/config.host
++++ b/libgcc/config.host
+@@ -223,12 +223,15 @@ arm*-*-netbsdelf*)
+ arm*-*-netbsd*)
+       ;;
+ arm*-*-linux*)                        # ARM GNU/Linux with ELF
++      tmake_file="${tmake_file} arm/t-divmod-ef"
+       ;;
+ arm*-*-uclinux*)              # ARM ucLinux
++      tmake_file="${tmake_file} arm/t-divmod-ef"
+       ;;
+ arm*-*-ecos-elf)
+       ;;
+ arm*-*-eabi* | arm*-*-symbianelf* )
++      tmake_file="${tmake_file} arm/t-divmod-ef"
+       ;;
+ arm*-*-rtems*)
+       ;;
+@@ -438,8 +441,12 @@ mips-sgi-irix[56]*)
+ mips*-*-netbsd*)                      # NetBSD/mips, either endian.
+       ;;
+ mips64*-*-linux*)
++      extra_parts="$extra_parts crtfastmath.o"
++      tmake_file="{$tmake_file} mips/t-crtfm"
+       ;;
+ mips*-*-linux*)                               # Linux MIPS, either endian.
++      extra_parts="$extra_parts crtfastmath.o"
++      tmake_file="{$tmake_file} mips/t-crtfm"
+       ;;
+ mips*-*-openbsd*)
+       ;;
+@@ -461,6 +468,10 @@ mips64vr-*-elf* | mips64vrel-*-elf*)
+         ;;
+ mips64orion-*-elf* | mips64orionel-*-elf*)
+       ;;
++mips64octeon-wrs-elf* | mips64octeonel-wrs-elf*)
++      ;;
++mips64octeon-montavista-elf*)
++      ;;
+ mips*-*-rtems*)
+       ;;
+ mips-wrs-vxworks)
+--- /dev/null
++++ b/libgcc/config/arm/t-divmod-ef
+@@ -0,0 +1,4 @@
++# On ARM, specifying -fnon-call-exceptions will needlessly pull in
++# the unwinder in simple programs which use 64-bit division.  Omitting
++# the option is safe.
++LIB2_DIVMOD_EXCEPTION_FLAGS := -fexceptions
+--- /dev/null
++++ b/libgcc/config/mips/t-crtfm
+@@ -0,0 +1,3 @@
++crtfastmath.o: $(gcc_srcdir)/config/mips/crtfastmath.c
++      $(gcc_compile) -c $(gcc_srcdir)/config/mips/crtfastmath.c
++
+--- a/libgcc/config/rs6000/t-ppccomm
++++ b/libgcc/config/rs6000/t-ppccomm
+@@ -1,5 +1,21 @@
+-EXTRA_PARTS += ecrti$(objext) ecrtn$(objext) ncrti$(objext) ncrtn$(objext) \
+-  crtsavres$(objext)
++LIB2ADD_ST += crtsavfpr.S crtresfpr.S \
++  crtsavgpr.S crtresgpr.S \
++  crtresxfpr.S crtresxgpr.S \
++  e500crtres32gpr.S \
++  e500crtres64gpr.S \
++  e500crtres64gprctr.S \
++  e500crtrest32gpr.S \
++  e500crtrest64gpr.S \
++  e500crtresx32gpr.S \
++  e500crtresx64gpr.S \
++  e500crtsav32gpr.S \
++  e500crtsav64gpr.S \
++  e500crtsav64gprctr.S \
++  e500crtsavg32gpr.S \
++  e500crtsavg64gpr.S \
++  e500crtsavg64gprctr.S
++
++EXTRA_PARTS += ecrti$(objext) ecrtn$(objext) ncrti$(objext) ncrtn$(objext)
+ # We build {e,n}crti.o and {e,n}crtn.o, which serve to add begin and
+ # end labels to all of the special sections used when we link using gcc.
+@@ -17,8 +33,62 @@ ncrti.S: $(gcc_srcdir)/config/rs6000/sol
+ ncrtn.S: $(gcc_srcdir)/config/rs6000/sol-cn.asm
+       cat $(gcc_srcdir)/config/rs6000/sol-cn.asm >ncrtn.S
+-crtsavres.S: $(gcc_srcdir)/config/rs6000/crtsavres.asm
+-      cat $(gcc_srcdir)/config/rs6000/crtsavres.asm >crtsavres.S
++crtsavfpr.S: $(gcc_srcdir)/config/rs6000/crtsavfpr.asm
++      cat $(gcc_srcdir)/config/rs6000/crtsavfpr.asm >crtsavfpr.S
++
++crtresfpr.S: $(gcc_srcdir)/config/rs6000/crtresfpr.asm
++      cat $(gcc_srcdir)/config/rs6000/crtresfpr.asm >crtresfpr.S
++
++crtsavgpr.S: $(gcc_srcdir)/config/rs6000/crtsavgpr.asm
++      cat $(gcc_srcdir)/config/rs6000/crtsavgpr.asm >crtsavgpr.S
++
++crtresgpr.S: $(gcc_srcdir)/config/rs6000/crtresgpr.asm
++      cat $(gcc_srcdir)/config/rs6000/crtresgpr.asm >crtresgpr.S
++
++crtresxfpr.S: $(gcc_srcdir)/config/rs6000/crtresxfpr.asm
++      cat $(gcc_srcdir)/config/rs6000/crtresxfpr.asm >crtresxfpr.S
++
++crtresxgpr.S: $(gcc_srcdir)/config/rs6000/crtresxgpr.asm
++      cat $(gcc_srcdir)/config/rs6000/crtresxgpr.asm >crtresxgpr.S
++
++e500crtres32gpr.S: $(gcc_srcdir)/config/rs6000/e500crtres32gpr.asm
++      cat $(gcc_srcdir)/config/rs6000/e500crtres32gpr.asm >e500crtres32gpr.S
++
++e500crtres64gpr.S: $(gcc_srcdir)/config/rs6000/e500crtres64gpr.asm
++      cat $(gcc_srcdir)/config/rs6000/e500crtres64gpr.asm >e500crtres64gpr.S
++
++e500crtres64gprctr.S: $(gcc_srcdir)/config/rs6000/e500crtres64gprctr.asm
++      cat $(gcc_srcdir)/config/rs6000/e500crtres64gprctr.asm >e500crtres64gprctr.S
++
++e500crtrest32gpr.S: $(gcc_srcdir)/config/rs6000/e500crtrest32gpr.asm
++      cat $(gcc_srcdir)/config/rs6000/e500crtrest32gpr.asm >e500crtrest32gpr.S
++
++e500crtrest64gpr.S: $(gcc_srcdir)/config/rs6000/e500crtrest64gpr.asm
++      cat $(gcc_srcdir)/config/rs6000/e500crtrest64gpr.asm >e500crtrest64gpr.S
++
++e500crtresx32gpr.S: $(gcc_srcdir)/config/rs6000/e500crtresx32gpr.asm
++      cat $(gcc_srcdir)/config/rs6000/e500crtresx32gpr.asm >e500crtresx32gpr.S
++
++e500crtresx64gpr.S: $(gcc_srcdir)/config/rs6000/e500crtresx64gpr.asm
++      cat $(gcc_srcdir)/config/rs6000/e500crtresx64gpr.asm >e500crtresx64gpr.S
++
++e500crtsav32gpr.S: $(gcc_srcdir)/config/rs6000/e500crtsav32gpr.asm
++      cat $(gcc_srcdir)/config/rs6000/e500crtsav32gpr.asm >e500crtsav32gpr.S
++
++e500crtsav64gpr.S: $(gcc_srcdir)/config/rs6000/e500crtsav64gpr.asm
++      cat $(gcc_srcdir)/config/rs6000/e500crtsav64gpr.asm >e500crtsav64gpr.S
++
++e500crtsav64gprctr.S: $(gcc_srcdir)/config/rs6000/e500crtsav64gprctr.asm
++      cat $(gcc_srcdir)/config/rs6000/e500crtsav64gprctr.asm >e500crtsav64gprctr.S
++
++e500crtsavg32gpr.S: $(gcc_srcdir)/config/rs6000/e500crtsavg32gpr.asm
++      cat $(gcc_srcdir)/config/rs6000/e500crtsavg32gpr.asm >e500crtsavg32gpr.S
++
++e500crtsavg64gpr.S: $(gcc_srcdir)/config/rs6000/e500crtsavg64gpr.asm
++      cat $(gcc_srcdir)/config/rs6000/e500crtsavg64gpr.asm >e500crtsavg64gpr.S
++
++e500crtsavg64gprctr.S: $(gcc_srcdir)/config/rs6000/e500crtsavg64gprctr.asm
++      cat $(gcc_srcdir)/config/rs6000/e500crtsavg64gprctr.asm >e500crtsavg64gprctr.S
+ ecrti$(objext): ecrti.S
+       $(crt_compile) -c ecrti.S
+@@ -34,3 +104,60 @@ ncrtn$(objext): ncrtn.S
+ crtsavres$(objext): crtsavres.S
+       $(crt_compile) -c crtsavres.S
++
++crtsavfpr$(objext): crtsavfpr.S
++      $(crt_compile) -c crtsavfpr.S
++
++crtresfpr$(objext): crtresfpr.S
++      $(crt_compile) -c crtresfpr.S
++
++crtsavgpr$(objext): crtsavgpr.S
++      $(crt_compile) -c crtsavgpr.S
++
++crtresgpr$(objext): crtresgpr.S
++      $(crt_compile) -c crtresgpr.S
++
++crtresxfpr$(objext): crtresxfpr.S
++      $(crt_compile) -c crtresxfpr.S
++
++crtresxgpr$(objext): crtresxgpr.S
++      $(crt_compile) -c crtresxgpr.S
++
++e500crtres32gpr$(objext): e500crtres32gpr.S
++      $(crt_compile) -c e500crtres32gpr.S
++
++e500crtres64gpr$(objext): e500crtres64gpr.S
++      $(crt_compile) -c e500crtres64gpr.S
++
++e500crtres64gprctr$(objext): e500crtres64gprctr.S
++      $(crt_compile) -c e500crtres64gprctr.S
++
++e500crtrest32gpr$(objext): e500crtrest32gpr.S
++      $(crt_compile) -c e500crtrest32gpr.S
++
++e500crtrest64gpr$(objext): e500crtrest64gpr.S
++      $(crt_compile) -c e500crtrest64gpr.S
++
++e500crtresx32gpr$(objext): e500crtresx32gpr.S
++      $(crt_compile) -c e500crtresx32gpr.S
++
++e500crtresx64gpr$(objext): e500crtresx64gpr.S
++      $(crt_compile) -c e500crtresx64gpr.S
++
++e500crtsav32gpr$(objext): e500crtsav32gpr.S
++      $(crt_compile) -c e500crtsav32gpr.S
++
++e500crtsav64gpr$(objext): e500crtsav64gpr.S
++      $(crt_compile) -c e500crtsav64gpr.S
++
++e500crtsav64gprctr$(objext): e500crtsav64gprctr.S
++      $(crt_compile) -c e500crtsav64gprctr.S
++
++e500crtsavg32gpr$(objext): e500crtsavg32gpr.S
++      $(crt_compile) -c e500crtsavg32gpr.S
++
++e500crtsavg64gpr$(objext): e500crtsavg64gpr.S
++      $(crt_compile) -c e500crtsavg64gpr.S
++
++e500crtsavg64gprctr$(objext): e500crtsavg64gprctr.S
++      $(crt_compile) -c e500crtsavg64gprctr.S
+--- a/libgcc/shared-object.mk
++++ b/libgcc/shared-object.mk
+@@ -8,11 +8,13 @@ base := $(basename $(notdir $o))
+ ifeq ($(suffix $o),.c)
++c_flags-$(base)$(objext) := $(c_flags)
+ $(base)$(objext): $o
+-      $(gcc_compile) $(c_flags) -c $< $(vis_hide)
++      $(gcc_compile) $(c_flags-$@) -c $< $(vis_hide)
++c_flags-$(base)_s$(objext) := $(c_flags)
+ $(base)_s$(objext): $o
+-      $(gcc_s_compile) $(c_flags) -c $<
++      $(gcc_s_compile) $(c_flags-$@) -c $<
+ else
+--- a/libgcc/static-object.mk
++++ b/libgcc/static-object.mk
+@@ -8,8 +8,9 @@ base := $(basename $(notdir $o))
+ ifeq ($(suffix $o),.c)
++c_flags-$(base)$(objext) := $(c_flags)
+ $(base)$(objext): $o
+-      $(gcc_compile) $(c_flags) -c $< $(vis_hide)
++      $(gcc_compile) $(c_flags-$@) -c $< $(vis_hide)
+ else
+--- a/libgomp/Makefile.am
++++ b/libgomp/Makefile.am
+@@ -1,5 +1,10 @@
+ ## Process this file with automake to produce Makefile.in
++datarootdir = @datarootdir@
++docdir = @docdir@
++htmldir = @htmldir@
++pdfdir = @pdfdir@
++
+ ACLOCAL_AMFLAGS = -I .. -I ../config
+ SUBDIRS = testsuite
+@@ -39,6 +44,12 @@ if USE_FORTRAN
+ nodist_finclude_HEADERS = omp_lib.h omp_lib.f90 omp_lib.mod omp_lib_kinds.mod
+ endif
++LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
++
++LINK = $(LIBTOOL) --tag CC --mode=link $(CCLD) $(AM_CCFLAGS) $(CFLAGS) \
++      $(AM_LDFLAGS) $(LTLDFLAGS) -o $@
++
++
+ omp_lib_kinds.mod: omp_lib.mod
+       :
+ omp_lib.mod: omp_lib.f90
+@@ -48,10 +59,31 @@ fortran.o: libgomp_f.h
+ env.lo: libgomp_f.h
+ env.o: libgomp_f.h
++HTMLS_INSTALL=libgomp
++HTMLS_BUILD=libgomp/index.html
+-# No install-html or install-pdf support in automake yet
+-.PHONY: install-html install-pdf
+-install-html:
++$(HTMLS_BUILD): $(info_TEXINFOS)
++      $(TEXI2HTML) $(MAKEINFOFLAGS) -I$(srcdir) -o $(@D) $<
++
++html__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
++
++install-data-local: install-html
++install-html: $(HTMLS_BUILD)
++      @$(NORMAL_INSTALL)
++      test -z "$(htmldir)" || $(mkinstalldirs) "$(DESTDIR)$(htmldir)"
++      @list='$(HTMLS_INSTALL)'; for p in $$list; do \
++        if test -f "$$p" || test -d "$$p"; then d=""; else d="$(srcdir)/"; fi; \
++        f=$(html__strip_dir) \
++        if test -d "$$d$$p"; then \
++          echo " $(mkinstalldirs) '$(DESTDIR)$(htmldir)/$$f'"; \
++          $(mkinstalldirs) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
++          echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \
++          $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f"; \
++        else \
++          echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'"; \
++          $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(htmldir)/$$f"; \
++        fi; \
++      done
+ install-pdf: $(PDFS)
+       @$(NORMAL_INSTALL)
+@@ -69,6 +101,7 @@ install-pdf: $(PDFS)
+ # `texinfo.tex' for your package. The value of this variable should be
+ # the relative path from the current `Makefile.am' to `texinfo.tex'.
+ TEXINFO_TEX   = ../gcc/doc/include/texinfo.tex
++TEXI2HTML = $(MAKEINFO) --html
+ # Defines info, dvi, pdf and html targets
+ MAKEINFOFLAGS = -I $(srcdir)/../gcc/doc/include
+--- a/libgomp/Makefile.in
++++ b/libgomp/Makefile.in
+@@ -94,8 +94,6 @@ LTCOMPILE = $(LIBTOOL) --tag=CC --mode=c
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(CFLAGS)
+ CCLD = $(CC)
+-LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+-      $(AM_LDFLAGS) $(LDFLAGS) -o $@
+ SOURCES = $(libgomp_la_SOURCES)
+ DIST_SOURCES = $(libgomp_la_SOURCES)
+ MULTISRCTOP = 
+@@ -217,9 +215,12 @@ USE_FORTRAN_TRUE = @USE_FORTRAN_TRUE@
+ VERSION = @VERSION@
+ XCFLAGS = @XCFLAGS@
+ XLDFLAGS = @XLDFLAGS@
++ac_ct_AR = @ac_ct_AR@
+ ac_ct_CC = @ac_ct_CC@
+ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ ac_ct_FC = @ac_ct_FC@
++ac_ct_RANLIB = @ac_ct_RANLIB@
++ac_ct_STRIP = @ac_ct_STRIP@
+ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+ am__include = @am__include@
+@@ -237,7 +238,6 @@ config_path = @config_path@
+ datadir = @datadir@
+ datarootdir = @datarootdir@
+ docdir = @docdir@
+-dvidir = @dvidir@
+ enable_shared = @enable_shared@
+ enable_static = @enable_static@
+ exec_prefix = @exec_prefix@
+@@ -254,7 +254,6 @@ libdir = @libdir@
+ libexecdir = @libexecdir@
+ libtool_VERSION = @libtool_VERSION@
+ link_gomp = @link_gomp@
+-localedir = @localedir@
+ localstatedir = @localstatedir@
+ lt_ECHO = @lt_ECHO@
+ mandir = @mandir@
+@@ -264,7 +263,6 @@ oldincludedir = @oldincludedir@
+ pdfdir = @pdfdir@
+ prefix = @prefix@
+ program_transform_name = @program_transform_name@
+-psdir = @psdir@
+ sbindir = @sbindir@
+ sharedstatedir = @sharedstatedir@
+ sysconfdir = @sysconfdir@
+@@ -297,6 +295,13 @@ libgomp_la_SOURCES = alloc.c barrier.c c
+ nodist_noinst_HEADERS = libgomp_f.h
+ nodist_libsubinclude_HEADERS = omp.h
+ @USE_FORTRAN_TRUE@nodist_finclude_HEADERS = omp_lib.h omp_lib.f90 omp_lib.mod omp_lib_kinds.mod
++LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
++LINK = $(LIBTOOL) --tag CC --mode=link $(CCLD) $(AM_CCFLAGS) $(CFLAGS) \
++      $(AM_LDFLAGS) $(LTLDFLAGS) -o $@
++
++HTMLS_INSTALL = libgomp
++HTMLS_BUILD = libgomp/index.html
++html__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+ # Automake Documentation:
+ # If your package has Texinfo files in many directories, you can use the
+@@ -304,6 +309,7 @@ nodist_libsubinclude_HEADERS = omp.h
+ # `texinfo.tex' for your package. The value of this variable should be
+ # the relative path from the current `Makefile.am' to `texinfo.tex'.
+ TEXINFO_TEX = ../gcc/doc/include/texinfo.tex
++TEXI2HTML = $(MAKEINFO) --html
+ # Defines info, dvi, pdf and html targets
+ MAKEINFOFLAGS = -I $(srcdir)/../gcc/doc/include
+@@ -545,13 +551,10 @@ dist-info: $(INFO_DEPS)
+           $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
+         esac; \
+         if test -f $$base; then d=.; else d=$(srcdir); fi; \
+-        base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \
+-        for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \
+-          if test -f $$file; then \
+-            relfile=`expr "$$file" : "$$d/\(.*\)"`; \
+-            test -f $(distdir)/$$relfile || \
+-              cp -p $$file $(distdir)/$$relfile; \
+-          else :; fi; \
++        for file in $$d/$$base*; do \
++          relfile=`expr "$$file" : "$$d/\(.*\)"`; \
++          test -f $(distdir)/$$relfile || \
++            cp -p $$file $(distdir)/$$relfile; \
+         done; \
+       done
+@@ -955,7 +958,8 @@ info: info-recursive
+ info-am: $(INFO_DEPS)
+-install-data-am: install-info-am install-nodist_fincludeHEADERS \
++install-data-am: install-data-local install-info-am \
++      install-nodist_fincludeHEADERS \
+       install-nodist_libsubincludeHEADERS
+ install-exec-am: install-multi install-nodist_toolexeclibHEADERS \
+@@ -1035,9 +1039,9 @@ uninstall-info: uninstall-info-recursive
+       distclean-multi distclean-recursive distclean-tags \
+       distcleancheck distdir distuninstallcheck dvi dvi-am html \
+       html-am info info-am install install-am install-data \
+-      install-data-am install-exec install-exec-am install-info \
+-      install-info-am install-man install-multi \
+-      install-nodist_fincludeHEADERS \
++      install-data-am install-data-local install-exec \
++      install-exec-am install-info install-info-am install-man \
++      install-multi install-nodist_fincludeHEADERS \
+       install-nodist_libsubincludeHEADERS \
+       install-nodist_toolexeclibHEADERS install-strip \
+       install-toolexeclibLTLIBRARIES installcheck installcheck-am \
+@@ -1064,9 +1068,26 @@ fortran.o: libgomp_f.h
+ env.lo: libgomp_f.h
+ env.o: libgomp_f.h
+-# No install-html or install-pdf support in automake yet
+-.PHONY: install-html install-pdf
+-install-html:
++$(HTMLS_BUILD): $(info_TEXINFOS)
++      $(TEXI2HTML) $(MAKEINFOFLAGS) -I$(srcdir) -o $(@D) $<
++
++install-data-local: install-html
++install-html: $(HTMLS_BUILD)
++      @$(NORMAL_INSTALL)
++      test -z "$(htmldir)" || $(mkinstalldirs) "$(DESTDIR)$(htmldir)"
++      @list='$(HTMLS_INSTALL)'; for p in $$list; do \
++        if test -f "$$p" || test -d "$$p"; then d=""; else d="$(srcdir)/"; fi; \
++        f=$(html__strip_dir) \
++        if test -d "$$d$$p"; then \
++          echo " $(mkinstalldirs) '$(DESTDIR)$(htmldir)/$$f'"; \
++          $(mkinstalldirs) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
++          echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \
++          $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f"; \
++        else \
++          echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'"; \
++          $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(htmldir)/$$f"; \
++        fi; \
++      done
+ install-pdf: $(PDFS)
+       @$(NORMAL_INSTALL)
+--- /dev/null
++++ b/libgomp/config/linux/mips/futex.h
+@@ -0,0 +1,75 @@
++/* Copyright (C) 2005, 2008 Free Software Foundation, Inc.
++   Contributed by Ilie Garbacea <ilie@mips.com>, Chao-ying Fu <fu@mips.com>.
++
++   This file is part of the GNU OpenMP Library (libgomp).
++
++   Libgomp is free software; you can redistribute it and/or modify it
++   under the terms of the GNU Lesser General Public License as published by
++   the Free Software Foundation; either version 2.1 of the License, or
++   (at your option) any later version.
++
++   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
++   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
++   more details.
++
++   You should have received a copy of the GNU Lesser General Public License 
++   along with libgomp; see the file COPYING.LIB.  If not, write to the
++   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
++   MA 02110-1301, USA.  */
++
++/* As a special exception, if you link this library with other files, some
++   of which are compiled with GCC, to produce an executable, this library
++   does not by itself cause the resulting executable to be covered by the
++   GNU General Public License.  This exception does not however invalidate
++   any other reasons why the executable file might be covered by the GNU
++   General Public License.  */
++
++/* Provide target-specific access to the futex system call.  */
++
++#include <sys/syscall.h>
++#define FUTEX_WAIT 0
++#define FUTEX_WAKE 1
++
++static inline void
++sys_futex0 (int *addr, int op, int val)
++{
++  register unsigned long __v0 asm("$2") = (unsigned long) SYS_futex;
++  register unsigned long __a0 asm("$4") = (unsigned long) addr;
++  register unsigned long __a1 asm("$5") = (unsigned long) op;
++  register unsigned long __a2 asm("$6") = (unsigned long) val;
++  register unsigned long __a3 asm("$7") = 0;
++
++  __asm volatile ("syscall"
++                /* returns $a3 (errno), $v0 (return value) */
++                : "=r" (__v0), "=r" (__a3)
++                /* arguments in v0 (syscall) a0-a3 */
++                : "r" (__v0), "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a3)
++                /* clobbers at, v1, t0-t9, memory */
++                : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14",
++                  "$15", "$24", "$25", "memory");
++}
++
++static inline void
++futex_wait (int *addr, int val)
++{
++  sys_futex0 (addr, FUTEX_WAIT, val);
++}
++
++static inline void
++futex_wake (int *addr, int count)
++{
++  sys_futex0 (addr, FUTEX_WAKE, count);
++}
++
++static inline void
++cpu_relax (void)
++{
++  __asm volatile ("" : : : "memory");
++}
++
++static inline void
++atomic_write_barrier (void)
++{
++  __sync_synchronize ();
++}
+--- a/libgomp/configure
++++ b/libgomp/configure
+@@ -457,7 +457,7 @@ ac_includes_default="\
+ # include <unistd.h>
+ #endif"
+-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS GENINSRC_TRUE GENINSRC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar multi_basedir toolexecdir toolexeclibdir CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CFLAGS AR ac_ct_AR RANLIB ac_ct_RANLIB PERL BUILD_INFO_TRUE BUILD_INFO_FALSE LIBTOOL SED EGREP FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S lt_ECHO CPP CPPFLAGS enable_shared enable_static MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT FC FCFLAGS LDFLAGS ac_ct_FC libtool_VERSION SECTION_LDFLAGS OPT_LDFLAGS LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE LIBGOMP_BUILD_VERSIONED_SHLIB_FALSE config_path XCFLAGS XLDFLAGS link_gomp USE_FORTRAN_TRUE USE_FORTRAN_FALSE OMP_LOCK_SIZE OMP_LOCK_ALIGN OMP_NEST_LOCK_SIZE OMP_NEST_LOCK_ALIGN OMP_LOCK_KIND OMP_NEST_LOCK_KIND LIBOBJS LTLIBOBJS'
++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS GENINSRC_TRUE GENINSRC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar multi_basedir toolexecdir toolexeclibdir datarootdir docdir pdfdir htmldir CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CFLAGS AR ac_ct_AR RANLIB ac_ct_RANLIB PERL BUILD_INFO_TRUE BUILD_INFO_FALSE LIBTOOL SED EGREP FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S lt_ECHO CPP CPPFLAGS enable_shared enable_static MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT FC FCFLAGS LDFLAGS ac_ct_FC libtool_VERSION SECTION_LDFLAGS OPT_LDFLAGS LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE LIBGOMP_BUILD_VERSIONED_SHLIB_FALSE config_path XCFLAGS XLDFLAGS link_gomp USE_FORTRAN_TRUE USE_FORTRAN_FALSE OMP_LOCK_SIZE OMP_LOCK_ALIGN OMP_NEST_LOCK_SIZE OMP_NEST_LOCK_ALIGN OMP_LOCK_KIND OMP_NEST_LOCK_KIND LIBOBJS LTLIBOBJS'
+ ac_subst_files=''
+ # Initialize some variables set by options.
+@@ -1028,6 +1028,10 @@ Optional Features:
+ Optional Packages:
+   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
++  --with-datarootdir=DIR  Use DIR as the data root [PREFIX/share]
++  --with-docdir=DIR       Install documentation in DIR [DATAROOTDIR]
++  --with-pdfdir           install pdf in this directory.
++  --with-htmldir=DIR      html documentation in in DIR [DOCDIR]
+   --with-pic              try to use only PIC/non-PIC objects [default=use
+                           both]
+   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+@@ -2174,6 +2178,46 @@ esac
++
++# Check whether --with-datarootdir or --without-datarootdir was given.
++if test "${with_datarootdir+set}" = set; then
++  withval="$with_datarootdir"
++  datarootdir="\${prefix}/$with_datarootdir"
++else
++  datarootdir='$(prefix)/share'
++fi;
++
++
++
++# Check whether --with-docdir or --without-docdir was given.
++if test "${with_docdir+set}" = set; then
++  withval="$with_docdir"
++  docdir="\${prefix}/$with_docdir"
++else
++  docdir='$(datarootdir)'
++fi;
++
++
++
++# Check whether --with-pdfdir or --without-pdfdir was given.
++if test "${with_pdfdir+set}" = set; then
++  withval="$with_pdfdir"
++  pdfdir="\${prefix}/${withval}"
++else
++  pdfdir="\${docdir}"
++fi;
++
++
++
++# Check whether --with-htmldir or --without-htmldir was given.
++if test "${with_htmldir+set}" = set; then
++  withval="$with_htmldir"
++  htmldir="\${prefix}/$with_htmldir"
++else
++  htmldir='$(docdir)'
++fi;
++
++
+ # Check the compiler.
+ # The same as in boehm-gc and libstdc++. Have to borrow it from there.
+ # We must force CC to /not/ be precious variables; otherwise
+@@ -4219,13 +4263,13 @@ if test "${lt_cv_nm_interface+set}" = se
+ else
+   lt_cv_nm_interface="BSD nm"
+   echo "int some_variable = 0;" > conftest.$ac_ext
+-  (eval echo "\"\$as_me:4242: $ac_compile\"" >&5)
++  (eval echo "\"\$as_me:4266: $ac_compile\"" >&5)
+   (eval "$ac_compile" 2>conftest.err)
+   cat conftest.err >&5
+-  (eval echo "\"\$as_me:4245: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
++  (eval echo "\"\$as_me:4269: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+   cat conftest.err >&5
+-  (eval echo "\"\$as_me:4248: output\"" >&5)
++  (eval echo "\"\$as_me:4272: output\"" >&5)
+   cat conftest.out >&5
+   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+     lt_cv_nm_interface="MS dumpbin"
+@@ -5281,7 +5325,7 @@ ia64-*-hpux*)
+   ;;
+ *-*-irix6*)
+   # Find out which ABI we are using.
+-  echo '#line 5304 "configure"' > conftest.$ac_ext
++  echo '#line 5328 "configure"' > conftest.$ac_ext
+   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+   (eval $ac_compile) 2>&5
+   ac_status=$?
+@@ -6381,11 +6425,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:6404: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:6428: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>conftest.err)
+    ac_status=$?
+    cat conftest.err >&5
+-   echo "$as_me:6408: \$? = $ac_status" >&5
++   echo "$as_me:6432: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s "$ac_outfile"; then
+      # The compiler can only warn and ignore the option if not recognized
+      # So say no if there are warnings other than the usual output.
+@@ -6703,11 +6747,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:6726: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:6750: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>conftest.err)
+    ac_status=$?
+    cat conftest.err >&5
+-   echo "$as_me:6730: \$? = $ac_status" >&5
++   echo "$as_me:6754: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s "$ac_outfile"; then
+      # The compiler can only warn and ignore the option if not recognized
+      # So say no if there are warnings other than the usual output.
+@@ -6808,11 +6852,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:6831: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:6855: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>out/conftest.err)
+    ac_status=$?
+    cat out/conftest.err >&5
+-   echo "$as_me:6835: \$? = $ac_status" >&5
++   echo "$as_me:6859: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s out/conftest2.$ac_objext
+    then
+      # The compiler can only warn and ignore the option if not recognized
+@@ -6863,11 +6907,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:6886: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:6910: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>out/conftest.err)
+    ac_status=$?
+    cat out/conftest.err >&5
+-   echo "$as_me:6890: \$? = $ac_status" >&5
++   echo "$as_me:6914: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s out/conftest2.$ac_objext
+    then
+      # The compiler can only warn and ignore the option if not recognized
+@@ -9660,7 +9704,7 @@ else
+   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+   lt_status=$lt_dlunknown
+   cat > conftest.$ac_ext <<_LT_EOF
+-#line 9683 "configure"
++#line 9707 "configure"
+ #include "confdefs.h"
+ #if HAVE_DLFCN_H
+@@ -9760,7 +9804,7 @@ else
+   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+   lt_status=$lt_dlunknown
+   cat > conftest.$ac_ext <<_LT_EOF
+-#line 9783 "configure"
++#line 9807 "configure"
+ #include "confdefs.h"
+ #if HAVE_DLFCN_H
+@@ -10115,7 +10159,7 @@ fi
+ # Provide some information about the compiler.
+-echo "$as_me:10138:" \
++echo "$as_me:10162:" \
+      "checking for Fortran compiler version" >&5
+ ac_compiler=`set X $ac_compile; echo $2`
+ { (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+@@ -10351,7 +10395,7 @@ fi
+ # Provide some information about the compiler.
+-echo "$as_me:10374:" \
++echo "$as_me:10398:" \
+      "checking for Fortran compiler version" >&5
+ ac_compiler=`set X $ac_compile; echo $2`
+ { (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+@@ -11067,11 +11111,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:11090: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:11114: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>conftest.err)
+    ac_status=$?
+    cat conftest.err >&5
+-   echo "$as_me:11094: \$? = $ac_status" >&5
++   echo "$as_me:11118: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s "$ac_outfile"; then
+      # The compiler can only warn and ignore the option if not recognized
+      # So say no if there are warnings other than the usual output.
+@@ -11166,11 +11210,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:11189: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:11213: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>out/conftest.err)
+    ac_status=$?
+    cat out/conftest.err >&5
+-   echo "$as_me:11193: \$? = $ac_status" >&5
++   echo "$as_me:11217: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s out/conftest2.$ac_objext
+    then
+      # The compiler can only warn and ignore the option if not recognized
+@@ -11218,11 +11262,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:11241: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:11265: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>out/conftest.err)
+    ac_status=$?
+    cat out/conftest.err >&5
+-   echo "$as_me:11245: \$? = $ac_status" >&5
++   echo "$as_me:11269: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s out/conftest2.$ac_objext
+    then
+      # The compiler can only warn and ignore the option if not recognized
+@@ -16777,7 +16821,7 @@ fi
+ rm -f conftest.err conftest.$ac_objext \
+       conftest$ac_exeext conftest.$ac_ext
+       ;;
+-        yes)
++      yes)
+       cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+@@ -20485,6 +20529,10 @@ s,@am__untar@,$am__untar,;t t
+ s,@multi_basedir@,$multi_basedir,;t t
+ s,@toolexecdir@,$toolexecdir,;t t
+ s,@toolexeclibdir@,$toolexeclibdir,;t t
++s,@datarootdir@,$datarootdir,;t t
++s,@docdir@,$docdir,;t t
++s,@pdfdir@,$pdfdir,;t t
++s,@htmldir@,$htmldir,;t t
+ s,@CC@,$CC,;t t
+ s,@ac_ct_CC@,$ac_ct_CC,;t t
+ s,@EXEEXT@,$EXEEXT,;t t
+--- a/libgomp/configure.ac
++++ b/libgomp/configure.ac
+@@ -94,6 +94,30 @@ esac
+ AC_SUBST(toolexecdir)
+ AC_SUBST(toolexeclibdir)
++AC_ARG_WITH(datarootdir,
++[  --with-datarootdir=DIR  Use DIR as the data root [[PREFIX/share]]],
++datarootdir="\${prefix}/$with_datarootdir",
++datarootdir='$(prefix)/share')
++AC_SUBST(datarootdir)
++
++AC_ARG_WITH(docdir,
++[  --with-docdir=DIR       Install documentation in DIR [[DATAROOTDIR]]],
++docdir="\${prefix}/$with_docdir",
++docdir='$(datarootdir)')
++AC_SUBST(docdir)
++
++AC_ARG_WITH(pdfdir,
++[  --with-pdfdir           install pdf in this directory.],
++[pdfdir="\${prefix}/${withval}"],
++[pdfdir="\${docdir}"])
++AC_SUBST(pdfdir)
++
++AC_ARG_WITH(htmldir,
++[  --with-htmldir=DIR      html documentation in in DIR [[DOCDIR]]],
++htmldir="\${prefix}/$with_htmldir",
++htmldir='$(docdir)')
++AC_SUBST(htmldir)
++
+ # Check the compiler.
+ # The same as in boehm-gc and libstdc++. Have to borrow it from there.
+ # We must force CC to /not/ be precious variables; otherwise
+--- a/libgomp/configure.tgt
++++ b/libgomp/configure.tgt
+@@ -35,6 +35,10 @@ if test $enable_linux_futex = yes; then
+       config_path="linux/ia64 linux posix"
+       ;;
++    mips*-*-linux*)
++      config_path="linux/mips linux posix"
++      ;;
++
+     powerpc*-*-linux*)
+       config_path="linux/powerpc linux posix"
+       ;;
+--- a/libgomp/libgomp.texi
++++ b/libgomp/libgomp.texi
+@@ -95,7 +95,7 @@ for multi-platform shared-memory paralle
+                                How you can copy and share this manual.
+ * Funding::                    How to help assure continued work for free 
+                                software.
+-* Index::                      Index of this documentation.
++* Library Index::              Index of this documentation.
+ @end menu
+@@ -1367,8 +1367,8 @@ Bugs in the GNU OpenMP implementation sh
+ @c Index
+ @c ---------------------------------------------------------------------
+-@node Index
+-@unnumbered Index
++@node Library Index
++@unnumbered Library Index
+ @printindex cp
+--- a/libiberty/Makefile.in
++++ b/libiberty/Makefile.in
+@@ -124,7 +124,7 @@ COMPILE.c = $(CC) -c @DEFS@ $(LIBCFLAGS)
+ CFILES = alloca.c argv.c asprintf.c atexit.c                          \
+       basename.c bcmp.c bcopy.c bsearch.c bzero.c                     \
+       calloc.c choose-temp.c clock.c concat.c cp-demangle.c           \
+-       cp-demint.c cplus-dem.c                                        \
++       cp-demint.c cplus-dem.c cygpath.c                              \
+       dyn-string.c                                                    \
+       fdmatch.c ffs.c fibheap.c filename_cmp.c floatformat.c          \
+       fnmatch.c fopen_unlocked.c                                      \
+@@ -180,7 +180,7 @@ REQUIRED_OFILES = ./regex.o ./cplus-dem.
+ # maint-missing" and "make check".
+ CONFIGURED_OFILES = ./asprintf.o ./atexit.o                           \
+       ./basename.o ./bcmp.o ./bcopy.o ./bsearch.o ./bzero.o           \
+-      ./calloc.o ./clock.o ./copysign.o                               \
++      ./calloc.o ./clock.o ./copysign.o ./cygpath.o                   \
+       ./_doprnt.o                                                     \
+       ./ffs.o                                                         \
+       ./getcwd.o ./getpagesize.o ./gettimeofday.o                     \
+@@ -615,6 +615,13 @@ $(CONFIGURED_OFILES): stamp-picdir
+       else true; fi
+       $(COMPILE.c) $(srcdir)/cplus-dem.c $(OUTPUT_OPTION)
++./cygpath.o: $(srcdir)/cygpath.c stamp-h $(INCDIR)/ansidecl.h \
++      $(INCDIR)/libiberty.h
++      if [ x"$(PICFLAG)" != x ]; then \
++        $(COMPILE.c) $(PICFLAG) $(srcdir)/cygpath.c -o pic/$@; \
++      else true; fi
++      $(COMPILE.c) $(srcdir)/cygpath.c $(OUTPUT_OPTION)
++
+ ./dyn-string.o: $(srcdir)/dyn-string.c stamp-h $(INCDIR)/ansidecl.h \
+       $(INCDIR)/dyn-string.h $(INCDIR)/libiberty.h
+       if [ x"$(PICFLAG)" != x ]; then \
+--- a/libiberty/configure
++++ b/libiberty/configure
+@@ -8524,6 +8524,20 @@ case "${host}" in
+ esac
++# On MinGW, add support for Cygwin paths.
++case "${host}" in
++     *-*-mingw*)
++      case $LIBOBJS in
++    "cygpath.$ac_objext"   | \
++  *" cygpath.$ac_objext"   | \
++    "cygpath.$ac_objext "* | \
++  *" cygpath.$ac_objext "* ) ;;
++  *) LIBOBJS="$LIBOBJS cygpath.$ac_objext" ;;
++esac
++
++      ;;
++esac
++
+ if test x$gcc_no_link = xyes; then
+   if test "x${ac_cv_func_mmap_fixed_mapped+set}" != xset; then
+     ac_cv_func_mmap_fixed_mapped=no
+--- a/libiberty/configure.ac
++++ b/libiberty/configure.ac
+@@ -686,6 +686,13 @@ case "${host}" in
+ esac
+ AC_SUBST(pexecute)
++# On MinGW, add support for Cygwin paths.
++case "${host}" in
++     *-*-mingw*)
++      AC_LIBOBJ([cygpath])
++      ;;
++esac
++
+ libiberty_AC_FUNC_STRNCMP
+ # Install a library built with a cross compiler in $(tooldir) rather
+--- a/libiberty/cp-demangle.c
++++ b/libiberty/cp-demangle.c
+@@ -1885,6 +1885,11 @@ cplus_demangle_builtin_types[D_BUILTIN_T
+ };
+ CP_STATIC_IF_GLIBCPP_V3
++const struct demangle_builtin_type_info
++cplus_demangle_builtin_Dh_type =
++  { NL ("__fp16"),    NL ("__fp16"),  D_PRINT_DEFAULT };
++
++CP_STATIC_IF_GLIBCPP_V3
+ struct demangle_component *
+ cplus_demangle_type (struct d_info *di)
+ {
+@@ -1936,6 +1941,21 @@ cplus_demangle_type (struct d_info *di)
+       d_advance (di, 1);
+       break;
++    case 'D':
++      d_advance (di, 1);
++      switch (d_peek_char (di))
++      {
++      case 'h':
++        ret = d_make_builtin_type (di, &cplus_demangle_builtin_Dh_type);
++        di->expansion += ret->u.s_builtin.type->len;
++        can_subst = 0;
++        d_advance (di, 1);
++        break;
++      default:
++        return NULL;
++      }
++      break;
++
+     case 'u':
+       d_advance (di, 1);
+       ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE,
+--- /dev/null
++++ b/libiberty/cygpath.c
+@@ -0,0 +1,591 @@
++/* Support Cygwin paths under MinGW.
++   Copyright (C) 2006 Free Software Foundation, Inc.
++   Written by CodeSourcery.
++
++This file is part of the libiberty library.
++Libiberty is free software; you can redistribute it and/or modify it
++under the terms of the GNU Library General Public License as published
++by the Free Software Foundation; either version 2 of the License, or
++(at your option) any later version.
++
++Libiberty is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++Library General Public License for more details.
++
++You should have received a copy of the GNU Library General Public
++License along with libiberty; see the file COPYING.LIB.  If not, write
++to the Free Software Foundation, Inc., 51 Franklin Street - Fifth
++Floor, Boston, MA 02110-1301, USA.  */
++
++#include <windows.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++#include <io.h>
++#include <process.h>
++#include <stdbool.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include "libiberty.h"
++
++/* If non-zero, we have attempted to use cygpath.  CYGPATH_PEX may
++   still be NULL, if cygpath is unavailable.  */
++static int cygpath_initialized;
++
++/* If non-NULL, an instance of cygpath connected via a pipe.  */
++static struct pex_obj *cygpath_pex;
++
++/* The input to cygpath.  */
++static FILE *cygpath_in;
++
++/* The output from cygpath.  */
++static FILE *cygpath_out;
++
++/* If non-NULL, a file to which path translations are logged.  */
++static FILE *cygpath_log;
++
++/* Record MESSAGE in the CYGPATH_LOG.  MESSAGE is a format string,
++   which is expected to have a single "%s" field, to be replaced by
++   ARG.  */
++static void
++cygpath_log_msg_arg (const char *message, const char *arg)
++{
++  if (!cygpath_log)
++    return;
++  fprintf (cygpath_log, "[%d] cygpath: ", _getpid ());
++  fprintf (cygpath_log, message, arg);
++  fprintf (cygpath_log, "\n");
++  fflush (cygpath_log);
++}
++
++/* Record MESSAGE in the CYGPATH_LOG.  */
++static void
++cygpath_log_msg (const char *message)
++{
++  cygpath_log_msg_arg ("%s", message);
++}
++
++/* An error has occured.  Add the MESSAGE to the CYGPATH_LOG, noting
++   the cause of the error based on errno.  */
++static void
++cygpath_perror (const char *message)
++{
++  if (!cygpath_log)
++    return;
++  fprintf (cygpath_log, "[%d] cygpath: error: %s: %s\n",
++         _getpid(), message, strerror (errno));
++  fflush (cygpath_log);
++}
++
++/* Closes CYGPATH_PEX and frees all associated
++   resoures.  */
++static void
++cygpath_close (void)
++{
++  /* Free resources.  */
++  if (cygpath_out)
++    {
++      fclose (cygpath_out);
++      cygpath_out = NULL;
++    }
++  if (cygpath_in)
++    {
++      fclose (cygpath_in);
++      cygpath_in = NULL;
++    }
++  if (cygpath_pex)
++    {
++      pex_free (cygpath_pex);
++      cygpath_pex = NULL;
++    }
++  if (cygpath_log)
++    {
++      cygpath_log_msg ("end");
++      cygpath_log = NULL;
++    }
++}
++
++/* CYG_PATH is a pointer to a Cygwin path.  This function converts the
++   Cygwin path to a Windows path, storing the result in
++   WIN32_PATH.  Returns true if the conversion was successful; false
++   otherwise.  */
++int
++cygpath (const char *cyg_path, char win32_path[MAX_PATH + 1])
++{
++  bool ok;
++  bool retrying;
++  
++  /* Special-case the empty path.  cygpath cannot handle the empty
++     path correctly.  It ignores the empty line, waiting for a
++     non-empty line, which in turn causes an application using this
++     function to appear stuck.  */
++  if (cyg_path[0] == '\0')
++    {
++      win32_path[0] = '\0';
++      return true;
++    }
++  
++  retrying = false;
++
++ retry:
++  if (!cygpath_initialized) 
++    {
++      const char *argv[] = { "cygpath", "-w", "-f", "-", NULL };
++      const char *cygpath_path;
++      const char *log;
++      int err;
++
++      /* If we are unable to invoke cygpath, we do not want to try
++       again.  So, we set the initialized flag at this point; if
++       errors occur during the invocation, it will remain set.  */
++      cygpath_initialized = 1;
++      /* Check to see if the user wants cygpath support.  */
++      cygpath_path = getenv ("CYGPATH");
++      if (!cygpath_path)
++      /* The user doesn't need to support Cygwin paths.  */
++      goto error;
++      /* If debugging, open the log file.  */
++      log = getenv ("CSL_DEBUG_CYGPATH");
++      if (log && log[0])
++      {
++        /* The log file is opened for "append" so that multiple
++           processes (perhaps invoked from "make") can share it.  */
++        cygpath_log = fopen (log, "a");
++        if (cygpath_log)
++          cygpath_log_msg ("begin");
++      }
++      /* If the environment variable is set to a non-empty string, use
++       that string as the path to cygpath.  */ 
++      if (cygpath_path[0] != '\0')
++      argv[0] = cygpath_path;
++      /* Create the pex object.  */
++      cygpath_pex = pex_init (PEX_SEARCH | PEX_USE_PIPES, 
++                            "cygpath", NULL);
++      if (!cygpath_pex)
++      goto error;
++      /* Get the FILE we will use to write to the child.  */
++      cygpath_in = pex_input_pipe (cygpath_pex, /*binary=*/0);
++      if (!cygpath_in)
++      goto error;
++      /* Start the child process.  */
++      if (pex_run (cygpath_pex, PEX_SEARCH | PEX_USE_PIPES, 
++                 argv[0], (char**) argv, 
++                 NULL, NULL,
++                 &err) != NULL)
++      goto error;
++      /* Get the FILE we will use to read from the child.  */
++      cygpath_out = pex_read_output (cygpath_pex, /*binary=*/1);
++      if (!cygpath_out)
++      goto error;
++    }
++  else if (!cygpath_pex) 
++    /* We previously tried to use cygpath, but something went wrong.  */
++    return false;
++
++  /* Write CYG_PATH to the child, on a line by itself.  */
++  cygpath_log_msg_arg ("-> %s", cyg_path);
++  if (fprintf (cygpath_in, "%s\n", cyg_path) < 0)
++    {
++      cygpath_perror ("write failed");
++      goto error;
++    }
++  /* Flush the output.  (We cannot set the stream into line-buffered
++     mode with setvbuf because Windows treats _IOLBF as a synonym for
++     _IOFBF.)  */
++  if (fflush (cygpath_in))
++    cygpath_perror ("flush failed");
++  /* Read the output.  */
++  ok = true;
++  while (1)
++    {
++      size_t pathlen;
++      if (!fgets (win32_path, MAX_PATH, cygpath_out))
++      {
++        if (ferror (cygpath_out))
++          cygpath_perror ("read failed");
++        else
++          {
++            cygpath_log_msg ("error: EOF");
++            /* Unfortunately, cygpath sometimes crashes for no
++               apparent reason.  We give it two chances... */
++            if (!retrying)
++              {
++                retrying = true;
++                cygpath_log_msg ("retrying");
++                cygpath_close ();
++                cygpath_initialized = 0;
++                goto retry;
++              }
++          }
++        goto error;
++      }
++      pathlen = strlen (win32_path);
++      if (pathlen == 0 && ok)
++      /* This isn't a well-formed response from cygpath.  */
++      goto error;
++      if (win32_path[pathlen - 1] == '\n')
++      {
++        win32_path[pathlen - 1] = '\0';
++        cygpath_log_msg_arg ("<- %s", win32_path);
++        break;
++      }
++      /* We didn't reach the end of the line.  There's no point in
++       trying to use this output, since we know the length of
++       paths are limited to MAX_PATH characters, but we read the
++       entire line so that we are still in sync with
++       cygpath.  */
++      ok = false;
++      if (cygpath_log)
++      cygpath_log_msg_arg ("error: invalid response: %s",
++                           win32_path);
++    }
++  
++  return ok;
++  
++ error:
++  cygpath_close();
++  return false;
++}
++
++/* Returns the handle for the MVCRT DLL, or NULL if it is not
++   available.  */
++static HMODULE
++msvcrt_dll (void)
++{
++  static HMODULE dll = (HMODULE)(-1);
++
++  /* After we call LoadLibrary, DLL will be either a valid handle or
++     NULL, so this check ensures that we only try to load the library
++     once.  */
++  if (dll == (HMODULE)(-1))
++    dll = LoadLibrary ("msvcrt.dll");
++
++  return dll;
++}
++
++/* Call the underlying MSVCRT fopen with PATH and MODE, and return
++   what it returns.  */
++static FILE *
++msvcrt_fopen (const char *path, const char *mode)
++{
++  typedef FILE *(fopen_type)(const char *path, 
++                           const char *mode);
++
++  static fopen_type *f = NULL;
++
++  /* Get the address of "fopen".  */
++  if (!f) 
++    {
++      HMODULE dll = msvcrt_dll ();
++      if (!dll)
++      {
++        errno = ENOSYS;
++        return NULL;
++      }
++      f = (fopen_type *) GetProcAddress (dll, "fopen");
++      if (!f)
++      {
++        errno = ENOSYS;
++        return NULL;
++      }
++    }
++
++  /* Call fopen.  */
++  return (*f)(path, mode);
++}
++
++FILE *
++fopen (const char *path, const char *mode)
++{
++  FILE *f;
++  char win32_path[MAX_PATH + 1];
++
++  /* Assume PATH is a Windows path.  */
++  f = msvcrt_fopen (path, mode);
++  if (f || errno != ENOENT)
++    return f;
++  /* Perhaps it is a Cygwin path?  */
++  if (cygpath (path, win32_path))
++    f = msvcrt_fopen (win32_path, mode);
++  return f;
++}
++
++int 
++open (const char *path, int oflag, ...)
++{
++  int fd;
++  char win32_path[MAX_PATH + 1];
++  int pmode = 0;
++
++  if ((oflag & _O_CREAT))
++    {
++      va_list ap;
++      va_start (ap, oflag);
++      pmode = va_arg (ap, int); 
++      va_end (ap);
++    }
++
++  /* Assume PATH is a Windows path.  */
++  fd = _open (path, oflag, pmode);
++  if (fd != -1 || errno != ENOENT)
++    return fd;
++  /* Perhaps it is a Cygwin path?  */
++  if (cygpath (path, win32_path))
++    fd = _open (win32_path, oflag, pmode);
++  return fd;
++}
++
++int
++stat (const char *path, struct stat *buffer)
++{
++  int r;
++  char win32_path[MAX_PATH + 1];
++
++  /* Assume PATH is a Windows path.  */
++  r = _stat (path, (struct _stat *) buffer);
++  if (r != -1 || errno != ENOENT)
++    return r;
++  /* Perhaps it is a Cygwin path?  */
++  if (cygpath (path, win32_path))
++    r = _stat (win32_path, (struct _stat *) buffer);
++  return r;
++}
++
++int
++access (const char *path, int mode)
++{
++  int r;
++  char win32_path[MAX_PATH + 1];
++
++#ifdef _WIN32
++  /* Some GNU tools mistakenly defined X_OK to 1 on Windows.  */
++  mode = mode & ~1;
++#endif
++  /* Assume PATH is a Windows path.  */
++  r = _access (path, mode);
++  if (r != -1 || errno != ENOENT)
++    return r;
++  /* Perhaps it is a Cygwin path?  */
++  if (cygpath (path, win32_path))
++    r = _access (win32_path, mode);
++  return r;
++}
++
++/* Given the WINDOWS_CODE (typically the result of GetLastError), set
++   ERRNO to the corresponding error code.  If there is no obvious
++   correspondence, ERRNO will be set to EACCES.  */
++static void
++set_errno_from_windows_code (DWORD windows_code)
++{
++  int mapping[][2] = {
++    {ERROR_ACCESS_DENIED, EACCES},
++    {ERROR_ACCOUNT_DISABLED, EACCES},
++    {ERROR_ACCOUNT_RESTRICTION, EACCES},
++    {ERROR_ALREADY_ASSIGNED, EBUSY},
++    {ERROR_ALREADY_EXISTS, EEXIST},
++    {ERROR_ARITHMETIC_OVERFLOW, ERANGE},
++    {ERROR_BAD_COMMAND, EIO},
++    {ERROR_BAD_DEVICE, ENODEV},
++    {ERROR_BAD_DRIVER_LEVEL, ENXIO},
++    {ERROR_BAD_EXE_FORMAT, ENOEXEC},
++    {ERROR_BAD_FORMAT, ENOEXEC},
++    {ERROR_BAD_LENGTH, EINVAL},
++    {ERROR_BAD_PATHNAME, ENOENT},
++    {ERROR_BAD_PIPE, EPIPE},
++    {ERROR_BAD_UNIT, ENODEV},
++    {ERROR_BAD_USERNAME, EINVAL},
++    {ERROR_BROKEN_PIPE, EPIPE},
++    {ERROR_BUFFER_OVERFLOW, ENOMEM},
++    {ERROR_BUSY, EBUSY},
++    {ERROR_BUSY_DRIVE, EBUSY},
++    {ERROR_CALL_NOT_IMPLEMENTED, ENOSYS},
++    {ERROR_CRC, EIO},
++    {ERROR_CURRENT_DIRECTORY, EINVAL},
++    {ERROR_DEVICE_IN_USE, EBUSY},
++    {ERROR_DIR_NOT_EMPTY, EEXIST},
++    {ERROR_DIRECTORY, ENOENT},
++    {ERROR_DISK_CHANGE, EIO},
++    {ERROR_DISK_FULL, ENOSPC},
++    {ERROR_DRIVE_LOCKED, EBUSY},
++    {ERROR_ENVVAR_NOT_FOUND, EINVAL},
++    {ERROR_EXE_MARKED_INVALID, ENOEXEC},
++    {ERROR_FILE_EXISTS, EEXIST},
++    {ERROR_FILE_INVALID, ENODEV},
++    {ERROR_FILE_NOT_FOUND, ENOENT},
++    {ERROR_FILENAME_EXCED_RANGE, ENAMETOOLONG},
++    {ERROR_GEN_FAILURE, EIO},
++    {ERROR_HANDLE_DISK_FULL, ENOSPC},
++    {ERROR_INSUFFICIENT_BUFFER,  ENOMEM},
++    {ERROR_INVALID_ACCESS, EINVAL},
++    {ERROR_INVALID_ADDRESS, EFAULT},
++    {ERROR_INVALID_BLOCK, EFAULT},
++    {ERROR_INVALID_DATA, EINVAL},
++    {ERROR_INVALID_DRIVE, ENODEV},
++    {ERROR_INVALID_EXE_SIGNATURE,  ENOEXEC},
++    {ERROR_INVALID_FLAGS, EINVAL},
++    {ERROR_INVALID_FUNCTION,  ENOSYS},
++    {ERROR_INVALID_HANDLE, EBADF},
++    {ERROR_INVALID_LOGON_HOURS,  EACCES},
++    {ERROR_INVALID_NAME, ENOENT},
++    {ERROR_INVALID_OWNER, EINVAL},
++    {ERROR_INVALID_PARAMETER, EINVAL},
++    {ERROR_INVALID_PASSWORD, EPERM},
++    {ERROR_INVALID_PRIMARY_GROUP, EINVAL},
++    {ERROR_INVALID_SIGNAL_NUMBER, EINVAL},
++    {ERROR_INVALID_TARGET_HANDLE, EIO},
++    {ERROR_INVALID_WORKSTATION, EACCES},
++    {ERROR_IO_DEVICE, EIO},
++    {ERROR_IO_INCOMPLETE, EINTR},
++    {ERROR_LOCKED, EBUSY},
++    {ERROR_LOGON_FAILURE, EACCES},
++    {ERROR_MAPPED_ALIGNMENT, EINVAL},
++    {ERROR_META_EXPANSION_TOO_LONG, E2BIG},
++    {ERROR_MORE_DATA, EPIPE},
++    {ERROR_NEGATIVE_SEEK, ESPIPE},
++    {ERROR_NO_DATA, EPIPE},
++    {ERROR_NO_MORE_SEARCH_HANDLES, EIO},
++    {ERROR_NO_PROC_SLOTS, EAGAIN},
++    {ERROR_NO_SUCH_PRIVILEGE, EACCES},
++    {ERROR_NOACCESS, EFAULT},
++    {ERROR_NONE_MAPPED, EINVAL},
++    {ERROR_NOT_ENOUGH_MEMORY, ENOMEM},
++    {ERROR_NOT_READY, ENODEV},
++    {ERROR_NOT_SAME_DEVICE, EXDEV},
++    {ERROR_OPEN_FAILED, EIO},
++    {ERROR_OPERATION_ABORTED, EINTR},
++    {ERROR_OUTOFMEMORY,  ENOMEM},
++    {ERROR_PASSWORD_EXPIRED, EACCES},
++    {ERROR_PATH_BUSY,  EBUSY},
++    {ERROR_PATH_NOT_FOUND, ENOTDIR},
++    {ERROR_PIPE_BUSY, EBUSY},
++    {ERROR_PIPE_CONNECTED, EPIPE},
++    {ERROR_PIPE_LISTENING, EPIPE},
++    {ERROR_PIPE_NOT_CONNECTED, EPIPE},
++    {ERROR_PRIVILEGE_NOT_HELD, EACCES},
++    {ERROR_READ_FAULT, EIO},
++    {ERROR_SEEK, ESPIPE},
++    {ERROR_SEEK_ON_DEVICE, ESPIPE},
++    {ERROR_SHARING_BUFFER_EXCEEDED, ENFILE},
++    {ERROR_STACK_OVERFLOW, ENOMEM},
++    {ERROR_SWAPERROR, ENOENT},
++    {ERROR_TOO_MANY_MODULES, EMFILE},
++    {ERROR_TOO_MANY_OPEN_FILES, EMFILE},
++    {ERROR_UNRECOGNIZED_MEDIA,  ENXIO},
++    {ERROR_UNRECOGNIZED_VOLUME,  ENODEV},
++    {ERROR_WAIT_NO_CHILDREN,  ECHILD},
++    {ERROR_WRITE_FAULT, EIO},
++    {ERROR_WRITE_PROTECT, EROFS}
++/*  MinGW does not define ETXTBSY as yet.  
++    {ERROR_LOCK_VIOLATION, ETXTBSY},
++    {ERROR_SHARING_VIOLATION, ETXTBSY}, 
++*/
++  };
++
++  size_t i;
++
++  for (i = 0; i < sizeof (mapping)/sizeof (mapping[0]); ++i)
++    if (mapping[i][0] == windows_code)
++      {
++      errno = mapping[i][1];
++      return;
++      }
++
++  /* Unrecognized error. Use EACCESS to have some error code,
++     not misleading "No error" thing.  */
++  errno = EACCES;      
++}
++
++int rename (const char *oldpath, const char *newpath)
++{
++  BOOL r;
++  int oldpath_converted = 0;
++  char win32_oldpath[MAX_PATH + 1];
++  char win32_newpath[MAX_PATH + 1];
++
++  /* Older versions of the cygpath program called FindFirstFile, but
++     not FindClose.  As a result, a long-running cygpath program ends
++     up leaking these handles, and, as a result, the Windows kernel
++     will not let us remove or rename things in directories.  Therefore,
++     we kill the child cygpath program now.
++
++     The defect in cygpath was corrected by this patch:
++
++       http://cygwin.com/ml/cygwin-patches/2007-q1/msg00033.html
++
++     but older versions of cygpath will be in use for the forseeable
++     future.  */
++
++  cygpath_close ();
++  cygpath_initialized = 0;
++
++  /* Assume all paths are Windows paths.  */
++  r = MoveFileEx (oldpath, newpath, MOVEFILE_REPLACE_EXISTING);
++  if (r)
++      return 0;
++  else if (GetLastError () != ERROR_PATH_NOT_FOUND)
++    goto error;
++
++  /* Perhaps the old path is a cygwin path?  */
++  if (cygpath (oldpath, win32_oldpath))
++    {
++      oldpath_converted = 1;
++      r = MoveFileEx (win32_oldpath, newpath, MOVEFILE_REPLACE_EXISTING);      
++      if (r)
++          return 0;
++      else if (GetLastError () != ERROR_PATH_NOT_FOUND)
++          goto error;
++    }
++
++  /* Perhaps the new path is a cygwin path?  */
++  if (cygpath (newpath, win32_newpath))
++    {
++      r = MoveFileEx (oldpath_converted ? win32_oldpath : oldpath,
++                    win32_newpath, MOVEFILE_REPLACE_EXISTING);
++      if (r == TRUE)
++      return 0;
++    }
++error:
++  set_errno_from_windows_code (GetLastError ());
++  return -1;      
++}
++
++int remove (const char *pathname)
++{
++  int r;
++  char win32_path[MAX_PATH + 1];
++
++  cygpath_close ();
++  cygpath_initialized = 0;
++
++  /* Assume PATH is a Windows path.  */
++  r = _unlink (pathname);
++  if (r != -1 || errno != ENOENT)
++    return r;
++  /* Perhaps it is a Cygwin path?  */
++  if (cygpath (pathname, win32_path))
++    r = _unlink (win32_path);
++  return r;
++}
++
++int unlink(const char *pathname)
++{
++    return remove (pathname);
++}
++
++int
++chdir (const char *path)
++{
++  int ret;
++  char win32_path[MAX_PATH + 1];
++
++  /* Assume PATH is a Windows path.  */
++  ret = _chdir (path);
++  if (ret != -1 || errno != ENOENT)
++    return ret;
++  /* Perhaps it is a Cygwin path?  */
++  if (cygpath (path, win32_path))
++    ret = _chdir (win32_path);
++  return ret;
++}
+--- a/libiberty/make-temp-file.c
++++ b/libiberty/make-temp-file.c
+@@ -23,6 +23,7 @@ Boston, MA 02110-1301, USA.  */
+ #include <stdio.h>    /* May get P_tmpdir.  */
+ #include <sys/types.h>
++#include <errno.h>
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
+@@ -35,6 +36,9 @@ Boston, MA 02110-1301, USA.  */
+ #ifdef HAVE_SYS_FILE_H
+ #include <sys/file.h>   /* May get R_OK, etc. on some systems.  */
+ #endif
++#if defined(_WIN32) && !defined(__CYGWIN__)
++#include <windows.h>
++#endif
+ #ifndef R_OK
+ #define R_OK 4
+@@ -55,6 +59,8 @@ extern int mkstemps (char *, int);
+ #define TEMP_FILE "ccXXXXXX"
+ #define TEMP_FILE_LEN (sizeof(TEMP_FILE) - 1)
++#if !defined(_WIN32) || defined(__CYGWIN__)
++
+ /* Subroutine of choose_tmpdir.
+    If BASE is non-NULL, return it.
+    Otherwise it checks if DIR is a usable directory.
+@@ -80,6 +86,8 @@ static const char usrtmp[] =
+ static const char vartmp[] =
+ { DIR_SEPARATOR, 'v', 'a', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 };
++#endif
++
+ static char *memoized_tmpdir;
+ /*
+@@ -96,40 +104,58 @@ files in.
+ char *
+ choose_tmpdir (void)
+ {
+-  const char *base = 0;
+-  char *tmpdir;
+-  unsigned int len;
+-
+-  if (memoized_tmpdir)
+-    return memoized_tmpdir;
+-
+-  base = try_dir (getenv ("TMPDIR"), base);
+-  base = try_dir (getenv ("TMP"), base);
+-  base = try_dir (getenv ("TEMP"), base);
+-
++  if (!memoized_tmpdir)
++    {
++#if !defined(_WIN32) || defined(__CYGWIN__)
++      const char *base = 0;
++      char *tmpdir;
++      unsigned int len;
++      
++      base = try_dir (getenv ("TMPDIR"), base);
++      base = try_dir (getenv ("TMP"), base);
++      base = try_dir (getenv ("TEMP"), base);
++      
+ #ifdef P_tmpdir
+-  base = try_dir (P_tmpdir, base);
++      base = try_dir (P_tmpdir, base);
+ #endif
+-  /* Try /var/tmp, /usr/tmp, then /tmp.  */
+-  base = try_dir (vartmp, base);
+-  base = try_dir (usrtmp, base);
+-  base = try_dir (tmp, base);
+- 
+-  /* If all else fails, use the current directory!  */
+-  if (base == 0)
+-    base = ".";
+-
+-  /* Append DIR_SEPARATOR to the directory we've chosen
+-     and return it.  */
+-  len = strlen (base);
+-  tmpdir = XNEWVEC (char, len + 2);
+-  strcpy (tmpdir, base);
+-  tmpdir[len] = DIR_SEPARATOR;
+-  tmpdir[len+1] = '\0';
++      /* Try /var/tmp, /usr/tmp, then /tmp.  */
++      base = try_dir (vartmp, base);
++      base = try_dir (usrtmp, base);
++      base = try_dir (tmp, base);
++      
++      /* If all else fails, use the current directory!  */
++      if (base == 0)
++      base = ".";
++      /* Append DIR_SEPARATOR to the directory we've chosen
++       and return it.  */
++      len = strlen (base);
++      tmpdir = XNEWVEC (char, len + 2);
++      strcpy (tmpdir, base);
++      tmpdir[len] = DIR_SEPARATOR;
++      tmpdir[len+1] = '\0';
++      memoized_tmpdir = tmpdir;
++#else /* defined(_WIN32) && !defined(__CYGWIN__) */
++      DWORD len;
++
++      /* Figure out how much space we need.  */
++      len = GetTempPath(0, NULL);
++      if (len)
++      {
++        memoized_tmpdir = XNEWVEC (char, len);
++        if (!GetTempPath(len, memoized_tmpdir))
++          {
++            XDELETEVEC (memoized_tmpdir);
++            memoized_tmpdir = NULL;
++          }
++      }
++      if (!memoized_tmpdir)
++      /* If all else fails, use the current directory.  */
++      memoized_tmpdir = xstrdup (".\\");
++#endif /* defined(_WIN32) && !defined(__CYGWIN__) */
++    }
+-  memoized_tmpdir = tmpdir;
+-  return tmpdir;
++  return memoized_tmpdir;
+ }
+ /*
+@@ -166,11 +192,14 @@ make_temp_file (const char *suffix)
+   strcpy (temp_filename + base_len + TEMP_FILE_LEN, suffix);
+   fd = mkstemps (temp_filename, suffix_len);
+-  /* If mkstemps failed, then something bad is happening.  Maybe we should
+-     issue a message about a possible security attack in progress?  */
++  /* Mkstemps failed.  It may be EPERM, ENOSPC etc.  */
+   if (fd == -1)
+-    abort ();
+-  /* Similarly if we can not close the file.  */
++    {
++      fprintf (stderr, "Cannot create temporary file in %s: %s\n",
++             base, strerror (errno));
++      abort ();
++    }
++  /* We abort on failed close out of sheer paranoia.  */
+   if (close (fd))
+     abort ();
+   return temp_filename;
+--- a/libiberty/mkstemps.c
++++ b/libiberty/mkstemps.c
+@@ -127,6 +127,13 @@ mkstemps (char *pattern, int suffix_len)
+       if (fd >= 0)
+       /* The file does not exist.  */
+       return fd;
++      if (errno != EEXIST
++#ifdef EISDIR
++        && errno != EISDIR
++#endif
++       )
++      /* Fatal error (EPERM, ENOSPC etc).  Doesn't make sense to loop.  */
++      break;
+       /* This is a random value.  It is only necessary that the next
+        TMP_MAX values generated by adding 7777 to VALUE are different
+--- a/libiberty/pex-win32.c
++++ b/libiberty/pex-win32.c
+@@ -119,7 +119,7 @@ static int
+ pex_win32_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
+                    int binary)
+ {
+-  return _open (name, _O_RDONLY | (binary ? _O_BINARY : _O_TEXT));
++  return open (name, _O_RDONLY | (binary ? _O_BINARY : _O_TEXT));
+ }
+ /* Open a file for writing.  */
+@@ -130,10 +130,10 @@ pex_win32_open_write (struct pex_obj *ob
+ {
+   /* Note that we can't use O_EXCL here because gcc may have already
+      created the temporary file via make_temp_file.  */
+-  return _open (name,
+-              (_O_WRONLY | _O_CREAT | _O_TRUNC
+-               | (binary ? _O_BINARY : _O_TEXT)),
+-              _S_IREAD | _S_IWRITE);
++  return open (name,
++             (_O_WRONLY | _O_CREAT | _O_TRUNC
++              | (binary ? _O_BINARY : _O_TEXT)),
++             _S_IREAD | _S_IWRITE);
+ }
+ /* Close a file.  */
+--- a/libjava/Makefile.am
++++ b/libjava/Makefile.am
+@@ -48,9 +48,14 @@ endif
+ dbexec_LTLIBRARIES = libjvm.la
+-pkgconfigdir = $(libdir)/pkgconfig
++# Install the pkgconfig file in a target-specific directory, since the
++# libraries it indicates
+-jardir = $(datadir)/java
++pkgconfigdir = $(toolexeclibdir)/pkgconfig
++
++# We install the JAR in a target-specific directory so that toolchains
++# build from different sources can be installed in the same directory.
++jardir = $(prefix)/$(target_noncanonical)/share/java
+ jar_DATA = libgcj-$(gcc_version).jar libgcj-tools-$(gcc_version).jar
+ if INSTALL_ECJ_JAR
+ jar_DATA += $(ECJ_BUILD_JAR)
+@@ -81,7 +86,7 @@ bin_PROGRAMS = jv-convert gij grmic grmi
+ dbexec_DATA = $(db_name)
+ endif
+-bin_SCRIPTS = addr2name.awk
++bin_SCRIPTS = 
+ if BUILD_ECJ1
+ ## We build ecjx and not ecj1 because in one mode, ecjx will not work
+@@ -107,12 +112,15 @@ if ANONVERSCRIPT
+ extra_ldflags_libjava += -Wl,--version-script=$(srcdir)/libgcj.ver
+ endif
++LTLDFLAGS = $(shell $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
+ GCJLINK = $(LIBTOOL) --tag=GCJ --mode=link $(GCJ) -L$(here) $(JC1FLAGS) \
+-          $(LDFLAGS) -o $@
++          $(LTLDFLAGS) -o $@
+ GCJ_FOR_ECJX = @GCJ_FOR_ECJX@
+ GCJ_FOR_ECJX_LINK = $(GCJ_FOR_ECJX) -o $@
+ LIBLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXX) -L$(here) $(JC1FLAGS) \
+-          $(LDFLAGS) $(extra_ldflags_libjava) $(extra_ldflags) -o $@
++          $(LTLDFLAGS) $(extra_ldflags_libjava) $(extra_ldflags) -o $@
++CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
++      $(CXXFLAGS) $(AM_LDFLAGS) $(LTLDFLAGS) -o $@
+ GCC_UNWIND_INCLUDE = @GCC_UNWIND_INCLUDE@
+--- a/libjava/Makefile.in
++++ b/libjava/Makefile.in
+@@ -508,8 +508,6 @@ LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mo
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CXXFLAGS) $(CXXFLAGS)
+ CXXLD = $(CXX)
+-CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+-      $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+ GCJCOMPILE = $(GCJ) $(AM_GCJFLAGS) $(GCJFLAGS)
+ LTGCJCOMPILE = $(LIBTOOL) --tag=GCJ --mode=compile $(GCJ) \
+       $(AM_GCJFLAGS) $(GCJFLAGS)
+@@ -836,8 +834,14 @@ toolexeclib_LTLIBRARIES = libgcj.la libg
+       $(am__append_2) $(am__append_3)
+ toolexecmainlib_DATA = libgcj.spec
+ dbexec_LTLIBRARIES = libjvm.la
+-pkgconfigdir = $(libdir)/pkgconfig
+-jardir = $(datadir)/java
++
++# Install the pkgconfig file in a target-specific directory, since the
++# libraries it indicates
++pkgconfigdir = $(toolexeclibdir)/pkgconfig
++
++# We install the JAR in a target-specific directory so that toolchains
++# build from different sources can be installed in the same directory.
++jardir = $(prefix)/$(target_noncanonical)/share/java
+ jar_DATA = libgcj-$(gcc_version).jar libgcj-tools-$(gcc_version).jar \
+       $(am__append_4)
+ @JAVA_HOME_SET_FALSE@JAVA_HOME_DIR = $(prefix)
+@@ -847,14 +851,18 @@ jar_DATA = libgcj-$(gcc_version).jar lib
+ db_name = classmap.db
+ db_pathtail = $(gcjsubdir)/$(db_name)
+ @NATIVE_TRUE@dbexec_DATA = $(db_name)
+-bin_SCRIPTS = addr2name.awk
++bin_SCRIPTS = 
+ GCJ_WITH_FLAGS = $(GCJ) --encoding=UTF-8 -Wno-deprecated
++LTLDFLAGS = $(shell $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
+ GCJLINK = $(LIBTOOL) --tag=GCJ --mode=link $(GCJ) -L$(here) $(JC1FLAGS) \
+-          $(LDFLAGS) -o $@
++          $(LTLDFLAGS) -o $@
+ GCJ_FOR_ECJX_LINK = $(GCJ_FOR_ECJX) -o $@
+ LIBLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXX) -L$(here) $(JC1FLAGS) \
+-          $(LDFLAGS) $(extra_ldflags_libjava) $(extra_ldflags) -o $@
++          $(LTLDFLAGS) $(extra_ldflags_libjava) $(extra_ldflags) -o $@
++
++CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
++      $(CXXFLAGS) $(AM_LDFLAGS) $(LTLDFLAGS) -o $@
+ WARNINGS = -Wextra -Wall
+ AM_CXXFLAGS = \
+--- a/libjava/classpath/Makefile.in
++++ b/libjava/classpath/Makefile.in
+@@ -357,9 +357,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ # lib first, to compile .class files before native code, last examples
+--- a/libjava/classpath/configure
++++ b/libjava/classpath/configure
+@@ -461,7 +461,7 @@ ac_includes_default="\
+ # include <unistd.h>
+ #endif"
+-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os JAVA_MAINTAINER_MODE_TRUE JAVA_MAINTAINER_MODE_FALSE GENINSRC_TRUE GENINSRC_FALSE multi_basedir LIBVERSION CLASSPATH_MODULE CLASSPATH_CONVENIENCE INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CREATE_COLLECTIONS_TRUE CREATE_COLLECTIONS_FALSE CREATE_JNI_LIBRARIES_TRUE CREATE_JNI_LIBRARIES_FALSE CREATE_CORE_JNI_LIBRARIES_TRUE CREATE_CORE_JNI_LIBRARIES_FALSE CREATE_GCONF_PEER_LIBRARIES_TRUE CREATE_GCONF_PEER_LIBRARIES_FALSE CREATE_GSTREAMER_PEER_LIBRARIES_TRUE CREATE_GSTREAMER_PEER_LIBRARIES_FALSE default_toolkit CREATE_XMLJ_LIBRARY_TRUE CREATE_XMLJ_LIBRARY_FALSE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP CREATE_ALSA_LIBRARIES_TRUE CREATE_ALSA_LIBRARIES_FALSE CREATE_DSSI_LIBRARIES_TRUE CREATE_DSSI_LIBRARIES_FALSE CREATE_GTK_PEER_LIBRARIES_TRUE CREATE_GTK_PEER_LIBRARIES_FALSE CREATE_QT_PEER_LIBRARIES_TRUE CREATE_QT_PEER_LIBRARIES_FALSE CREATE_PLUGIN_TRUE CREATE_PLUGIN_FALSE toolexeclibdir nativeexeclibdir glibjdir VM_BINARY CREATE_JNI_HEADERS_TRUE CREATE_JNI_HEADERS_FALSE CREATE_WRAPPERS_TRUE CREATE_WRAPPERS_FALSE LN_S LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM AR ac_ct_AR RANLIB ac_ct_RANLIB lt_ECHO CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP PERL COLLECTIONS_PREFIX LIBMAGIC LIBICONV LTLIBICONV WARNING_CFLAGS STRICT_WARNING_CFLAGS ERROR_CFLAGS PKG_CONFIG XML_CFLAGS XML_LIBS XSLT_CFLAGS XSLT_LIBS X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS GTK_CFLAGS GTK_LIBS FREETYPE2_CFLAGS FREETYPE2_LIBS PANGOFT2_CFLAGS PANGOFT2_LIBS CAIRO_CFLAGS CAIRO_LIBS XTEST_LIBS GCONF_CFLAGS GCONF_LIBS GDK_CFLAGS GDK_LIBS GSTREAMER_CFLAGS GSTREAMER_LIBS GSTREAMER_BASE_CFLAGS GSTREAMER_BASE_LIBS GSTREAMER_PLUGINS_BASE_CFLAGS GSTREAMER_PLUGINS_BASE_LIBS GST_PLUGIN_LDFLAGS GSTREAMER_FILE_READER GSTREAMER_MIXER_PROVIDER QT_CFLAGS QT_LIBS MOC MOZILLA_CFLAGS MOZILLA_LIBS GLIB_CFLAGS GLIB_LIBS PLUGIN_DIR USER_JAVAH CLASSPATH_INCLUDES GCJ JIKES JIKESENCODING JIKESWARNINGS KJC ECJ JAVAC FOUND_GCJ_TRUE FOUND_GCJ_FALSE FOUND_JIKES_TRUE FOUND_JIKES_FALSE FOUND_ECJ_TRUE FOUND_ECJ_FALSE FOUND_JAVAC_TRUE FOUND_JAVAC_FALSE FOUND_KJC_TRUE FOUND_KJC_FALSE USER_CLASSLIB USER_SPECIFIED_CLASSLIB_TRUE USER_SPECIFIED_CLASSLIB_FALSE vm_classes MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LIBDEBUG INIT_LOAD_LIBRARY ECJ_JAR JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION REMOVE MKDIR CP DATE FIND ZIP FASTJAR INSTALL_GLIBJ_ZIP_TRUE INSTALL_GLIBJ_ZIP_FALSE INSTALL_CLASS_FILES_TRUE INSTALL_CLASS_FILES_FALSE BUILD_CLASS_FILES_TRUE BUILD_CLASS_FILES_FALSE EXAMPLESDIR GJDOC CREATE_API_DOCS_TRUE CREATE_API_DOCS_FALSE JAY JAY_SKELETON REGEN_PARSERS_TRUE REGEN_PARSERS_FALSE USE_PREBUILT_GLIBJ_ZIP_TRUE USE_PREBUILT_GLIBJ_ZIP_FALSE PATH_TO_GLIBJ_ZIP USE_ESCHER_TRUE USE_ESCHER_FALSE PATH_TO_ESCHER ENABLE_LOCAL_SOCKETS_TRUE ENABLE_LOCAL_SOCKETS_FALSE DEFAULT_PREFS_PEER LIBOBJS LTLIBOBJS'
++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os JAVA_MAINTAINER_MODE_TRUE JAVA_MAINTAINER_MODE_FALSE GENINSRC_TRUE GENINSRC_FALSE multi_basedir LIBVERSION CLASSPATH_MODULE CLASSPATH_CONVENIENCE INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CREATE_COLLECTIONS_TRUE CREATE_COLLECTIONS_FALSE CREATE_JNI_LIBRARIES_TRUE CREATE_JNI_LIBRARIES_FALSE CREATE_CORE_JNI_LIBRARIES_TRUE CREATE_CORE_JNI_LIBRARIES_FALSE CREATE_GCONF_PEER_LIBRARIES_TRUE CREATE_GCONF_PEER_LIBRARIES_FALSE CREATE_GSTREAMER_PEER_LIBRARIES_TRUE CREATE_GSTREAMER_PEER_LIBRARIES_FALSE default_toolkit CREATE_XMLJ_LIBRARY_TRUE CREATE_XMLJ_LIBRARY_FALSE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP CREATE_ALSA_LIBRARIES_TRUE CREATE_ALSA_LIBRARIES_FALSE CREATE_DSSI_LIBRARIES_TRUE CREATE_DSSI_LIBRARIES_FALSE CREATE_GTK_PEER_LIBRARIES_TRUE CREATE_GTK_PEER_LIBRARIES_FALSE CREATE_QT_PEER_LIBRARIES_TRUE CREATE_QT_PEER_LIBRARIES_FALSE CREATE_PLUGIN_TRUE CREATE_PLUGIN_FALSE target_noncanonical toolexecdir toolexecmainlibdir toolexeclibdir nativeexeclibdir glibjdir VM_BINARY CREATE_JNI_HEADERS_TRUE CREATE_JNI_HEADERS_FALSE CREATE_WRAPPERS_TRUE CREATE_WRAPPERS_FALSE LN_S LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM AR ac_ct_AR RANLIB ac_ct_RANLIB lt_ECHO CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP PERL COLLECTIONS_PREFIX LIBMAGIC LIBICONV LTLIBICONV WARNING_CFLAGS STRICT_WARNING_CFLAGS ERROR_CFLAGS PKG_CONFIG XML_CFLAGS XML_LIBS XSLT_CFLAGS XSLT_LIBS X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS GTK_CFLAGS GTK_LIBS FREETYPE2_CFLAGS FREETYPE2_LIBS PANGOFT2_CFLAGS PANGOFT2_LIBS CAIRO_CFLAGS CAIRO_LIBS XTEST_LIBS GCONF_CFLAGS GCONF_LIBS GDK_CFLAGS GDK_LIBS GSTREAMER_CFLAGS GSTREAMER_LIBS GSTREAMER_BASE_CFLAGS GSTREAMER_BASE_LIBS GSTREAMER_PLUGINS_BASE_CFLAGS GSTREAMER_PLUGINS_BASE_LIBS GST_PLUGIN_LDFLAGS GSTREAMER_FILE_READER GSTREAMER_MIXER_PROVIDER QT_CFLAGS QT_LIBS MOC MOZILLA_CFLAGS MOZILLA_LIBS GLIB_CFLAGS GLIB_LIBS PLUGIN_DIR USER_JAVAH CLASSPATH_INCLUDES GCJ JIKES JIKESENCODING JIKESWARNINGS KJC ECJ JAVAC FOUND_GCJ_TRUE FOUND_GCJ_FALSE FOUND_JIKES_TRUE FOUND_JIKES_FALSE FOUND_ECJ_TRUE FOUND_ECJ_FALSE FOUND_JAVAC_TRUE FOUND_JAVAC_FALSE FOUND_KJC_TRUE FOUND_KJC_FALSE USER_CLASSLIB USER_SPECIFIED_CLASSLIB_TRUE USER_SPECIFIED_CLASSLIB_FALSE vm_classes MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LIBDEBUG INIT_LOAD_LIBRARY ECJ_JAR JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION REMOVE MKDIR CP DATE FIND ZIP FASTJAR INSTALL_GLIBJ_ZIP_TRUE INSTALL_GLIBJ_ZIP_FALSE INSTALL_CLASS_FILES_TRUE INSTALL_CLASS_FILES_FALSE BUILD_CLASS_FILES_TRUE BUILD_CLASS_FILES_FALSE EXAMPLESDIR GJDOC CREATE_API_DOCS_TRUE CREATE_API_DOCS_FALSE JAY JAY_SKELETON REGEN_PARSERS_TRUE REGEN_PARSERS_FALSE USE_PREBUILT_GLIBJ_ZIP_TRUE USE_PREBUILT_GLIBJ_ZIP_FALSE PATH_TO_GLIBJ_ZIP USE_ESCHER_TRUE USE_ESCHER_FALSE PATH_TO_ESCHER ENABLE_LOCAL_SOCKETS_TRUE ENABLE_LOCAL_SOCKETS_FALSE DEFAULT_PREFS_PEER LIBOBJS LTLIBOBJS'
+ ac_subst_files=''
+ # Initialize some variables set by options.
+@@ -1058,6 +1058,9 @@ Optional Features:
+                           default=no
+   --disable-plugin        compile gcjwebplugin (disabled by --disable-plugin)
+                           default=yes
++  --enable-version-specific-runtime-libs
++                          specify that runtime libraries should be installed
++                          in a compiler-specific directory
+   --enable-regen-headers  automatically regenerate JNI headers default=no
+   --enable-tool-wrappers  create tool wrapper binaries default=no
+   --enable-static[=PKGS]
+@@ -4753,16 +4756,64 @@ else
+ fi
++case ${host_alias} in
++  "") host_noncanonical=${build_noncanonical} ;;
++  *) host_noncanonical=${host_alias} ;;
++esac
++case ${target_alias} in
++  "") target_noncanonical=${host_noncanonical} ;;
++  *) target_noncanonical=${target_alias} ;;
++esac
++
++
++# Check whether --enable-version-specific-runtime-libs or --disable-version-specific-runtime-libs was given.
++if test "${enable_version_specific_runtime_libs+set}" = set; then
++  enableval="$enable_version_specific_runtime_libs"
++  case "$enableval" in
++      yes) version_specific_libs=yes ;;
++      no)  version_specific_libs=no ;;
++      *)   { { echo "$as_me:$LINENO: error: Unknown argument to enable/disable version-specific libs" >&5
++echo "$as_me: error: Unknown argument to enable/disable version-specific libs" >&2;}
++   { (exit 1); exit 1; }; };;
++     esac
++else
++  version_specific_libs=no
++
++fi;
+-  multi_os_directory=`$CC -print-multi-os-directory`
+-  case $multi_os_directory in
+-    .) toolexeclibdir=${libdir} ;; # Avoid trailing /.
+-    *) toolexeclibdir=${libdir}/${multi_os_directory} ;;
++  case ${version_specific_libs} in
++    yes)
++      # Need the gcc compiler version to know where to install libraries
++      # and header files if --enable-version-specific-runtime-libs option
++      # is selected.
++      includedir='$(libdir)/gcc/$(target_noncanonical)/$(gcc_version)/include/'
++      toolexecdir='$(libdir)/gcc/$(target_noncanonical)'
++      toolexecmainlibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)'
++      toolexeclibdir=$toolexecmainlibdir
++      ;;
++    no)
++      if test -n "$with_cross_host" &&
++       test x"$with_cross_host" != x"no"; then
++      # Install a library built with a cross compiler in tooldir, not libdir.
++      toolexecdir='$(exec_prefix)/$(target_noncanonical)'
++      toolexecmainlibdir='$(toolexecdir)/lib'
++      else
++      toolexecdir='$(libdir)/gcc-lib/$(target_noncanonical)'
++      toolexecmainlibdir='$(libdir)'
++      fi
++      multi_os_directory=`$CC -print-multi-os-directory`
++      case $multi_os_directory in
++      .) toolexeclibdir=$toolexecmainlibdir ;; # Avoid trailing /.
++      *) toolexeclibdir=$toolexecmainlibdir/$multi_os_directory ;;
++      esac
++      ;;
+   esac
++
++
+ # Check whether --with-native-libdir or --without-native-libdir was given.
+ if test "${with_native_libdir+set}" = set; then
+   withval="$with_native_libdir"
+@@ -5702,13 +5753,13 @@ if test "${lt_cv_nm_interface+set}" = se
+ else
+   lt_cv_nm_interface="BSD nm"
+   echo "int some_variable = 0;" > conftest.$ac_ext
+-  (eval echo "\"\$as_me:5705: $ac_compile\"" >&5)
++  (eval echo "\"\$as_me:5756: $ac_compile\"" >&5)
+   (eval "$ac_compile" 2>conftest.err)
+   cat conftest.err >&5
+-  (eval echo "\"\$as_me:5708: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
++  (eval echo "\"\$as_me:5759: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+   cat conftest.err >&5
+-  (eval echo "\"\$as_me:5711: output\"" >&5)
++  (eval echo "\"\$as_me:5762: output\"" >&5)
+   cat conftest.out >&5
+   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+     lt_cv_nm_interface="MS dumpbin"
+@@ -6752,7 +6803,7 @@ ia64-*-hpux*)
+   ;;
+ *-*-irix6*)
+   # Find out which ABI we are using.
+-  echo '#line 6755 "configure"' > conftest.$ac_ext
++  echo '#line 6806 "configure"' > conftest.$ac_ext
+   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+   (eval $ac_compile) 2>&5
+   ac_status=$?
+@@ -7384,11 +7435,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:7387: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:7438: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>conftest.err)
+    ac_status=$?
+    cat conftest.err >&5
+-   echo "$as_me:7391: \$? = $ac_status" >&5
++   echo "$as_me:7442: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s "$ac_outfile"; then
+      # The compiler can only warn and ignore the option if not recognized
+      # So say no if there are warnings other than the usual output.
+@@ -7706,11 +7757,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:7709: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:7760: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>conftest.err)
+    ac_status=$?
+    cat conftest.err >&5
+-   echo "$as_me:7713: \$? = $ac_status" >&5
++   echo "$as_me:7764: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s "$ac_outfile"; then
+      # The compiler can only warn and ignore the option if not recognized
+      # So say no if there are warnings other than the usual output.
+@@ -7811,11 +7862,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:7814: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:7865: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>out/conftest.err)
+    ac_status=$?
+    cat out/conftest.err >&5
+-   echo "$as_me:7818: \$? = $ac_status" >&5
++   echo "$as_me:7869: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s out/conftest2.$ac_objext
+    then
+      # The compiler can only warn and ignore the option if not recognized
+@@ -7866,11 +7917,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:7869: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:7920: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>out/conftest.err)
+    ac_status=$?
+    cat out/conftest.err >&5
+-   echo "$as_me:7873: \$? = $ac_status" >&5
++   echo "$as_me:7924: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s out/conftest2.$ac_objext
+    then
+      # The compiler can only warn and ignore the option if not recognized
+@@ -10718,7 +10769,7 @@ else
+   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+   lt_status=$lt_dlunknown
+   cat > conftest.$ac_ext <<_LT_EOF
+-#line 10721 "configure"
++#line 10772 "configure"
+ #include "confdefs.h"
+ #if HAVE_DLFCN_H
+@@ -10818,7 +10869,7 @@ else
+   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+   lt_status=$lt_dlunknown
+   cat > conftest.$ac_ext <<_LT_EOF
+-#line 10821 "configure"
++#line 10872 "configure"
+ #include "confdefs.h"
+ #if HAVE_DLFCN_H
+@@ -15215,11 +15266,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:15218: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:15269: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>conftest.err)
+    ac_status=$?
+    cat conftest.err >&5
+-   echo "$as_me:15222: \$? = $ac_status" >&5
++   echo "$as_me:15273: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s "$ac_outfile"; then
+      # The compiler can only warn and ignore the option if not recognized
+      # So say no if there are warnings other than the usual output.
+@@ -15314,11 +15365,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:15317: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:15368: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>out/conftest.err)
+    ac_status=$?
+    cat out/conftest.err >&5
+-   echo "$as_me:15321: \$? = $ac_status" >&5
++   echo "$as_me:15372: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s out/conftest2.$ac_objext
+    then
+      # The compiler can only warn and ignore the option if not recognized
+@@ -15366,11 +15417,11 @@ else
+    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+    -e 's:$: $lt_compiler_flag:'`
+-   (eval echo "\"\$as_me:15369: $lt_compile\"" >&5)
++   (eval echo "\"\$as_me:15420: $lt_compile\"" >&5)
+    (eval "$lt_compile" 2>out/conftest.err)
+    ac_status=$?
+    cat out/conftest.err >&5
+-   echo "$as_me:15373: \$? = $ac_status" >&5
++   echo "$as_me:15424: \$? = $ac_status" >&5
+    if (exit $ac_status) && test -s out/conftest2.$ac_objext
+    then
+      # The compiler can only warn and ignore the option if not recognized
+@@ -30956,6 +31007,9 @@ s,@CREATE_QT_PEER_LIBRARIES_TRUE@,$CREAT
+ s,@CREATE_QT_PEER_LIBRARIES_FALSE@,$CREATE_QT_PEER_LIBRARIES_FALSE,;t t
+ s,@CREATE_PLUGIN_TRUE@,$CREATE_PLUGIN_TRUE,;t t
+ s,@CREATE_PLUGIN_FALSE@,$CREATE_PLUGIN_FALSE,;t t
++s,@target_noncanonical@,$target_noncanonical,;t t
++s,@toolexecdir@,$toolexecdir,;t t
++s,@toolexecmainlibdir@,$toolexecmainlibdir,;t t
+ s,@toolexeclibdir@,$toolexeclibdir,;t t
+ s,@nativeexeclibdir@,$nativeexeclibdir,;t t
+ s,@glibjdir@,$glibjdir,;t t
+--- a/libjava/classpath/configure.ac
++++ b/libjava/classpath/configure.ac
+@@ -289,6 +289,16 @@ dnl defined to the same value for all mu
+ dnl so that we can refer to the multilib installation directories from
+ dnl classpath's build files.
+ dnl -----------------------------------------------------------
++AC_ARG_ENABLE(version-specific-runtime-libs,
++  AS_HELP_STRING([--enable-version-specific-runtime-libs],    
++                 [specify that runtime libraries should be installed in a compiler-specific directory]),
++    [case "$enableval" in
++      yes) version_specific_libs=yes ;;
++      no)  version_specific_libs=no ;;
++      *)   AC_MSG_ERROR([Unknown argument to enable/disable version-specific libs]);;
++     esac],
++    [version_specific_libs=no]
++)
+ CLASSPATH_TOOLEXECLIBDIR
+ dnl -----------------------------------------------------------
+--- a/libjava/classpath/doc/Makefile.in
++++ b/libjava/classpath/doc/Makefile.in
+@@ -334,9 +334,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ SUBDIRS = api
+ EXTRA_DIST = README.jaxp texi2pod.pl $(man_MANS)
+--- a/libjava/classpath/doc/api/Makefile.in
++++ b/libjava/classpath/doc/api/Makefile.in
+@@ -311,9 +311,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ @CREATE_API_DOCS_TRUE@noinst_DATA = html
+ sourcepath = $(top_builddir):$(top_srcdir):$(top_srcdir)/vm/reference:$(top_srcdir)/external/w3c_dom:$(top_srcdir)/external/sax
+--- a/libjava/classpath/examples/Makefile.in
++++ b/libjava/classpath/examples/Makefile.in
+@@ -320,9 +320,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ GLIBJ_CLASSPATH = '$(top_builddir)/lib':'$(top_builddir)/lib/glibj.zip':'$(top_builddir)/tools/tools.zip'
+ @FOUND_ECJ_FALSE@@FOUND_JAVAC_TRUE@JCOMPILER = $(JAVAC) -encoding UTF-8 -bootclasspath $(GLIBJ_CLASSPATH) -classpath .
+--- a/libjava/classpath/external/Makefile.in
++++ b/libjava/classpath/external/Makefile.in
+@@ -318,9 +318,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ SUBDIRS = sax w3c_dom relaxngDatatype jsr166
+ EXTRA_DIST = README
+--- a/libjava/classpath/external/jsr166/Makefile.in
++++ b/libjava/classpath/external/jsr166/Makefile.in
+@@ -309,9 +309,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ EXTRA_DIST = IMPORTING \
+ readme \
+--- a/libjava/classpath/external/relaxngDatatype/Makefile.in
++++ b/libjava/classpath/external/relaxngDatatype/Makefile.in
+@@ -309,9 +309,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ EXTRA_DIST = README.txt \
+ copying.txt \
+--- a/libjava/classpath/external/sax/Makefile.in
++++ b/libjava/classpath/external/sax/Makefile.in
+@@ -309,9 +309,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ EXTRA_DIST = README \
+ org/xml/sax/ext/Attributes2.java \
+--- a/libjava/classpath/external/w3c_dom/Makefile.in
++++ b/libjava/classpath/external/w3c_dom/Makefile.in
+@@ -309,9 +309,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ EXTRA_DIST = README \
+ org/w3c/dom/Attr.java \
+--- a/libjava/classpath/include/Makefile.in
++++ b/libjava/classpath/include/Makefile.in
+@@ -310,9 +310,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ DISTCLEANFILES = jni_md.h config-int.h
+ ARG_JNI_JAVAH = -jni
+--- a/libjava/classpath/lib/Makefile.in
++++ b/libjava/classpath/lib/Makefile.in
+@@ -314,9 +314,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ JAVA_DEPEND = java.dep
+ compile_classpath = $(vm_classes):$(top_srcdir):$(top_srcdir)/external/w3c_dom:$(top_srcdir)/external/sax:$(top_srcdir)/external/relaxngDatatype:$(top_srcdir)/external/jsr166:.:$(USER_CLASSLIB):$(PATH_TO_ESCHER)
+--- a/libjava/classpath/m4/acinclude.m4
++++ b/libjava/classpath/m4/acinclude.m4
+@@ -427,11 +427,45 @@ dnl GCJ LOCAL: Calculate toolexeclibdir
+ dnl -----------------------------------------------------------
+ AC_DEFUN([CLASSPATH_TOOLEXECLIBDIR],
+ [
+-  multi_os_directory=`$CC -print-multi-os-directory`
+-  case $multi_os_directory in
+-    .) toolexeclibdir=${libdir} ;; # Avoid trailing /.
+-    *) toolexeclibdir=${libdir}/${multi_os_directory} ;;
++  case ${host_alias} in
++    "") host_noncanonical=${build_noncanonical} ;;
++    *) host_noncanonical=${host_alias} ;;
+   esac
++  case ${target_alias} in
++    "") target_noncanonical=${host_noncanonical} ;;
++    *) target_noncanonical=${target_alias} ;;
++  esac
++  AC_SUBST(target_noncanonical)
++
++  case ${version_specific_libs} in
++    yes)
++      # Need the gcc compiler version to know where to install libraries
++      # and header files if --enable-version-specific-runtime-libs option
++      # is selected.
++      includedir='$(libdir)/gcc/$(target_noncanonical)/$(gcc_version)/include/'
++      toolexecdir='$(libdir)/gcc/$(target_noncanonical)'
++      toolexecmainlibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)'
++      toolexeclibdir=$toolexecmainlibdir
++      ;;
++    no)
++      if test -n "$with_cross_host" &&
++       test x"$with_cross_host" != x"no"; then
++      # Install a library built with a cross compiler in tooldir, not libdir.
++      toolexecdir='$(exec_prefix)/$(target_noncanonical)'
++      toolexecmainlibdir='$(toolexecdir)/lib'
++      else
++      toolexecdir='$(libdir)/gcc-lib/$(target_noncanonical)'
++      toolexecmainlibdir='$(libdir)'
++      fi
++      multi_os_directory=`$CC -print-multi-os-directory`
++      case $multi_os_directory in
++      .) toolexeclibdir=$toolexecmainlibdir ;; # Avoid trailing /.
++      *) toolexeclibdir=$toolexecmainlibdir/$multi_os_directory ;;
++      esac
++      ;;
++  esac
++  AC_SUBST(toolexecdir)
++  AC_SUBST(toolexecmainlibdir)
+   AC_SUBST(toolexeclibdir)
+ ])
+--- a/libjava/classpath/native/Makefile.in
++++ b/libjava/classpath/native/Makefile.in
+@@ -317,9 +317,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ @CREATE_JNI_LIBRARIES_TRUE@JNIDIR = jni
+ @CREATE_GTK_PEER_LIBRARIES_TRUE@JAWTDIR = jawt
+--- a/libjava/classpath/native/fdlibm/Makefile.in
++++ b/libjava/classpath/native/fdlibm/Makefile.in
+@@ -336,9 +336,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ noinst_LTLIBRARIES = libfdlibm.la 
+ libfdlibm_la_SOURCES = \
+--- a/libjava/classpath/native/jawt/Makefile.in
++++ b/libjava/classpath/native/jawt/Makefile.in
+@@ -336,9 +336,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ nativeexeclib_LTLIBRARIES = libjawt.la
+ libjawt_la_SOURCES = jawt.c
+--- a/libjava/classpath/native/jni/Makefile.in
++++ b/libjava/classpath/native/jni/Makefile.in
+@@ -317,9 +317,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ @CREATE_CORE_JNI_LIBRARIES_TRUE@JNIDIRS = native-lib java-io java-lang java-net java-nio java-util
+ @CREATE_ALSA_LIBRARIES_TRUE@ALSADIR = midi-alsa
+--- a/libjava/classpath/native/jni/classpath/Makefile.in
++++ b/libjava/classpath/native/jni/classpath/Makefile.in
+@@ -327,9 +327,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ # Header needed for jawt implementations such as the one found in ../gtk-peer.
+--- a/libjava/classpath/native/jni/gconf-peer/Makefile.in
++++ b/libjava/classpath/native/jni/gconf-peer/Makefile.in
+@@ -336,9 +336,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ nativeexeclib_LTLIBRARIES = libgconfpeer.la
+ libgconfpeer_la_SOURCES = GConfNativePeer.c
+--- a/libjava/classpath/native/jni/gstreamer-peer/Makefile.in
++++ b/libjava/classpath/native/jni/gstreamer-peer/Makefile.in
+@@ -337,9 +337,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ nativeexeclib_LTLIBRARIES = libgstreamerpeer.la
+ libgstreamerpeer_la_SOURCES = GStreamerIOPeer.c \
+--- a/libjava/classpath/native/jni/gtk-peer/Makefile.in
++++ b/libjava/classpath/native/jni/gtk-peer/Makefile.in
+@@ -374,9 +374,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ nativeexeclib_LTLIBRARIES = libgtkpeer.la
+--- a/libjava/classpath/native/jni/java-io/Makefile.in
++++ b/libjava/classpath/native/jni/java-io/Makefile.in
+@@ -338,9 +338,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ nativeexeclib_LTLIBRARIES = libjavaio.la 
+ libjavaio_la_SOURCES = java_io_VMFile.c \
+--- a/libjava/classpath/native/jni/java-lang/Makefile.in
++++ b/libjava/classpath/native/jni/java-lang/Makefile.in
+@@ -352,9 +352,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ nativeexeclib_LTLIBRARIES = libjavalang.la libjavalangreflect.la libjavalangmanagement.la
+ libjavalang_la_SOURCES = java_lang_VMSystem.c \
+--- a/libjava/classpath/native/jni/java-net/Makefile.in
++++ b/libjava/classpath/native/jni/java-net/Makefile.in
+@@ -348,9 +348,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ nativeexeclib_LTLIBRARIES = libjavanet.la
+ @ENABLE_LOCAL_SOCKETS_FALSE@local_sources = gnu_java_net_local_LocalSocketImpl.c
+--- a/libjava/classpath/native/jni/java-nio/Makefile.in
++++ b/libjava/classpath/native/jni/java-nio/Makefile.in
+@@ -346,9 +346,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ nativeexeclib_LTLIBRARIES = libjavanio.la
+ libjavanio_la_SOURCES = gnu_java_nio_VMPipe.c \
+--- a/libjava/classpath/native/jni/java-util/Makefile.in
++++ b/libjava/classpath/native/jni/java-util/Makefile.in
+@@ -335,9 +335,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ nativeexeclib_LTLIBRARIES = libjavautil.la
+ libjavautil_la_SOURCES = java_util_VMTimeZone.c
+--- a/libjava/classpath/native/jni/midi-alsa/Makefile.in
++++ b/libjava/classpath/native/jni/midi-alsa/Makefile.in
+@@ -338,9 +338,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ nativeexeclib_LTLIBRARIES = libgjsmalsa.la 
+ libgjsmalsa_la_SOURCES = gnu_javax_sound_midi_alsa_AlsaMidiSequencerDevice.c \
+--- a/libjava/classpath/native/jni/midi-dssi/Makefile.in
++++ b/libjava/classpath/native/jni/midi-dssi/Makefile.in
+@@ -338,9 +338,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ nativeexeclib_LTLIBRARIES = libgjsmdssi.la 
+ libgjsmdssi_la_SOURCES = gnu_javax_sound_midi_dssi_DSSIMidiDeviceProvider.c \
+--- a/libjava/classpath/native/jni/native-lib/Makefile.in
++++ b/libjava/classpath/native/jni/native-lib/Makefile.in
+@@ -327,9 +327,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ noinst_LTLIBRARIES = libclasspathnative.la
+ libclasspathnative_la_SOURCES = cpnet.c \
+--- a/libjava/classpath/native/jni/qt-peer/Makefile.in
++++ b/libjava/classpath/native/jni/qt-peer/Makefile.in
+@@ -353,9 +353,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ noinst_LTLIBRARIES = libqtpeer.la
+ AM_LDFLAGS = @CLASSPATH_MODULE@ @QT_LIBS@
+--- a/libjava/classpath/native/jni/xmlj/Makefile.in
++++ b/libjava/classpath/native/jni/xmlj/Makefile.in
+@@ -337,9 +337,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ nativeexeclib_LTLIBRARIES = libxmlj.la
+ libxmlj_la_SOURCES = \
+--- a/libjava/classpath/native/plugin/Makefile.in
++++ b/libjava/classpath/native/plugin/Makefile.in
+@@ -335,9 +335,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ nativeexeclib_LTLIBRARIES = libgcjwebplugin.la
+ libgcjwebplugin_la_SOURCES = gcjwebplugin.cc
+--- a/libjava/classpath/resource/Makefile.in
++++ b/libjava/classpath/resource/Makefile.in
+@@ -320,9 +320,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ logging_DATA = java/util/logging/logging.properties
+ loggingdir = $(toolexeclibdir)
+--- a/libjava/classpath/scripts/Makefile.in
++++ b/libjava/classpath/scripts/Makefile.in
+@@ -310,9 +310,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ EXTRA_DIST = check_jni_methods.sh generate-locale-list.sh import-cacerts.sh
+ all: all-am
+--- a/libjava/classpath/tools/Makefile.in
++++ b/libjava/classpath/tools/Makefile.in
+@@ -412,9 +412,12 @@ sysconfdir = @sysconfdir@
+ target = @target@
+ target_alias = @target_alias@
+ target_cpu = @target_cpu@
++target_noncanonical = @target_noncanonical@
+ target_os = @target_os@
+ target_vendor = @target_vendor@
++toolexecdir = @toolexecdir@
+ toolexeclibdir = @toolexeclibdir@
++toolexecmainlibdir = @toolexecmainlibdir@
+ vm_classes = @vm_classes@
+ GLIBJ_BOOTCLASSPATH = '$(top_srcdir)/lib'
+ GLIBJ_CLASSPATH = $(srcdir)/asm
+--- a/libjava/configure
++++ b/libjava/configure
+@@ -18552,6 +18552,9 @@ if { (eval echo "$as_me:$LINENO: \"$ac_c
+     enable_sjlj_exceptions=yes
+   elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then
+     enable_sjlj_exceptions=no
++  elif grep __cxa_end_cleanup conftest.s >/dev/null 2>&1 ; then
++    # ARM EH ABI.
++    enable_sjlj_exceptions=no
+   fi
+ fi
+ CXXFLAGS="$old_CXXFLAGS"
+@@ -26229,10 +26232,10 @@ gcjsubdir=gcj-$gcjversion-$libgcj_sovers
+ multi_os_directory=`$CC -print-multi-os-directory`
+ case $multi_os_directory in
+   .)
+-   dbexecdir='$(libdir)/'$gcjsubdir # Avoid /.
++   dbexecdir='$(toolexeclibdir)/'$gcjsubdir # Avoid /.
+    ;;
+   *)
+-   dbexecdir='$(libdir)/'$multi_os_directory/$gcjsubdir
++   dbexecdir='$(toolexeclibdir)/'$multi_os_directory/$gcjsubdir
+    ;;
+ esac
+--- a/libjava/configure.ac
++++ b/libjava/configure.ac
+@@ -605,6 +605,9 @@ if AC_TRY_EVAL(ac_compile); then
+     enable_sjlj_exceptions=yes
+   elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then
+     enable_sjlj_exceptions=no
++  elif grep __cxa_end_cleanup conftest.s >/dev/null 2>&1 ; then
++    # ARM EH ABI.
++    enable_sjlj_exceptions=no
+   fi
+ fi
+ CXXFLAGS="$old_CXXFLAGS"
+@@ -1406,10 +1409,10 @@ gcjsubdir=gcj-$gcjversion-$libgcj_sovers
+ multi_os_directory=`$CC -print-multi-os-directory`
+ case $multi_os_directory in
+   .)
+-   dbexecdir='$(libdir)/'$gcjsubdir # Avoid /.
++   dbexecdir='$(toolexeclibdir)/'$gcjsubdir # Avoid /.
+    ;;
+   *)
+-   dbexecdir='$(libdir)/'$multi_os_directory/$gcjsubdir
++   dbexecdir='$(toolexeclibdir)/'$multi_os_directory/$gcjsubdir
+    ;;
+ esac
+ AC_SUBST(dbexecdir)
+--- a/libstdc++-v3/Makefile.in
++++ b/libstdc++-v3/Makefile.in
+@@ -189,6 +189,8 @@ LIBMATHOBJS = @LIBMATHOBJS@
+ LIBOBJS = @LIBOBJS@
+ LIBS = @LIBS@
+ LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@
++LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@
++LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBICONV = @LTLIBICONV@
+--- a/libstdc++-v3/config.h.in
++++ b/libstdc++-v3/config.h.in
+@@ -114,12 +114,6 @@
+ /* Define to 1 if you have the `frexpl' function. */
+ #undef HAVE_FREXPL
+-/* Define to 1 if you have the <gconf.h> header file. */
+-#undef HAVE_GCONF_H
+-
+-/* Define to 1 if you have the <gconv.h> header file. */
+-#undef HAVE_GCONV_H
+-
+ /* Define if _Unwind_GetIPInfo is available. */
+ #undef HAVE_GETIPINFO
+--- a/libstdc++-v3/config/cpu/mips/atomicity.h
++++ b/libstdc++-v3/config/cpu/mips/atomicity.h
+@@ -41,16 +41,18 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
+     
+     __asm__ __volatile__
+       ("/* Inline exchange & add */\n\t"
+-       "1:\n\t"
+        ".set  push\n\t"
+ #if _MIPS_SIM == _ABIO32
+        ".set  mips2\n\t"
+ #endif
++       "sync  \n\t"
++       "1:\n\t"
+        "ll    %0,0(%2)\n\t"
+        "addu  %1,%3,%0\n\t"
+        "sc    %1,0(%2)\n\t"
+-       ".set  pop\n\t"
+        "beqz  %1,1b\n\t"
++       "sync  \n\t"
++       ".set  pop\n\t"
+        "/* End exchange & add */"
+        : "=&r"(__result), "=&r"(__tmp)
+        : "r"(__mem), "r"(__val)
+@@ -67,16 +69,18 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
+     
+     __asm__ __volatile__
+       ("/* Inline atomic add */\n\t"
+-       "1:\n\t"
+        ".set  push\n\t"
+ #if _MIPS_SIM == _ABIO32
+        ".set  mips2\n\t"
+ #endif
++       "sync  \n\t"
++       "1:\n\t"
+        "ll    %0,0(%1)\n\t"
+        "addu  %0,%2,%0\n\t"
+        "sc    %0,0(%1)\n\t"
+-       ".set  pop\n\t"
+        "beqz  %0,1b\n\t"
++       "sync  \n\t"
++       ".set  pop\n\t"
+        "/* End atomic add */"
+        : "=&r"(__result)
+        : "r"(__mem), "r"(__val)
+--- a/libstdc++-v3/config/cpu/sh/atomicity.h
++++ b/libstdc++-v3/config/cpu/sh/atomicity.h
+@@ -30,47 +30,48 @@
+ #ifdef __SH4A__
+-#ifndef _GLIBCXX_ATOMICITY_H
+-#define _GLIBCXX_ATOMICITY_H  1
++#include <ext/atomicity.h>
+-typedef int _Atomic_word;
++_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
+-static inline _Atomic_word
+-__attribute__ ((__unused__))
+-__exchange_and_add (volatile _Atomic_word* __mem, int __val)
+-{
+-  _Atomic_word __result;
++  typedef int _Atomic_word;
+-  __asm__ __volatile__
+-    ("0:\n"
+-     "\tmovli.l\t@%2,r0\n"
+-     "\tmov\tr0,%1\n"
+-     "\tadd\t%3,r0\n"
+-     "\tmovco.l\tr0,@%2\n"
+-     "\tbf\t0b"
+-     : "+m" (*__mem), "=r" (__result)
+-     : "r" (__mem), "rI08" (__val)
+-     : "r0");
+-
+-  return __result;
+-}
+-
+-
+-static inline void
+-__attribute__ ((__unused__))
+-__atomic_add (volatile _Atomic_word* __mem, int __val)
+-{
+-  asm("0:\n"
+-      "\tmovli.l\t@%1,r0\n"
+-      "\tadd\t%2,r0\n"
+-      "\tmovco.l\tr0,@%1\n"
+-      "\tbf\t0b"
+-      : "+m" (*__mem)
+-      : "r" (__mem), "rI08" (__val)
+-      : "r0");
+-}
++  _Atomic_word
++  __attribute__ ((__unused__))
++  __exchange_and_add (volatile _Atomic_word* __mem, int __val)
++  {
++    _Atomic_word __result;
+-#endif
++    __asm__ __volatile__
++      ("0:\n"
++       "\tmovli.l\t@%2,r0\n"
++       "\tmov\tr0,%1\n"
++       "\tadd\t%3,r0\n"
++       "\tmovco.l\tr0,@%2\n"
++       "\tbf\t0b"
++       : "+m" (*__mem), "=r" (__result)
++       : "r" (__mem), "rI08" (__val)
++       : "r0");
++
++    return __result;
++  }
++
++
++  void
++  __attribute__ ((__unused__))
++  __atomic_add (volatile _Atomic_word* __mem, int __val)
++  {
++    asm("0:\n"
++      "\tmovli.l\t@%1,r0\n"
++      "\tadd\t%2,r0\n"
++      "\tmovco.l\tr0,@%1\n"
++      "\tbf\t0b"
++      : "+m" (*__mem)
++      : "r" (__mem), "rI08" (__val)
++      : "r0");
++  }
++
++_GLIBCXX_END_NAMESPACE
+ #else /* !__SH4A__ */
+--- /dev/null
++++ b/libstdc++-v3/config/os/gnu-linux/arm-eabi-extra.ver
+@@ -0,0 +1,18 @@
++# Appended to version file.
++
++CXXABI_ARM_1.3.3 {
++   # ARM ABI helper functions provided in libsupc++.
++   __aeabi_atexit;
++   __aeabi_vec_ctor_nocookie_nodtor;
++   __aeabi_vec_ctor_cookie_nodtor;
++   __aeabi_vec_cctor_nocookie_nodtor;
++   __aeabi_vec_new_cookie_noctor;
++   __aeabi_vec_new_nocookie;
++   __aeabi_vec_new_cookie_nodtor;
++   __aeabi_vec_new_cookie;
++   __aeabi_vec_dtor;
++   __aeabi_vec_dtor_cookie;
++   __aeabi_vec_delete;
++   __aeabi_vec_delete3;
++   __aeabi_vec_delete3_nodtor;
++};
+--- a/libstdc++-v3/configure
++++ b/libstdc++-v3/configure
+@@ -458,7 +458,7 @@ ac_includes_default="\
+ # include <unistd.h>
+ #endif"
+-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libtool_VERSION multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar glibcxx_builddir glibcxx_srcdir toplevel_srcdir CC ac_ct_CC EXEEXT OBJEXT CXX ac_ct_CXX CFLAGS CXXFLAGS LN_S AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CPP CPPFLAGS EGREP LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM lt_ECHO LDFLAGS CXXCPP enable_shared enable_static GLIBCXX_HOSTED_TRUE GLIBCXX_HOSTED_FALSE GLIBCXX_BUILD_PCH_TRUE GLIBCXX_BUILD_PCH_FALSE glibcxx_PCHFLAGS CSTDIO_H BASIC_FILE_H BASIC_FILE_CC check_msgfmt glibcxx_MOFILES glibcxx_POFILES glibcxx_localedir USE_NLS CLOCALE_H CMESSAGES_H CCODECVT_CC CCOLLATE_CC CCTYPE_CC CMESSAGES_CC CMONEY_CC CNUMERIC_CC CTIME_H CTIME_CC CLOCALE_CC CLOCALE_INTERNAL_H ALLOCATOR_H ALLOCATOR_NAME C_INCLUDE_DIR GLIBCXX_C_HEADERS_C_TRUE GLIBCXX_C_HEADERS_C_FALSE GLIBCXX_C_HEADERS_C_STD_TRUE GLIBCXX_C_HEADERS_C_STD_FALSE GLIBCXX_C_HEADERS_C_GLOBAL_TRUE GLIBCXX_C_HEADERS_C_GLOBAL_FALSE GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE GLIBCXX_C_HEADERS_EXTRA_TRUE GLIBCXX_C_HEADERS_EXTRA_FALSE DEBUG_FLAGS GLIBCXX_BUILD_DEBUG_TRUE GLIBCXX_BUILD_DEBUG_FALSE ENABLE_PARALLEL_TRUE ENABLE_PARALLEL_FALSE EXTRA_CXX_FLAGS glibcxx_thread_h WERROR SECTION_FLAGS SECTION_LDFLAGS OPT_LDFLAGS LIBMATHOBJS LIBICONV LTLIBICONV SYMVER_FILE port_specific_symbol_files ENABLE_SYMVERS_TRUE ENABLE_SYMVERS_FALSE ENABLE_SYMVERS_GNU_TRUE ENABLE_SYMVERS_GNU_FALSE ENABLE_SYMVERS_GNU_NAMESPACE_TRUE ENABLE_SYMVERS_GNU_NAMESPACE_FALSE ENABLE_SYMVERS_DARWIN_TRUE ENABLE_SYMVERS_DARWIN_FALSE ENABLE_VISIBILITY_TRUE ENABLE_VISIBILITY_FALSE GLIBCXX_LDBL_COMPAT_TRUE GLIBCXX_LDBL_COMPAT_FALSE baseline_dir ATOMICITY_SRCDIR ATOMIC_WORD_SRCDIR ATOMIC_FLAGS CPU_DEFINES_SRCDIR ABI_TWEAKS_SRCDIR OS_INC_SRCDIR ERROR_CONSTANTS_SRCDIR glibcxx_prefixdir gxx_include_dir glibcxx_toolexecdir glibcxx_toolexeclibdir GLIBCXX_INCLUDES TOPLEVEL_INCLUDES OPTIMIZE_CXXFLAGS WARN_FLAGS LIBSUPCXX_PICFLAGS LIBOBJS LTLIBOBJS'
++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libtool_VERSION multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar glibcxx_builddir glibcxx_srcdir toplevel_srcdir CC ac_ct_CC EXEEXT OBJEXT CXX ac_ct_CXX CFLAGS CXXFLAGS LN_S AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CPP CPPFLAGS EGREP LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM lt_ECHO LDFLAGS CXXCPP enable_shared enable_static GLIBCXX_HOSTED_TRUE GLIBCXX_HOSTED_FALSE GLIBCXX_BUILD_PCH_TRUE GLIBCXX_BUILD_PCH_FALSE glibcxx_PCHFLAGS CSTDIO_H BASIC_FILE_H BASIC_FILE_CC check_msgfmt glibcxx_MOFILES glibcxx_POFILES glibcxx_localedir USE_NLS CLOCALE_H CMESSAGES_H CCODECVT_CC CCOLLATE_CC CCTYPE_CC CMESSAGES_CC CMONEY_CC CNUMERIC_CC CTIME_H CTIME_CC CLOCALE_CC CLOCALE_INTERNAL_H ALLOCATOR_H ALLOCATOR_NAME C_INCLUDE_DIR GLIBCXX_C_HEADERS_C_TRUE GLIBCXX_C_HEADERS_C_FALSE GLIBCXX_C_HEADERS_C_STD_TRUE GLIBCXX_C_HEADERS_C_STD_FALSE GLIBCXX_C_HEADERS_C_GLOBAL_TRUE GLIBCXX_C_HEADERS_C_GLOBAL_FALSE GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE GLIBCXX_C_HEADERS_EXTRA_TRUE GLIBCXX_C_HEADERS_EXTRA_FALSE DEBUG_FLAGS GLIBCXX_BUILD_DEBUG_TRUE GLIBCXX_BUILD_DEBUG_FALSE ENABLE_PARALLEL_TRUE ENABLE_PARALLEL_FALSE EXTRA_CXX_FLAGS glibcxx_thread_h WERROR SECTION_FLAGS SECTION_LDFLAGS OPT_LDFLAGS LIBMATHOBJS LIBICONV LTLIBICONV SYMVER_FILE port_specific_symbol_files ENABLE_SYMVERS_TRUE ENABLE_SYMVERS_FALSE ENABLE_SYMVERS_GNU_TRUE ENABLE_SYMVERS_GNU_FALSE ENABLE_SYMVERS_GNU_NAMESPACE_TRUE ENABLE_SYMVERS_GNU_NAMESPACE_FALSE ENABLE_SYMVERS_DARWIN_TRUE ENABLE_SYMVERS_DARWIN_FALSE ENABLE_VISIBILITY_TRUE ENABLE_VISIBILITY_FALSE GLIBCXX_LDBL_COMPAT_TRUE GLIBCXX_LDBL_COMPAT_FALSE baseline_dir ATOMICITY_SRCDIR ATOMIC_WORD_SRCDIR ATOMIC_FLAGS CPU_DEFINES_SRCDIR ABI_TWEAKS_SRCDIR OS_INC_SRCDIR ERROR_CONSTANTS_SRCDIR LIBSUPCXX_PRONLY_TRUE LIBSUPCXX_PRONLY_FALSE glibcxx_prefixdir gxx_include_dir glibcxx_toolexecdir glibcxx_toolexeclibdir GLIBCXX_INCLUDES TOPLEVEL_INCLUDES OPTIMIZE_CXXFLAGS WARN_FLAGS LIBSUPCXX_PICFLAGS LIBOBJS LTLIBOBJS'
+ ac_subst_files=''
+ # Initialize some variables set by options.
+@@ -17195,9 +17195,8 @@ if $GLIBCXX_IS_NATIVE; then
+-
+ for ac_header in nan.h ieeefp.h endian.h sys/isa_defs.h machine/endian.h \
+-  machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h gconv.h \
++  machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h \
+   sys/types.h sys/ipc.h sys/sem.h
+ do
+ as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+@@ -62933,9 +62932,8 @@ _ACEOF
+-
+ for ac_header in nan.h ieeefp.h endian.h sys/isa_defs.h machine/endian.h \
+-    machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h gconv.h \
++    machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h \
+     sys/types.h
+ do
+ as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+@@ -86333,11 +86331,10 @@ _ACEOF
+-
+ for ac_header in nan.h ieeefp.h endian.h sys/isa_defs.h \
+       machine/endian.h machine/param.h sys/machine.h sys/types.h \
+       fp.h float.h endian.h inttypes.h locale.h float.h stdint.h \
+-      sys/ipc.h sys/sem.h gconf.h
++      sys/ipc.h sys/sem.h
+ do
+ as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ if eval "test \"\${$as_ac_Header+set}\" = set"; then
+@@ -108853,6 +108850,223 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
++    cat >>confdefs.h <<\_ACEOF
++#define _GLIBCXX_USE_RANDOM_TR1 1
++_ACEOF
++
++
++
++  if test "${ac_cv_header_locale_h+set}" = set; then
++  echo "$as_me:$LINENO: checking for locale.h" >&5
++echo $ECHO_N "checking for locale.h... $ECHO_C" >&6
++if test "${ac_cv_header_locale_h+set}" = set; then
++  echo $ECHO_N "(cached) $ECHO_C" >&6
++fi
++echo "$as_me:$LINENO: result: $ac_cv_header_locale_h" >&5
++echo "${ECHO_T}$ac_cv_header_locale_h" >&6
++else
++  # Is the header compilable?
++echo "$as_me:$LINENO: checking locale.h usability" >&5
++echo $ECHO_N "checking locale.h usability... $ECHO_C" >&6
++cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++$ac_includes_default
++#include <locale.h>
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++  (eval $ac_compile) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } &&
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
++  ac_header_compiler=yes
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++ac_header_compiler=no
++fi
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
++echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
++echo "${ECHO_T}$ac_header_compiler" >&6
++
++# Is the header present?
++echo "$as_me:$LINENO: checking locale.h presence" >&5
++echo $ECHO_N "checking locale.h presence... $ECHO_C" >&6
++cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++#include <locale.h>
++_ACEOF
++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
++  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } >/dev/null; then
++  if test -s conftest.err; then
++    ac_cpp_err=$ac_c_preproc_warn_flag
++    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
++  else
++    ac_cpp_err=
++  fi
++else
++  ac_cpp_err=yes
++fi
++if test -z "$ac_cpp_err"; then
++  ac_header_preproc=yes
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++  ac_header_preproc=no
++fi
++rm -f conftest.err conftest.$ac_ext
++echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
++echo "${ECHO_T}$ac_header_preproc" >&6
++
++# So?  What about this header?
++case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
++  yes:no: )
++    { echo "$as_me:$LINENO: WARNING: locale.h: accepted by the compiler, rejected by the preprocessor!" >&5
++echo "$as_me: WARNING: locale.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
++    { echo "$as_me:$LINENO: WARNING: locale.h: proceeding with the compiler's result" >&5
++echo "$as_me: WARNING: locale.h: proceeding with the compiler's result" >&2;}
++    ac_header_preproc=yes
++    ;;
++  no:yes:* )
++    { echo "$as_me:$LINENO: WARNING: locale.h: present but cannot be compiled" >&5
++echo "$as_me: WARNING: locale.h: present but cannot be compiled" >&2;}
++    { echo "$as_me:$LINENO: WARNING: locale.h:     check for missing prerequisite headers?" >&5
++echo "$as_me: WARNING: locale.h:     check for missing prerequisite headers?" >&2;}
++    { echo "$as_me:$LINENO: WARNING: locale.h: see the Autoconf documentation" >&5
++echo "$as_me: WARNING: locale.h: see the Autoconf documentation" >&2;}
++    { echo "$as_me:$LINENO: WARNING: locale.h:     section \"Present But Cannot Be Compiled\"" >&5
++echo "$as_me: WARNING: locale.h:     section \"Present But Cannot Be Compiled\"" >&2;}
++    { echo "$as_me:$LINENO: WARNING: locale.h: proceeding with the preprocessor's result" >&5
++echo "$as_me: WARNING: locale.h: proceeding with the preprocessor's result" >&2;}
++    { echo "$as_me:$LINENO: WARNING: locale.h: in the future, the compiler will take precedence" >&5
++echo "$as_me: WARNING: locale.h: in the future, the compiler will take precedence" >&2;}
++    (
++      cat <<\_ASBOX
++## ----------------------------------------- ##
++## Report this to the package-unused lists.  ##
++## ----------------------------------------- ##
++_ASBOX
++    ) |
++      sed "s/^/$as_me: WARNING:     /" >&2
++    ;;
++esac
++echo "$as_me:$LINENO: checking for locale.h" >&5
++echo $ECHO_N "checking for locale.h... $ECHO_C" >&6
++if test "${ac_cv_header_locale_h+set}" = set; then
++  echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++  ac_cv_header_locale_h=$ac_header_preproc
++fi
++echo "$as_me:$LINENO: result: $ac_cv_header_locale_h" >&5
++echo "${ECHO_T}$ac_cv_header_locale_h" >&6
++
++fi
++if test $ac_cv_header_locale_h = yes; then
++
++    echo "$as_me:$LINENO: checking for LC_MESSAGES" >&5
++echo $ECHO_N "checking for LC_MESSAGES... $ECHO_C" >&6
++if test "${ac_cv_val_LC_MESSAGES+set}" = set; then
++  echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++  if test x$gcc_no_link = xyes; then
++  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
++echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
++   { (exit 1); exit 1; }; }
++fi
++cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++#include <locale.h>
++int
++main ()
++{
++return LC_MESSAGES
++  ;
++  return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++  (eval $ac_link) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } &&
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest$ac_exeext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
++  ac_cv_val_LC_MESSAGES=yes
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++ac_cv_val_LC_MESSAGES=no
++fi
++rm -f conftest.err conftest.$ac_objext \
++      conftest$ac_exeext conftest.$ac_ext
++fi
++echo "$as_me:$LINENO: result: $ac_cv_val_LC_MESSAGES" >&5
++echo "${ECHO_T}$ac_cv_val_LC_MESSAGES" >&6
++    if test $ac_cv_val_LC_MESSAGES = yes; then
++
++cat >>confdefs.h <<\_ACEOF
++#define HAVE_LC_MESSAGES 1
++_ACEOF
++
++    fi
++
++fi
++
++
++
++
+     # Check for sigsetjmp
+     cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+@@ -108905,6 +109119,266 @@ sed 's/^/| /' conftest.$ac_ext >&5
+ fi
+ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
++
++    cat >>confdefs.h <<\_ACEOF
++#define HAVE_MMAP 1
++_ACEOF
++
++
++    # For iconv support.
++
++
++
++
++
++          am_save_CPPFLAGS="$CPPFLAGS"
++
++  for element in $INCICONV; do
++    haveit=
++    for x in $CPPFLAGS; do
++
++  acl_save_prefix="$prefix"
++  prefix="$acl_final_prefix"
++  acl_save_exec_prefix="$exec_prefix"
++  exec_prefix="$acl_final_exec_prefix"
++  eval x=\"$x\"
++  exec_prefix="$acl_save_exec_prefix"
++  prefix="$acl_save_prefix"
++
++      if test "X$x" = "X$element"; then
++        haveit=yes
++        break
++      fi
++    done
++    if test -z "$haveit"; then
++      CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element"
++    fi
++  done
++
++
++  echo "$as_me:$LINENO: checking for iconv" >&5
++echo $ECHO_N "checking for iconv... $ECHO_C" >&6
++if test "${am_cv_func_iconv+set}" = set; then
++  echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++
++    am_cv_func_iconv="no, consider installing GNU libiconv"
++    am_cv_lib_iconv=no
++    if test x$gcc_no_link = xyes; then
++  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
++echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
++   { (exit 1); exit 1; }; }
++fi
++cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++#include <stdlib.h>
++#include <iconv.h>
++int
++main ()
++{
++iconv_t cd = iconv_open("","");
++       iconv(cd,NULL,NULL,NULL,NULL);
++       iconv_close(cd);
++  ;
++  return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++  (eval $ac_link) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } &&
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest$ac_exeext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
++  am_cv_func_iconv=yes
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++fi
++rm -f conftest.err conftest.$ac_objext \
++      conftest$ac_exeext conftest.$ac_ext
++    if test "$am_cv_func_iconv" != yes; then
++      am_save_LIBS="$LIBS"
++      LIBS="$LIBS $LIBICONV"
++      if test x$gcc_no_link = xyes; then
++  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
++echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
++   { (exit 1); exit 1; }; }
++fi
++cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++#include <stdlib.h>
++#include <iconv.h>
++int
++main ()
++{
++iconv_t cd = iconv_open("","");
++         iconv(cd,NULL,NULL,NULL,NULL);
++         iconv_close(cd);
++  ;
++  return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++  (eval $ac_link) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } &&
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest$ac_exeext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
++  am_cv_lib_iconv=yes
++        am_cv_func_iconv=yes
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++fi
++rm -f conftest.err conftest.$ac_objext \
++      conftest$ac_exeext conftest.$ac_ext
++      LIBS="$am_save_LIBS"
++    fi
++
++fi
++echo "$as_me:$LINENO: result: $am_cv_func_iconv" >&5
++echo "${ECHO_T}$am_cv_func_iconv" >&6
++  if test "$am_cv_func_iconv" = yes; then
++
++cat >>confdefs.h <<\_ACEOF
++#define HAVE_ICONV 1
++_ACEOF
++
++  fi
++  if test "$am_cv_lib_iconv" = yes; then
++    echo "$as_me:$LINENO: checking how to link with libiconv" >&5
++echo $ECHO_N "checking how to link with libiconv... $ECHO_C" >&6
++    echo "$as_me:$LINENO: result: $LIBICONV" >&5
++echo "${ECHO_T}$LIBICONV" >&6
++  else
++            CPPFLAGS="$am_save_CPPFLAGS"
++    LIBICONV=
++    LTLIBICONV=
++  fi
++
++
++
++  if test "$am_cv_func_iconv" = yes; then
++    echo "$as_me:$LINENO: checking for iconv declaration" >&5
++echo $ECHO_N "checking for iconv declaration... $ECHO_C" >&6
++    if test "${am_cv_proto_iconv+set}" = set; then
++  echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++
++      cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++
++#include <stdlib.h>
++#include <iconv.h>
++extern
++#ifdef __cplusplus
++"C"
++#endif
++#if defined(__STDC__) || defined(__cplusplus)
++size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
++#else
++size_t iconv();
++#endif
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++  (eval $ac_compile) 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } &&
++       { ac_try='test -z "$ac_c_werror_flag"
++                       || test ! -s conftest.err'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; } &&
++       { ac_try='test -s conftest.$ac_objext'
++  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); }; }; then
++  am_cv_proto_iconv_arg1=""
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++am_cv_proto_iconv_arg1="const"
++fi
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
++      am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"
++fi
++
++    am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
++    echo "$as_me:$LINENO: result: ${ac_t:-
++         }$am_cv_proto_iconv" >&5
++echo "${ECHO_T}${ac_t:-
++         }$am_cv_proto_iconv" >&6
++
++cat >>confdefs.h <<_ACEOF
++#define ICONV_CONST $am_cv_proto_iconv_arg1
++_ACEOF
++
++  fi
++
+     ;;
+   *-mingw32*)
+@@ -109059,6 +109533,14 @@ fi
+ done
++    cat >>confdefs.h <<\_ACEOF
++#define HAVE_STRTOF 1
++_ACEOF
++
++    cat >>confdefs.h <<\_ACEOF
++#define HAVE_STRTOLD 1
++_ACEOF
++
+   # If we're not using GNU ld, then there's no point in even trying these
+   # tests.  Check for that first.  We should have already tested for gld
+@@ -115963,6 +116445,24 @@ ABI_TWEAKS_SRCDIR=config/${abi_tweaks_di
++# For SymbianOS, we use a highly cut-down libsupc++. This lets us
++# conditionalise libsupc++'s Makefile.am to include only the necessary sources.
++case "$target" in
++  *arm*-symbianelf)
++  LIBSUPCXX_PRONLY=yes;;
++  *);;
++esac
++
++
++if test x$LIBSUPCXX_PRONLY = xyes; then
++  LIBSUPCXX_PRONLY_TRUE=
++  LIBSUPCXX_PRONLY_FALSE='#'
++else
++  LIBSUPCXX_PRONLY_TRUE='#'
++  LIBSUPCXX_PRONLY_FALSE=
++fi
++
++
+ # Determine cross-compile flags and AM_CONDITIONALs.
+ #AC_SUBST(GLIBCXX_IS_NATIVE)
+ #AM_CONDITIONAL(CANADIAN, test $CANADIAN = yes)
+@@ -116543,6 +117043,13 @@ echo "$as_me: error: conditional \"GLIBC
+ Usually this means the macro was only invoked conditionally." >&2;}
+    { (exit 1); exit 1; }; }
+ fi
++if test -z "${LIBSUPCXX_PRONLY_TRUE}" && test -z "${LIBSUPCXX_PRONLY_FALSE}"; then
++  { { echo "$as_me:$LINENO: error: conditional \"LIBSUPCXX_PRONLY\" was never defined.
++Usually this means the macro was only invoked conditionally." >&5
++echo "$as_me: error: conditional \"LIBSUPCXX_PRONLY\" was never defined.
++Usually this means the macro was only invoked conditionally." >&2;}
++   { (exit 1); exit 1; }; }
++fi
+ : ${CONFIG_STATUS=./config.status}
+ ac_clean_files_save=$ac_clean_files
+@@ -117580,6 +118087,8 @@ s,@CPU_DEFINES_SRCDIR@,$CPU_DEFINES_SRCD
+ s,@ABI_TWEAKS_SRCDIR@,$ABI_TWEAKS_SRCDIR,;t t
+ s,@OS_INC_SRCDIR@,$OS_INC_SRCDIR,;t t
+ s,@ERROR_CONSTANTS_SRCDIR@,$ERROR_CONSTANTS_SRCDIR,;t t
++s,@LIBSUPCXX_PRONLY_TRUE@,$LIBSUPCXX_PRONLY_TRUE,;t t
++s,@LIBSUPCXX_PRONLY_FALSE@,$LIBSUPCXX_PRONLY_FALSE,;t t
+ s,@glibcxx_prefixdir@,$glibcxx_prefixdir,;t t
+ s,@gxx_include_dir@,$gxx_include_dir,;t t
+ s,@glibcxx_toolexecdir@,$glibcxx_toolexecdir,;t t
+--- a/libstdc++-v3/configure.ac
++++ b/libstdc++-v3/configure.ac
+@@ -138,7 +138,7 @@ if $GLIBCXX_IS_NATIVE; then
+   # Check for available headers.
+   AC_CHECK_HEADERS([nan.h ieeefp.h endian.h sys/isa_defs.h machine/endian.h \
+-  machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h gconv.h \
++  machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h \
+   sys/types.h sys/ipc.h sys/sem.h])
+   GLIBCXX_CHECK_LINKER_FEATURES
+@@ -344,13 +344,22 @@ AC_SUBST(OS_INC_SRCDIR)
+ AC_SUBST(ERROR_CONSTANTS_SRCDIR)
++# For SymbianOS, we use a highly cut-down libsupc++. This lets us
++# conditionalise libsupc++'s Makefile.am to include only the necessary sources.
++case "$target" in
++  *arm*-symbianelf)
++  LIBSUPCXX_PRONLY=yes;;
++  *);;
++esac
++AM_CONDITIONAL(LIBSUPCXX_PRONLY, test x$LIBSUPCXX_PRONLY = xyes)
++
+ # Determine cross-compile flags and AM_CONDITIONALs.
+ #AC_SUBST(GLIBCXX_IS_NATIVE)
+ #AM_CONDITIONAL(CANADIAN, test $CANADIAN = yes)
+ # from GLIBCXX_CHECK_COMPLEX_MATH_SUPPORT:
+ #AM_CONDITIONAL(GLIBCXX_BUILD_LIBMATH,  test $need_libmath = yes)
+ GLIBCXX_EVALUATE_CONDITIONALS
+- 
++
+ AC_CACHE_SAVE
+ if test ${multilib} = yes; then
+--- a/libstdc++-v3/configure.host
++++ b/libstdc++-v3/configure.host
+@@ -320,6 +320,11 @@ case "${host}" in
+           abi_baseline_pair=${try_cpu}-linux-gnu
+         fi
+     esac
++    case "${host}" in
++      arm*-*-linux-*eabi)
++      port_specific_symbol_files="\$(srcdir)/../config/os/gnu-linux/arm-eabi-extra.ver"
++      ;;
++    esac
+     ;;
+   mips*-*-*)
+     case "${host_os}" in
+--- a/libstdc++-v3/crossconfig.m4
++++ b/libstdc++-v3/crossconfig.m4
+@@ -46,7 +46,7 @@ case "${host}" in
+     # so we just check for all the features here.
+     # Check for available headers.
+     AC_CHECK_HEADERS([nan.h ieeefp.h endian.h sys/isa_defs.h machine/endian.h \
+-    machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h gconv.h \
++    machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h \
+     sys/types.h])
+     # Don't call GLIBCXX_CHECK_LINKER_FEATURES, Darwin doesn't have a GNU ld
+@@ -197,7 +197,7 @@ case "${host}" in
+     AC_CHECK_HEADERS([nan.h ieeefp.h endian.h sys/isa_defs.h \
+       machine/endian.h machine/param.h sys/machine.h sys/types.h \
+       fp.h float.h endian.h inttypes.h locale.h float.h stdint.h \
+-      sys/ipc.h sys/sem.h gconf.h])
++      sys/ipc.h sys/sem.h])
+     SECTION_FLAGS='-ffunction-sections -fdata-sections'
+     AC_SUBST(SECTION_FLAGS)
+     GLIBCXX_CHECK_COMPILER_FEATURES
+@@ -223,6 +223,10 @@ case "${host}" in
+     # For C99 support to TR1.
+     GLIBCXX_CHECK_C99_TR1
++    AC_DEFINE(_GLIBCXX_USE_RANDOM_TR1)
++
++    AC_LC_MESSAGES
++
+     # Check for sigsetjmp
+     AC_TRY_COMPILE(
+       [#include <setjmp.h>],
+@@ -231,9 +235,16 @@ case "${host}" in
+          siglongjmp (env, 1);
+       ],
+       [AC_DEFINE(HAVE_SIGSETJMP, 1, [Define if sigsetjmp is available.])])
++
++    AC_DEFINE(HAVE_MMAP) 
++
++    # For iconv support.
++    AM_ICONV
+     ;;
+   *-mingw32*)
+     AC_CHECK_HEADERS([sys/types.h locale.h float.h])
++    AC_DEFINE(HAVE_STRTOF)
++    AC_DEFINE(HAVE_STRTOLD)
+     GLIBCXX_CHECK_LINKER_FEATURES
+     GLIBCXX_CHECK_COMPLEX_MATH_SUPPORT
+     ;;
+--- a/libstdc++-v3/doc/Makefile.in
++++ b/libstdc++-v3/doc/Makefile.in
+@@ -157,6 +157,8 @@ LIBMATHOBJS = @LIBMATHOBJS@
+ LIBOBJS = @LIBOBJS@
+ LIBS = @LIBS@
+ LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@
++LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@
++LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBICONV = @LTLIBICONV@
+--- a/libstdc++-v3/include/Makefile.am
++++ b/libstdc++-v3/include/Makefile.am
+@@ -1103,8 +1103,14 @@ ${pch3_output}: ${pch3_source} ${pch2_ou
+ if GLIBCXX_HOSTED
+ install-data-local: install-headers
+ else
++if LIBSUPCXX_PRONLY
++# Don't install any headers if we're only putting eh_personality in
++# libsupc++ (e.g. on SymbianOS)
++install-data-local:
++else
+ install-data-local: install-freestanding-headers
+ endif
++endif
+ # This is a subset of the full install-headers rule.  We only need <cstddef>,
+ # <limits>, <cstdlib>, <cstdarg>, <new>, <typeinfo>, <exception>, and any
+--- a/libstdc++-v3/include/Makefile.in
++++ b/libstdc++-v3/include/Makefile.in
+@@ -157,6 +157,8 @@ LIBMATHOBJS = @LIBMATHOBJS@
+ LIBOBJS = @LIBOBJS@
+ LIBS = @LIBS@
+ LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@
++LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@
++LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBICONV = @LTLIBICONV@
+@@ -1492,7 +1494,10 @@ ${pch3_output}: ${pch3_source} ${pch2_ou
+ # the rest are taken from the original source tree.
+ @GLIBCXX_HOSTED_TRUE@install-data-local: install-headers
+-@GLIBCXX_HOSTED_FALSE@install-data-local: install-freestanding-headers
++# Don't install any headers if we're only putting eh_personality in
++# libsupc++ (e.g. on SymbianOS)
++@GLIBCXX_HOSTED_FALSE@@LIBSUPCXX_PRONLY_TRUE@install-data-local:
++@GLIBCXX_HOSTED_FALSE@@LIBSUPCXX_PRONLY_FALSE@install-data-local: install-freestanding-headers
+ # This is a subset of the full install-headers rule.  We only need <cstddef>,
+ # <limits>, <cstdlib>, <cstdarg>, <new>, <typeinfo>, <exception>, and any
+--- a/libstdc++-v3/include/std/type_traits
++++ b/libstdc++-v3/include/std/type_traits
+@@ -455,15 +455,18 @@ namespace std
+     struct __make_unsigned_selector<_Tp, false, true>
+     {
+     private:
+-      // GNU enums start with sizeof short.
+-      typedef unsigned short __smallest;
+-      static const bool __b1 = sizeof(_Tp) <= sizeof(__smallest);
++      // With -fshort-enums, an enum may be as small as a char.
++      typedef unsigned char __smallest;
++      static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
++      static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
+       static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
+-      typedef conditional<__b2, unsigned int, unsigned long> __cond;
+-      typedef typename __cond::type __cond_type;
++      typedef conditional<__b2, unsigned int, unsigned long> __cond2;
++      typedef typename __cond2::type __cond2_type;
++      typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
++      typedef typename __cond1::type __cond1_type;
+     public:
+-      typedef typename conditional<__b1, __smallest, __cond_type>::type __type;
++      typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
+     };
+   // Given an integral/enum type, return the corresponding unsigned
+@@ -530,15 +533,18 @@ namespace std
+     struct __make_signed_selector<_Tp, false, true>
+     {
+     private:
+-      // GNU enums start with sizeof short.
+-      typedef signed short __smallest;
+-      static const bool __b1 = sizeof(_Tp) <= sizeof(__smallest);
++      // With -fshort-enums, an enum may be as small as a char.
++      typedef signed char __smallest;
++      static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
++      static const bool __b1 = sizeof(_Tp) <= sizeof(signed short);
+       static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
+-      typedef conditional<__b2, signed int, signed long> __cond;
+-      typedef typename __cond::type __cond_type;
++      typedef conditional<__b2, signed int, signed long> __cond2;
++      typedef typename __cond2::type __cond2_type;
++      typedef conditional<__b1, signed short, __cond2_type> __cond1;
++      typedef typename __cond1::type __cond1_type;
+     public:
+-      typedef typename conditional<__b1, __smallest, __cond_type>::type __type;
++      typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
+     };
+   // Given an integral/enum type, return the corresponding signed
+--- a/libstdc++-v3/libmath/Makefile.in
++++ b/libstdc++-v3/libmath/Makefile.in
+@@ -172,6 +172,8 @@ LIBMATHOBJS = @LIBMATHOBJS@
+ LIBOBJS = @LIBOBJS@
+ LIBS = @LIBS@
+ LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@
++LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@
++LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@
+ # Only compiling "C" sources in this directory.
+ LIBTOOL = @LIBTOOL@ --tag CC
+--- a/libstdc++-v3/libsupc++/Makefile.am
++++ b/libstdc++-v3/libsupc++/Makefile.am
+@@ -31,6 +31,11 @@ toolexeclib_LTLIBRARIES = libsupc++.la
+ # 2) integrated libsupc++convenience.la that is to be a part of libstdc++.a
+ noinst_LTLIBRARIES = libsupc++convenience.la
++if LIBSUPCXX_PRONLY
++sources = \
++      eh_personality.cc
++
++else
+ headers = \
+       exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h
+@@ -83,6 +88,7 @@ sources = \
+       vec.cc \
+       vmi_class_type_info.cc \
+       vterminate.cc
++endif
+ libsupc___la_SOURCES = $(sources) $(c_sources)
+ libsupc__convenience_la_SOURCES = $(sources) $(c_sources)
+--- a/libstdc++-v3/libsupc++/Makefile.in
++++ b/libstdc++-v3/libsupc++/Makefile.in
+@@ -38,7 +38,7 @@ POST_UNINSTALL = :
+ build_triplet = @build@
+ host_triplet = @host@
+ target_triplet = @target@
+-DIST_COMMON = $(glibcxxinstall_HEADERS) $(srcdir)/Makefile.am \
++DIST_COMMON = $(am__glibcxxinstall_HEADERS_DIST) $(srcdir)/Makefile.am \
+       $(srcdir)/Makefile.in $(top_srcdir)/fragment.am
+ subdir = libsupc++
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+@@ -84,19 +84,29 @@ am__libsupc___la_SOURCES_DIST = array_ty
+       pmem_type_info.cc pointer_type_info.cc pure.cc \
+       si_class_type_info.cc tinfo.cc tinfo2.cc vec.cc \
+       vmi_class_type_info.cc vterminate.cc cp-demangle.c
+-am__objects_1 = array_type_info.lo atexit_arm.lo bad_cast.lo \
+-      bad_typeid.lo class_type_info.lo del_op.lo del_opnt.lo \
+-      del_opv.lo del_opvnt.lo dyncast.lo eh_alloc.lo eh_arm.lo \
+-      eh_aux_runtime.lo eh_call.lo eh_catch.lo eh_exception.lo \
+-      eh_globals.lo eh_personality.lo eh_term_handler.lo \
+-      eh_terminate.lo eh_throw.lo eh_type.lo eh_unex_handler.lo \
+-      enum_type_info.lo function_type_info.lo \
+-      fundamental_type_info.lo guard.lo new_handler.lo new_op.lo \
+-      new_opnt.lo new_opv.lo new_opvnt.lo pbase_type_info.lo \
+-      pmem_type_info.lo pointer_type_info.lo pure.lo \
+-      si_class_type_info.lo tinfo.lo tinfo2.lo vec.lo \
+-      vmi_class_type_info.lo vterminate.lo
+-@GLIBCXX_HOSTED_TRUE@am__objects_2 = cp-demangle.lo
++@LIBSUPCXX_PRONLY_FALSE@am__objects_1 = array_type_info.lo \
++@LIBSUPCXX_PRONLY_FALSE@      atexit_arm.lo bad_cast.lo \
++@LIBSUPCXX_PRONLY_FALSE@      bad_typeid.lo class_type_info.lo \
++@LIBSUPCXX_PRONLY_FALSE@      del_op.lo del_opnt.lo del_opv.lo \
++@LIBSUPCXX_PRONLY_FALSE@      del_opvnt.lo dyncast.lo eh_alloc.lo \
++@LIBSUPCXX_PRONLY_FALSE@      eh_arm.lo eh_aux_runtime.lo eh_call.lo \
++@LIBSUPCXX_PRONLY_FALSE@      eh_catch.lo eh_exception.lo \
++@LIBSUPCXX_PRONLY_FALSE@      eh_globals.lo eh_personality.lo \
++@LIBSUPCXX_PRONLY_FALSE@      eh_term_handler.lo eh_terminate.lo \
++@LIBSUPCXX_PRONLY_FALSE@      eh_throw.lo eh_type.lo \
++@LIBSUPCXX_PRONLY_FALSE@      eh_unex_handler.lo enum_type_info.lo \
++@LIBSUPCXX_PRONLY_FALSE@      function_type_info.lo \
++@LIBSUPCXX_PRONLY_FALSE@      fundamental_type_info.lo guard.lo \
++@LIBSUPCXX_PRONLY_FALSE@      new_handler.lo new_op.lo new_opnt.lo \
++@LIBSUPCXX_PRONLY_FALSE@      new_opv.lo new_opvnt.lo \
++@LIBSUPCXX_PRONLY_FALSE@      pbase_type_info.lo pmem_type_info.lo \
++@LIBSUPCXX_PRONLY_FALSE@      pointer_type_info.lo pure.lo \
++@LIBSUPCXX_PRONLY_FALSE@      si_class_type_info.lo tinfo.lo \
++@LIBSUPCXX_PRONLY_FALSE@      tinfo2.lo vec.lo \
++@LIBSUPCXX_PRONLY_FALSE@      vmi_class_type_info.lo vterminate.lo
++@LIBSUPCXX_PRONLY_TRUE@am__objects_1 = eh_personality.lo
++@GLIBCXX_HOSTED_TRUE@@LIBSUPCXX_PRONLY_FALSE@am__objects_2 =  \
++@GLIBCXX_HOSTED_TRUE@@LIBSUPCXX_PRONLY_FALSE@ cp-demangle.lo
+ am_libsupc___la_OBJECTS = $(am__objects_1) $(am__objects_2)
+ libsupc___la_OBJECTS = $(am_libsupc___la_OBJECTS)
+ libsupc__convenience_la_LIBADD =
+@@ -129,6 +139,8 @@ CXXLD = $(CXX)
+ SOURCES = $(libsupc___la_SOURCES) $(libsupc__convenience_la_SOURCES)
+ DIST_SOURCES = $(am__libsupc___la_SOURCES_DIST) \
+       $(am__libsupc__convenience_la_SOURCES_DIST)
++am__glibcxxinstall_HEADERS_DIST = exception new typeinfo cxxabi.h \
++      cxxabi-forced.h exception_defines.h
+ glibcxxinstallHEADERS_INSTALL = $(INSTALL_HEADER)
+ HEADERS = $(glibcxxinstall_HEADERS)
+ ETAGS = etags
+@@ -227,6 +239,8 @@ LIBMATHOBJS = @LIBMATHOBJS@
+ LIBOBJS = @LIBOBJS@
+ LIBS = @LIBS@
+ LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@
++LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@
++LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBICONV = @LTLIBICONV@
+@@ -350,55 +364,58 @@ AM_CPPFLAGS = $(GLIBCXX_INCLUDES)
+ toolexeclib_LTLIBRARIES = libsupc++.la
+ # 2) integrated libsupc++convenience.la that is to be a part of libstdc++.a
+ noinst_LTLIBRARIES = libsupc++convenience.la
+-headers = \
+-      exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h
++@LIBSUPCXX_PRONLY_FALSE@sources = \
++@LIBSUPCXX_PRONLY_FALSE@      array_type_info.cc \
++@LIBSUPCXX_PRONLY_FALSE@      atexit_arm.cc \
++@LIBSUPCXX_PRONLY_FALSE@      bad_cast.cc \
++@LIBSUPCXX_PRONLY_FALSE@      bad_typeid.cc \
++@LIBSUPCXX_PRONLY_FALSE@      class_type_info.cc \
++@LIBSUPCXX_PRONLY_FALSE@      del_op.cc \
++@LIBSUPCXX_PRONLY_FALSE@      del_opnt.cc \
++@LIBSUPCXX_PRONLY_FALSE@      del_opv.cc \
++@LIBSUPCXX_PRONLY_FALSE@      del_opvnt.cc \
++@LIBSUPCXX_PRONLY_FALSE@      dyncast.cc \
++@LIBSUPCXX_PRONLY_FALSE@      eh_alloc.cc \
++@LIBSUPCXX_PRONLY_FALSE@      eh_arm.cc \
++@LIBSUPCXX_PRONLY_FALSE@      eh_aux_runtime.cc \
++@LIBSUPCXX_PRONLY_FALSE@      eh_call.cc \
++@LIBSUPCXX_PRONLY_FALSE@      eh_catch.cc \
++@LIBSUPCXX_PRONLY_FALSE@      eh_exception.cc \
++@LIBSUPCXX_PRONLY_FALSE@      eh_globals.cc \
++@LIBSUPCXX_PRONLY_FALSE@      eh_personality.cc \
++@LIBSUPCXX_PRONLY_FALSE@      eh_term_handler.cc \
++@LIBSUPCXX_PRONLY_FALSE@      eh_terminate.cc \
++@LIBSUPCXX_PRONLY_FALSE@      eh_throw.cc \
++@LIBSUPCXX_PRONLY_FALSE@      eh_type.cc \
++@LIBSUPCXX_PRONLY_FALSE@      eh_unex_handler.cc \
++@LIBSUPCXX_PRONLY_FALSE@      enum_type_info.cc \
++@LIBSUPCXX_PRONLY_FALSE@      function_type_info.cc \
++@LIBSUPCXX_PRONLY_FALSE@      fundamental_type_info.cc \
++@LIBSUPCXX_PRONLY_FALSE@      guard.cc \
++@LIBSUPCXX_PRONLY_FALSE@      new_handler.cc \
++@LIBSUPCXX_PRONLY_FALSE@      new_op.cc \
++@LIBSUPCXX_PRONLY_FALSE@      new_opnt.cc \
++@LIBSUPCXX_PRONLY_FALSE@      new_opv.cc \
++@LIBSUPCXX_PRONLY_FALSE@      new_opvnt.cc \
++@LIBSUPCXX_PRONLY_FALSE@      pbase_type_info.cc \
++@LIBSUPCXX_PRONLY_FALSE@      pmem_type_info.cc \
++@LIBSUPCXX_PRONLY_FALSE@      pointer_type_info.cc \
++@LIBSUPCXX_PRONLY_FALSE@      pure.cc \
++@LIBSUPCXX_PRONLY_FALSE@      si_class_type_info.cc \
++@LIBSUPCXX_PRONLY_FALSE@      tinfo.cc \
++@LIBSUPCXX_PRONLY_FALSE@      tinfo2.cc \
++@LIBSUPCXX_PRONLY_FALSE@      vec.cc \
++@LIBSUPCXX_PRONLY_FALSE@      vmi_class_type_info.cc \
++@LIBSUPCXX_PRONLY_FALSE@      vterminate.cc
+-@GLIBCXX_HOSTED_TRUE@c_sources = \
+-@GLIBCXX_HOSTED_TRUE@ cp-demangle.c 
++@LIBSUPCXX_PRONLY_TRUE@sources = \
++@LIBSUPCXX_PRONLY_TRUE@       eh_personality.cc
+-sources = \
+-      array_type_info.cc \
+-      atexit_arm.cc \
+-      bad_cast.cc \
+-      bad_typeid.cc \
+-      class_type_info.cc \
+-      del_op.cc \
+-      del_opnt.cc \
+-      del_opv.cc \
+-      del_opvnt.cc \
+-      dyncast.cc \
+-      eh_alloc.cc \
+-      eh_arm.cc \
+-      eh_aux_runtime.cc \
+-      eh_call.cc \
+-      eh_catch.cc \
+-      eh_exception.cc \
+-      eh_globals.cc \
+-      eh_personality.cc \
+-      eh_term_handler.cc \
+-      eh_terminate.cc \
+-      eh_throw.cc \
+-      eh_type.cc \
+-      eh_unex_handler.cc \
+-      enum_type_info.cc \
+-      function_type_info.cc \
+-      fundamental_type_info.cc \
+-      guard.cc \
+-      new_handler.cc \
+-      new_op.cc \
+-      new_opnt.cc \
+-      new_opv.cc \
+-      new_opvnt.cc \
+-      pbase_type_info.cc \
+-      pmem_type_info.cc \
+-      pointer_type_info.cc \
+-      pure.cc \
+-      si_class_type_info.cc \
+-      tinfo.cc \
+-      tinfo2.cc \
+-      vec.cc \
+-      vmi_class_type_info.cc \
+-      vterminate.cc
++@LIBSUPCXX_PRONLY_FALSE@headers = \
++@LIBSUPCXX_PRONLY_FALSE@      exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h
++
++@GLIBCXX_HOSTED_TRUE@@LIBSUPCXX_PRONLY_FALSE@c_sources = \
++@GLIBCXX_HOSTED_TRUE@@LIBSUPCXX_PRONLY_FALSE@ cp-demangle.c 
+ libsupc___la_SOURCES = $(sources) $(c_sources)
+ libsupc__convenience_la_SOURCES = $(sources) $(c_sources)
+--- a/libstdc++-v3/libsupc++/eh_arm.cc
++++ b/libstdc++-v3/libsupc++/eh_arm.cc
+@@ -46,12 +46,14 @@ __cxa_type_match(_Unwind_Exception* ue_h
+                bool is_reference __attribute__((__unused__)),
+                void** thrown_ptr_p)
+ {
+-  bool foreign_exception = !__is_gxx_exception_class(ue_header->exception_class);
++  bool forced_unwind = __is_gxx_forced_unwind_class(ue_header->exception_class);
++  bool foreign_exception = !forced_unwind && !__is_gxx_exception_class(ue_header->exception_class);
+   __cxa_exception* xh = __get_exception_header_from_ue(ue_header);
+   const std::type_info* throw_type;
+-  // XXX What to do with forced unwind?
+-  if (foreign_exception)
++  if (forced_unwind)
++    throw_type = &typeid(abi::__forced_unwind);
++  else if (foreign_exception)
+     throw_type = &typeid(abi::__foreign_exception);
+   else
+     throw_type = xh->exceptionType;
+--- a/libstdc++-v3/libsupc++/eh_personality.cc
++++ b/libstdc++-v3/libsupc++/eh_personality.cc
+@@ -544,8 +544,12 @@ PERSONALITY_FUNCTION (int version,
+ #ifdef __ARM_EABI_UNWINDER__
+       throw_type = ue_header;
+-      if ((actions & _UA_FORCE_UNWIND)
+-        || foreign_exception)
++      if (actions & _UA_FORCE_UNWIND)
++      {
++        __GXX_INIT_FORCED_UNWIND_CLASS(ue_header->exception_class);
++        thrown_ptr = 0;
++      }
++      else if (foreign_exception)
+       thrown_ptr = 0;
+ #else
+       // During forced unwinding, match a magic exception type.
+--- a/libstdc++-v3/libsupc++/unwind-cxx.h
++++ b/libstdc++-v3/libsupc++/unwind-cxx.h
+@@ -201,6 +201,32 @@ __GXX_INIT_EXCEPTION_CLASS(_Unwind_Excep
+   c[7] = '\0';
+ }
++static inline bool
++__is_gxx_forced_unwind_class(_Unwind_Exception_Class c)
++{
++  return c[0] == 'G'
++       && c[1] == 'N'
++       && c[2] == 'U'
++       && c[3] == 'C'
++       && c[4] == 'F'
++       && c[5] == 'O'
++       && c[6] == 'R'
++       && c[7] == '\0';
++}
++
++static inline void
++__GXX_INIT_FORCED_UNWIND_CLASS(_Unwind_Exception_Class c)
++{
++  c[0] = 'G';
++  c[1] = 'N';
++  c[2] = 'U';
++  c[3] = 'C';
++  c[4] = 'F';
++  c[5] = 'O';
++  c[6] = 'R';
++  c[7] = '\0';
++}
++
+ static inline void*
+ __gxx_caught_object(_Unwind_Exception* eo)
+ {
+--- a/libstdc++-v3/libsupc++/vec.cc
++++ b/libstdc++-v3/libsupc++/vec.cc
+@@ -461,6 +461,9 @@ namespace __aeabiv1
+   __aeabi_vec_dtor_cookie (void *array_address, 
+                          abi::__cxa_cdtor_type destructor)
+   {
++    if (!array_address)
++      return NULL;
++
+     abi::__cxa_vec_dtor (array_address, 
+                        reinterpret_cast<std::size_t *>(array_address)[-1],
+                        reinterpret_cast<std::size_t *>(array_address)[-2],
+@@ -473,6 +476,9 @@ namespace __aeabiv1
+   __aeabi_vec_delete (void *array_address, 
+                     abi::__cxa_cdtor_type destructor)
+   {
++    if (!array_address)
++      return;
++
+     abi::__cxa_vec_delete (array_address,
+                          reinterpret_cast<std::size_t *>(array_address)[-2],
+                          2 * sizeof (std::size_t),
+@@ -484,6 +490,9 @@ namespace __aeabiv1
+                      abi::__cxa_cdtor_type destructor,
+                      void (*dealloc) (void *, std::size_t))
+   {
++    if (!array_address)
++      return;
++
+     abi::__cxa_vec_delete3 (array_address,
+                           reinterpret_cast<std::size_t *>(array_address)[-2],
+                           2 * sizeof (std::size_t),
+@@ -494,6 +503,9 @@ namespace __aeabiv1
+   __aeabi_vec_delete3_nodtor (void *array_address,
+                             void (*dealloc) (void *, std::size_t))
+   {
++    if (!array_address)
++      return;
++
+     abi::__cxa_vec_delete3 (array_address,
+                           reinterpret_cast<std::size_t *>(array_address)[-2],
+                           2 * sizeof (std::size_t),
+--- a/libstdc++-v3/po/Makefile.in
++++ b/libstdc++-v3/po/Makefile.in
+@@ -157,6 +157,8 @@ LIBMATHOBJS = @LIBMATHOBJS@
+ LIBOBJS = @LIBOBJS@
+ LIBS = @LIBS@
+ LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@
++LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@
++LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBICONV = @LTLIBICONV@
+--- a/libstdc++-v3/src/Makefile.in
++++ b/libstdc++-v3/src/Makefile.in
+@@ -211,6 +211,8 @@ LIBMATHOBJS = @LIBMATHOBJS@
+ LIBOBJS = @LIBOBJS@
+ LIBS = @LIBS@
+ LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@
++LIBSUPCXX_PRONLY_FALSE = @LIBSUPCXX_PRONLY_FALSE@
++LIBSUPCXX_PRONLY_TRUE = @LIBSUPCXX_PRONLY_TRUE@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBICONV = @LTLIBICONV@
diff --git a/toolchain/gcc/patches/4.3.3+cs/105-libtool.patch b/toolchain/gcc/patches/4.3.3+cs/105-libtool.patch
new file mode 100644 (file)
index 0000000..015f28d
--- /dev/null
@@ -0,0 +1,84 @@
+2008-03-02  Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+       Backport from upstream Libtool:
+
+       2007-10-12  Eric Blake  <ebb9@byu.net>
+
+       Deal with Autoconf 2.62's semantic change in m4_append.
+       * ltsugar.m4 (lt_append): Replace broken versions of
+       m4_append.
+       (lt_if_append_uniq): Don't require separator to be overquoted, and
+       avoid broken m4_append.
+       (lt_dict_add): Fix typo.
+       * libtool.m4 (_LT_DECL): Don't overquote separator.
+
+diff --git a/libtool.m4 b/libtool.m4
+index e86cd02..26a039a 100644
+--- a/libtool.m4
++++ b/libtool.m4
+@@ -319,7 +319,7 @@ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ # VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+ # VARNAME.  Any other value will be used directly.
+ m4_define([_LT_DECL],
+-[lt_if_append_uniq([lt_decl_varnames], [$2], [[, ]],
++[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+     [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+       [m4_ifval([$1], [$1], [$2])])
+     lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+diff --git a/ltsugar.m4 b/ltsugar.m4
+index fc51dc7..dd4f871 100644
+--- a/ltsugar.m4
++++ b/ltsugar.m4
+@@ -1,13 +1,13 @@
+ # ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
+ #
+-# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
++# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+ # Written by Gary V. Vaughan.
+ #
+ # This file is free software; the Free Software Foundation gives
+ # unlimited permission to copy and/or distribute it, with or without
+ # modifications, as long as this notice is preserved.
+-# serial 3 ltsugar.m4
++# serial 4 ltsugar.m4
+ # This is to help aclocal find these macros, as it can't see m4_define.
+ AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+@@ -46,6 +46,20 @@ m4_define([lt_cdr],
+ m4_define([lt_unquote], $1)
++# lt_append(MACRO-NAME, STRING, [SEPARATOR])
++# ------------------------------------------
++# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
++# Note that neither SEPARATOR nor STRING are expanded.  No SEPARATOR is
++# output if MACRO-NAME was previously undefined (different than defined
++# and empty).
++# This macro is needed until we can rely on Autoconf 2.62, since earlier
++# versions of m4 mistakenly expanded SEPARATOR.
++m4_define([lt_append],
++[m4_define([$1],
++         m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
++
++
++
+ # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+ # ----------------------------------------------------------
+ # Produce a SEP delimited list of all paired combinations of elements of
+@@ -67,10 +81,10 @@ m4_define([lt_combine],
+ # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+ m4_define([lt_if_append_uniq],
+ [m4_ifdef([$1],
+-      [m4_bmatch($3[]m4_defn([$1])$3, $3[]m4_re_escape([$2])$3,
+-              [$5],
+-          [m4_append([$1], [$2], [$3])$4])],
+-    [m4_append([$1], [$2], [$3])$4])])
++        [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
++               [lt_append([$1], [$2], [$3])$4],
++               [$5])],
++    [lt_append([$1], [$2], [$3])$4])])
+ # lt_dict_add(DICT, KEY, VALUE)
+
diff --git a/toolchain/gcc/patches/4.3.3+cs/106-fix_linker_error.patch b/toolchain/gcc/patches/4.3.3+cs/106-fix_linker_error.patch
new file mode 100644 (file)
index 0000000..4dd83db
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/gcc/cp/Make-lang.in
++++ b/gcc/cp/Make-lang.in
+@@ -73,7 +73,7 @@ g++-cross$(exeext): g++$(exeext)
+ CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
+       c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o c-pch.o \
+       c-incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o \
+-      c-gimplify.o c-omp.o tree-inline.o
++      c-gimplify.o c-omp.o
+ # Language-specific object files for C++ and Objective C++.
+ CXX_AND_OBJCXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
diff --git a/toolchain/gcc/patches/4.3.3+cs/301-missing-execinfo_h.patch b/toolchain/gcc/patches/4.3.3+cs/301-missing-execinfo_h.patch
new file mode 100644 (file)
index 0000000..b3f1e68
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/boehm-gc/include/gc.h
++++ b/boehm-gc/include/gc.h
+@@ -503,7 +503,7 @@ GC_API GC_PTR GC_malloc_atomic_ignore_of
+ #if defined(__linux__) || defined(__GLIBC__)
+ # include <features.h>
+ # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
+-     && !defined(__ia64__)
++     && !defined(__ia64__) && !defined(__UCLIBC__)
+ #   ifndef GC_HAVE_BUILTIN_BACKTRACE
+ #     define GC_HAVE_BUILTIN_BACKTRACE
+ #   endif
diff --git a/toolchain/gcc/patches/4.3.3+cs/302-c99-snprintf.patch b/toolchain/gcc/patches/4.3.3+cs/302-c99-snprintf.patch
new file mode 100644 (file)
index 0000000..ba51a0e
--- /dev/null
@@ -0,0 +1,13 @@
+Index: gcc-4.3.0/libstdc++-v3/include/c_global/cstdio
+===================================================================
+--- gcc-4.3.0/libstdc++-v3/include/c_global/cstdio     (revision 129202)
++++ gcc-4.3.0/libstdc++-v3/include/c_global/cstdio     (working copy)
+@@ -144,7 +144,7 @@
+ _GLIBCXX_END_NAMESPACE
+-#if _GLIBCXX_USE_C99
++#if _GLIBCXX_USE_C99 || defined __UCLIBC__
+ #undef snprintf
+ #undef vfscanf
diff --git a/toolchain/gcc/patches/4.3.3+cs/305-libmudflap-susv3-legacy.patch b/toolchain/gcc/patches/4.3.3+cs/305-libmudflap-susv3-legacy.patch
new file mode 100644 (file)
index 0000000..374b1f8
--- /dev/null
@@ -0,0 +1,49 @@
+Index: gcc-4.2/libmudflap/mf-hooks2.c
+===================================================================
+--- gcc-4.2/libmudflap/mf-hooks2.c     (revision 119834)
++++ gcc-4.2/libmudflap/mf-hooks2.c     (working copy)
+@@ -427,7 +427,7 @@
+ {
+   TRACE ("%s\n", __PRETTY_FUNCTION__);
+   MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
+-  bzero (s, n);
++  memset (s, 0, n);
+ }
+@@ -437,7 +437,7 @@
+   TRACE ("%s\n", __PRETTY_FUNCTION__);
+   MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
+   MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
+-  bcopy (src, dest, n);
++  memmove (dest, src, n);
+ }
+@@ -447,7 +447,7 @@
+   TRACE ("%s\n", __PRETTY_FUNCTION__);
+   MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
+   MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
+-  return bcmp (s1, s2, n);
++  return n == 0 ? 0 : memcmp (s1, s2, n);
+ }
+@@ -456,7 +456,7 @@
+   size_t n = strlen (s);
+   TRACE ("%s\n", __PRETTY_FUNCTION__);
+   MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
+-  return index (s, c);
++  return strchr (s, c);
+ }
+@@ -465,7 +465,7 @@
+   size_t n = strlen (s);
+   TRACE ("%s\n", __PRETTY_FUNCTION__);
+   MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
+-  return rindex (s, c);
++  return strrchr (s, c);
+ }
+ /* XXX:  stpcpy, memccpy */
diff --git a/toolchain/gcc/patches/4.3.3+cs/410-fix_pr37436.patch b/toolchain/gcc/patches/4.3.3+cs/410-fix_pr37436.patch
new file mode 100644 (file)
index 0000000..e86768e
--- /dev/null
@@ -0,0 +1,71 @@
+--- a/gcc/config/arm/arm.c
++++ b/gcc/config/arm/arm.c
+@@ -5073,6 +5073,7 @@ arm_legitimate_address_p (enum machine_m
+       rtx xop1 = XEXP (x, 1);
+       return ((arm_address_register_rtx_p (xop0, strict_p)
++             && GET_CODE(xop1) == CONST_INT
+              && arm_legitimate_index_p (mode, xop1, outer, strict_p))
+             || (arm_address_register_rtx_p (xop1, strict_p)
+                 && arm_legitimate_index_p (mode, xop0, outer, strict_p)));
+--- a/gcc/config/arm/arm.md
++++ b/gcc/config/arm/arm.md
+@@ -4683,7 +4683,7 @@
+ (define_expand "extendqihi2"
+   [(set (match_dup 2)
+-      (ashift:SI (match_operand:QI 1 "general_operand" "")
++      (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
+                  (const_int 24)))
+    (set (match_operand:HI 0 "s_register_operand" "")
+       (ashiftrt:SI (match_dup 2)
+@@ -4708,7 +4708,7 @@
+ (define_insn "*arm_extendqihi_insn"
+   [(set (match_operand:HI 0 "s_register_operand" "=r")
+-      (sign_extend:HI (match_operand:QI 1 "memory_operand" "Uq")))]
++      (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
+   "TARGET_ARM && arm_arch4"
+   "ldr%(sb%)\\t%0, %1"
+   [(set_attr "type" "load_byte")
+@@ -4719,7 +4719,7 @@
+ (define_expand "extendqisi2"
+   [(set (match_dup 2)
+-      (ashift:SI (match_operand:QI 1 "general_operand" "")
++      (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
+                  (const_int 24)))
+    (set (match_operand:SI 0 "s_register_operand" "")
+       (ashiftrt:SI (match_dup 2)
+@@ -4751,7 +4751,7 @@
+ (define_insn "*arm_extendqisi"
+   [(set (match_operand:SI 0 "s_register_operand" "=r")
+-      (sign_extend:SI (match_operand:QI 1 "memory_operand" "Uq")))]
++      (sign_extend:SI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
+   "TARGET_ARM && arm_arch4 && !arm_arch6"
+   "ldr%(sb%)\\t%0, %1"
+   [(set_attr "type" "load_byte")
+@@ -4762,7 +4762,8 @@
+ (define_insn "*arm_extendqisi_v6"
+   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
+-      (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uq")))]
++      (sign_extend:SI
++       (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
+   "TARGET_ARM && arm_arch6"
+   "@
+    sxtb%?\\t%0, %1
+--- a/gcc/config/arm/predicates.md
++++ b/gcc/config/arm/predicates.md
+@@ -239,6 +239,10 @@
+        (match_test "arm_legitimate_address_p (mode, XEXP (op, 0), SIGN_EXTEND,
+                                             0)")))
++(define_special_predicate "arm_reg_or_extendqisi_mem_op"
++  (ior (match_operand 0 "arm_extendqisi_mem_op")
++       (match_operand 0 "s_register_operand")))
++
+ (define_predicate "power_of_two_operand"
+   (match_code "const_int")
+ {
diff --git a/toolchain/gcc/patches/4.3.3+cs/420-fix_pr26515.patch b/toolchain/gcc/patches/4.3.3+cs/420-fix_pr26515.patch
new file mode 100644 (file)
index 0000000..24b3720
--- /dev/null
@@ -0,0 +1,13 @@
+--- a/gcc/config/cris/cris.md
++++ b/gcc/config/cris/cris.md
+@@ -4920,7 +4920,9 @@
+   "REGNO (operands[2]) == REGNO (operands[0])
+    && INTVAL (operands[3]) <= 65535 && INTVAL (operands[3]) >= 0
+    && !CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'I')
+-   && !side_effects_p (operands[1])"
++   && !side_effects_p (operands[1])
++   && (!REG_P (operands[1])
++       || REGNO (operands[1]) <= CRIS_LAST_GENERAL_REGISTER)"
+   ;; FIXME: CC0 valid except for M (i.e. CC_NOT_NEGATIVE).
+   [(set (match_dup 0) (match_dup 4))
+    (set (match_dup 5) (match_dup 6))]
diff --git a/toolchain/gcc/patches/4.3.3+cs/810-arm-softfloat-libgcc.patch b/toolchain/gcc/patches/4.3.3+cs/810-arm-softfloat-libgcc.patch
new file mode 100644 (file)
index 0000000..e3385d2
--- /dev/null
@@ -0,0 +1,25 @@
+--- a/gcc/config/arm/t-linux
++++ b/gcc/config/arm/t-linux
+@@ -3,7 +3,10 @@
+ TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC
+ LIB1ASMSRC = arm/lib1funcs.asm
+-LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
++LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx \
++      _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
++      _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
++      _fixsfsi _fixunssfsi _floatdidf _floatundidf _floatdisf _floatundisf
+ # MULTILIB_OPTIONS = mhard-float/msoft-float
+ # MULTILIB_DIRNAMES = hard-float soft-float
+--- a/gcc/config/arm/linux-elf.h
++++ b/gcc/config/arm/linux-elf.h
+@@ -60,7 +60,7 @@
+    %{shared:-lc} \
+    %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
+-#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc"
++#define LIBGCC_SPEC "-lgcc"
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
diff --git a/toolchain/gcc/patches/4.3.3+cs/910-mbsd_multi.patch b/toolchain/gcc/patches/4.3.3+cs/910-mbsd_multi.patch
new file mode 100644 (file)
index 0000000..17a0173
--- /dev/null
@@ -0,0 +1,270 @@
+
+       This patch brings over a few features from MirBSD:
+       * -fhonour-copts
+         If this option is not given, it's warned (depending
+         on environment variables). This is to catch errors
+         of misbuilt packages which override CFLAGS themselves.
+       * -Werror-maybe-reset
+         Has the effect of -Wno-error if GCC_NO_WERROR is
+         set and not '0', a no-operation otherwise. This is
+         to be able to use -Werror in "make" but prevent
+         GNU autoconf generated configure scripts from
+         freaking out.
+       * Make -fno-strict-aliasing and -fno-delete-null-pointer-checks
+         the default for -O2/-Os, because they trigger gcc bugs
+         and can delete code with security implications.
+
+       This patch was authored by Thorsten Glaser <tg at mirbsd.de>
+       with copyright assignment to the FSF in effect.
+
+--- a/gcc/c-opts.c
++++ b/gcc/c-opts.c
+@@ -108,6 +108,9 @@ static size_t deferred_count;
+ /* Number of deferred options scanned for -include.  */
+ static size_t include_cursor;
++/* Check if a port honours COPTS.  */
++static int honour_copts = 0;
++
+ static void set_Wimplicit (int);
+ static void handle_OPT_d (const char *);
+ static void set_std_cxx98 (int);
+@@ -462,6 +465,14 @@ c_common_handle_option (size_t scode, co
+       enable_warning_as_error ("implicit-function-declaration", value, CL_C | CL_ObjC); 
+       break;
++    case OPT_Werror_maybe_reset:
++      {
++      char *ev = getenv ("GCC_NO_WERROR");
++      if ((ev != NULL) && (*ev != '0'))
++        cpp_opts->warnings_are_errors = 0;
++      }
++      break;
++
+     case OPT_Wformat:
+       set_Wformat (value);
+       break;
+@@ -708,6 +719,12 @@ c_common_handle_option (size_t scode, co
+       flag_exceptions = value;
+       break;
++    case OPT_fhonour_copts:
++      if (c_language == clk_c) {
++      honour_copts++;
++      }
++      break;
++
+     case OPT_fimplement_inlines:
+       flag_implement_inlines = value;
+       break;
+@@ -1248,6 +1265,47 @@ c_common_init (void)
+   /* Has to wait until now so that cpplib has its hash table.  */
+   init_pragma ();
++  if (c_language == clk_c) {
++    char *ev = getenv ("GCC_HONOUR_COPTS");
++    int evv;
++    if (ev == NULL)
++      evv = -1;
++    else if ((*ev == '0') || (*ev == '\0'))
++      evv = 0;
++    else if (*ev == '1')
++      evv = 1;
++    else if (*ev == '2')
++      evv = 2;
++    else if (*ev == 's')
++      evv = -1;
++    else {
++      warning (0, "unknown GCC_HONOUR_COPTS value, assuming 1");
++      evv = 1; /* maybe depend this on something like MIRBSD_NATIVE?  */
++    }
++    if (evv == 1) {
++      if (honour_copts == 0) {
++      error ("someone does not honour COPTS at all in lenient mode");
++      return false;
++      } else if (honour_copts != 1) {
++      warning (0, "someone does not honour COPTS correctly, passed %d times",
++       honour_copts);
++      }
++    } else if (evv == 2) {
++      if (honour_copts == 0) {
++      error ("someone does not honour COPTS at all in strict mode");
++      return false;
++      } else if (honour_copts != 1) {
++      error ("someone does not honour COPTS correctly, passed %d times",
++       honour_copts);
++      return false;
++      }
++    } else if (evv == 0) {
++      if (honour_copts != 1)
++      inform ("someone does not honour COPTS correctly, passed %d times",
++       honour_copts);
++    }
++  }
++
+   return true;
+ }
+--- a/gcc/c.opt
++++ b/gcc/c.opt
+@@ -207,6 +207,10 @@ Werror-implicit-function-declaration
+ C ObjC RejectNegative Warning
+ This switch is deprecated; use -Werror=implicit-function-declaration instead
++Werror-maybe-reset
++C ObjC C++ ObjC++
++; Documented in common.opt
++
+ Wfloat-equal
+ C ObjC C++ ObjC++ Var(warn_float_equal) Warning
+ Warn if testing floating point numbers for equality
+@@ -590,6 +594,9 @@ C++ ObjC++ Optimization
+ fhonor-std
+ C++ ObjC++
++fhonour-copts
++C ObjC C++ ObjC++ RejectNegative
++
+ fhosted
+ C ObjC
+ Assume normal C execution environment
+--- a/gcc/common.opt
++++ b/gcc/common.opt
+@@ -102,6 +102,10 @@ Werror=
+ Common Joined
+ Treat specified warning as error
++Werror-maybe-reset
++Common
++If environment variable GCC_NO_WERROR is set, act as -Wno-error
++
+ Wextra
+ Common Warning
+ Print extra (possibly unwanted) warnings
+@@ -542,6 +546,9 @@ fguess-branch-probability
+ Common Report Var(flag_guess_branch_prob) Optimization
+ Enable guessing of branch probabilities
++fhonour-copts
++Common RejectNegative
++
+ ; Nonzero means ignore `#ident' directives.  0 means handle them.
+ ; Generate position-independent code for executables if possible
+ ; On SVR4 targets, it also controls whether or not to emit a
+--- a/gcc/opts.c
++++ b/gcc/opts.c
+@@ -830,9 +830,6 @@ decode_options (unsigned int argc, const
+       flag_schedule_insns_after_reload = 1;
+ #endif
+       flag_regmove = 1;
+-      flag_strict_aliasing = 1;
+-      flag_strict_overflow = 1;
+-      flag_delete_null_pointer_checks = 1;
+       flag_reorder_blocks = 1;
+       flag_reorder_functions = 1;
+       flag_tree_store_ccp = 1;
+@@ -853,6 +850,10 @@ decode_options (unsigned int argc, const
+   if (optimize >= 3)
+     {
++      flag_strict_aliasing = 1;
++      flag_strict_overflow = 1;
++      flag_delete_null_pointer_checks = 1;
++
+       flag_predictive_commoning = 1;
+       flag_inline_functions = 1;
+       flag_unswitch_loops = 1;
+@@ -1444,6 +1445,17 @@ common_handle_option (size_t scode, cons
+       enable_warning_as_error (arg, value, lang_mask);
+       break;
++    case OPT_Werror_maybe_reset:
++      {
++      char *ev = getenv ("GCC_NO_WERROR");
++      if ((ev != NULL) && (*ev != '0'))
++        warnings_are_errors = 0;
++      }
++      break;
++
++    case OPT_fhonour_copts:
++      break;
++
+     case OPT_Wextra:
+       set_Wextra (value);
+       break;
+--- a/gcc/doc/cppopts.texi
++++ b/gcc/doc/cppopts.texi
+@@ -168,6 +168,11 @@ in older programs.  This warning is on b
+ Make all warnings into hard errors.  Source code which triggers warnings
+ will be rejected.
++ at item -Werror-maybe-reset
++ at opindex Werror-maybe-reset
++Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
++variable is set to anything other than 0 or empty.
++
+ @item -Wsystem-headers
+ @opindex Wsystem-headers
+ Issue warnings for code in system headers.  These are normally unhelpful
+--- a/gcc/doc/invoke.texi
++++ b/gcc/doc/invoke.texi
+@@ -233,7 +233,7 @@ Objective-C and Objective-C++ Dialects}.
+ -Wconversion  -Wcoverage-mismatch  -Wno-deprecated-declarations @gol
+ -Wdisabled-optimization  -Wno-div-by-zero  @gol
+ -Wempty-body  -Wno-endif-labels @gol
+--Werror  -Werror=* @gol
++-Werror  -Werror=* -Werror-maybe-reset @gol
+ -Wfatal-errors  -Wfloat-equal  -Wformat  -Wformat=2 @gol
+ -Wno-format-extra-args -Wformat-nonliteral @gol
+ -Wformat-security  -Wformat-y2k -Wignored-qualifiers @gol
+@@ -4047,6 +4047,22 @@ This option is only supported for C and 
+ @option{-Wall} and by @option{-pedantic}, which can be disabled with
+ @option{-Wno-pointer-sign}.
++ at item -Werror-maybe-reset
++ at opindex Werror-maybe-reset
++Act like @samp{-Wno-error} if the @env{GCC_NO_WERROR} environment
++variable is set to anything other than 0 or empty.
++
++ at item -fhonour-copts
++ at opindex fhonour-copts
++If @env{GCC_HONOUR_COPTS} is set to 1, abort if this option is not
++given at least once, and warn if it is given more than once.
++If @env{GCC_HONOUR_COPTS} is set to 2, abort if this option is not
++given exactly once.
++If @env{GCC_HONOUR_COPTS} is set to 0 or unset, warn if this option
++is not given exactly once.
++The warning is quelled if @env{GCC_HONOUR_COPTS} is set to @samp{s}.
++This flag and environment variable only affect the C language.
++
+ @item -Wstack-protector
+ @opindex Wstack-protector
+ @opindex Wno-stack-protector
+@@ -5522,7 +5538,7 @@ so, the first branch is redirected to ei
+ second branch or a point immediately following it, depending on whether
+ the condition is known to be true or false.
+-Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
++Enabled at levels @option{-O3}.
+ @item -fsplit-wide-types
+ @opindex fsplit-wide-types
+@@ -5667,7 +5683,7 @@ safely dereference null pointers.  Use
+ @option{-fno-delete-null-pointer-checks} to disable this optimization
+ for programs which depend on that behavior.
+-Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
++Enabled at levels @option{-O3}.
+ @item -fexpensive-optimizations
+ @opindex fexpensive-optimizations
+--- a/gcc/java/jvspec.c
++++ b/gcc/java/jvspec.c
+@@ -670,6 +670,7 @@ lang_specific_pre_link (void)
+      class name.  Append dummy `.c' that can be stripped by set_input so %b
+      is correct.  */ 
+   set_input (concat (main_class_name, "main.c", NULL));
++  putenv ("GCC_HONOUR_COPTS=s"); /* XXX hack!  */
+   err = do_spec (jvgenmain_spec);
+   if (err == 0)
+     {
diff --git a/toolchain/gcc/patches/4.3.3+cs/993-arm_insn-opinit-RTX_CODE-fixup.patch b/toolchain/gcc/patches/4.3.3+cs/993-arm_insn-opinit-RTX_CODE-fixup.patch
new file mode 100644 (file)
index 0000000..cbe9f1b
--- /dev/null
@@ -0,0 +1,32 @@
+gcc/ChangeLog
+2007-11-27  Bernhard Fischer  <>
+
+       * config/arm/arm-protos.h (arm_vector_mode_supported_p,
+       arm_hard_regno_mode_ok, const_ok_for_arm): Do not hide non-rtx related
+       function prototypes in RTX_CODE.
+       * genopinit.c: Include tm_p.h.
+
+--- a/gcc/config/arm/arm-protos.h
++++ b/gcc/config/arm/arm-protos.h
+@@ -43,10 +43,10 @@ extern unsigned int arm_dbx_register_num
+ extern void arm_output_fn_unwind (FILE *, bool);
+   
+-#ifdef RTX_CODE
+ extern bool arm_vector_mode_supported_p (enum machine_mode);
+ extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
+ extern int const_ok_for_arm (HOST_WIDE_INT);
++#ifdef RTX_CODE
+ extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
+                              HOST_WIDE_INT, rtx, rtx, int);
+ extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, enum machine_mode,
+--- a/gcc/genopinit.c
++++ b/gcc/genopinit.c
+@@ -487,6 +487,7 @@ from the machine description file `md'. 
+   printf ("#include \"expr.h\"\n");
+   printf ("#include \"optabs.h\"\n");
+   printf ("#include \"reload.h\"\n\n");
++  printf ("#include \"tm_p.h\"\n\n");
+   printf ("void\ninit_all_optabs (void)\n{\n");
diff --git a/toolchain/gcc/patches/4.3.3+cs/998-gcc-4.3.0-fix-header.00.patch b/toolchain/gcc/patches/4.3.3+cs/998-gcc-4.3.0-fix-header.00.patch
new file mode 100644 (file)
index 0000000..fd19873
--- /dev/null
@@ -0,0 +1,13 @@
+\\\\
+\\ gcc PR33200
+--- a/gcc/config.gcc
++++ b/gcc/config.gcc
+@@ -1460,7 +1460,7 @@ i[34567]86-*-uwin*)
+       if test x$enable_threads = xyes; then
+               thread_file='win32'
+       fi
+-      use_fixproto=yes
++      # XXX: why? use_fixproto=yes
+       ;;
+ i[34567]86-*-interix3*)
+       tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/i386-interix.h i386/i386-interix3.h interix.h interix3.h"
diff --git a/toolchain/gcc/patches/4.3.3+cs/999-coldfire.patch b/toolchain/gcc/patches/4.3.3+cs/999-coldfire.patch
new file mode 100644 (file)
index 0000000..0e2a8c1
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/gcc/config.gcc
++++ b/gcc/config.gcc
+@@ -1678,6 +1678,7 @@ m68k-*-linux*)           # Motorola m68k's runnin
+       if test x$sjlj != x1; then
+           tmake_file="$tmake_file m68k/t-slibgcc-elf-ver"
+       fi
++      tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-m68kelf"
+       ;;
+ m68k-*-rtems*)
+       default_m68k_cpu=68020