Merge remote-tracking branch 'origin/master' into hjl/lto/master
diff --git a/COPYING.NEWLIB b/COPYING.NEWLIB
index 6849eb5..73379ff 100644
--- a/COPYING.NEWLIB
+++ b/COPYING.NEWLIB
@@ -894,3 +894,34 @@
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(40) - Altera Corportion (nios2-* targets)
+
+Copyright (c) 2003 Altera Corporation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+   o Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer. 
+   o Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the 
+     documentation and/or other materials provided with the distribution. 
+   o Neither the name of Altera Corporation nor the names of its 
+     contributors may be used to endorse or promote products derived from
+     this software without specific prior written permission. 
+ 
+THIS SOFTWARE IS PROVIDED BY ALTERA CORPORATION, THE COPYRIGHT HOLDER,
+AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
+
diff --git a/ChangeLog b/ChangeLog
index 06c7d47..2d6d310 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-05-06  Sandra Loosemore  <sandra@codesourcery.com>
+
+	* COPYING.NEWLIB: Add Altera Corporation copyright.
+
 2013-04-29  Jan-Benedict Glaw  <jbglaw@lug-owl.de>
 
 	* config.guess: Update from config repo.
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 06bdfe7..d01e687 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,148 @@
+2013-05-23  Alan Modra  <amodra@gmail.com>
+
+	* format.c (bfd_check_format_matches): Don't match a target in
+	targ_selvecs if some other target is a better match.  If
+	targets implement match priority, fall back to the first of
+	the best matches.
+
+2013-05-22  Eric Herman  <eric@freesa.org>
+
+	PR binutils/15462
+	* elfxx-mips.c (_bfd_mips_elf_relocate_section): Warning fix.
+
+2013-05-22  Ralf Dreesen  <gamma@dreesen.net>
+
+	PR binutils/15474
+	* srec.c (srec_set_section_contents): Properly convert size
+	and offset to address when octets_per_byte is not unity.
+
+2013-05-20  Maciej W. Rozycki  <macro@linux-mips.org>
+
+	* elf32-vax.c (elf_vax_instantiate_got_entries): Only set the
+	refcount member of the gotplt_union when resetting the reference
+	count.  Adjust comment.
+
+2013-05-20  Will Newton  <will.newton@linaro.org>
+
+	* elf64-aarch64.c (elf64_aarch64_link_hash_entry): Remove
+	relocs_copied member.
+	(elf64_aarch64_link_hash_newfunc): Remove initialization of
+	relocs_copied member.
+	(elf64_aarch64_copy_indirect_symbol): Remove code to copy
+	relocs_copied member.
+
+2013-05-19  Maciej W. Rozycki  <macro@linux-mips.org>
+
+	* elf32-vax.c (elf_vax_adjust_dynamic_symbol): Convert K&R
+	function definition.
+
+2013-05-16  Cary Coutant  <ccoutant@google.com>
+
+	* ecoff.c (ecoff_link_check_archive_element): Add initializers for
+	external_ext_size and esize.
+
+2013-05-16  Tristan Gingold  <gingold@adacore.com>
+
+	* coff-rs6000.c (_bfd_xcoff_reloc_type_lookup): Handle BFD_RELOC_16.
+	* coff64-rs6000.c (xcoff64_reloc_type_lookup): Likewise.
+
+2013-05-15  Andreas Schwab  <schwab@suse.de>
+
+	* elf64-aarch64.c (elf_backend_default_execstack): Define to 0.
+
+2013-05-10  Joel Brobecker  <brobecker@adacore.com>
+
+	* coffcode.h (styp_to_sec_flags) [RS6000COFF_C]: Add handling
+	of STYP_EXCEPT, STYP_LOADER and STYP_TYPCHK sections.
+
+2013-05-09  Joel Brobecker  <brobecker@adacore.com>
+
+	* bfd.c (_bfd_default_error_handler): Replace use of putc
+	by fputc.  Add comment explaining why.
+
+2013-05-09  Alan Modra  <amodra@gmail.com>
+
+	* elflink.c (elf_link_add_object_symbols): Don't omit reading
+	of symbols when hashes already exist.
+
+2013-05-07  Will Newton  <will.newton@linaro.org>
+
+	* elf-ifunc.c (_bfd_elf_allocate_ifunc_dyn_relocs): Add a
+	plt_header_size argument for ports where it differs from
+	plt_entry_size.
+	* elf-bfd.h: Likewise.
+	* elf32-i386.c: Pass plt_header_size to
+	_bfd_elf_allocate_ifunc_dyn_relocs.
+	* elf64-x86-64.c: Likewise.
+
+2013-05-07  Will Newton  <will.newton@linaro.org>
+
+	* elf-ifunc.c (_bfd_elf_create_ifunc_dyn_reloc): Remove unused
+	function.
+	* elf-bfd.h: Likewise.
+
+2013-05-06  Paul Brook  <paul@codesourcery.com>
+
+	* elf64-mips.c (elf_mips_gnu_pcrel32): New.
+	(bfd_elf64_bfd_reloc_type_lookup, bfd_elf64_bfd_reloc_name_lookup,
+	mips_elf64_rtype_to_howto): Handle R_MIPS_PC32.
+	* elfn32-mips.c (elf_mips_gnu_pcrel32): New.
+	(bfd_elfn32_bfd_reloc_type_lookup, bfd_elfn32_bfd_reloc_name_lookup,
+	mips_elfn32_rtype_to_howto): Handle R_MIPS_PC32.
+
+2013-05-06  Alan Modra  <amodra@gmail.com>
+
+	* elf64-ppc.c (opd_entry_value): Handle case where symbol
+	hashes are not available.
+
+2013-05-06  Alan Modra  <amodra@gmail.com>
+
+	* elflink.c (elf_link_add_object_symbols): Don't save symbol
+	hashes around loading as-needed library.  Zero them on allocation,
+	and restore to initial all-zero state if library not needed.
+	Arrange to reuse hashes if we load library again later.
+
+2013-05-04  Richard Sandiford  <rdsandiford@googlemail.com>
+
+	* elf32-mips.c (elf_mips_copy_howto, elf_mips_jump_slot_howto):
+	Use _bfd_mips_elf_generic_reloc instead of bfd_elf_generic_reloc.
+	* elfn32-mips.c: Likewise.
+	* elf64-mips.c: Likewise.
+
+2013-05-02  Nick Clifton  <nickc@redhat.com>
+
+	* archures.c: Add some more MSP430 machine numbers.
+	* config.bfd (msp430): Define targ_selvecs.
+	* configure.in: Add bfd_elf32_msp430_ti_vec.
+	* cpu-msp430.c: Add some more MSP430 machine numbers.
+	* elf32-msp430.c Add support for MSP430X relocations.
+	Add support for TI compiler generated relocations.
+	Add support for sym_diff relocations.
+	Add support for relaxing out of range short branches into long
+	branches.
+	Add support for MSP430 attribute section.
+	* reloc.c: Add MSP430X relocations.
+	* targets.c: Add bfd_elf32_msp430_ti_vec.
+	* bfd-in2.h: Regenerate.
+	* configure: Regenerate.
+	* libbfd.h: Regenerate.
+
+2013-05-01  Maciej W. Rozycki  <macro@codesourcery.com>
+
+	* config.bfd: Replace alpha*-*-linuxecoff* pattern with
+	alpha*-*-linux*ecoff*.
+
+2013-04-30  Olaf Flebbe  <o.flebbe@science-computing.de>
+
+	PR binutils/15417
+	* elflink.c (elf_link_add_object_symbols): Initialise 'idx' to
+	zero.
+
+2013-04-30  Alan Modra  <amodra@gmail.com>
+
+	* elflink.c (bfd_elf_record_link_assignment): Dont make
+	STV_INTERNAL symbols STV_HIDDEN.
+
 2013-04-29  Nick Clifton  <nickc@redhat.com>
 
 	* elflink.c (_bfd_elf_gc_mark_extra_sections): Remove mark from
diff --git a/bfd/archures.c b/bfd/archures.c
index 0be72da..f7cef8b 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -1,7 +1,5 @@
 /* BFD library support routines for architectures.
-   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
-   2012, 2013 Free Software Foundation, Inc.
+   Copyright 1990-2013 Free Software Foundation, Inc.
    Hacked by John Gilmore and Steve Chamberlain of Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -437,7 +435,12 @@
 .#define bfd_mach_msp14          14
 .#define bfd_mach_msp15          15
 .#define bfd_mach_msp16          16
+.#define bfd_mach_msp20          20
 .#define bfd_mach_msp21          21
+.#define bfd_mach_msp22          22
+.#define bfd_mach_msp23          23
+.#define bfd_mach_msp24          24
+.#define bfd_mach_msp26          26
 .#define bfd_mach_msp31          31
 .#define bfd_mach_msp32          32
 .#define bfd_mach_msp33          33
@@ -445,6 +448,10 @@
 .#define bfd_mach_msp42          42
 .#define bfd_mach_msp43          43
 .#define bfd_mach_msp44          44
+.#define bfd_mach_msp430x        45
+.#define bfd_mach_msp46          46
+.#define bfd_mach_msp47          47
+.#define bfd_mach_msp54          54
 .  bfd_arch_xc16x,     {* Infineon's XC16X Series.               *}
 .#define bfd_mach_xc16x         1
 .#define bfd_mach_xc16xl        2
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 9fc98fe..878def7 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2176,7 +2176,12 @@
 #define bfd_mach_msp14          14
 #define bfd_mach_msp15          15
 #define bfd_mach_msp16          16
+#define bfd_mach_msp20          20
 #define bfd_mach_msp21          21
+#define bfd_mach_msp22          22
+#define bfd_mach_msp23          23
+#define bfd_mach_msp24          24
+#define bfd_mach_msp26          26
 #define bfd_mach_msp31          31
 #define bfd_mach_msp32          32
 #define bfd_mach_msp33          33
@@ -2184,6 +2189,10 @@
 #define bfd_mach_msp42          42
 #define bfd_mach_msp43          43
 #define bfd_mach_msp44          44
+#define bfd_mach_msp430x        45
+#define bfd_mach_msp46          46
+#define bfd_mach_msp47          47
+#define bfd_mach_msp54          54
   bfd_arch_xc16x,     /* Infineon's XC16X Series.               */
 #define bfd_mach_xc16x         1
 #define bfd_mach_xc16xl        2
@@ -4924,6 +4933,21 @@
   BFD_RELOC_MSP430_16_BYTE,
   BFD_RELOC_MSP430_2X_PCREL,
   BFD_RELOC_MSP430_RL_PCREL,
+  BFD_RELOC_MSP430_ABS8,
+  BFD_RELOC_MSP430X_PCR20_EXT_SRC,
+  BFD_RELOC_MSP430X_PCR20_EXT_DST,
+  BFD_RELOC_MSP430X_PCR20_EXT_ODST,
+  BFD_RELOC_MSP430X_ABS20_EXT_SRC,
+  BFD_RELOC_MSP430X_ABS20_EXT_DST,
+  BFD_RELOC_MSP430X_ABS20_EXT_ODST,
+  BFD_RELOC_MSP430X_ABS20_ADR_SRC,
+  BFD_RELOC_MSP430X_ABS20_ADR_DST,
+  BFD_RELOC_MSP430X_PCR16,
+  BFD_RELOC_MSP430X_PCR20_CALL,
+  BFD_RELOC_MSP430X_ABS16,
+  BFD_RELOC_MSP430_ABS_HI16,
+  BFD_RELOC_MSP430_PREL31,
+  BFD_RELOC_MSP430_SYM_DIFF,
 
 /* Relocations used by the Altera Nios II core.  */
   BFD_RELOC_NIOS2_S16,
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 416efdc..2ef48a7 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -747,7 +747,9 @@
   vfprintf (stderr, new_fmt, ap);
   va_end (ap);
 
-  putc ('\n', stderr);
+  /* On AIX, putc is implemented as a macro that triggers a -Wunused-value
+     warning, so use the fputc function to avoid it.  */
+  fputc ('\n', stderr);
   fflush (stderr);
 }
 
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index 0945aca..aa61afb 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -1098,7 +1098,6 @@
 	 0xffff,		/* src_mask */
 	 0xffff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
-
 };
 
 void
@@ -1146,6 +1145,9 @@
       return &xcoff_howto_table[8];
     case BFD_RELOC_PPC_TOC16:
       return &xcoff_howto_table[3];
+    case BFD_RELOC_16:
+      /* Note that this relocation is only internally used by gas.  */
+      return &xcoff_howto_table[0xc];
     case BFD_RELOC_32:
     case BFD_RELOC_CTOR:
       return &xcoff_howto_table[0];
diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c
index 5f4a502..56a0d25 100644
--- a/bfd/coff64-rs6000.c
+++ b/bfd/coff64-rs6000.c
@@ -1826,6 +1826,9 @@
       return &xcoff64_howto_table[8];
     case BFD_RELOC_PPC_TOC16:
       return &xcoff64_howto_table[3];
+    case BFD_RELOC_16:
+      /* Note that this relocation is only internally used by gas.  */
+      return &xcoff64_howto_table[0xc];
     case BFD_RELOC_32:
     case BFD_RELOC_CTOR:
       return &xcoff64_howto_table[0x1c];
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 9d9c992..2a1a172 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -795,6 +795,12 @@
   else if (styp_flags & STYP_PAD)
     sec_flags = 0;
 #ifdef RS6000COFF_C
+  else if (styp_flags & STYP_EXCEPT)
+    sec_flags |= SEC_LOAD;
+  else if (styp_flags & STYP_LOADER)
+    sec_flags |= SEC_LOAD;
+  else if (styp_flags & STYP_TYPCHK)
+    sec_flags |= SEC_LOAD;
   else if (styp_flags & STYP_DWARF)
     sec_flags |= SEC_DEBUGGING;
 #endif
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 228e7c1..ebc9d40 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -202,7 +202,7 @@
     targ_selvecs=nlm32_alpha_vec
     want64=true
     ;;
-  alpha*-*-linuxecoff*)
+  alpha*-*-linux*ecoff*)
     targ_defvec=ecoffalpha_little_vec
     targ_selvecs=bfd_elf64_alpha_vec
     want64=true
@@ -1134,6 +1134,7 @@
 
   msp430-*-*)
     targ_defvec=bfd_elf32_msp430_vec
+    targ_selvecs=bfd_elf32_msp430_ti_vec
     ;;
 
   ns32k-pc532-mach* | ns32k-pc532-ux*)
diff --git a/bfd/configure b/bfd/configure
index 24f6fd3..5fc08e4 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -15292,6 +15292,7 @@
     bfd_elf32_mn10300_vec)	tb="$tb elf-m10300.lo elf32.lo $elf" ;;
     bfd_elf32_mt_vec)           tb="$tb elf32-mt.lo elf32.lo $elf" ;;
     bfd_elf32_msp430_vec)	tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
+    bfd_elf32_msp430_ti_vec)	tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
     bfd_elf32_nbigmips_vec)	tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     bfd_elf32_nlittlemips_vec)	tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     bfd_elf32_ntradbigmips_vec | bfd_elf32_ntradbigmips_freebsd_vec)
diff --git a/bfd/configure.in b/bfd/configure.in
index d9bef83..befcf27 100644
--- a/bfd/configure.in
+++ b/bfd/configure.in
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf to produce a configure script.
 dnl
-dnl   Copyright 2012 Free Software Foundation
+dnl   Copyright 2012-2013 Free Software Foundation
 dnl
 dnl This file is free software; you can redistribute it and/or modify
 dnl it under the terms of the GNU General Public License as published by
@@ -789,6 +789,7 @@
     bfd_elf32_mn10300_vec)	tb="$tb elf-m10300.lo elf32.lo $elf" ;;
     bfd_elf32_mt_vec)           tb="$tb elf32-mt.lo elf32.lo $elf" ;;
     bfd_elf32_msp430_vec)	tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
+    bfd_elf32_msp430_ti_vec)	tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
     bfd_elf32_nbigmips_vec)	tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     bfd_elf32_nlittlemips_vec)	tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     bfd_elf32_ntradbigmips_vec | bfd_elf32_ntradbigmips_freebsd_vec)
diff --git a/bfd/cpu-msp430.c b/bfd/cpu-msp430.c
index 09c0e54..73b6e66 100644
--- a/bfd/cpu-msp430.c
+++ b/bfd/cpu-msp430.c
@@ -1,6 +1,5 @@
 /* BFD library support routines for the MSP architecture.
-   Copyright (C) 2002, 2003, 2005, 2007, 2012
-   Free Software Foundation, Inc.
+   Copyright (C) 2002-2013 Free Software Foundation, Inc.
    Contributed by Dmitry Diky <diwil@mail.ru>
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -82,29 +81,56 @@
   /* msp430x16x.  */
   N (16, bfd_mach_msp16, "msp:16", FALSE, & arch_info_struct[7]),
 
+  /* msp430x20x.  */
+  N (16, bfd_mach_msp20, "msp:20", FALSE, & arch_info_struct[8]),
+
   /* msp430x21x.  */
-  N (16, bfd_mach_msp21, "msp:21", FALSE, & arch_info_struct[8]),
+  N (16, bfd_mach_msp21, "msp:21", FALSE, & arch_info_struct[9]),
+
+  /* msp430x22x.  */
+  N (16, bfd_mach_msp22, "msp:22", FALSE, & arch_info_struct[10]),
+
+  /* msp430x23x.  */
+  N (16, bfd_mach_msp23, "msp:23", FALSE, & arch_info_struct[11]),
+
+  /* msp430x24x.  */
+  N (16, bfd_mach_msp24, "msp:24", FALSE, & arch_info_struct[12]),
+
+  /* msp430x26x.  */
+  N (16, bfd_mach_msp26, "msp:26", FALSE, & arch_info_struct[13]),
 
   /* msp430x31x.  */
-  N (16, bfd_mach_msp31, "msp:31", FALSE, & arch_info_struct[9]),
+  N (16, bfd_mach_msp31, "msp:31", FALSE, & arch_info_struct[14]),
 
   /* msp430x32x.  */
-  N (16, bfd_mach_msp32, "msp:32", FALSE, & arch_info_struct[10]),
+  N (16, bfd_mach_msp32, "msp:32", FALSE, & arch_info_struct[15]),
 
   /* msp430x33x.  */
-  N (16, bfd_mach_msp33, "msp:33", FALSE, & arch_info_struct[11]),
+  N (16, bfd_mach_msp33, "msp:33", FALSE, & arch_info_struct[16]),
 
   /* msp430x41x.  */
-  N (16, bfd_mach_msp41, "msp:41", FALSE, & arch_info_struct[12]),
+  N (16, bfd_mach_msp41, "msp:41", FALSE, & arch_info_struct[17]),
 
   /* msp430x42x.  */
-  N (16, bfd_mach_msp42, "msp:42", FALSE, & arch_info_struct[13]),
+  N (16, bfd_mach_msp42, "msp:42", FALSE, & arch_info_struct[18]),
 
   /* msp430x43x.  */
-  N (16, bfd_mach_msp43, "msp:43", FALSE, & arch_info_struct[14]),
+  N (16, bfd_mach_msp43, "msp:43", FALSE, & arch_info_struct[19]),
 
   /* msp430x44x.  */
-  N (16, bfd_mach_msp43, "msp:44", FALSE, NULL)
+  N (16, bfd_mach_msp43, "msp:44", FALSE, & arch_info_struct[20]),
+
+  /* msp430x46x.  */
+  N (16, bfd_mach_msp46, "msp:46", FALSE, & arch_info_struct[21]),
+
+  /* msp430x47x.  */
+  N (16, bfd_mach_msp47, "msp:47", FALSE, & arch_info_struct[22]),
+
+  /* msp430x54x.  */
+  N (16, bfd_mach_msp54, "msp:54", FALSE, & arch_info_struct[23]),
+
+  N (32, bfd_mach_msp430x, "msp:430X", FALSE, NULL)
+
 };
 
 const bfd_arch_info_type bfd_msp430_arch =
diff --git a/bfd/ecoff.c b/bfd/ecoff.c
index 5add50c..7bfb333 100644
--- a/bfd/ecoff.c
+++ b/bfd/ecoff.c
@@ -3561,9 +3561,9 @@
   void (* const swap_ext_in) (bfd *, void *, EXTR *)
     = backend->debug_swap.swap_ext_in;
   HDRR *symhdr;
-  bfd_size_type external_ext_size;
+  bfd_size_type external_ext_size = 0;
   void * external_ext = NULL;
-  bfd_size_type esize;
+  bfd_size_type esize = 0;
   char *ssext = NULL;
   char *ext_ptr;
   char *ext_end;
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index b643dbc..4a67d02 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2378,12 +2378,9 @@
 
 extern bfd_boolean _bfd_elf_create_ifunc_sections
   (bfd *, struct bfd_link_info *);
-extern asection * _bfd_elf_create_ifunc_dyn_reloc
-  (bfd *, struct bfd_link_info *, asection *sec, asection *sreloc,
-   struct elf_dyn_relocs **);
 extern bfd_boolean _bfd_elf_allocate_ifunc_dyn_relocs
   (struct bfd_link_info *, struct elf_link_hash_entry *,
-   struct elf_dyn_relocs **, unsigned int, unsigned int);
+   struct elf_dyn_relocs **, unsigned int, unsigned int, unsigned int);
 
 extern void elf_append_rela (bfd *, asection *, Elf_Internal_Rela *);
 extern void elf_append_rel (bfd *, asection *, Elf_Internal_Rela *);
diff --git a/bfd/elf-ifunc.c b/bfd/elf-ifunc.c
index c2fa163..8d48e66 100644
--- a/bfd/elf-ifunc.c
+++ b/bfd/elf-ifunc.c
@@ -104,51 +104,6 @@
   return TRUE;
 }
 
-/* For a STT_GNU_IFUNC symbol, create a dynamic reloc section, SRELOC,
-   for the input section, SEC, and append this reloc to HEAD.  */
-
-asection *
-_bfd_elf_create_ifunc_dyn_reloc (bfd *abfd, struct bfd_link_info *info,
-				 asection *sec, asection *sreloc,
-				 struct elf_dyn_relocs **head)
-{
-  struct elf_dyn_relocs *p;
-  struct elf_link_hash_table *htab = elf_hash_table (info);
-
-  if (sreloc == NULL)
-    {
-      const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-
-      if (htab->dynobj == NULL)
-	htab->dynobj = abfd;
-
-      sreloc = _bfd_elf_make_dynamic_reloc_section (sec, htab->dynobj,
-						    bed->s->log_file_align,
-						    abfd,
-						    bed->rela_plts_and_copies_p);
-      if (sreloc == NULL)
-	return NULL;
-    }
-
-  p = *head;
-  if (p == NULL || p->sec != sec)
-    {
-      bfd_size_type amt = sizeof *p;
-
-      p = ((struct elf_dyn_relocs *) bfd_alloc (htab->dynobj, amt));
-      if (p == NULL)
-	return NULL;
-      p->next = *head;
-      *head = p;
-      p->sec = sec;
-      p->count = 0;
-      p->pc_count = 0;
-    }
-  p->count += 1;
-
-  return sreloc;
-}
-
 /* Allocate space in .plt, .got and associated reloc sections for
    dynamic relocs against a STT_GNU_IFUNC symbol definition.  */
 
@@ -157,6 +112,7 @@
 				    struct elf_link_hash_entry *h,
 				    struct elf_dyn_relocs **head,
 				    unsigned int plt_entry_size,
+				    unsigned int plt_header_size,
 				    unsigned int got_entry_size)
 {
   asection *plt, *gotplt, *relplt;
@@ -238,7 +194,7 @@
       /* If this is the first .plt entry, make room for the special
 	 first entry.  */
       if (plt->size == 0)
-	plt->size += plt_entry_size;
+	plt->size += plt_header_size;
     }
   else
     {
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 2609130..cc8b48e 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -2197,7 +2197,8 @@
   if (h->type == STT_GNU_IFUNC
       && h->def_regular)
     return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs,
-                                               plt_entry_size, 4);
+                                               plt_entry_size,
+					       plt_entry_size, 4);
   else if (htab->elf.dynamic_sections_created
 	   && h->plt.refcount > 0)
     {
diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
index cb7692b..54ae641 100644
--- a/bfd/elf32-mips.c
+++ b/bfd/elf32-mips.c
@@ -1515,7 +1515,7 @@
 	 FALSE,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_bitfield, /* complain_on_overflow */
-	 bfd_elf_generic_reloc,	/* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_COPY",		/* name */
 	 FALSE,			/* partial_inplace */
 	 0x0,         		/* src_mask */
@@ -1531,7 +1531,7 @@
 	 FALSE,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_bitfield, /* complain_on_overflow */
-	 bfd_elf_generic_reloc,	/* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_JUMP_SLOT",	/* name */
 	 FALSE,			/* partial_inplace */
 	 0x0,         		/* src_mask */
diff --git a/bfd/elf32-msp430.c b/bfd/elf32-msp430.c
index b46e72c..6f66282 100644
--- a/bfd/elf32-msp430.c
+++ b/bfd/elf32-msp430.c
@@ -1,6 +1,5 @@
 /*  MSP430-specific support for 32-bit ELF
-    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2010, 2012
-    Free Software Foundation, Inc.
+    Copyright (C) 2002-2013 Free Software Foundation, Inc.
     Contributed by Dmitry Diky <diwil@mail.ru>
 
     This file is part of BFD, the Binary File Descriptor library.
@@ -27,9 +26,6 @@
 #include "elf-bfd.h"
 #include "elf/msp430.h"
 
-/* Use RELA instead of REL.  */
-#undef USE_REL
-
 static reloc_howto_type elf_msp430_howto_table[] =
 {
   HOWTO (R_MSP430_NONE,		/* type */
@@ -69,7 +65,7 @@
 	 0,			/* bitpos */
 	 complain_overflow_bitfield,/* complain_on_overflow */
 	 bfd_elf_generic_reloc,	/* special_function */
-	 "R_MSP430_13_PCREL",	/* name */
+	 "R_MSP430_10_PCREL",	/* name */
 	 FALSE,			/* partial_inplace */
 	 0xfff,			/* src_mask */
 	 0xfff,			/* dst_mask */
@@ -90,7 +86,7 @@
 	 0xffff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
 
-  /* A 16 bit absolute relocation for command address.  */
+  /* A 16 bit PC relative relocation for command address.  */
   HOWTO (R_MSP430_16_PCREL,	/* type */
 	 1,			/* rightshift */
 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
@@ -164,6 +160,340 @@
 	 0,			/* src_mask */
 	 0xffff,		/* dst_mask */
 	 TRUE)			/* pcrel_offset */
+
+  /* A 8-bit absolute relocation.  */
+  , HOWTO (R_MSP430_8,		/* type */
+	 0,			/* rightshift */
+	 0,			/* size (0 = byte, 1 = short, 2 = long) */
+	 8,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430_8",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* Together with a following reloc, allows for the difference
+     between two symbols to be the real addend of the second reloc.  */
+  HOWTO (R_MSP430_SYM_DIFF,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 NULL, 			/* special handler.  */
+	 "R_MSP430_SYM_DIFF",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0xffffffff,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 FALSE)			/* pcrel_offset */  
+};
+
+static reloc_howto_type elf_msp430x_howto_table[] =
+{
+  HOWTO (R_MSP430_NONE,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430_NONE",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0,			/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  HOWTO (R_MSP430_ABS32,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430_ABS32",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0xffffffff,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  HOWTO (R_MSP430_ABS16,	/* type */
+	 0,			/* rightshift */
+	 1,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430_ABS16",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  HOWTO (R_MSP430_ABS8,		/* type */
+	 0,			/* rightshift */
+	 0,			/* size (0 = byte, 1 = short, 2 = long) */
+	 8,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430_ABS8",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0xff,			/* src_mask */
+	 0xff,			/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  HOWTO (R_MSP430_PCR16,	/* type */
+	 1,			/* rightshift */
+	 1,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430_PCR16",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  HOWTO (R_MSP430X_PCR20_EXT_SRC,/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430X_PCR20_EXT_SRC",/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  HOWTO (R_MSP430X_PCR20_EXT_DST,/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430X_PCR20_EXT_DST",/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  HOWTO (R_MSP430X_PCR20_EXT_ODST,/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430X_PCR20_EXT_ODST",/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  HOWTO (R_MSP430X_ABS20_EXT_SRC,/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430X_ABS20_EXT_SRC",/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  HOWTO (R_MSP430X_ABS20_EXT_DST,/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430X_ABS20_EXT_DST",/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  HOWTO (R_MSP430X_ABS20_EXT_ODST,/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430X_ABS20_EXT_ODST",/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  HOWTO (R_MSP430X_ABS20_ADR_SRC,/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430X_ABS20_ADR_SRC",/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  HOWTO (R_MSP430X_ABS20_ADR_DST,/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430X_ABS20_ADR_DST",/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  HOWTO (R_MSP430X_PCR16,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430X_PCR16",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  HOWTO (R_MSP430X_PCR20_CALL,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430X_PCR20_CALL",/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  HOWTO (R_MSP430X_ABS16,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430X_ABS16",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  HOWTO (R_MSP430_ABS_HI16,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430_ABS_HI16",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  HOWTO (R_MSP430_PREL31,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430_PREL31",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffff,		/* dst_mask */
+	 TRUE),                 /* pcrel_offset */
+
+  EMPTY_HOWTO (R_MSP430_EHTYPE),
+  
+  /* A 13 bit PC relative relocation.  */
+  HOWTO (R_MSP430X_10_PCREL,	/* type */
+	 1,			/* rightshift */
+	 1,			/* size (0 = byte, 1 = short, 2 = long) */
+	 10,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430X_10_PCREL",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0xfff,			/* src_mask */
+	 0xfff,			/* dst_mask */
+	 TRUE),  		/* pcrel_offset */
+
+  /* A 13 bit PC relative relocation for complicated polymorphs.  */
+  HOWTO (R_MSP430X_2X_PCREL,	/* type */
+	 1,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 10,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield,/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_MSP430X_2X_PCREL",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0xfff,			/* src_mask */
+	 0xfff,			/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  /* Together with a following reloc, allows for the difference
+     between two symbols to be the real addend of the second reloc.  */
+  HOWTO (R_MSP430X_SYM_DIFF,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,/* complain_on_overflow */
+	 NULL, 			/* special handler.  */
+	 "R_MSP430X_SYM_DIFF",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0xffffffff,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 FALSE)			/* pcrel_offset */  
 };
 
 /* Map BFD reloc types to MSP430 ELF reloc types.  */
@@ -175,18 +505,55 @@
 };
 
 static const struct msp430_reloc_map msp430_reloc_map[] =
-  {
-    {BFD_RELOC_NONE,                 R_MSP430_NONE},
-    {BFD_RELOC_32,                   R_MSP430_32},
-    {BFD_RELOC_MSP430_10_PCREL,      R_MSP430_10_PCREL},
-    {BFD_RELOC_16,                   R_MSP430_16_BYTE},
-    {BFD_RELOC_MSP430_16_PCREL,      R_MSP430_16_PCREL},
-    {BFD_RELOC_MSP430_16,            R_MSP430_16},
-    {BFD_RELOC_MSP430_16_PCREL_BYTE, R_MSP430_16_PCREL_BYTE},
-    {BFD_RELOC_MSP430_16_BYTE,       R_MSP430_16_BYTE},
-    {BFD_RELOC_MSP430_2X_PCREL,      R_MSP430_2X_PCREL},
-    {BFD_RELOC_MSP430_RL_PCREL,      R_MSP430_RL_PCREL}
-  };
+{
+  {BFD_RELOC_NONE,                 R_MSP430_NONE},
+  {BFD_RELOC_32,                   R_MSP430_32},
+  {BFD_RELOC_MSP430_10_PCREL,      R_MSP430_10_PCREL},
+  {BFD_RELOC_16,                   R_MSP430_16_BYTE},
+  {BFD_RELOC_MSP430_16_PCREL,      R_MSP430_16_PCREL},
+  {BFD_RELOC_MSP430_16,            R_MSP430_16},
+  {BFD_RELOC_MSP430_16_PCREL_BYTE, R_MSP430_16_PCREL_BYTE},
+  {BFD_RELOC_MSP430_16_BYTE,       R_MSP430_16_BYTE},
+  {BFD_RELOC_MSP430_2X_PCREL,      R_MSP430_2X_PCREL},
+  {BFD_RELOC_MSP430_RL_PCREL,      R_MSP430_RL_PCREL},
+  {BFD_RELOC_8,                    R_MSP430_8},
+  {BFD_RELOC_MSP430_SYM_DIFF,      R_MSP430_SYM_DIFF}
+};
+
+static const struct msp430_reloc_map msp430x_reloc_map[] =
+{
+  {BFD_RELOC_NONE,                    R_MSP430_NONE},
+  {BFD_RELOC_32,                      R_MSP430_ABS32},
+  {BFD_RELOC_16,                      R_MSP430_ABS16},
+  {BFD_RELOC_8,                       R_MSP430_ABS8},
+  {BFD_RELOC_MSP430_ABS8,             R_MSP430_ABS8},
+  {BFD_RELOC_MSP430X_PCR20_EXT_SRC,   R_MSP430X_PCR20_EXT_SRC},
+  {BFD_RELOC_MSP430X_PCR20_EXT_DST,   R_MSP430X_PCR20_EXT_DST},
+  {BFD_RELOC_MSP430X_PCR20_EXT_ODST,  R_MSP430X_PCR20_EXT_ODST},
+  {BFD_RELOC_MSP430X_ABS20_EXT_SRC,   R_MSP430X_ABS20_EXT_SRC},
+  {BFD_RELOC_MSP430X_ABS20_EXT_DST,   R_MSP430X_ABS20_EXT_DST},
+  {BFD_RELOC_MSP430X_ABS20_EXT_ODST,  R_MSP430X_ABS20_EXT_ODST},
+  {BFD_RELOC_MSP430X_ABS20_ADR_SRC,   R_MSP430X_ABS20_ADR_SRC},
+  {BFD_RELOC_MSP430X_ABS20_ADR_DST,   R_MSP430X_ABS20_ADR_DST},
+  {BFD_RELOC_MSP430X_PCR16,           R_MSP430X_PCR16},
+  {BFD_RELOC_MSP430X_PCR20_CALL,      R_MSP430X_PCR20_CALL},
+  {BFD_RELOC_MSP430X_ABS16,           R_MSP430X_ABS16},
+  {BFD_RELOC_MSP430_ABS_HI16,         R_MSP430_ABS_HI16},
+  {BFD_RELOC_MSP430_PREL31,           R_MSP430_PREL31},
+  {BFD_RELOC_MSP430_10_PCREL,         R_MSP430X_10_PCREL},
+  {BFD_RELOC_MSP430_2X_PCREL,         R_MSP430X_2X_PCREL},
+  {BFD_RELOC_MSP430_RL_PCREL,         R_MSP430X_PCR16},
+  {BFD_RELOC_MSP430_SYM_DIFF,         R_MSP430X_SYM_DIFF}
+};
+
+static inline bfd_boolean
+uses_msp430x_relocs (bfd * abfd)
+{
+  extern const bfd_target bfd_elf32_msp430_ti_vec;
+
+  return bfd_get_mach (abfd) == bfd_mach_msp430x
+    || abfd->xvec == & bfd_elf32_msp430_ti_vec;
+}
 
 static reloc_howto_type *
 bfd_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
@@ -194,9 +561,18 @@
 {
   unsigned int i;
 
-  for (i = 0; i < ARRAY_SIZE (msp430_reloc_map); i++)
-    if (msp430_reloc_map[i].bfd_reloc_val == code)
-      return &elf_msp430_howto_table[msp430_reloc_map[i].elf_reloc_val];
+  if (uses_msp430x_relocs (abfd))
+    {
+      for (i = ARRAY_SIZE (msp430x_reloc_map); i--;)
+	if (msp430x_reloc_map[i].bfd_reloc_val == code)
+	  return elf_msp430x_howto_table + msp430x_reloc_map[i].elf_reloc_val;
+    }
+  else
+    {
+      for (i = 0; i < ARRAY_SIZE (msp430_reloc_map); i++)
+	if (msp430_reloc_map[i].bfd_reloc_val == code)
+	  return &elf_msp430_howto_table[msp430_reloc_map[i].elf_reloc_val];
+    }
 
   return NULL;
 }
@@ -207,13 +583,23 @@
 {
   unsigned int i;
 
-  for (i = 0;
-       i < (sizeof (elf_msp430_howto_table)
-	    / sizeof (elf_msp430_howto_table[0]));
-       i++)
-    if (elf_msp430_howto_table[i].name != NULL
-	&& strcasecmp (elf_msp430_howto_table[i].name, r_name) == 0)
-      return &elf_msp430_howto_table[i];
+  if (uses_msp430x_relocs (abfd))
+    {
+      for (i = ARRAY_SIZE (elf_msp430x_howto_table); i--;)
+	if (elf_msp430x_howto_table[i].name != NULL
+	    && strcasecmp (elf_msp430x_howto_table[i].name, r_name) == 0)
+	  return elf_msp430x_howto_table + i;
+    }
+  else
+    {
+      for (i = 0;
+	   i < (sizeof (elf_msp430_howto_table)
+		/ sizeof (elf_msp430_howto_table[0]));
+	   i++)
+	if (elf_msp430_howto_table[i].name != NULL
+	    && strcasecmp (elf_msp430_howto_table[i].name, r_name) == 0)
+	  return &elf_msp430_howto_table[i];
+    }
 
   return NULL;
 }
@@ -228,6 +614,14 @@
   unsigned int r_type;
 
   r_type = ELF32_R_TYPE (dst->r_info);
+
+  if (uses_msp430x_relocs (abfd))
+    {
+      BFD_ASSERT (r_type < (unsigned int) R_MSP430x_max);
+      cache_ptr->howto = elf_msp430x_howto_table + r_type;
+      return;
+    }
+
   BFD_ASSERT (r_type < (unsigned int) R_MSP430_max);
   cache_ptr->howto = &elf_msp430_howto_table[r_type];
 }
@@ -280,16 +674,413 @@
    routines, but a few relocs, we have to do them ourselves.  */
 
 static bfd_reloc_status_type
-msp430_final_link_relocate (reloc_howto_type * howto, bfd * input_bfd,
-			    asection * input_section, bfd_byte * contents,
-			    Elf_Internal_Rela * rel, bfd_vma relocation)
+msp430_final_link_relocate (reloc_howto_type *     howto,
+			    bfd *                  input_bfd,
+			    asection *             input_section,
+			    bfd_byte *             contents,
+			    Elf_Internal_Rela *    rel,
+			    bfd_vma                relocation,
+			    struct bfd_link_info * info)
 {
+  static asection *  sym_diff_section;
+  static bfd_vma     sym_diff_value;
+
+  struct bfd_elf_section_data * esd = elf_section_data (input_section);
   bfd_reloc_status_type r = bfd_reloc_ok;
   bfd_vma x;
   bfd_signed_vma srel;
+  bfd_boolean is_rel_reloc = FALSE;
 
-  switch (howto->type)
+  if (uses_msp430x_relocs (input_bfd))
     {
+      /* See if we have a REL type relocation.  */
+      is_rel_reloc = (esd->rel.hdr != NULL);
+      /* Sanity check - only one type of relocation per section.
+	 FIXME: Theoretically it is possible to have both types,
+	 but if that happens how can we distinguish between the two ?  */
+      BFD_ASSERT (! is_rel_reloc || ! esd->rela.hdr);
+      /* If we are using a REL relocation then the addend should be empty.  */
+      BFD_ASSERT (! is_rel_reloc || rel->r_addend == 0);
+    }
+
+  if (sym_diff_section != NULL)
+    {
+      BFD_ASSERT (sym_diff_section == input_section);
+ 
+     if (uses_msp430x_relocs (input_bfd))
+       switch (howto->type)
+	 {
+	 case R_MSP430_ABS32:
+	  /* If we are computing a 32-bit value for the location lists
+	     and the result is 0 then we add one to the value.  A zero
+	     value can result because of linker relaxation deleteing
+	     prologue instructions and using a value of 1 (for the begin
+	     and end offsets in the location list entry) results in a
+	     nul entry which does not prevent the following entries from
+	     being parsed.  */
+	   if (relocation == sym_diff_value
+	       && strcmp (input_section->name, ".debug_loc") == 0)
+	     ++ relocation;
+	   /* Fall through.  */
+	 case R_MSP430_ABS16:
+	 case R_MSP430X_ABS16:
+	 case R_MSP430_ABS8:
+	   BFD_ASSERT (! is_rel_reloc);
+	   relocation -= sym_diff_value;
+	  break;
+
+	 default:
+	   return bfd_reloc_dangerous;
+	 }
+     else
+       switch (howto->type)
+	 {
+	 case R_MSP430_32:
+	 case R_MSP430_16:
+	 case R_MSP430_16_BYTE:
+	 case R_MSP430_8:
+	   relocation -= sym_diff_value;
+	  break;
+
+	 default:
+	   return bfd_reloc_dangerous;
+	 }
+       
+      sym_diff_section = NULL;
+    }
+
+  if (uses_msp430x_relocs (input_bfd))
+    switch (howto->type)
+      {
+      case R_MSP430X_SYM_DIFF:
+	/* Cache the input section and value.
+	   The offset is unreliable, since relaxation may
+	   have reduced the following reloc's offset.  */
+	BFD_ASSERT (! is_rel_reloc);
+	sym_diff_section = input_section;
+	sym_diff_value = relocation;
+	return bfd_reloc_ok;
+
+      case R_MSP430_ABS16:
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  srel += bfd_get_16 (input_bfd, contents);
+	else
+	  srel += rel->r_addend;
+	bfd_put_16 (input_bfd, srel & 0xffff, contents);
+	break;
+
+      case R_MSP430X_10_PCREL:
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  srel += bfd_get_16 (input_bfd, contents) & 0x3ff;
+	else
+	  srel += rel->r_addend;
+	srel -= rel->r_offset;
+	srel -= 2;		/* Branch instructions add 2 to the PC...  */
+	srel -= (input_section->output_section->vma +
+		 input_section->output_offset);
+	if (srel & 1)
+	  return bfd_reloc_outofrange;
+
+	/* MSP430 addresses commands as words.  */
+	srel >>= 1;
+
+	/* Check for an overflow.  */
+	if (srel < -512 || srel > 511)
+	  {
+	    if (info->disable_target_specific_optimizations < 0)
+	      {
+		static bfd_boolean warned = FALSE;
+		if (! warned)
+		  {
+		    info->callbacks->warning
+		      (info,
+		       _("Try enabling relaxation to avoid relocation truncations"),
+		       NULL, input_bfd, input_section, relocation);
+		    warned = TRUE;
+		  }
+	      }
+	    return bfd_reloc_overflow;
+	  }
+
+	x = bfd_get_16 (input_bfd, contents);
+	x = (x & 0xfc00) | (srel & 0x3ff);
+	bfd_put_16 (input_bfd, x, contents);
+	break;
+
+      case R_MSP430X_PCR20_EXT_ODST:
+	/* [0,4]+[48,16] = ---F ---- FFFF */
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  {
+	    bfd_vma addend;
+	    addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
+	    addend |= bfd_get_16 (input_bfd, contents+4);
+	    srel += addend;
+	    
+	  }
+	else
+	  srel += rel->r_addend;
+	srel -= rel->r_offset;
+	srel -= (input_section->output_section->vma +
+		 input_section->output_offset);
+	bfd_put_16 (input_bfd, (srel & 0xffff), contents + 6);
+	x = bfd_get_16 (input_bfd, contents);
+	x = (x & 0xfff0) | ((srel >> 16) & 0xf);
+	bfd_put_16 (input_bfd, x, contents);
+	break;
+
+      case R_MSP430X_ABS20_EXT_SRC:
+	/* [7,4]+[32,16] = -78- FFFF */
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  {
+	    bfd_vma addend;
+	    addend = (bfd_get_16 (input_bfd, contents) & 0x0780) << 9;
+	    addend |= bfd_get_16 (input_bfd, contents+2);
+	    srel += addend;
+	  }
+	else
+	  srel += rel->r_addend;
+	bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
+	srel >>= 16;
+	x = bfd_get_16 (input_bfd, contents);
+	x = (x & 0xf87f) | ((srel << 7) & 0x0780);
+	bfd_put_16 (input_bfd, x, contents);
+	break;
+
+      case R_MSP430_16_PCREL:
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  srel += bfd_get_16 (input_bfd, contents);
+	else
+	  srel += rel->r_addend;
+	srel -= rel->r_offset;
+	/* Only branch instructions add 2 to the PC...  */
+	srel -= (input_section->output_section->vma +
+		 input_section->output_offset);
+	if (srel & 1)
+	  return bfd_reloc_outofrange;
+	bfd_put_16 (input_bfd, srel & 0xffff, contents);
+	break;
+
+      case R_MSP430X_PCR20_EXT_DST:
+	/* [0,4]+[32,16] = ---F FFFF */
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  {
+	    bfd_vma addend;
+	    addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
+	    addend |= bfd_get_16 (input_bfd, contents+2);
+	    srel += addend;
+	  }
+	else
+	  srel += rel->r_addend;
+	srel -= rel->r_offset;
+	srel -= (input_section->output_section->vma +
+		 input_section->output_offset);
+	bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
+	srel >>= 16;
+	x = bfd_get_16 (input_bfd, contents);
+	x = (x & 0xfff0) | (srel & 0xf);
+	bfd_put_16 (input_bfd, x, contents);
+	break;
+
+      case R_MSP430X_PCR20_EXT_SRC:
+	/* [7,4]+32,16] = -78- FFFF */
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  {
+	    bfd_vma addend;
+	    addend = ((bfd_get_16 (input_bfd, contents) & 0x0780) << 9);
+	    addend |= bfd_get_16 (input_bfd, contents+2);
+	    srel += addend;;
+	  }
+	else
+	  srel += rel->r_addend;
+	srel -= rel->r_offset;
+	/* Only branch instructions add 2 to the PC...  */
+	srel -= (input_section->output_section->vma +
+		 input_section->output_offset);
+	bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
+	srel >>= 16;
+	x = bfd_get_16 (input_bfd, contents);
+	x = (x & 0xf87f) | ((srel << 7) & 0x0780);
+	bfd_put_16 (input_bfd, x, contents);
+	break;
+
+      case R_MSP430_ABS8:
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  srel += bfd_get_8 (input_bfd, contents);
+	else
+	  srel += rel->r_addend;
+	bfd_put_8 (input_bfd, srel & 0xff, contents);
+	break;
+
+      case R_MSP430X_ABS20_EXT_DST:
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  srel += bfd_get_16 (input_bfd, contents) & 0xf;
+	else
+	  srel += rel->r_addend;
+	bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
+	srel >>= 16;
+	x = bfd_get_16 (input_bfd, contents);
+	x = (x & 0xfff0) | (srel & 0xf);
+	bfd_put_16 (input_bfd, x, contents);
+	break;
+
+      case R_MSP430X_ABS20_EXT_ODST:
+	/* [0,4]+[48,16] = ---F ---- FFFF */
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  {
+	    bfd_vma addend;
+	    addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
+	    addend |= bfd_get_16 (input_bfd, contents+4);
+	    srel += addend;
+	  }
+	else
+	  srel += rel->r_addend;
+	bfd_put_16 (input_bfd, (srel & 0xffff), contents + 6);
+	srel >>= 16;
+	x = bfd_get_16 (input_bfd, contents);
+	x = (x & 0xfff0) | (srel & 0xf);
+	bfd_put_16 (input_bfd, x, contents);
+	break;
+
+      case R_MSP430X_ABS20_ADR_SRC:
+	/* [8,4]+[32,16] = -F-- FFFF */
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  {
+	    bfd_vma addend;
+
+	    addend = ((bfd_get_16 (input_bfd, contents) & 0xf00) << 8);
+	    addend |= bfd_get_16 (input_bfd, contents+2);
+	    srel += addend;
+	  }
+	else
+	  srel += rel->r_addend;
+	bfd_put_16 (input_bfd, (srel & 0xffff), contents + 2);
+	srel >>= 16;
+	x = bfd_get_16 (input_bfd, contents);
+	x = (x & 0xf0ff) | ((srel << 8) & 0x0f00);
+	bfd_put_16 (input_bfd, x, contents);
+	break;
+
+      case R_MSP430X_ABS20_ADR_DST:
+	/* [0,4]+[32,16] = ---F FFFF */
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  {
+	    bfd_vma addend;
+	    addend = ((bfd_get_16 (input_bfd, contents) & 0xf) << 16);
+	    addend |= bfd_get_16 (input_bfd, contents+2);
+	    srel += addend;
+	  }
+	else
+	  srel += rel->r_addend;
+	bfd_put_16 (input_bfd, (srel & 0xffff), contents + 2);
+	srel >>= 16;
+	x = bfd_get_16 (input_bfd, contents);
+	x = (x & 0xfff0) | (srel & 0xf);
+	bfd_put_16 (input_bfd, x, contents);
+	break;
+
+      case R_MSP430X_ABS16:
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  srel += bfd_get_16 (input_bfd, contents);
+	else
+	  srel += rel->r_addend;
+	x = srel;
+	if (x > 0xffff)
+	  return bfd_reloc_overflow;	
+	bfd_put_16 (input_bfd, srel & 0xffff, contents);
+	break;
+
+      case R_MSP430_ABS_HI16:
+	/* The EABI specifies that this must be a RELA reloc.  */
+	BFD_ASSERT (! is_rel_reloc);
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	srel += rel->r_addend;
+	bfd_put_16 (input_bfd, (srel >> 16) & 0xffff, contents);
+	break;
+      
+      case R_MSP430X_PCR20_CALL:
+	/* [0,4]+[32,16] = ---F FFFF*/
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  {
+	    bfd_vma addend;
+	    addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
+	    addend |= bfd_get_16 (input_bfd, contents+2);
+	    srel += addend;
+	  }
+	else
+	  srel += rel->r_addend;
+	srel -= rel->r_offset;
+	srel -= (input_section->output_section->vma +
+		 input_section->output_offset);
+	bfd_put_16 (input_bfd, srel & 0xffff, contents + 2);
+	srel >>= 16;
+	x = bfd_get_16 (input_bfd, contents);
+	x = (x & 0xfff0) | (srel & 0xf);
+	bfd_put_16 (input_bfd, x, contents);
+	break;
+	
+      case R_MSP430X_PCR16:
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  srel += bfd_get_16 (input_bfd, contents);
+	else
+	  srel += rel->r_addend;
+	srel -= rel->r_offset;
+	srel -= (input_section->output_section->vma +
+		 input_section->output_offset);
+	bfd_put_16 (input_bfd, srel & 0xffff, contents);
+	break;
+      
+      case R_MSP430_PREL31:
+	contents += rel->r_offset;
+	srel = (bfd_signed_vma) relocation;
+	if (is_rel_reloc)
+	  srel += (bfd_get_32 (input_bfd, contents) & 0x7fffffff);
+	else
+	  srel += rel->r_addend;
+	srel += rel->r_addend;
+	x = bfd_get_32 (input_bfd, contents);
+	x = (x & 0x80000000) | ((srel >> 31) & 0x7fffffff);
+	bfd_put_32 (input_bfd, x, contents);
+	break;
+	
+      default:
+	r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+				      contents, rel->r_offset,
+				      relocation, rel->r_addend);
+      }
+  else
+    switch (howto->type)
+      {
     case R_MSP430_10_PCREL:
       contents += rel->r_offset;
       srel = (bfd_signed_vma) relocation;
@@ -307,8 +1098,22 @@
 
       /* Check for an overflow.  */
       if (srel < -512 || srel > 511)
-	return bfd_reloc_overflow;
-
+	{
+	  if (info->disable_target_specific_optimizations < 0)
+	    {
+	      static bfd_boolean warned = FALSE;
+	      if (! warned)
+		{
+		  info->callbacks->warning
+		    (info,
+		     _("Try enabling relaxation to avoid relocation truncations"),
+		     NULL, input_bfd, input_section, relocation);
+		  warned = TRUE;
+		}
+	    }
+	  return bfd_reloc_overflow;
+	}
+      
       x = bfd_get_16 (input_bfd, contents);
       x = (x & 0xfc00) | (srel & 0x3ff);
       bfd_put_16 (input_bfd, x, contents);
@@ -389,11 +1194,27 @@
       bfd_put_16 (input_bfd, srel & 0xffff, contents);
       break;
 
-    default:
-      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
-				    contents, rel->r_offset,
-				    relocation, rel->r_addend);
-    }
+    case R_MSP430_8:
+      contents += rel->r_offset;
+      srel = (bfd_signed_vma) relocation;
+      srel += rel->r_addend;
+
+      bfd_put_8 (input_bfd, srel & 0xff, contents);
+      break;
+	 
+    case R_MSP430_SYM_DIFF:
+      /* Cache the input section and value.
+	 The offset is unreliable, since relaxation may
+	 have reduced the following reloc's offset.  */
+      sym_diff_section = input_section;
+      sym_diff_value = relocation;
+      return bfd_reloc_ok;
+
+      default:
+	r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+				      contents, rel->r_offset,
+				      relocation, rel->r_addend);
+      }
 
   return r;
 }
@@ -433,7 +1254,12 @@
 
       r_type = ELF32_R_TYPE (rel->r_info);
       r_symndx = ELF32_R_SYM (rel->r_info);
-      howto = elf_msp430_howto_table + r_type;
+
+      if (uses_msp430x_relocs (input_bfd))
+	howto = elf_msp430x_howto_table + r_type;
+      else
+	howto = elf_msp430_howto_table + r_type;
+
       h = NULL;
       sym = NULL;
       sec = NULL;
@@ -446,7 +1272,7 @@
 
 	  name = bfd_elf_string_from_elf_section
 	      (input_bfd, symtab_hdr->sh_link, sym->st_name);
-	  name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
+	  name = (name == NULL || * name == 0) ? bfd_section_name (input_bfd, sec) : name;
 	}
       else
 	{
@@ -456,6 +1282,7 @@
 				   r_symndx, symtab_hdr, sym_hashes,
 				   h, sec, relocation,
 				   unresolved_reloc, warned);
+	  name = h->root.root.string;
 	}
 
       if (sec != NULL && discarded_section (sec))
@@ -466,7 +1293,7 @@
 	continue;
 
       r = msp430_final_link_relocate (howto, input_bfd, input_section,
-				      contents, rel, relocation);
+				      contents, rel, relocation, info);
 
       if (r != bfd_reloc_ok)
 	{
@@ -476,7 +1303,7 @@
 	    {
 	    case bfd_reloc_overflow:
 	      r = info->callbacks->reloc_overflow
-		  (info, (h ? &h->root : NULL), name, howto->name,
+		(info, (h ? &h->root : NULL), name, howto->name,
 		   (bfd_vma) 0, input_bfd, input_section,
 		   rel->r_offset);
 	      break;
@@ -487,7 +1314,7 @@
 	      break;
 
 	    case bfd_reloc_outofrange:
-	      msg = _("internal error: out of range error");
+	      msg = _("internal error: branch/jump to an odd address detected");
 	      break;
 
 	    case bfd_reloc_notsupported:
@@ -529,61 +1356,29 @@
   switch (bfd_get_mach (abfd))
     {
     default:
-    case bfd_mach_msp110:
-      val = E_MSP430_MACH_MSP430x11x1;
-      break;
-
-    case bfd_mach_msp11:
-      val = E_MSP430_MACH_MSP430x11;
-      break;
-
-    case bfd_mach_msp12:
-      val = E_MSP430_MACH_MSP430x12;
-      break;
-
-    case bfd_mach_msp13:
-      val = E_MSP430_MACH_MSP430x13;
-      break;
-
-    case bfd_mach_msp14:
-      val = E_MSP430_MACH_MSP430x14;
-      break;
-
-    case bfd_mach_msp15:
-      val = E_MSP430_MACH_MSP430x15;
-      break;
-
-    case bfd_mach_msp16:
-      val = E_MSP430_MACH_MSP430x16;
-      break;
-
-    case bfd_mach_msp31:
-      val = E_MSP430_MACH_MSP430x31;
-      break;
-
-    case bfd_mach_msp32:
-      val = E_MSP430_MACH_MSP430x32;
-      break;
-
-    case bfd_mach_msp33:
-      val = E_MSP430_MACH_MSP430x33;
-      break;
-
-    case bfd_mach_msp41:
-      val = E_MSP430_MACH_MSP430x41;
-      break;
-
-    case bfd_mach_msp42:
-      val = E_MSP430_MACH_MSP430x42;
-      break;
-
-    case bfd_mach_msp43:
-      val = E_MSP430_MACH_MSP430x43;
-      break;
-
-    case bfd_mach_msp44:
-      val = E_MSP430_MACH_MSP430x44;
-      break;
+    case bfd_mach_msp110: val = E_MSP430_MACH_MSP430x11x1; break;
+    case bfd_mach_msp11: val = E_MSP430_MACH_MSP430x11; break;
+    case bfd_mach_msp12: val = E_MSP430_MACH_MSP430x12; break;
+    case bfd_mach_msp13: val = E_MSP430_MACH_MSP430x13; break;
+    case bfd_mach_msp14: val = E_MSP430_MACH_MSP430x14; break;
+    case bfd_mach_msp15: val = E_MSP430_MACH_MSP430x15; break;
+    case bfd_mach_msp16: val = E_MSP430_MACH_MSP430x16; break;
+    case bfd_mach_msp31: val = E_MSP430_MACH_MSP430x31; break;
+    case bfd_mach_msp32: val = E_MSP430_MACH_MSP430x32; break;
+    case bfd_mach_msp33: val = E_MSP430_MACH_MSP430x33; break;
+    case bfd_mach_msp41: val = E_MSP430_MACH_MSP430x41; break;
+    case bfd_mach_msp42: val = E_MSP430_MACH_MSP430x42; break;
+    case bfd_mach_msp43: val = E_MSP430_MACH_MSP430x43; break;
+    case bfd_mach_msp44: val = E_MSP430_MACH_MSP430x44; break;
+    case bfd_mach_msp20: val = E_MSP430_MACH_MSP430x20; break;
+    case bfd_mach_msp22: val = E_MSP430_MACH_MSP430x22; break;
+    case bfd_mach_msp23: val = E_MSP430_MACH_MSP430x23; break;
+    case bfd_mach_msp24: val = E_MSP430_MACH_MSP430x24; break;
+    case bfd_mach_msp26: val = E_MSP430_MACH_MSP430x26; break;
+    case bfd_mach_msp46: val = E_MSP430_MACH_MSP430x46; break;
+    case bfd_mach_msp47: val = E_MSP430_MACH_MSP430x47; break;
+    case bfd_mach_msp54: val = E_MSP430_MACH_MSP430x54; break;
+    case bfd_mach_msp430x: val = E_MSP430_MACH_MSP430X; break;
     }
 
   elf_elfheader (abfd)->e_machine = EM_MSP430;
@@ -606,64 +1401,32 @@
       switch (e_mach)
 	{
 	default:
-	case E_MSP430_MACH_MSP430x11:
-	  e_set = bfd_mach_msp11;
-	  break;
-
-	case E_MSP430_MACH_MSP430x11x1:
-	  e_set = bfd_mach_msp110;
-	  break;
-
-	case E_MSP430_MACH_MSP430x12:
-	  e_set = bfd_mach_msp12;
-	  break;
-
-	case E_MSP430_MACH_MSP430x13:
-	  e_set = bfd_mach_msp13;
-	  break;
-
-	case E_MSP430_MACH_MSP430x14:
-	  e_set = bfd_mach_msp14;
-	  break;
-
-	case E_MSP430_MACH_MSP430x15:
-	  e_set = bfd_mach_msp15;
-	  break;
-
-	case E_MSP430_MACH_MSP430x16:
-	  e_set = bfd_mach_msp16;
-	  break;
-
-	case E_MSP430_MACH_MSP430x31:
-	  e_set = bfd_mach_msp31;
-	  break;
-
-	case E_MSP430_MACH_MSP430x32:
-	  e_set = bfd_mach_msp32;
-	  break;
-
-	case E_MSP430_MACH_MSP430x33:
-	  e_set = bfd_mach_msp33;
-	  break;
-
-	case E_MSP430_MACH_MSP430x41:
-	  e_set = bfd_mach_msp41;
-	  break;
-
-	case E_MSP430_MACH_MSP430x42:
-	  e_set = bfd_mach_msp42;
-	  break;
-
-	case E_MSP430_MACH_MSP430x43:
-	  e_set = bfd_mach_msp43;
-	  break;
-
-	case E_MSP430_MACH_MSP430x44:
-	  e_set = bfd_mach_msp44;
-	  break;
+	case E_MSP430_MACH_MSP430x11: e_set = bfd_mach_msp11; break;
+	case E_MSP430_MACH_MSP430x11x1: e_set = bfd_mach_msp110; break;
+	case E_MSP430_MACH_MSP430x12: e_set = bfd_mach_msp12; break;
+	case E_MSP430_MACH_MSP430x13: e_set = bfd_mach_msp13; break;
+	case E_MSP430_MACH_MSP430x14: e_set = bfd_mach_msp14; break;
+	case E_MSP430_MACH_MSP430x15: e_set = bfd_mach_msp15; break;
+	case E_MSP430_MACH_MSP430x16: e_set = bfd_mach_msp16; break;
+	case E_MSP430_MACH_MSP430x31: e_set = bfd_mach_msp31; break;
+	case E_MSP430_MACH_MSP430x32: e_set = bfd_mach_msp32; break;
+	case E_MSP430_MACH_MSP430x33: e_set = bfd_mach_msp33; break;
+	case E_MSP430_MACH_MSP430x41: e_set = bfd_mach_msp41; break;
+	case E_MSP430_MACH_MSP430x42: e_set = bfd_mach_msp42; break;
+	case E_MSP430_MACH_MSP430x43: e_set = bfd_mach_msp43; break;
+	case E_MSP430_MACH_MSP430x44: e_set = bfd_mach_msp44; break;
+	case E_MSP430_MACH_MSP430x20: e_set = bfd_mach_msp20; break;
+	case E_MSP430_MACH_MSP430x22: e_set = bfd_mach_msp22; break;
+	case E_MSP430_MACH_MSP430x23: e_set = bfd_mach_msp23; break;
+	case E_MSP430_MACH_MSP430x24: e_set = bfd_mach_msp24; break;
+	case E_MSP430_MACH_MSP430x26: e_set = bfd_mach_msp26; break;
+	case E_MSP430_MACH_MSP430x46: e_set = bfd_mach_msp46; break;
+	case E_MSP430_MACH_MSP430x47: e_set = bfd_mach_msp47; break;
+	case E_MSP430_MACH_MSP430x54: e_set = bfd_mach_msp54; break;
+	case E_MSP430_MACH_MSP430X: e_set = bfd_mach_msp430x; break;
 	}
     }
-
+  
   return bfd_default_set_arch_mach (abfd, bfd_arch_msp430, e_set);
 }
 
@@ -674,6 +1437,8 @@
     - Sibling calls. This will affect only 'jump label' polymorph. Without
       relaxing this enlarges code by 2 bytes. Sibcalls implemented but
       do not work in gcc's port by the reason I do not know.
+    - To convert out of range conditional jump instructions (found inside
+      a function) into inverted jumps over an unconditional branch instruction.
    Anyway, if a relaxation required, user should pass -relax option to the
    linker.
 
@@ -797,11 +1562,13 @@
   return FALSE;
 }
 
-/* Adjust all local symbols defined as '.section + 0xXXXX' (.section has sec_shndx)
-    referenced from current and other sections.  */
+/* Adjust all local symbols defined as '.section + 0xXXXX' (.section has
+   sec_shndx) referenced from current and other sections.  */
+
 static bfd_boolean
-msp430_elf_relax_adjust_locals(bfd * abfd, asection * sec, bfd_vma addr,
-    int count, unsigned int sec_shndx, bfd_vma toaddr)
+msp430_elf_relax_adjust_locals (bfd * abfd, asection * sec, bfd_vma addr,
+				int count, unsigned int sec_shndx,
+				bfd_vma toaddr)
 {
   Elf_Internal_Shdr *symtab_hdr;
   Elf_Internal_Rela *irel;
@@ -809,21 +1576,24 @@
   Elf_Internal_Sym *isym;
 
   irel = elf_section_data (sec)->relocs;
+  if (irel == NULL)
+    return TRUE;
+
   irelend = irel + sec->reloc_count;
   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
-
-  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+  
+  for (;irel < irelend; irel++)
     {
       int sidx = ELF32_R_SYM(irel->r_info);
       Elf_Internal_Sym *lsym = isym + sidx;
-
+      
       /* Adjust symbols referenced by .sec+0xXX */
-      if (irel->r_addend > addr && irel->r_addend < toaddr
+      if (irel->r_addend > addr && irel->r_addend < toaddr 
 	  && lsym->st_shndx == sec_shndx)
 	irel->r_addend -= count;
     }
-
+  
   return TRUE;
 }
 
@@ -863,7 +1633,7 @@
   /* Adjust all the relocs.  */
   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
-  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+  for (; irel < irelend; irel++)
     {
       /* Get the new reloc address.  */
       if ((irel->r_offset > addr && irel->r_offset < toaddr))
@@ -871,8 +1641,8 @@
     }
 
   for (p = abfd->sections; p != NULL; p = p->next)
-    msp430_elf_relax_adjust_locals(abfd,p,addr,count,sec_shndx,toaddr);
-
+    msp430_elf_relax_adjust_locals (abfd,p,addr,count,sec_shndx,toaddr);
+  
   /* Adjust the local symbols defined in this section.  */
   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
@@ -901,6 +1671,82 @@
   return TRUE;
 }
 
+/* Insert two words into a section whilst relaxing.  */
+
+static bfd_byte *
+msp430_elf_relax_add_two_words (bfd * abfd, asection * sec, bfd_vma addr,
+				int word1, int word2)
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  unsigned int sec_shndx;
+  bfd_byte *contents;
+  Elf_Internal_Rela *irel;
+  Elf_Internal_Rela *irelend;
+  Elf_Internal_Sym *isym;
+  Elf_Internal_Sym *isymend;
+  struct elf_link_hash_entry **sym_hashes;
+  struct elf_link_hash_entry **end_hashes;
+  unsigned int symcount;
+  bfd_vma sec_end;
+  asection *p;
+
+  contents = elf_section_data (sec)->this_hdr.contents;
+  sec_end = sec->size;
+
+  /* Make space for the new words.  */
+  contents = bfd_realloc (contents, sec_end + 4);
+  memmove (contents + addr + 4, contents + addr, sec_end - addr);
+
+  /* Insert the new words.  */
+  bfd_put_16 (abfd, word1, contents + addr);
+  bfd_put_16 (abfd, word2, contents + addr + 2);
+
+  /* Update the section information.  */
+  sec->size += 4;
+  elf_section_data (sec)->this_hdr.contents = contents;  
+
+  /* Adjust all the relocs.  */
+  irel = elf_section_data (sec)->relocs;
+  irelend = irel + sec->reloc_count;
+
+  for (; irel < irelend; irel++)
+    if ((irel->r_offset >= addr && irel->r_offset < sec_end))
+      irel->r_offset += 4;
+
+  /* Adjust the local symbols defined in this section.  */
+  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+  for (p = abfd->sections; p != NULL; p = p->next)
+    msp430_elf_relax_adjust_locals (abfd, p, addr, -4,
+				    sec_shndx, sec_end);
+
+  /* Adjust the global symbols affected by the move.  */
+  symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
+  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+  for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+    if (isym->st_shndx == sec_shndx
+	&& isym->st_value >= addr && isym->st_value < sec_end)
+      isym->st_value += 4;
+
+  /* Now adjust the global symbols defined in this section.  */
+  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+	      - symtab_hdr->sh_info);
+  sym_hashes = elf_sym_hashes (abfd);
+  end_hashes = sym_hashes + symcount;
+  for (; sym_hashes < end_hashes; sym_hashes++)
+    {
+      struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+      if ((sym_hash->root.type == bfd_link_hash_defined
+	   || sym_hash->root.type == bfd_link_hash_defweak)
+	  && sym_hash->root.u.def.section == sec
+	  && sym_hash->root.u.def.value >= addr
+	  && sym_hash->root.u.def.value < sec_end)
+	sym_hash->root.u.def.value += 4;
+    }
+
+  return contents;
+}
+   
 static bfd_boolean
 msp430_elf_relax_section (bfd * abfd, asection * sec,
 			  struct bfd_link_info * link_info,
@@ -913,6 +1759,7 @@
   bfd_byte *          contents = NULL;
   Elf_Internal_Sym *  isymbuf = NULL;
 
+
   /* Assume nothing changes.  */
   *again = FALSE;
 
@@ -920,8 +1767,8 @@
      this section does not have relocs, or if this is not a
      code section.  */
   if (link_info->relocatable
-      || (sec->flags & SEC_RELOC) == 0
-      || sec->reloc_count == 0 || (sec->flags & SEC_CODE) == 0)
+    || (sec->flags & SEC_RELOC) == 0
+    || sec->reloc_count == 0 || (sec->flags & SEC_CODE) == 0)
     return TRUE;
 
   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
@@ -934,13 +1781,21 @@
 
   /* Walk through them looking for relaxing opportunities.  */
   irelend = internal_relocs + sec->reloc_count;
+
+  /* Do code size growing relocs first.  */
   for (irel = internal_relocs; irel < irelend; irel++)
     {
       bfd_vma symval;
 
       /* If this isn't something that can be relaxed, then ignore
          this reloc.  */
-      if (ELF32_R_TYPE (irel->r_info) != (int) R_MSP430_RL_PCREL)
+      if (uses_msp430x_relocs (abfd)
+          && ELF32_R_TYPE (irel->r_info) == (int) R_MSP430X_10_PCREL)
+	;
+      else if (! uses_msp430x_relocs (abfd)
+               && ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_10_PCREL)
+	;
+      else
 	continue;
 
       /* Get the section contents if we haven't done so already.  */
@@ -1014,109 +1869,288 @@
          that would be more work, but would require less memory when
          the linker is run.  */
 
-      /* Try to turn a 16bit pc-relative branch into a 10bit pc-relative
-         branch.  */
-      /* Paranoia? paranoia...  */
-      if (ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_RL_PCREL)
+      bfd_signed_vma value = symval;
+      int opcode;
+
+      /* Compute the value that will be relocated.  */
+      value += irel->r_addend;
+      /* Convert to PC relative.  */
+      value -= (sec->output_section->vma + sec->output_offset);
+      value -= irel->r_offset;
+      value -= 2;
+      /* Scale.  */
+      value >>= 1;
+
+      /* If it is in range then no modifications are needed.  */
+      if (value >= -512 && value <= 511)
+	continue;
+
+      /* Get the opcode.  */
+      opcode = bfd_get_16 (abfd, contents + irel->r_offset);
+	  
+      /* Compute the new opcode.  We are going to convert:
+	 J<cond> label
+	 into:
+	 J<inv-cond> 1f
+	 BR[A] #label
+	 1:                     */
+      switch (opcode & 0xfc00)
 	{
-	  bfd_vma value = symval;
-
-	  /* Deal with pc-relative gunk.  */
-	  value -= (sec->output_section->vma + sec->output_offset);
-	  value -= irel->r_offset;
-	  value += irel->r_addend;
-
-	  /* See if the value will fit in 10 bits, note the high value is
-	     1016 as the target will be two bytes closer if we are
-	     able to relax. */
-	  if ((long) value < 1016 && (long) value > -1016)
-	    {
-	      int code0 = 0, code1 = 0, code2 = 0;
-	      int i;
-	      struct rcodes_s *rx;
-
-	      /* Get the opcode.  */
-	      if (irel->r_offset >= 6)
-		code0 = bfd_get_16 (abfd, contents + irel->r_offset - 6);
-
-	      if (irel->r_offset >= 4)
-		code1 = bfd_get_16 (abfd, contents + irel->r_offset - 4);
-
-	      code2 = bfd_get_16 (abfd, contents + irel->r_offset - 2);
-
-	      if (code2 != 0x4010)
-		continue;
-
-	      /* Check r4 and r3.  */
-	      for (i = NUMB_RELAX_CODES - 1; i >= 0; i--)
-		{
-		  rx = &rcode[i];
-		  if (rx->cdx == 2 && rx->f0 == code0 && rx->f1 == code1)
-		    break;
-		  else if (rx->cdx == 1 && rx->f1 == code1)
-		    break;
-		  else if (rx->cdx == 0)	/* This is an unconditional jump.  */
-		    break;
-		}
-
-	      /* Check labels:
-		   .Label0:       ; we do not care about this label
-		      jeq    +6
-		   .Label1:       ; make sure there is no label here
-		      jl     +4
-		   .Label2:       ; make sure there is no label here
-		      br .Label_dst
-
-	         So, if there is .Label1 or .Label2 we cannot relax this code.
-	         This actually should not happen, cause for relaxable
-		 instructions we use RL_PCREL reloc instead of 16_PCREL.
-		 Will change this in the future. */
-
-	      if (rx->cdx > 0
-		  && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
-						  irel->r_offset - 2))
-		continue;
-	      if (rx->cdx > 1
-		  && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
-						  irel->r_offset - 4))
-		continue;
-
-	      /* Note that we've changed the relocs, section contents, etc.  */
-	      elf_section_data (sec)->relocs = internal_relocs;
-	      elf_section_data (sec)->this_hdr.contents = contents;
-	      symtab_hdr->contents = (unsigned char *) isymbuf;
-
-	      /* Fix the relocation's type.  */
-	      if (rx->labels == 3)	/* Handle special cases.  */
-		irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
-					   R_MSP430_2X_PCREL);
-	      else
-		irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
-					   R_MSP430_10_PCREL);
-
-	      /* Fix the opcode right way.  */
-	      bfd_put_16 (abfd, rx->t0, contents + irel->r_offset - rx->off);
-	      if (rx->t1)
-		bfd_put_16 (abfd, rx->t1,
-			    contents + irel->r_offset - rx->off + 2);
-
-	      /* Delete bytes. */
-	      if (!msp430_elf_relax_delete_bytes (abfd, sec,
-						  irel->r_offset - rx->off +
-						  rx->ncl, rx->bs))
-		goto error_return;
-
-	      /* Handle unconditional jumps.  */
-	      if (rx->cdx == 0)
-		irel->r_offset -= 2;
-
-	      /* That will change things, so, we should relax again.
-	         Note that this is not required, and it may be slow.  */
-	      *again = TRUE;
-	    }
+	case 0x3800: opcode = 0x3402; break; /* Jl  -> Jge +2 */  
+	case 0x3400: opcode = 0x3802; break; /* Jge -> Jl  +2 */
+	case 0x2c00: opcode = 0x2802; break; /* Jhs -> Jlo +2 */
+	case 0x2800: opcode = 0x2c02; break; /* Jlo -> Jhs +2 */
+	case 0x2400: opcode = 0x2002; break; /* Jeq -> Jne +2 */
+	case 0x2000: opcode = 0x2402; break; /* jne -> Jeq +2 */
+	case 0x3000: /* jn    */
+	  /* There is no direct inverse of the Jn insn.
+	     FIXME: we could do this as:
+	        Jn 1f
+	        br 2f
+	     1: br label
+	     2:                */
+	  continue;
+	default:
+	  /* Not a conditional branch instruction.  */
+	  /* fprintf (stderr, "unrecog: %x\n", opcode); */
+	  goto error_return;
 	}
+
+      /* Note that we've changed the relocs, section contents, etc.  */
+      elf_section_data (sec)->relocs = internal_relocs;
+      elf_section_data (sec)->this_hdr.contents = contents;
+      symtab_hdr->contents = (unsigned char *) isymbuf;
+
+      /* Install the new opcode.  */
+      bfd_put_16 (abfd, opcode, contents + irel->r_offset);
+
+      /* Insert the new branch instruction.  */
+      if (uses_msp430x_relocs (abfd))
+	{
+	  /* Insert an absolute branch (aka MOVA) instruction.  */	  
+	  contents = msp430_elf_relax_add_two_words
+	    (abfd, sec, irel->r_offset + 2, 0x0080, 0x0000);
+
+	  /* Update the relocation to point to the inserted branch
+	     instruction.  Note - we are changing a PC-relative reloc
+	     into an absolute reloc, but this is OK because we have
+	     arranged with the assembler to have the reloc's value be
+	     a (local) symbol, not a section+offset value.  */
+	  irel->r_offset += 2;
+	  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+				       R_MSP430X_ABS20_ADR_SRC);
+	}
+      else
+	{
+	  contents = msp430_elf_relax_add_two_words
+	    (abfd, sec, irel->r_offset + 2, 0x4030, 0x0000);
+
+	  /* See comment above about converting a 10-bit PC-rel
+	     relocation into a 16-bit absolute relocation.  */
+	  irel->r_offset += 4;
+	  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+				       R_MSP430_16);
+	}
+
+      /* Growing the section may mean that other
+	 conditional branches need to be fixed.  */
+      *again = TRUE;
     }
 
+  if (! uses_msp430x_relocs (abfd))
+    /* Now perform the relocations that shrink the code size.
+       We only do this for non msp430x as gas only generates the RL
+       reloc for the msp430.  */
+    for (irel = internal_relocs; irel < irelend; irel++)
+      {
+	bfd_vma symval;
+
+	/* Get the section contents if we haven't done so already.  */
+	if (contents == NULL)
+	  {
+	    /* Get cached copy if it exists.  */
+	    if (elf_section_data (sec)->this_hdr.contents != NULL)
+	      contents = elf_section_data (sec)->this_hdr.contents;
+	    else if (! bfd_malloc_and_get_section (abfd, sec, &contents))
+	      goto error_return;
+	  }
+
+	/* Read this BFD's local symbols if we haven't done so already.  */
+	if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+	  {
+	    isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+	    if (isymbuf == NULL)
+	      isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+					      symtab_hdr->sh_info, 0,
+					      NULL, NULL, NULL);
+	    if (isymbuf == NULL)
+	      goto error_return;
+	  }
+
+	/* Get the value of the symbol referred to by the reloc.  */
+	if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+	  {
+	    /* A local symbol.  */
+	    Elf_Internal_Sym *isym;
+	    asection *sym_sec;
+
+	    isym = isymbuf + ELF32_R_SYM (irel->r_info);
+	    if (isym->st_shndx == SHN_UNDEF)
+	      sym_sec = bfd_und_section_ptr;
+	    else if (isym->st_shndx == SHN_ABS)
+	      sym_sec = bfd_abs_section_ptr;
+	    else if (isym->st_shndx == SHN_COMMON)
+	      sym_sec = bfd_com_section_ptr;
+	    else
+	      sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+	    symval = (isym->st_value
+		      + sym_sec->output_section->vma + sym_sec->output_offset);
+	  }
+	else
+	  {
+	    unsigned long indx;
+	    struct elf_link_hash_entry *h;
+
+	    /* An external symbol.  */
+	    indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+	    h = elf_sym_hashes (abfd)[indx];
+	    BFD_ASSERT (h != NULL);
+
+	    if (h->root.type != bfd_link_hash_defined
+		&& h->root.type != bfd_link_hash_defweak)
+	      /* This appears to be a reference to an undefined
+		 symbol.  Just ignore it--it will be caught by the
+		 regular reloc processing.  */
+	      continue;
+
+	    symval = (h->root.u.def.value
+		      + h->root.u.def.section->output_section->vma
+		      + h->root.u.def.section->output_offset);
+	  }
+
+	/* For simplicity of coding, we are going to modify the section
+	   contents, the section relocs, and the BFD symbol table.  We
+	   must tell the rest of the code not to free up this
+	   information.  It would be possible to instead create a table
+	   of changes which have to be made, as is done in coff-mips.c;
+	   that would be more work, but would require less memory when
+	   the linker is run.  */
+
+	/* Try to turn a 16bit pc-relative branch into a 10bit pc-relative
+	   branch.  */
+	/* Paranoia? paranoia...  */      
+	if (ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_RL_PCREL)
+	  {
+	    bfd_vma value = symval;
+
+	    /* Deal with pc-relative gunk.  */
+	    value -= (sec->output_section->vma + sec->output_offset);
+	    value -= irel->r_offset;
+	    value += irel->r_addend;
+
+	    /* See if the value will fit in 10 bits, note the high value is
+	       1016 as the target will be two bytes closer if we are
+	       able to relax.  */
+	    if ((long) value < 1016 && (long) value > -1016)
+	      {
+		int code0 = 0, code1 = 0, code2 = 0;
+		int i;
+		struct rcodes_s *rx;
+
+		/* Get the opcode.  */
+		if (irel->r_offset >= 6)
+		  code0 = bfd_get_16 (abfd, contents + irel->r_offset - 6);
+
+		if (irel->r_offset >= 4)
+		  code1 = bfd_get_16 (abfd, contents + irel->r_offset - 4);
+
+		code2 = bfd_get_16 (abfd, contents + irel->r_offset - 2);
+
+		if (code2 != 0x4010)
+		  continue;
+
+		/* Check r4 and r3.  */
+		for (i = NUMB_RELAX_CODES - 1; i >= 0; i--)
+		  {
+		    rx = &rcode[i];
+		    if (rx->cdx == 2 && rx->f0 == code0 && rx->f1 == code1)
+		      break;
+		    else if (rx->cdx == 1 && rx->f1 == code1)
+		      break;
+		    else if (rx->cdx == 0)	/* This is an unconditional jump.  */
+		      break;
+		  }
+
+		/* Check labels:
+		   .Label0:       ; we do not care about this label
+		   jeq    +6
+		   .Label1:       ; make sure there is no label here
+		   jl     +4
+		   .Label2:       ; make sure there is no label here
+		   br .Label_dst
+
+		   So, if there is .Label1 or .Label2 we cannot relax this code.
+		   This actually should not happen, cause for relaxable
+		   instructions we use RL_PCREL reloc instead of 16_PCREL.
+		   Will change this in the future. */
+
+		if (rx->cdx > 0
+		    && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
+						    irel->r_offset - 2))
+		  continue;
+		if (rx->cdx > 1
+		    && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
+						    irel->r_offset - 4))
+		  continue;
+
+		/* Note that we've changed the relocs, section contents, etc.  */
+		elf_section_data (sec)->relocs = internal_relocs;
+		elf_section_data (sec)->this_hdr.contents = contents;
+		symtab_hdr->contents = (unsigned char *) isymbuf;
+
+		/* Fix the relocation's type.  */
+		if (uses_msp430x_relocs (abfd))
+		  {
+		    if (rx->labels == 3)	/* Handle special cases.  */
+		      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+						   R_MSP430X_2X_PCREL);
+		    else
+		      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+						   R_MSP430X_10_PCREL);
+		  }
+		else
+		  {
+		    if (rx->labels == 3)	/* Handle special cases.  */
+		      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+						   R_MSP430_2X_PCREL);
+		    else
+		      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+						   R_MSP430_10_PCREL);
+		  }
+
+		/* Fix the opcode right way.  */
+		bfd_put_16 (abfd, rx->t0, contents + irel->r_offset - rx->off);
+		if (rx->t1)
+		  bfd_put_16 (abfd, rx->t1,
+			      contents + irel->r_offset - rx->off + 2);
+
+		/* Delete bytes. */
+		if (!msp430_elf_relax_delete_bytes (abfd, sec,
+						    irel->r_offset - rx->off +
+						    rx->ncl, rx->bs))
+		  goto error_return;
+
+		/* Handle unconditional jumps.  */
+		if (rx->cdx == 0)
+		  irel->r_offset -= 2;
+
+		/* That will change things, so, we should relax again.
+		   Note that this is not required, and it may be slow.  */
+		*again = TRUE;
+	      }
+	  }
+      }
+
   if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
     {
       if (!link_info->keep_memory)
@@ -1159,11 +2193,259 @@
   return FALSE;
 }
 
+/* Handle an MSP430 specific section when reading an object file.
+   This is called when bfd_section_from_shdr finds a section with
+   an unknown type.  */
+
+static bfd_boolean
+elf32_msp430_section_from_shdr (bfd *abfd,
+				Elf_Internal_Shdr * hdr,
+				const char *name,
+				int shindex)
+{
+  switch (hdr->sh_type)
+    {
+    case SHT_MSP430_SEC_FLAGS:
+    case SHT_MSP430_SYM_ALIASES:
+    case SHT_MSP430_ATTRIBUTES:
+      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+    default:
+      return FALSE;
+    }
+}
+
+static bfd_boolean
+elf32_msp430_obj_attrs_handle_unknown (bfd *abfd, int tag)
+{
+  _bfd_error_handler
+    (_("Warning: %B: Unknown MSPABI object attribute %d"),
+     abfd, tag);
+  return TRUE;
+}
+
+/* Determine whether an object attribute tag takes an integer, a
+   string or both.  */
+
+static int
+elf32_msp430_obj_attrs_arg_type (int tag)
+{
+  if (tag == Tag_compatibility)
+    return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL;
+
+  if (tag < 32)
+    return ATTR_TYPE_FLAG_INT_VAL;
+
+  return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL;
+}
+
+static inline const char *
+isa_type (int isa)
+{
+  switch (isa)
+    {
+    case 1: return "MSP430";
+    case 2: return "MSP430X";
+    default: return "unknown";
+    }
+}
+
+static inline const char *
+code_model (int model)
+{
+  switch (model)
+    {
+    case 1: return "small";
+    case 2: return "large";
+    default: return "unknown";
+    }
+}
+
+static inline const char *
+data_model (int model)
+{
+  switch (model)
+    {
+    case 1: return "small";
+    case 2: return "large";
+    case 3: return "restricted large";
+    default: return "unknown";
+    }
+}
+
+/* Merge MSPABI object attributes from IBFD into OBFD.
+   Raise an error if there are conflicting attributes.  */
+
+static bfd_boolean
+elf32_msp430_merge_mspabi_attributes (bfd *ibfd, bfd *obfd)
+{
+  obj_attribute *in_attr;
+  obj_attribute *out_attr;
+  bfd_boolean result = TRUE;
+  static bfd * first_input_bfd = NULL;
+
+  /* Skip linker created files.  */
+  if (ibfd->flags & BFD_LINKER_CREATED)
+    return TRUE;
+
+  /* If this is the first real object just copy the attributes.  */
+  if (!elf_known_obj_attributes_proc (obfd)[0].i)
+    {
+      _bfd_elf_copy_obj_attributes (ibfd, obfd);
+
+      out_attr = elf_known_obj_attributes_proc (obfd);
+
+      /* Use the Tag_null value to indicate that
+	 the attributes have been initialized.  */
+      out_attr[0].i = 1;
+
+      first_input_bfd = ibfd;
+      return TRUE;
+    }
+
+  in_attr = elf_known_obj_attributes_proc (ibfd);
+  out_attr = elf_known_obj_attributes_proc (obfd);
+
+  /* The ISAs must be the same.  */
+  if (in_attr[OFBA_MSPABI_Tag_ISA].i != out_attr[OFBA_MSPABI_Tag_ISA].i)
+    {
+      _bfd_error_handler
+	(_("error: %B uses %s instructions but %B uses %s"),
+	 ibfd, first_input_bfd,
+	 isa_type (in_attr[OFBA_MSPABI_Tag_ISA].i),
+	 isa_type (out_attr[OFBA_MSPABI_Tag_ISA].i));
+      result = FALSE;
+    }
+
+  /* The code models must be the same.  */
+  if (in_attr[OFBA_MSPABI_Tag_Code_Model].i !=
+      out_attr[OFBA_MSPABI_Tag_Code_Model].i)
+    {
+      _bfd_error_handler
+	(_("error: %B uses the %s code model whereas %B uses the %s code model"),
+	 ibfd, first_input_bfd,
+	 code_model (in_attr[OFBA_MSPABI_Tag_Code_Model].i),
+	 code_model (out_attr[OFBA_MSPABI_Tag_Code_Model].i));
+      result = FALSE;
+    }
+
+  /* The large code model is only supported by the MSP430X.  */
+  if (in_attr[OFBA_MSPABI_Tag_Code_Model].i == 2
+      && out_attr[OFBA_MSPABI_Tag_ISA].i != 2)
+    {
+      _bfd_error_handler
+	(_("error: %B uses the large code model but %B uses MSP430 instructions"),
+	 ibfd, first_input_bfd);
+      result = FALSE;
+    }
+
+  /* The data models must be the same.  */
+  if (in_attr[OFBA_MSPABI_Tag_Data_Model].i !=
+      out_attr[OFBA_MSPABI_Tag_Data_Model].i)
+    {
+      _bfd_error_handler
+	(_("error: %B uses the %s data model whereas %B uses the %s data model"),
+	 ibfd, first_input_bfd,
+	 data_model (in_attr[OFBA_MSPABI_Tag_Data_Model].i),
+	 data_model (out_attr[OFBA_MSPABI_Tag_Data_Model].i));
+      result = FALSE;
+    }
+
+  /* The small code model requires the use of the small data model.  */
+  if (in_attr[OFBA_MSPABI_Tag_Code_Model].i == 1
+      && out_attr[OFBA_MSPABI_Tag_Data_Model].i != 1)
+    {
+      _bfd_error_handler
+	(_("error: %B uses the small code model but %B uses the %s data model"),
+	 ibfd, first_input_bfd,
+	 data_model (out_attr[OFBA_MSPABI_Tag_Data_Model].i));
+      result = FALSE;
+    }
+
+  /* The large data models are only supported by the MSP430X.  */
+  if (in_attr[OFBA_MSPABI_Tag_Data_Model].i > 1
+      && out_attr[OFBA_MSPABI_Tag_ISA].i != 2)
+    {
+      _bfd_error_handler
+	(_("error: %B uses the %s data model but %B only uses MSP430 instructions"),
+	 ibfd, first_input_bfd,
+	 data_model (in_attr[OFBA_MSPABI_Tag_Data_Model].i));
+      result = FALSE;
+    }
+  
+  return result;
+}
+
+/* Merge backend specific data from an object file to the output
+   object file when linking.  */
+
+static bfd_boolean
+elf32_msp430_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
+{
+  /* Make sure that the machine number reflects the most
+     advanced version of the MSP architecture required.  */
+#define max(a,b) ((a) > (b) ? (a) : (b))
+  if (bfd_get_mach (ibfd) != bfd_get_mach (obfd))
+    bfd_default_set_arch_mach (obfd, bfd_get_arch (obfd),
+			       max (bfd_get_mach (ibfd), bfd_get_mach (obfd)));
+#undef max
+
+  return elf32_msp430_merge_mspabi_attributes (ibfd, obfd);
+}
+
+/* Copy backend specific data from one object module to another.  */
+
+static bfd_boolean
+elf32_msp430_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+  /* Copy object attributes.  */
+  _bfd_elf_copy_obj_attributes (ibfd, obfd);
+
+  return TRUE;
+}
+
+static bfd_boolean
+msp430_elf_is_target_special_symbol (bfd *abfd, asymbol *sym)
+{
+  return _bfd_elf_is_local_label_name (abfd, sym->name);
+}
+
+/* This is gross.  The MSP430 EABI says that (sec 11.5):
+
+     "An implementation may choose to use Rel or Rela
+      type relocations for other relocations."
+
+   But it also says that:
+   
+     "Certain relocations are identified as Rela only. [snip]
+      Where Rela is specified, an implementation must honor
+      this requirement."
+
+  There is one relocation marked as requiring RELA - R_MSP430_ABS_HI16 - but
+  to keep things simple we choose to use RELA relocations throughout.  The
+  problem is that the TI compiler generates REL relocations, so we have to
+  be able to accept those as well.  */
+
+#define elf_backend_may_use_rel_p  1
+#define elf_backend_may_use_rela_p 1
+#define elf_backend_default_use_rela_p 1
+
+#undef  elf_backend_obj_attrs_vendor
+#define elf_backend_obj_attrs_vendor		"mspabi"
+#undef  elf_backend_obj_attrs_section
+#define elf_backend_obj_attrs_section		".MSP430.attributes"
+#undef  elf_backend_obj_attrs_section_type
+#define elf_backend_obj_attrs_section_type	SHT_MSP430_ATTRIBUTES
+#define elf_backend_section_from_shdr  		elf32_msp430_section_from_shdr
+#define elf_backend_obj_attrs_handle_unknown 	elf32_msp430_obj_attrs_handle_unknown
+#undef  elf_backend_obj_attrs_arg_type
+#define elf_backend_obj_attrs_arg_type		elf32_msp430_obj_attrs_arg_type
+#define bfd_elf32_bfd_copy_private_bfd_data	elf32_msp430_copy_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data	elf32_msp430_merge_private_bfd_data
 
 #define ELF_ARCH		bfd_arch_msp430
 #define ELF_MACHINE_CODE	EM_MSP430
 #define ELF_MACHINE_ALT1	EM_MSP430_OLD
-#define ELF_MAXPAGESIZE		1
+#define ELF_MAXPAGESIZE		4
 #define	ELF_OSABI		ELFOSABI_STANDALONE
 
 #define TARGET_LITTLE_SYM       bfd_elf32_msp430_vec
@@ -1178,5 +2460,30 @@
 #define elf_backend_object_p		     elf32_msp430_object_p
 #define elf_backend_post_process_headers     _bfd_elf_set_osabi
 #define bfd_elf32_bfd_relax_section	     msp430_elf_relax_section
+#define bfd_elf32_bfd_is_target_special_symbol	msp430_elf_is_target_special_symbol
+
+#undef  elf32_bed
+#define elf32_bed		elf32_msp430_bed
+
+#include "elf32-target.h"
+
+/* The TI compiler sets the OSABI field to ELFOSABI_NONE.  */
+#undef  TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM       bfd_elf32_msp430_ti_vec
+
+#undef  elf32_bed
+#define elf32_bed		elf32_msp430_ti_bed
+
+#undef	ELF_OSABI		
+#define	ELF_OSABI		ELFOSABI_NONE
+
+static const struct bfd_elf_special_section msp430_ti_elf_special_sections[] =
+{
+  /* prefix, prefix_length,        suffix_len, type,               attributes.  */
+  { STRING_COMMA_LEN (".TI.symbol.alias"),  0, SHT_MSP430_SYM_ALIASES, 0 },
+  { STRING_COMMA_LEN (".TI.section.flags"), 0, SHT_MSP430_SEC_FLAGS,   0 },
+  { STRING_COMMA_LEN ("_TI_build_attrib"),  0, SHT_MSP430_ATTRIBUTES,  0 },
+  { NULL, 0,                                0, 0,                      0 }
+};
 
 #include "elf32-target.h"
diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c
index f13ec1b..77b8e0d 100644
--- a/bfd/elf32-vax.c
+++ b/bfd/elf32-vax.c
@@ -914,9 +914,8 @@
    understand.  */
 
 static bfd_boolean
-elf_vax_adjust_dynamic_symbol (info, h)
-     struct bfd_link_info *info;
-     struct elf_link_hash_entry *h;
+elf_vax_adjust_dynamic_symbol (struct bfd_link_info *info,
+			       struct elf_link_hash_entry *h)
 {
   bfd *dynobj;
   asection *s;
@@ -1263,10 +1262,10 @@
 
 /* This function is called via elf_link_hash_traverse.  It looks for entries
    that have GOT or PLT (.GOT) references.  If creating a static object or a
-   shared object with -Bsymbolic, it resets the reference count back to 0
-   and sets the offset to -1 so normal PC32 relocation will be done.  If
-   creating a shared object or executable, space in the .got and .rela.got
-   will be reserved for the symbol.  */
+   shared object with -Bsymbolic, or the symbol has been forced local, then
+   it resets the reference count back to -1 so normal PC32 relocation will
+   be done.  Otherwise space in the .got and .rela.got will be reserved for
+   the symbol.  */
 
 static bfd_boolean
 elf_vax_instantiate_got_entries (struct elf_link_hash_entry *h, void * infoptr)
@@ -1291,10 +1290,8 @@
       || (info->shared && info->symbolic)
       || h->forced_local)
     {
-      h->got.refcount = 0;
-      h->got.offset = (bfd_vma) -1;
-      h->plt.refcount = 0;
-      h->plt.offset = (bfd_vma) -1;
+      h->got.refcount = -1;
+      h->plt.refcount = -1;
     }
   else if (h->got.refcount > 0)
     {
diff --git a/bfd/elf64-aarch64.c b/bfd/elf64-aarch64.c
index e3cae95..fe9d5b1 100644
--- a/bfd/elf64-aarch64.c
+++ b/bfd/elf64-aarch64.c
@@ -1730,26 +1730,6 @@
 				  AARCH64_ELF_DATA);
 }
 
-/* The AArch64 linker needs to keep track of the number of relocs that it
-   decides to copy in check_relocs for each symbol.  This is so that
-   it can discard PC relative relocs if it doesn't need them when
-   linking with -Bsymbolic.  We store the information in a field
-   extending the regular ELF linker hash table.  */
-
-/* This structure keeps track of the number of relocs we have copied
-   for a given symbol.  */
-struct elf64_aarch64_relocs_copied
-{
-  /* Next section.  */
-  struct elf64_aarch64_relocs_copied *next;
-  /* A section in dynobj.  */
-  asection *section;
-  /* Number of relocs copied in this section.  */
-  bfd_size_type count;
-  /* Number of PC-relative relocs copied in this section.  */
-  bfd_size_type pc_count;
-};
-
 #define elf64_aarch64_hash_entry(ent) \
   ((struct elf64_aarch64_link_hash_entry *)(ent))
 
@@ -1769,9 +1749,6 @@
   /* Track dynamic relocs copied for this symbol.  */
   struct elf_dyn_relocs *dyn_relocs;
 
-  /* Number of PC relative relocs copied for this symbol.  */
-  struct elf64_aarch64_relocs_copied *relocs_copied;
-
   /* Since PLT entries have variable size, we need to record the
      index into .got.plt instead of recomputing it from the PLT
      offset.  */
@@ -1950,7 +1927,6 @@
   if (ret != NULL)
     {
       ret->dyn_relocs = NULL;
-      ret->relocs_copied = NULL;
       ret->got_type = GOT_UNKNOWN;
       ret->plt_got_offset = (bfd_vma) - 1;
       ret->stub_cache = NULL;
@@ -2041,37 +2017,6 @@
       eind->dyn_relocs = NULL;
     }
 
-  if (eind->relocs_copied != NULL)
-    {
-      if (edir->relocs_copied != NULL)
-	{
-	  struct elf64_aarch64_relocs_copied **pp;
-	  struct elf64_aarch64_relocs_copied *p;
-
-	  /* Add reloc counts against the indirect sym to the direct sym
-	     list.  Merge any entries against the same section.  */
-	  for (pp = &eind->relocs_copied; (p = *pp) != NULL;)
-	    {
-	      struct elf64_aarch64_relocs_copied *q;
-
-	      for (q = edir->relocs_copied; q != NULL; q = q->next)
-		if (q->section == p->section)
-		  {
-		    q->pc_count += p->pc_count;
-		    q->count += p->count;
-		    *pp = p->next;
-		    break;
-		  }
-	      if (q == NULL)
-		pp = &p->next;
-	    }
-	  *pp = edir->relocs_copied;
-	}
-
-      edir->relocs_copied = eind->relocs_copied;
-      eind->relocs_copied = NULL;
-    }
-
   if (ind->root.type == bfd_link_hash_indirect)
     {
       /* Copy over PLT info.  */
@@ -7181,6 +7126,7 @@
 #define elf_backend_may_use_rela_p     1
 #define elf_backend_default_use_rela_p 1
 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
+#define elf_backend_default_execstack  0
 
 #undef  elf_backend_obj_attrs_section
 #define elf_backend_obj_attrs_section		".ARM.attributes"
diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c
index c24a4ee..e692099 100644
--- a/bfd/elf64-mips.c
+++ b/bfd/elf64-mips.c
@@ -2622,6 +2622,23 @@
 	 0,			/* src_mask */
 	 0x0000ffff,		/* dst_mask */
 	 TRUE);			/* pcrel_offset */
+
+/* 32 bit pc-relative.  Used for compact EH tables.  */
+static reloc_howto_type elf_mips_gnu_pcrel32 =
+  HOWTO (R_MIPS_PC32,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 "R_MIPS_PC32",		/* name */
+	 TRUE,			/* partial_inplace */
+	 0xffffffff,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 TRUE);			/* pcrel_offset */
+
 
 /* Originally a VxWorks extension, but now used for other systems too.  */
 static reloc_howto_type elf_mips_copy_howto =
@@ -2632,7 +2649,7 @@
 	 FALSE,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_bitfield, /* complain_on_overflow */
-	 bfd_elf_generic_reloc,	/* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_COPY",		/* name */
 	 FALSE,			/* partial_inplace */
 	 0x0,         		/* src_mask */
@@ -2648,7 +2665,7 @@
 	 FALSE,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_bitfield, /* complain_on_overflow */
-	 bfd_elf_generic_reloc,	/* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_JUMP_SLOT",	/* name */
 	 FALSE,			/* partial_inplace */
 	 0x0,         		/* src_mask */
@@ -3257,6 +3274,8 @@
       return &elf_mips_gnu_vtinherit_howto;
     case BFD_RELOC_VTABLE_ENTRY:
       return &elf_mips_gnu_vtentry_howto;
+    case BFD_RELOC_32_PCREL:
+      return &elf_mips_gnu_pcrel32;
     case BFD_RELOC_MIPS_COPY:
       return &elf_mips_copy_howto;
     case BFD_RELOC_MIPS_JUMP_SLOT:
@@ -3304,6 +3323,8 @@
     return &elf_mips_gnu_rel16_s2;
   if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
     return &elf_mips_gnu_rela16_s2;
+  if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
+    return &elf_mips_gnu_pcrel32;
   if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
     return &elf_mips_copy_howto;
   if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
@@ -3328,6 +3349,8 @@
 	return &elf_mips_gnu_rela16_s2;
       else
 	return &elf_mips_gnu_rel16_s2;
+    case R_MIPS_PC32:
+      return &elf_mips_gnu_pcrel32;
     case R_MIPS_COPY:
       return &elf_mips_copy_howto;
     case R_MIPS_JUMP_SLOT:
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index cb33821..d4415e4 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -5665,11 +5665,30 @@
 
 		  sym_hashes = elf_sym_hashes (opd_bfd);
 		  rh = sym_hashes[symndx - symtab_hdr->sh_info];
-		  rh = elf_follow_link (rh);
-		  BFD_ASSERT (rh->root.type == bfd_link_hash_defined
-			      || rh->root.type == bfd_link_hash_defweak);
-		  val = rh->root.u.def.value;
-		  sec = rh->root.u.def.section;
+		  if (rh != NULL)
+		    {
+		      rh = elf_follow_link (rh);
+		      BFD_ASSERT (rh->root.type == bfd_link_hash_defined
+				  || rh->root.type == bfd_link_hash_defweak);
+		      val = rh->root.u.def.value;
+		      sec = rh->root.u.def.section;
+		    }
+		  else
+		    {
+		      /* Handle the odd case where we can be called
+			 during bfd_elf_link_add_symbols before the
+			 symbol hashes have been fully populated.  */
+		      Elf_Internal_Sym *sym;
+
+		      sym = bfd_elf_get_elf_syms (opd_bfd, symtab_hdr, 1,
+						  symndx, NULL, NULL, NULL);
+		      if (sym == NULL)
+			break;
+
+		      val = sym->st_value;
+		      sec = bfd_section_from_elf_index (opd_bfd, sym->st_shndx);
+		      free (sym);
+		    }
 		}
 	      val += look->r_addend;
 	      if (code_off != NULL)
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 9adc959..758231e 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -2260,6 +2260,7 @@
     return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
 					       &eh->dyn_relocs,
 					       plt_entry_size,
+					       plt_entry_size,
 					       GOT_ENTRY_SIZE);
   else if (htab->elf.dynamic_sections_created
 	   && h->plt.refcount > 0)
diff --git a/bfd/elflink.c b/bfd/elflink.c
index f5a36d2..692cb7a 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -573,7 +573,8 @@
   if (hidden)
     {
       bed = get_elf_backend_data (output_bfd);
-      h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
+      if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
+	h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
       (*bed->elf_backend_hide_symbol) (info, h, TRUE);
     }
 
@@ -3351,14 +3352,12 @@
   unsigned int old_size = 0;
   unsigned int old_count = 0;
   void *old_tab = NULL;
-  void *old_hash;
   void *old_ent;
   struct bfd_link_hash_entry *old_undefs = NULL;
   struct bfd_link_hash_entry *old_undefs_tail = NULL;
   long old_dynsymcount = 0;
   bfd_size_type old_dynstr_size = 0;
   size_t tabsize = 0;
-  size_t hashsize = 0;
 
   htab = elf_hash_table (info);
   bed = get_elf_backend_data (abfd);
@@ -3713,7 +3712,7 @@
       extsymoff = hdr->sh_info;
     }
 
-  sym_hash = NULL;
+  sym_hash = elf_sym_hashes (abfd);
   if (extsymcount != 0)
     {
       isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff,
@@ -3721,13 +3720,16 @@
       if (isymbuf == NULL)
 	goto error_return;
 
-      /* We store a pointer to the hash table entry for each external
-	 symbol.  */
-      amt = extsymcount * sizeof (struct elf_link_hash_entry *);
-      sym_hash = (struct elf_link_hash_entry **) bfd_alloc (abfd, amt);
       if (sym_hash == NULL)
-	goto error_free_sym;
-      elf_sym_hashes (abfd) = sym_hash;
+	{
+	  /* We store a pointer to the hash table entry for each
+	     external symbol.  */
+	  amt = extsymcount * sizeof (struct elf_link_hash_entry *);
+	  sym_hash = (struct elf_link_hash_entry **) bfd_zalloc (abfd, amt);
+	  if (sym_hash == NULL)
+	    goto error_free_sym;
+	  elf_sym_hashes (abfd) = sym_hash;
+	}
     }
 
   if (dynamic)
@@ -3777,8 +3779,7 @@
 	}
 
       tabsize = htab->root.table.size * sizeof (struct bfd_hash_entry *);
-      hashsize = extsymcount * sizeof (struct elf_link_hash_entry *);
-      old_tab = bfd_malloc (tabsize + entsize + hashsize);
+      old_tab = bfd_malloc (tabsize + entsize);
       if (old_tab == NULL)
 	goto error_free_vers;
 
@@ -3794,12 +3795,10 @@
 				       notice_as_needed, 0, NULL))
 	goto error_free_vers;
 
-      /* Clone the symbol table and sym hashes.  Remember some
-	 pointers into the symbol table, and dynamic symbol count.  */
-      old_hash = (char *) old_tab + tabsize;
-      old_ent = (char *) old_hash + hashsize;
+      /* Clone the symbol table.  Remember some pointers into the
+	 symbol table, and dynamic symbol count.  */
+      old_ent = (char *) old_tab + tabsize;
       memcpy (old_tab, htab->root.table.table, tabsize);
-      memcpy (old_hash, sym_hash, hashsize);
       old_undefs = htab->root.undefs;
       old_undefs_tail = htab->root.undefs_tail;
       old_table = htab->root.table.table;
@@ -3856,7 +3855,6 @@
       flags = BSF_NO_FLAGS;
       sec = NULL;
       value = isym->st_value;
-      *sym_hash = NULL;
       common = bed->common_definition (isym);
 
       bind = ELF_ST_BIND (isym->st_info);
@@ -4490,14 +4488,13 @@
       /* Restore the symbol table.  */
       if (bed->as_needed_cleanup)
 	(*bed->as_needed_cleanup) (abfd, info);
-      old_hash = (char *) old_tab + tabsize;
-      old_ent = (char *) old_hash + hashsize;
-      sym_hash = elf_sym_hashes (abfd);
+      old_ent = (char *) old_tab + tabsize;
+      memset (elf_sym_hashes (abfd), 0,
+	      extsymcount * sizeof (struct elf_link_hash_entry *));
       htab->root.table.table = old_table;
       htab->root.table.size = old_size;
       htab->root.table.count = old_count;
       memcpy (htab->root.table.table, old_tab, tabsize);
-      memcpy (sym_hash, old_hash, hashsize);
       htab->root.undefs = old_undefs;
       htab->root.undefs_tail = old_undefs_tail;
       _bfd_elf_strtab_restore_size (htab->dynstr, old_dynstr_size);
@@ -4678,7 +4675,7 @@
 	  struct elf_link_hash_entry *hlook;
 	  asection *slook;
 	  bfd_vma vlook;
-	  size_t i, j, idx;
+	  size_t i, j, idx = 0;
 
 	  hlook = weaks;
 	  weaks = hlook->u.weakdef;
diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c
index 18c3d40..131de33 100644
--- a/bfd/elfn32-mips.c
+++ b/bfd/elfn32-mips.c
@@ -2587,6 +2587,23 @@
 	 0,			/* src_mask */
 	 0x0000ffff,		/* dst_mask */
 	 TRUE);			/* pcrel_offset */
+
+/* 32 bit pc-relative.  Used for compact EH tables.  */
+static reloc_howto_type elf_mips_gnu_pcrel32 =
+  HOWTO (R_MIPS_PC32,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 "R_MIPS_PC32",		/* name */
+	 TRUE,			/* partial_inplace */
+	 0xffffffff,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 TRUE);			/* pcrel_offset */
+
 
 /* Originally a VxWorks extension, but now used for other systems too.  */
 static reloc_howto_type elf_mips_copy_howto =
@@ -2597,7 +2614,7 @@
 	 FALSE,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_bitfield, /* complain_on_overflow */
-	 bfd_elf_generic_reloc,	/* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_COPY",		/* name */
 	 FALSE,			/* partial_inplace */
 	 0x0,         		/* src_mask */
@@ -2613,7 +2630,7 @@
 	 FALSE,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_bitfield, /* complain_on_overflow */
-	 bfd_elf_generic_reloc,	/* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_JUMP_SLOT",	/* name */
 	 FALSE,			/* partial_inplace */
 	 0x0,         		/* src_mask */
@@ -3073,6 +3090,8 @@
       return &elf_mips_gnu_vtinherit_howto;
     case BFD_RELOC_VTABLE_ENTRY:
       return &elf_mips_gnu_vtentry_howto;
+    case BFD_RELOC_32_PCREL:
+      return &elf_mips_gnu_pcrel32;
     case BFD_RELOC_MIPS_COPY:
       return &elf_mips_copy_howto;
     case BFD_RELOC_MIPS_JUMP_SLOT:
@@ -3121,6 +3140,8 @@
     return &elf_mips_gnu_rel16_s2;
   if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
     return &elf_mips_gnu_rela16_s2;
+  if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
+    return &elf_mips_gnu_pcrel32;
   if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
     return &elf_mips_copy_howto;
   if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
@@ -3145,6 +3166,8 @@
 	return &elf_mips_gnu_rela16_s2;
       else
 	return &elf_mips_gnu_rel16_s2;
+    case R_MIPS_PC32:
+      return &elf_mips_gnu_pcrel32;
     case R_MIPS_COPY:
       return &elf_mips_copy_howto;
     case R_MIPS_JUMP_SLOT:
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index fa807713..a3b50f3 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -9354,7 +9354,7 @@
       const char *name;
       bfd_vma value = 0;
       reloc_howto_type *howto;
-      bfd_boolean cross_mode_jump_p;
+      bfd_boolean cross_mode_jump_p = FALSE;
       /* TRUE if the relocation is a RELA relocation, rather than a
          REL relocation.  */
       bfd_boolean rela_relocation_p = TRUE;
diff --git a/bfd/format.c b/bfd/format.c
index 2c602e5..b0fb483 100644
--- a/bfd/format.c
+++ b/bfd/format.c
@@ -406,6 +406,9 @@
 	}
     }
 
+  /* We have more than one equally good match.  If any of the best
+     matches is a target in config.bfd targ_defvec or targ_selvecs,
+     choose it.  */
   if (match_count > 1)
     {
       const bfd_target * const *assoc = bfd_associated_vector;
@@ -415,7 +418,8 @@
 	  int i = match_count;
 
 	  while (--i >= 0)
-	    if (matching_vector[i] == right_targ)
+	    if (matching_vector[i] == right_targ
+		&& right_targ->match_priority <= best_match)
 	      break;
 
 	  if (i >= 0)
@@ -426,6 +430,22 @@
 	}
     }
 
+  /* We still have more than one equally good match, and at least some
+     of the targets support match priority.  Choose the first of the
+     best matches.  */
+  if (match_count > 1 && best_count != match_count)
+    {
+      int i;
+
+      for (i = 0; i < match_count; i++)
+	{
+	  right_targ = matching_vector[i];
+	  if (right_targ->match_priority <= best_match)
+	    break;
+	}
+      match_count = 1;
+    }
+
   /* There is way too much undoing of half-known state here.  We
      really shouldn't iterate on live bfd's.  Note that saving the
      whole bfd and restoring it would be even worse; the first thing
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 6a4b572..1c4d36f 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2376,6 +2376,21 @@
   "BFD_RELOC_MSP430_16_BYTE",
   "BFD_RELOC_MSP430_2X_PCREL",
   "BFD_RELOC_MSP430_RL_PCREL",
+  "BFD_RELOC_MSP430_ABS8",
+  "BFD_RELOC_MSP430X_PCR20_EXT_SRC",
+  "BFD_RELOC_MSP430X_PCR20_EXT_DST",
+  "BFD_RELOC_MSP430X_PCR20_EXT_ODST",
+  "BFD_RELOC_MSP430X_ABS20_EXT_SRC",
+  "BFD_RELOC_MSP430X_ABS20_EXT_DST",
+  "BFD_RELOC_MSP430X_ABS20_EXT_ODST",
+  "BFD_RELOC_MSP430X_ABS20_ADR_SRC",
+  "BFD_RELOC_MSP430X_ABS20_ADR_DST",
+  "BFD_RELOC_MSP430X_PCR16",
+  "BFD_RELOC_MSP430X_PCR20_CALL",
+  "BFD_RELOC_MSP430X_ABS16",
+  "BFD_RELOC_MSP430_ABS_HI16",
+  "BFD_RELOC_MSP430_PREL31",
+  "BFD_RELOC_MSP430_SYM_DIFF",
   "BFD_RELOC_NIOS2_S16",
   "BFD_RELOC_NIOS2_U16",
   "BFD_RELOC_NIOS2_CALL26",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index e93b3b9..57df51b 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -5662,6 +5662,36 @@
   BFD_RELOC_MSP430_2X_PCREL
 ENUMX
   BFD_RELOC_MSP430_RL_PCREL
+ENUMX
+  BFD_RELOC_MSP430_ABS8
+ENUMX
+  BFD_RELOC_MSP430X_PCR20_EXT_SRC
+ENUMX
+  BFD_RELOC_MSP430X_PCR20_EXT_DST
+ENUMX
+  BFD_RELOC_MSP430X_PCR20_EXT_ODST
+ENUMX
+  BFD_RELOC_MSP430X_ABS20_EXT_SRC
+ENUMX
+  BFD_RELOC_MSP430X_ABS20_EXT_DST
+ENUMX
+  BFD_RELOC_MSP430X_ABS20_EXT_ODST
+ENUMX
+  BFD_RELOC_MSP430X_ABS20_ADR_SRC
+ENUMX
+  BFD_RELOC_MSP430X_ABS20_ADR_DST
+ENUMX
+  BFD_RELOC_MSP430X_PCR16
+ENUMX
+  BFD_RELOC_MSP430X_PCR20_CALL
+ENUMX
+  BFD_RELOC_MSP430X_ABS16
+ENUMX
+  BFD_RELOC_MSP430_ABS_HI16
+ENUMX
+  BFD_RELOC_MSP430_PREL31
+ENUMX
+  BFD_RELOC_MSP430_SYM_DIFF
 ENUMDOC
   msp430 specific relocation codes
 
diff --git a/bfd/srec.c b/bfd/srec.c
index 6226773..ded9e76 100644
--- a/bfd/srec.c
+++ b/bfd/srec.c
@@ -870,6 +870,7 @@
 			   file_ptr offset,
 			   bfd_size_type bytes_to_do)
 {
+  int opb = bfd_octets_per_byte (abfd);
   tdata_type *tdata = abfd->tdata.srec_data;
   srec_data_list_type *entry;
 
@@ -892,16 +893,16 @@
 	 regardless of the siez of the addresses.  */
       if (S3Forced)
 	tdata->type = 3;
-      else if ((section->lma + offset + bytes_to_do - 1) <= 0xffff)
+      else if ((section->lma + (offset + bytes_to_do) / opb - 1) <= 0xffff)
 	;  /* The default, S1, is OK.  */
-      else if ((section->lma + offset + bytes_to_do - 1) <= 0xffffff
+      else if ((section->lma + (offset + bytes_to_do) / opb - 1) <= 0xffffff
 	       && tdata->type <= 2)
 	tdata->type = 2;
       else
 	tdata->type = 3;
 
       entry->data = data;
-      entry->where = section->lma + offset;
+      entry->where = section->lma + offset / opb;
       entry->size = bytes_to_do;
 
       /* Sort the records by address.  Optimize for the common case of
diff --git a/bfd/targets.c b/bfd/targets.c
index c9fbbc2..c6794ee 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -1,7 +1,5 @@
 /* Generic target-file-type support for the BFD library.
-   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
-   Free Software Foundation, Inc.
+   Copyright 1990-2013 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -668,6 +666,7 @@
 extern const bfd_target bfd_elf32_mn10300_vec;
 extern const bfd_target bfd_elf32_mt_vec;
 extern const bfd_target bfd_elf32_msp430_vec;
+extern const bfd_target bfd_elf32_msp430_ti_vec;
 extern const bfd_target bfd_elf32_nbigmips_vec;
 extern const bfd_target bfd_elf32_nlittlemips_vec;
 extern const bfd_target bfd_elf32_ntradbigmips_vec;
@@ -1047,6 +1046,7 @@
 	&bfd_elf32_mn10300_vec,
 	&bfd_elf32_mt_vec,
 	&bfd_elf32_msp430_vec,
+	&bfd_elf32_msp430_ti_vec,
 #ifdef BFD64
 	&bfd_elf32_nbigmips_vec,
 	&bfd_elf32_nlittlemips_vec,
diff --git a/bfd/version.h b/bfd/version.h
index 291d2f2..5a98504 100644
--- a/bfd/version.h
+++ b/bfd/version.h
@@ -1,4 +1,4 @@
-#define BFD_VERSION_DATE 20130429
+#define BFD_VERSION_DATE 20130524
 #define BFD_VERSION @bfd_version@
 #define BFD_VERSION_STRING  @bfd_version_package@ @bfd_version_string@
 #define REPORT_BUGS_TO @report_bugs_to@
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 58f7657..fa6abb5 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,28 @@
+2013-05-15  Cary Coutant  <ccoutant@google.com>
+
+	* dwarf.c (SAFE_BYTE_GET64): Correct end-of-buffer check;
+	don't increment PTR.
+	(decode_location_expression): DW_OP_const2u should read 2 bytes.
+	(display_debug_lines_decoded): Adjust formatting.
+	* elfcomm.c (byte_get_little_endian): Add cases for 5-, 6-, and
+	7-byte reads.
+	(byte_get_big_endian): Likewise.
+	(byte_get_signed): Likewise.
+
+2013-05-09  Andrew Pinski  <apinski@cavium.com>
+
+	* doc/binutils.texi: Document -Mvirt disassembler option.
+
+2013-05-02  Nick Clifton  <nickc@redhat.com>
+
+	* readelf.c: Add support for MSP430X architecture.
+
+2013-05-02  Nick Clifton  <nickc@redhat.com>
+
+	* dwarf.c (display_debug_lines_raw): Do not treat .debug_line.dwo
+	sections as if they were fragmentary .debug_line sections.
+	(display_debug_lines_decoded): Likewise.
+
 2013-04-29  Nick Clifton  <nickc@redhat.com>
 
 	* dwarf.c (read_debug_line_header): New function.  Reads in a
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 0bb1d92..aaa0bdb 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -2113,6 +2113,9 @@
 instruction mnemonic.  I.e., print 'daddu' or 'or' instead of 'move',
 'sll' instead of 'nop', etc.
 
+@item virt
+Disassemble the virtualization ASE instructions.
+
 @item gpr-names=@var{ABI}
 Print GPR (general-purpose register) names as appropriate
 for the specified ABI.  By default, GPR names are selected according to
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index b11169b..862a060 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -337,13 +337,12 @@
 #define SAFE_BYTE_GET64(PTR, HIGH, LOW, END)		\
   do							\
     {							\
-      if (((PTR) + 8) < (END))				\
+      if (((PTR) + 8) <= (END))				\
 	{						\
 	  byte_get_64 ((PTR), (HIGH), (LOW));		\
 	}						\
       else						\
 	{						\
-	  PTR = END;					\
 	  * (LOW) = * (HIGH) = 0;			\
 	}						\
     }							\
@@ -883,7 +882,7 @@
 	  printf ("DW_OP_const1s: %ld", (long) svalue);
 	  break;
 	case DW_OP_const2u:
-	  SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+	  SAFE_BYTE_GET_AND_INC (uvalue, data, 2, end);
 	  printf ("DW_OP_const2u: %lu", (unsigned long) uvalue);
 	  break;
 	case DW_OP_const2s:
@@ -2659,7 +2658,10 @@
       unsigned char *end_of_sequence;
        int i;
 
-      if (const_strneq (section->name, ".debug_line."))
+      if (const_strneq (section->name, ".debug_line.")
+	  /* Note: the following does not apply to .debug_line.dwo sections.
+	     These are full debug_line sections.  */
+	  && strcmp (section->name, ".debug_line.dwo") != 0)
 	{
 	  /* Sections named .debug_line.<foo> are fragments of a .debug_line
 	     section containing just the Line Number Statements.  They are
@@ -2668,9 +2670,9 @@
 	     garbage collection decides to discard a .text.<foo> section it
 	     can then also discard the line number information in .debug_line.<foo>.
 
-	     Since the section is a fragmnent it does not have the details
+	     Since the section is a fragment it does not have the details
 	     needed to fill out a LineInfo structure, so instead we use the
-	     details from the last one we processed.  */
+	     details from the last full debug_line section that we processed.  */
 	  end_of_sequence = end;
 	  standard_opcodes = NULL;
 	  linfo = saved_linfo;
@@ -2994,18 +2996,12 @@
       unsigned char **directory_table = NULL;
       unsigned int n_directories = 0;
 
-      if (const_strneq (section->name, ".debug_line."))
+      if (const_strneq (section->name, ".debug_line.")
+	  /* Note: the following does not apply to .debug_line.dwo sections.
+	     These are full debug_line sections.  */
+	  && strcmp (section->name, ".debug_line.dwo") != 0)
         {
-	  /* Sections named .debug_line.<foo> are fragments of a .debug_line
-	     section containing just the Line Number Statements.  They are
-	     created by the assembler and intended to be used alongside gcc's
-	     -ffunction-sections command line option.  When the linker's
-	     garbage collection decides to discard a .text.<foo> section it
-	     can then also discard the line number information in .debug_line.<foo>.
-
-	     Since the section is a fragmnent it does not have the details
-	     needed to fill out a LineInfo structure, so instead we use the
-	     details from the last one we processed.  */
+	  /* See comment in display_debug_lines_raw().  */
 	  end_of_sequence = end;
 	  standard_opcodes = NULL;
 	  linfo = saved_linfo;
@@ -3187,7 +3183,8 @@
 			 break;
 		       case DW_LNE_set_address:
 			 SAFE_BYTE_GET_AND_INC (state_machine_regs.address,
-						op_code_data, ext_op_code_len - bytes_read - 1,
+						op_code_data,
+						ext_op_code_len - bytes_read - 1,
 						end);
 			 state_machine_regs.op_index = 0;
 			 break;
diff --git a/binutils/elfcomm.c b/binutils/elfcomm.c
index 1a1fae9..d5b4313 100644
--- a/binutils/elfcomm.c
+++ b/binutils/elfcomm.c
@@ -150,6 +150,57 @@
 	|    (((unsigned long) (field[2])) << 16)
 	|    (((unsigned long) (field[3])) << 24);
 
+    case 5:
+      if (sizeof (elf_vma) == 8)
+	return  ((elf_vma) (field[0]))
+	  |    (((elf_vma) (field[1])) << 8)
+	  |    (((elf_vma) (field[2])) << 16)
+	  |    (((elf_vma) (field[3])) << 24)
+	  |    (((elf_vma) (field[4])) << 32);
+      else if (sizeof (elf_vma) == 4)
+	/* We want to extract data from an 8 byte wide field and
+	   place it into a 4 byte wide field.  Since this is a little
+	   endian source we can just use the 4 byte extraction code.  */
+	return  ((unsigned long) (field[0]))
+	  |    (((unsigned long) (field[1])) << 8)
+	  |    (((unsigned long) (field[2])) << 16)
+	  |    (((unsigned long) (field[3])) << 24);
+
+    case 6:
+      if (sizeof (elf_vma) == 8)
+	return  ((elf_vma) (field[0]))
+	  |    (((elf_vma) (field[1])) << 8)
+	  |    (((elf_vma) (field[2])) << 16)
+	  |    (((elf_vma) (field[3])) << 24)
+	  |    (((elf_vma) (field[4])) << 32)
+	  |    (((elf_vma) (field[5])) << 40);
+      else if (sizeof (elf_vma) == 4)
+	/* We want to extract data from an 8 byte wide field and
+	   place it into a 4 byte wide field.  Since this is a little
+	   endian source we can just use the 4 byte extraction code.  */
+	return  ((unsigned long) (field[0]))
+	  |    (((unsigned long) (field[1])) << 8)
+	  |    (((unsigned long) (field[2])) << 16)
+	  |    (((unsigned long) (field[3])) << 24);
+
+    case 7:
+      if (sizeof (elf_vma) == 8)
+	return  ((elf_vma) (field[0]))
+	  |    (((elf_vma) (field[1])) << 8)
+	  |    (((elf_vma) (field[2])) << 16)
+	  |    (((elf_vma) (field[3])) << 24)
+	  |    (((elf_vma) (field[4])) << 32)
+	  |    (((elf_vma) (field[5])) << 40)
+	  |    (((elf_vma) (field[6])) << 48);
+      else if (sizeof (elf_vma) == 4)
+	/* We want to extract data from an 8 byte wide field and
+	   place it into a 4 byte wide field.  Since this is a little
+	   endian source we can just use the 4 byte extraction code.  */
+	return  ((unsigned long) (field[0]))
+	  |    (((unsigned long) (field[1])) << 8)
+	  |    (((unsigned long) (field[2])) << 16)
+	  |    (((unsigned long) (field[3])) << 24);
+
     case 8:
       if (sizeof (elf_vma) == 8)
 	return  ((elf_vma) (field[0]))
@@ -197,6 +248,63 @@
 	|   (((unsigned long) (field[1])) << 16)
 	|   (((unsigned long) (field[0])) << 24);
 
+    case 5:
+      if (sizeof (elf_vma) == 8)
+	return ((elf_vma) (field[4]))
+	  |   (((elf_vma) (field[3])) << 8)
+	  |   (((elf_vma) (field[2])) << 16)
+	  |   (((elf_vma) (field[1])) << 24)
+	  |   (((elf_vma) (field[0])) << 32);
+      else if (sizeof (elf_vma) == 4)
+	{
+	  /* Although we are extracting data from an 8 byte wide field,
+	     we are returning only 4 bytes of data.  */
+	  field += 1;
+	  return ((unsigned long) (field[3]))
+	    |   (((unsigned long) (field[2])) << 8)
+	    |   (((unsigned long) (field[1])) << 16)
+	    |   (((unsigned long) (field[0])) << 24);
+	}
+
+    case 6:
+      if (sizeof (elf_vma) == 8)
+	return ((elf_vma) (field[5]))
+	  |   (((elf_vma) (field[4])) << 8)
+	  |   (((elf_vma) (field[3])) << 16)
+	  |   (((elf_vma) (field[2])) << 24)
+	  |   (((elf_vma) (field[1])) << 32)
+	  |   (((elf_vma) (field[0])) << 40);
+      else if (sizeof (elf_vma) == 4)
+	{
+	  /* Although we are extracting data from an 8 byte wide field,
+	     we are returning only 4 bytes of data.  */
+	  field += 2;
+	  return ((unsigned long) (field[3]))
+	    |   (((unsigned long) (field[2])) << 8)
+	    |   (((unsigned long) (field[1])) << 16)
+	    |   (((unsigned long) (field[0])) << 24);
+	}
+
+    case 7:
+      if (sizeof (elf_vma) == 8)
+	return ((elf_vma) (field[6]))
+	  |   (((elf_vma) (field[5])) << 8)
+	  |   (((elf_vma) (field[4])) << 16)
+	  |   (((elf_vma) (field[3])) << 24)
+	  |   (((elf_vma) (field[2])) << 32)
+	  |   (((elf_vma) (field[1])) << 40)
+	  |   (((elf_vma) (field[0])) << 48);
+      else if (sizeof (elf_vma) == 4)
+	{
+	  /* Although we are extracting data from an 8 byte wide field,
+	     we are returning only 4 bytes of data.  */
+	  field += 3;
+	  return ((unsigned long) (field[3]))
+	    |   (((unsigned long) (field[2])) << 8)
+	    |   (((unsigned long) (field[1])) << 16)
+	    |   (((unsigned long) (field[0])) << 24);
+	}
+
     case 8:
       if (sizeof (elf_vma) == 8)
 	return ((elf_vma) (field[7]))
@@ -209,7 +317,7 @@
 	  |   (((elf_vma) (field[0])) << 56);
       else if (sizeof (elf_vma) == 4)
 	{
-	  /* Although we are extracing data from an 8 byte wide field,
+	  /* Although we are extracting data from an 8 byte wide field,
 	     we are returning only 4 bytes of data.  */
 	  field += 4;
 	  return ((unsigned long) (field[3]))
@@ -235,9 +343,18 @@
       return (x ^ 0x80) - 0x80;
     case 2:
       return (x ^ 0x8000) - 0x8000;
+    case 3:
+      return (x ^ 0x800000) - 0x800000;
     case 4:
       return (x ^ 0x80000000) - 0x80000000;
+    case 5:
+    case 6:
+    case 7:
     case 8:
+      /* Reads of 5-, 6-, and 7-byte numbers are the result of
+         trying to read past the end of a buffer, and will therefore
+         not have meaningful values, so we don't try to deal with
+         the sign in these cases.  */
       return x;
     default:
       abort ();
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 8298557..cd429ef 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -131,6 +131,7 @@
 #include "elf/moxie.h"
 #include "elf/mt.h"
 #include "elf/msp430.h"
+#include "elf/nios2.h"
 #include "elf/or32.h"
 #include "elf/pj.h"
 #include "elf/ppc.h"
@@ -153,8 +154,6 @@
 #include "elf/xstormy16.h"
 #include "elf/xtensa.h"
 
-#include "elf/nios2.h"
-
 #include "getopt.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
@@ -903,6 +902,17 @@
   return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
 }
 
+static inline bfd_boolean
+uses_msp430x_relocs (void)
+{
+  return
+    elf_header.e_machine == EM_MSP430 /* Paranoia.  */
+    /* GCC uses osabi == ELFOSBI_STANDALONE.  */
+    && (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
+	/* TI compiler uses ELFOSABI_NONE.  */
+	|| (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
+}
+
 /* Display the contents of the relocation data found at the specified
    offset.  */
 
@@ -1125,6 +1135,11 @@
 	  break;
 
 	case EM_MSP430:
+	  if (uses_msp430x_relocs ())
+	    {
+	      rtype = elf_msp430x_reloc_type (type);
+	      break;
+	    }
 	case EM_MSP430_OLD:
 	  rtype = elf_msp430_reloc_type (type);
 	  break;
@@ -2781,6 +2796,32 @@
 	  if ((e_flags & EF_C6000_REL))
 	    strcat (buf, ", relocatable module");
 	  break;
+
+	case EM_MSP430:
+	  strcat (buf, _(": architecture variant: "));
+	  switch (e_flags & EF_MSP430_MACH)
+	    {
+	    case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
+	    case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
+	    case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
+	    case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
+	    case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
+	    case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
+	    case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
+	    case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
+	    case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
+	    case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
+	    case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
+	    case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
+	    case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
+	    case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
+	    case E_MSP430_MACH_MSP430X  : strcat (buf, "MSP430X"); break;
+	    default:
+	      strcat (buf, _(": unknown")); break;
+	    }
+
+	  if (e_flags & ~ EF_MSP430_MACH)
+	    strcat (buf, _(": unknown extra flag bits also present"));
 	}
     }
 
@@ -3206,6 +3247,18 @@
 }
 
 static const char *
+get_msp430x_section_type_name (unsigned int sh_type)
+{
+  switch (sh_type)
+    {
+    case SHT_MSP430_SEC_FLAGS:   return "MSP430_SEC_FLAGS";
+    case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
+    case SHT_MSP430_ATTRIBUTES:  return "MSP430_ATTRIBUTES";
+    default: return NULL;
+    }
+}
+
+static const char *
 get_section_type_name (unsigned int sh_type)
 {
   static char buff[32];
@@ -3271,6 +3324,9 @@
 	    case EM_TI_C6000:
 	      result = get_tic6x_section_type_name (sh_type);
 	      break;
+	    case EM_MSP430:
+	      result = get_msp430x_section_type_name (sh_type);
+	      break;
 	    default:
 	      result = NULL;
 	      break;
@@ -8995,8 +9051,13 @@
     default:
       if (type >= STT_LOPROC && type <= STT_HIPROC)
 	{
-	  if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
-	    return "THUMB_FUNC";
+	  if (elf_header.e_machine == EM_ARM)
+	    {
+	      if (type == STT_ARM_TFUNC)
+		return "THUMB_FUNC";
+	      if (type == STT_ARM_16BIT)
+		return "THUMB_LABEL";
+	    }
 
 	  if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
 	    return "REGISTER";
@@ -9962,6 +10023,60 @@
 
   switch (elf_header.e_machine)
     {
+    case EM_MSP430:
+    case EM_MSP430_OLD:
+      {
+	static Elf_Internal_Sym * saved_sym = NULL;
+
+	switch (reloc_type)
+	  {
+	  case 10: /* R_MSP430_SYM_DIFF */
+	    if (uses_msp430x_relocs ())
+	      break;
+	  case 21: /* R_MSP430X_SYM_DIFF */
+	    saved_sym = symtab + get_reloc_symindex (reloc->r_info);
+	    return TRUE;
+
+	  case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
+	  case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
+	    goto handle_sym_diff;
+	    
+	  case 5: /* R_MSP430_16_BYTE */
+	  case 9: /* R_MSP430_8 */
+	    if (uses_msp430x_relocs ())
+	      break;
+	    goto handle_sym_diff;
+
+	  case 2: /* R_MSP430_ABS16 */
+	  case 15: /* R_MSP430X_ABS16 */
+	    if (! uses_msp430x_relocs ())
+	      break;
+	    goto handle_sym_diff;
+	    
+	  handle_sym_diff:
+	    if (saved_sym != NULL)
+	      {
+		bfd_vma value;
+
+		value = reloc->r_addend
+		  + (symtab[get_reloc_symindex (reloc->r_info)].st_value
+		     - saved_sym->st_value);
+
+		byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
+
+		saved_sym = NULL;
+		return TRUE;
+	      }
+	    break;
+
+	  default:
+	    if (saved_sym != NULL)
+	      error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc"));
+	    break;
+	  }
+	break;
+      }
+
     case EM_MN10300:
     case EM_CYGNUS_MN10300:
       {
@@ -10101,7 +10216,7 @@
       return reloc_type == 1; /* R_MOXIE_32.  */
     case EM_MSP430_OLD:
     case EM_MSP430:
-      return reloc_type == 1; /* R_MSP43_32.  */
+      return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32.  */
     case EM_MT:
       return reloc_type == 2; /* R_MT_32.  */
     case EM_ALTERA_NIOS2:
@@ -10353,6 +10468,8 @@
     case EM_M32C:
       return reloc_type == 1; /* R_M32C_16 */
     case EM_MSP430:
+      if (uses_msp430x_relocs ())
+	return reloc_type == 2; /* R_MSP430_ABS16.  */
     case EM_MSP430_OLD:
       return reloc_type == 5; /* R_MSP430_16_BYTE.  */
     case EM_ALTERA_NIOS2:
@@ -11906,6 +12023,79 @@
   putchar ('\n');
 }
 
+static unsigned char *
+display_msp430x_attribute (unsigned char * p,
+			   const unsigned char * const end)
+{
+  unsigned int len;
+  int val;
+  int tag;
+
+  tag = read_uleb128 (p, & len, end);
+  p += len;
+  
+  switch (tag)
+    {
+    case OFBA_MSPABI_Tag_ISA:
+      val = read_uleb128 (p, &len, end);
+      p += len;
+      printf ("  Tag_ISA: ");
+      switch (val)
+	{
+	case 0: printf (_("None\n")); break;
+	case 1: printf (_("MSP430\n")); break;
+	case 2: printf (_("MSP430X\n")); break;
+	default: printf ("??? (%d)\n", val); break;
+	}
+      break;
+
+    case OFBA_MSPABI_Tag_Code_Model:
+      val = read_uleb128 (p, &len, end);
+      p += len;
+      printf ("  Tag_Code_Model: ");
+      switch (val)
+	{
+	case 0: printf (_("None\n")); break;
+	case 1: printf (_("Small\n")); break;
+	case 2: printf (_("Large\n")); break;
+	default: printf ("??? (%d)\n", val); break;
+	}
+      break;
+
+    case OFBA_MSPABI_Tag_Data_Model:
+      val = read_uleb128 (p, &len, end);
+      p += len;
+      printf ("  Tag_Data_Model: ");
+      switch (val)
+	{
+	case 0: printf (_("None\n")); break;
+	case 1: printf (_("Small\n")); break;
+	case 2: printf (_("Large\n")); break;
+	case 3: printf (_("Restricted Large\n")); break;
+	default: printf ("??? (%d)\n", val); break;
+	}
+      break;
+
+    default:
+      printf (_("  <unknown tag %d>: "), tag);
+
+      if (tag & 1)
+	{
+	  printf ("\"%s\"\n", p);
+	  p += strlen ((char *) p) + 1;
+	}
+      else
+	{
+	  val = read_uleb128 (p, &len, end);
+	  p += len;
+	  printf ("%d (0x%x)\n", val, val);
+	}
+      break;
+   }
+
+  return p;
+}
+
 static int
 process_attributes (FILE * file,
 		    const char * public_name,
@@ -12077,6 +12267,13 @@
 			     display_tic6x_attribute, NULL);
 }
 
+static int
+process_msp430x_specific (FILE * file)
+{
+  return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
+			     display_msp430x_attribute, NULL);
+}
+
 /* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
    Print the Address, Access and Initial fields of an entry at VMA ADDR
    and return the VMA of the next entry.  */
@@ -13555,6 +13752,8 @@
     case EM_TI_C6000:
       return process_tic6x_specific (file);
       break;
+    case EM_MSP430:
+      return process_msp430x_specific (file);
     default:
       break;
     }
diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog
index 06fd5e4..37cb9d6 100644
--- a/binutils/testsuite/ChangeLog
+++ b/binutils/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2013-05-02  Nick Clifton  <nickc@redhat.com>
+
+	* readelf.exp: Expect -wi test to fail for the MSP430.
+
+2013-05-01  Maciej W. Rozycki  <macro@codesourcery.com>
+
+	* lib/binutils-common.exp (is_elf_format): Also exclude
+	*-*-linux*ecoff*.
+
 2013-02-26  Nick Clifton  <nickc@redhat.com>
 
 	PR binutils/15191
diff --git a/binutils/testsuite/binutils-all/readelf.exp b/binutils/testsuite/binutils-all/readelf.exp
index c1d7286..db56a86 100644
--- a/binutils/testsuite/binutils-all/readelf.exp
+++ b/binutils/testsuite/binutils-all/readelf.exp
@@ -1,5 +1,4 @@
-#   Copyright 1999, 2000, 2001, 2003, 2004, 2007, 2009, 2012
-#   Free Software Foundation, Inc.
+#   Copyright 1999-2013 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -196,6 +195,9 @@
 	".*\(DW_OP_addr: 0\).*"
     }
 
+    # The MSP430 in LARGE mode does not generate a DW_OP_addr.
+    setup_xfail msp430*-*-*
+
     foreach looked_for $sought {
 	set lines [grep $output $looked_for]
 	if ![llength $lines] then {
diff --git a/binutils/testsuite/lib/binutils-common.exp b/binutils/testsuite/lib/binutils-common.exp
index 68efb90..af0040e 100644
--- a/binutils/testsuite/lib/binutils-common.exp
+++ b/binutils/testsuite/lib/binutils-common.exp
@@ -44,6 +44,7 @@
     }
 
     if { [istarget *-*-linux*aout*]
+	 || [istarget *-*-linux*ecoff*]
 	 || [istarget *-*-linux*oldld*]
 	 || [istarget h8500-*-rtems*]
 	 || [istarget i960-*-rtems*]
diff --git a/config/ChangeLog b/config/ChangeLog
index c6e8b25..cdc733c 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,13 @@
+2013-03-27  Kai Tietz  <ktietz@redhat.com>
+
+	* dfp.m4: Add support for cygwin x64 target.
+	* picflag.m4: Likewise.
+
+2013-02-25  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* bootstrap-asan.mk (POSTSTAGE1_LDFLAGS): Add
+	-B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/asan/.
+
 2013-01-15  Richard Biener  <rguenther@suse.de>
 
 	PR other/55973
diff --git a/config/bootstrap-asan.mk b/config/bootstrap-asan.mk
index d37a9da..e3f34f5 100644
--- a/config/bootstrap-asan.mk
+++ b/config/bootstrap-asan.mk
@@ -3,4 +3,5 @@
 STAGE2_CFLAGS += -fsanitize=address
 STAGE3_CFLAGS += -fsanitize=address
 POSTSTAGE1_LDFLAGS += -fsanitize=address -static-libasan \
+		      -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/asan/ \
 		      -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/asan/.libs
diff --git a/config/dfp.m4 b/config/dfp.m4
index e971db4..48683f0 100644
--- a/config/dfp.m4
+++ b/config/dfp.m4
@@ -23,7 +23,7 @@
     powerpc*-*-linux* | i?86*-*-linux* | x86_64*-*-linux* | s390*-*-linux* | \
     i?86*-*-gnu* | \
     i?86*-*-mingw* | x86_64*-*-mingw* | \
-    i?86*-*-cygwin*)
+    i?86*-*-cygwin* | x86_64*-*-cygwin*)
       enable_decimal_float=yes
       ;;
     *)
diff --git a/config/picflag.m4 b/config/picflag.m4
index bd81812..2ee5cd0 100644
--- a/config/picflag.m4
+++ b/config/picflag.m4
@@ -17,7 +17,9 @@
     hppa*64*-*-hpux*)
 	# PIC is the default for 64-bit PA HP-UX.
 	;;
-    i[[34567]]86-*-cygwin* | i[[34567]]86-*-mingw* | x86_64-*-mingw*)
+    i[[34567]]86-*-cygwin* | x86_64-*-cygwin*)
+	;;
+    i[[34567]]86-*-mingw* | x86_64-*-mingw*)
 	;;
     i[[34567]]86-*-interix[[3-9]]*)
 	# Interix 3.x gcc -fpic/-fPIC options generate broken code.
diff --git a/gas/ChangeLog b/gas/ChangeLog
index ec756d8..83fb073 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,113 @@
+2013-05-22  Jürgen Urban  <JuergenUrban@gmx.de>
+
+	* config/tc-mips.c (macro): Handle M_LQC2_AB and M_SQC2_AB.
+
+2013-05-20  Peter Bergner <bergner@vnet.ibm.com>
+
+	* config/tc-ppc.c (ppc_setup_opcodes): Use new_seg to fix error
+	and clean up warning when using PRINT_OPCODE_TABLE.
+
+2013-05-20  Alan Modra  <amodra@gmail.com>
+
+	* config/tc-ppc.c (md_apply_fix): Hoist code common to insn
+	and data fixups performing shift/high adjust/sign extension on
+	fieldval.  Sink fx_pcrel handling and checks.  Use fixP->fx_size
+	when writing data fixups rather than recalculating size.
+
+2013-05-16  Jan-Benedict Glaw  <jbglaw@lug-owl.de>
+
+	* doc/c-msp430.texi: Fix typo.
+
+2013-05-16  Tristan Gingold  <gingold@adacore.com>
+
+	* config/tc-ppc.c (ppc_is_toc_sym): Symbols of class XMC_TC
+	are also TOC symbols.
+
+2013-05-16  Nick Clifton  <nickc@redhat.com>
+
+	* config/tc-msp430.c: Make -mmcu recognise more part numbers.
+	Add -mcpu command to specify core type.
+	* doc/c-msp430.texi: Update documentation.
+
+2013-05-09  Andrew Pinski  <apinski@cavium.com>
+
+	* config/tc-mips.c (struct mips_set_options): New ase_virt field.
+	(mips_opts): Update for the new field.
+	(file_ase_virt): New variable.
+	(ISA_SUPPORTS_VIRT_ASE): New macro.
+	(ISA_SUPPORTS_VIRT64_ASE): New macro.
+	(MIPS_CPU_ASE_VIRT): New define.
+	(is_opcode_valid): Handle ase_virt.
+	(macro_build): Handle "+J".
+	(validate_mips_insn): Likewise.
+	(mips_ip): Likewise.
+	(enum options): Add OPTION_VIRT and OPTION_NO_VIRT.
+	(md_longopts): Add mvirt and mnovirt
+	(md_parse_option): Handle OPTION_VIRT and OPTION_NO_VIRT.
+	(mips_after_parse_args): Handle ase_virt field.
+	(s_mipsset): Handle "virt" and "novirt".
+	(mips_elf_final_processing): Add a comment about virt ASE might need
+	a new flag.
+	(md_show_usage): Print out the usage of -mvirt and mno-virt options.
+	* doc/c-mips.texi: Document -mvirt and -mno-virt.
+	Document ".set virt" and ".set novirt".
+
+2013-05-09  Alan Modra  <amodra@gmail.com>
+
+	* config/tc-ppc.c (md_apply_fix): Sign extend fieldval under
+	control of operand flag bits.
+
+2013-05-07  Alan Modra  <amodra@gmail.com>
+
+	* config/tc-ppc.c (PPC_VLE_SPLIT16A): Delete unused macro.
+	(PPC_VLE_SPLIT16D, PPC_VLE_LO16A, PPC_VLE_LO16D): Likewise.
+	(PPC_VLE_HI16A, PPC_VLE_HI16D): Likewise.
+	(PPC_VLE_HA16A, PPC_VLE_HA16D): Likewise.
+	(md_apply_fix): Set fx_no_overflow for assorted relocations.
+	Shift and sign-extend fieldval for use by some VLE reloc
+	operand->insert functions.
+
+2013-05-06  Paul Brook  <paul@codesourcery.com>
+	    Catherine Moore  <clm@codesourcery.com>
+
+	* config/tc-mips.c (md_pcrel_from): Handle BFD_RELOC_32_PCREL.
+	(limited_pcrel_reloc_p): Likewise.
+	(md_apply_fix): Likewise.
+	(tc_gen_reloc): Likewise.
+
+2013-05-06  Richard Sandiford  <rdsandiford@googlemail.com>
+
+	* config/tc-mips.c (limited_pcrel_reloc_p): New function.
+	(mips_fix_adjustable): Adjust pc-relative check to use
+	limited_pc_reloc_p.
+
+2013-05-02  Richard Sandiford  <rdsandiford@googlemail.com>
+
+	* config/tc-mips.c (mips_pseudo_table): Add stabd and stabs entries.
+	(s_mips_stab): Do not restrict to stabn only.
+
+2013-05-02  Nick Clifton  <nickc@redhat.com>
+
+	* config/tc-msp430.c: Add support for the MSP430X architecture.
+	Add code to insert a NOP instruction after any instruction that
+	might change the interrupt state.
+	Add support for the LARGE memory model.
+	Add code to initialise the .MSP430.attributes section.
+	* config/tc-msp430.h: Add support for the MSP430X architecture.
+	* doc/c-msp430.texi: Document the new -mL and -mN command line
+	options.
+	* NEWS: Mention support for the MSP430X architecture.
+
+2013-05-01  Maciej W. Rozycki  <macro@codesourcery.com>
+
+	* configure.tgt: Replace alpha*-*-linuxecoff* pattern with
+	alpha*-*-linux*ecoff*.
+
+2013-04-30  Chao-ying Fu  <Chao-ying.Fu@imgtec.com>
+
+	* config/tc-mips.c (mips_ip): Add sizelo.
+	For "+C", "+G", and "+H", set sizelo and compare against it.
+
 2013-04-29  Nick Clifton  <nickc@redhat.com>
 
 	* as.c (Options): Add -gdwarf-sections.
diff --git a/gas/NEWS b/gas/NEWS
index 202db36..29b0fdf 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,7 @@
 -*- text -*-
 
+* Add support for the Texas Instruments MSP430X processor.
+
 * Add -gdwarf-sections command line option to enable per-code-section
   generation of DWARF .debug_line sections.
 
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index a9b46e9..9b191bb 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -218,6 +218,7 @@
   int ase_dspr2;
   int ase_mt;
   int ase_mcu;
+  int ase_virt;
   /* Whether we are assembling for the mips16 processor.  0 if we are
      not, 1 if we are, and -1 if the value has not been initialized.
      Changed by `.set mips16' and `.set nomips16', and the -mips16 and
@@ -292,10 +293,11 @@
 {
   /* isa */ ISA_UNKNOWN, /* ase_mips3d */ -1, /* ase_mdmx */ -1,
   /* ase_smartmips */ 0, /* ase_dsp */ -1, /* ase_dspr2 */ -1, /* ase_mt */ -1,
-  /* ase_mcu */ -1, /* mips16 */ -1, /* micromips */ -1, /* noreorder */ 0,
-  /* at */ ATREG, /* warn_about_macros */ 0, /* nomove */ 0, /* nobopt */ 0,
-  /* noautoextend */ 0, /* gp32 */ 0, /* fp32 */ 0, /* arch */ CPU_UNKNOWN,
-  /* sym32 */ FALSE, /* soft_float */ FALSE, /* single_float */ FALSE
+  /* ase_mcu */ -1, /* ase_virt */ -1, /* mips16 */ -1,/* micromips */ -1,
+  /* noreorder */ 0,  /* at */ ATREG, /* warn_about_macros */ 0,
+  /* nomove */ 0, /* nobopt */ 0, /* noautoextend */ 0, /* gp32 */ 0,
+  /* fp32 */ 0, /* arch */ CPU_UNKNOWN, /* sym32 */ FALSE,
+  /* soft_float */ FALSE, /* single_float */ FALSE
 };
 
 /* These variables are filled in with the masks of registers used.
@@ -374,6 +376,15 @@
 			      || mips_opts.isa == ISA_MIPS64R2		\
 			      || mips_opts.micromips)
 
+/* True if -mvirt was passed or implied by arguments passed on the
+   command line (e.g., by -march). */
+static int file_ase_virt;
+
+#define ISA_SUPPORTS_VIRT_ASE (mips_opts.isa == ISA_MIPS32R2		\
+			       || mips_opts.isa == ISA_MIPS64R2)
+
+#define ISA_SUPPORTS_VIRT64_ASE (mips_opts.isa == ISA_MIPS64R2)
+
 /* The argument of the -march= flag.  The architecture we are assembling.  */
 static int file_mips_arch = CPU_UNKNOWN;
 static const char *mips_arch_string;
@@ -1395,6 +1406,7 @@
 #define MIPS_CPU_ASE_MDMX	0x0020	/* CPU implements MDMX ASE */
 #define MIPS_CPU_ASE_DSPR2	0x0040	/* CPU implements DSP R2 ASE */
 #define MIPS_CPU_ASE_MCU	0x0080	/* CPU implements MCU ASE */
+#define MIPS_CPU_ASE_VIRT	0x0100  /* CPU implements Virtualization ASE */
 
 static const struct mips_cpu_info *mips_parse_cpu (const char *, const char *);
 static const struct mips_cpu_info *mips_cpu_info_from_isa (int);
@@ -1472,7 +1484,9 @@
   {"section", s_change_section, 0},
   {"short", s_cons, 1},
   {"single", s_float_cons, 'f'},
+  {"stabd", s_mips_stab, 'd'},
   {"stabn", s_mips_stab, 'n'},
+  {"stabs", s_mips_stab, 's'},
   {"text", s_change_sec, 't'},
   {"word", s_cons, 2},
 
@@ -2256,6 +2270,10 @@
     isa |= INSN_SMARTMIPS;
   if (mips_opts.ase_mcu)
     isa |= INSN_MCU;
+  if (mips_opts.ase_virt)
+    isa |= INSN_VIRT;
+  if (mips_opts.ase_virt && ISA_SUPPORTS_VIRT64_ASE)
+    isa |= INSN_VIRT64;
 
   if (!opcode_is_member (mo, isa, mips_opts.arch))
     return FALSE;
@@ -2742,6 +2760,28 @@
   return reloc == BFD_RELOC_MIPS_JALR || reloc == BFD_RELOC_MICROMIPS_JALR;
 }
 
+/* Return true if RELOC is a PC-relative relocation that does not have
+   full address range.  */
+
+static inline bfd_boolean
+limited_pcrel_reloc_p (bfd_reloc_code_real_type reloc)
+{
+  switch (reloc)
+    {
+    case BFD_RELOC_16_PCREL_S2:
+    case BFD_RELOC_MICROMIPS_7_PCREL_S1:
+    case BFD_RELOC_MICROMIPS_10_PCREL_S1:
+    case BFD_RELOC_MICROMIPS_16_PCREL_S1:
+      return TRUE;
+
+    case BFD_RELOC_32_PCREL:
+      return HAVE_64BIT_ADDRESSES;
+
+    default:
+      return FALSE;
+    }
+}
+
 /* Return true if the given relocation might need a matching %lo().
    This is only "might" because SVR4 R_MIPS_GOT16 relocations only
    need a matching %lo() when applied to local symbols.  */
@@ -5012,6 +5052,11 @@
 			      INSMSB, insn, va_arg (args, int));
 	      continue;
 
+	    case 'J':
+	      gas_assert (!mips_opts.micromips);
+	      INSERT_OPERAND (0, CODE10, insn, va_arg (args, int));
+	      continue;
+
 	    case 'C':
 	    case 'G':
 	    case 'H':
@@ -8156,6 +8201,13 @@
       /* Itbl support may require additional care here.  */
       coproc = 1;
       goto ld_st;
+    case M_LQC2_AB:
+      ab = 1;
+      s = "lqc2";
+      fmt = "E,o(b)";
+      /* Itbl support may require additional care here.  */
+      coproc = 1;
+      goto ld_st;
     case M_LDC3_AB:
       ab = 1;
       s = "ldc3";
@@ -8345,6 +8397,13 @@
       /* Itbl support may require additional care here.  */
       coproc = 1;
       goto ld_st;
+    case M_SQC2_AB:
+      ab = 1;
+      s = "sqc2";
+      fmt = "E,o(b)";
+      /* Itbl support may require additional care here.  */
+      coproc = 1;
+      goto ld_st;
     case M_SDC3_AB:
       ab = 1;
       gas_assert (!mips_opts.micromips);
@@ -10392,6 +10451,7 @@
 	  case 'G': USE_BITS (OP_MASK_EXTMSBD,	OP_SH_EXTMSBD);	break;
 	  case 'H': USE_BITS (OP_MASK_EXTMSBD,	OP_SH_EXTMSBD);	break;
 	  case 'I': break;
+	  case 'J': USE_BITS (OP_MASK_CODE10,	OP_SH_CODE10);	break;
 	  case 't': USE_BITS (OP_MASK_RT,	OP_SH_RT);	break;
 	  case 'T': USE_BITS (OP_MASK_RT,	OP_SH_RT);
 		    USE_BITS (OP_MASK_SEL,	OP_SH_SEL);	break;
@@ -10790,6 +10850,7 @@
   unsigned int destregno = 0;
   unsigned int lastpos = 0;
   unsigned int limlo, limhi;
+  int sizelo;
   char *s_reset;
   offsetT min_range, max_range;
   long opend;
@@ -11314,6 +11375,23 @@
 		  }
 		  continue;
 
+		case 'J':		/* 10-bit hypcall code.  */
+		  gas_assert (!mips_opts.micromips);
+		  {
+		    unsigned long mask = OP_MASK_CODE10;
+
+		    my_getExpression (&imm_expr, s);
+		    check_absolute_expr (ip, &imm_expr);
+		    if ((unsigned long) imm_expr.X_add_number > mask)
+		      as_warn (_("Code for %s not in range 0..%lu (%lu)"),
+			       ip->insn_mo->name,
+			       mask, (unsigned long) imm_expr.X_add_number);
+		    INSERT_OPERAND (0, CODE10, *ip, imm_expr.X_add_number);
+		    imm_expr.X_op = O_absent;
+		    s = expr_end;
+		  }
+		  continue;
+
 		case 'A':		/* ins/ext position, becomes LSB.  */
 		  limlo = 0;
 		  limhi = 31;
@@ -11374,23 +11452,25 @@
 		case 'C':		/* ext size, becomes MSBD.  */
 		  limlo = 1;
 		  limhi = 32;
+		  sizelo = 1;
 		  goto do_msbd;
 		case 'G':
 		  limlo = 33;
 		  limhi = 64;
+		  sizelo = 33;
 		  goto do_msbd;
 		case 'H':
 		  limlo = 33;
 		  limhi = 64;
+		  sizelo = 1;
 		  goto do_msbd;
 		do_msbd:
 		  my_getExpression (&imm_expr, s);
 		  check_absolute_expr (ip, &imm_expr);
-		  /* Check for negative input so that small negative numbers
-		     will not succeed incorrectly.  The checks against
-		     (pos+size) transitively check "size" itself,
-		     assuming that "pos" is reasonable.  */
-		  if ((long) imm_expr.X_add_number < 0
+		  /* The checks against (pos+size) don't transitively check
+		     "size" itself, assuming that "pos" is reasonable.
+		     We also need to check the lower bound of "size".  */
+		  if ((long) imm_expr.X_add_number < sizelo
 		      || ((unsigned long) imm_expr.X_add_number
 			  + lastpos) < limlo
 		      || ((unsigned long) imm_expr.X_add_number
@@ -14469,6 +14549,8 @@
     OPTION_NO_DSP,
     OPTION_MT,
     OPTION_NO_MT,
+    OPTION_VIRT,
+    OPTION_NO_VIRT,
     OPTION_SMARTMIPS,
     OPTION_NO_SMARTMIPS,
     OPTION_DSPR2,
@@ -14573,6 +14655,8 @@
   {"mno-micromips", no_argument, NULL, OPTION_NO_MICROMIPS},
   {"mmcu", no_argument, NULL, OPTION_MCU},
   {"mno-mcu", no_argument, NULL, OPTION_NO_MCU},
+  {"mvirt", no_argument, NULL, OPTION_VIRT},
+  {"mno-virt", no_argument, NULL, OPTION_NO_VIRT},
 
   /* Old-style architecture options.  Don't add more of these.  */
   {"m4650", no_argument, NULL, OPTION_M4650},
@@ -14850,6 +14934,14 @@
       mips_no_prev_insn ();
       break;
 
+    case OPTION_VIRT:
+      mips_opts.ase_virt = 1;
+      break;
+
+    case OPTION_NO_VIRT:
+      mips_opts.ase_virt = 0;
+      break;
+
     case OPTION_MIPS16:
       if (mips_opts.micromips == 1)
 	{
@@ -15343,6 +15435,12 @@
       as_warn (_("%s ISA does not support MCU ASE"),
 	       mips_cpu_info_from_isa (mips_opts.isa)->name);
 
+  if (mips_opts.ase_virt == -1)
+    mips_opts.ase_virt = (arch_info->flags & MIPS_CPU_ASE_VIRT) ? 1 : 0;
+  if (mips_opts.ase_virt && !ISA_SUPPORTS_VIRT_ASE)
+    as_warn (_("%s ISA does not support Virtualization ASE"),
+	     mips_cpu_info_from_isa (mips_opts.isa)->name);
+
   file_mips_isa = mips_opts.isa;
   file_ase_mips3d = mips_opts.ase_mips3d;
   file_ase_mdmx = mips_opts.ase_mdmx;
@@ -15350,6 +15448,7 @@
   file_ase_dsp = mips_opts.ase_dsp;
   file_ase_dspr2 = mips_opts.ase_dspr2;
   file_ase_mt = mips_opts.ase_mt;
+  file_ase_virt = mips_opts.ase_virt;
   mips_opts.gp32 = file_mips_gp32;
   mips_opts.fp32 = file_mips_fp32;
   mips_opts.soft_float = file_mips_soft_float;
@@ -15392,6 +15491,9 @@
       /* Return the address of the delay slot.  */
       return addr + 4;
 
+    case BFD_RELOC_32_PCREL:
+      return addr;
+
     default:
       /* We have no relocation type for PC relative MIPS16 instructions.  */
       if (fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != now_seg)
@@ -15614,7 +15716,8 @@
   gas_assert (!fixP->fx_pcrel || fixP->fx_r_type == BFD_RELOC_16_PCREL_S2
 	      || fixP->fx_r_type == BFD_RELOC_MICROMIPS_7_PCREL_S1
 	      || fixP->fx_r_type == BFD_RELOC_MICROMIPS_10_PCREL_S1
-	      || fixP->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1);
+	      || fixP->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1
+	      || fixP->fx_r_type == BFD_RELOC_32_PCREL);
 
   /* Don't treat parts of a composite relocation as done.  There are two
      reasons for this:
@@ -15762,6 +15865,7 @@
 
     case BFD_RELOC_RVA:
     case BFD_RELOC_32:
+    case BFD_RELOC_32_PCREL:
     case BFD_RELOC_16:
       /* If we are deleting this reloc entry, we must fill in the
 	 value now.  This can happen if we have a .word which is not
@@ -16414,6 +16518,15 @@
     mips_opts.ase_mcu = 1;
   else if (strcmp (name, "nomcu") == 0)
     mips_opts.ase_mcu = 0;
+  else if (strcmp (name, "virt") == 0)
+    {
+      if (!ISA_SUPPORTS_VIRT_ASE)
+	as_warn (_("%s ISA does not support Virtualization ASE"), 
+		 mips_cpu_info_from_isa (mips_opts.isa)->name);
+      mips_opts.ase_virt = 1;
+    }
+  else if (strcmp (name, "novirt") == 0)
+    mips_opts.ase_virt = 0;
   else if (strncmp (name, "mips", 4) == 0 || strncmp (name, "arch=", 5) == 0)
     {
       int reset = 0;
@@ -17085,18 +17198,24 @@
   demand_empty_rest_of_line ();
 }
 
-/* Handle a .stabn directive.  We need these in order to mark a label
-   as being a mips16 text label correctly.  Sometimes the compiler
-   will emit a label, followed by a .stabn, and then switch sections.
-   If the label and .stabn are in mips16 mode, then the label is
-   really a mips16 text label.  */
+/* Handle a .stab[snd] directive.  Ideally these directives would be
+   implemented in a transparent way, so that removing them would not
+   have any effect on the generated instructions.  However, s_stab
+   internally changes the section, so in practice we need to decide
+   now whether the preceding label marks compressed code.  We do not
+   support changing the compression mode of a label after a .stab*
+   directive, such as in:
+
+   foo:
+   	.stabs ...
+	.set mips16
+
+   so the current mode wins.  */
 
 static void
 s_mips_stab (int type)
 {
-  if (type == 'n')
-    mips_mark_labels ();
-
+  mips_mark_labels ();
   s_stab (type);
 }
 
@@ -17803,11 +17922,12 @@
     return 0;
 
   /* There is no place to store an in-place offset for JALR relocations.
-     Likewise an in-range offset of PC-relative relocations may overflow
-     the in-place relocatable field if recalculated against the start
-     address of the symbol's containing section.  */
+     Likewise an in-range offset of limited PC-relative relocations may
+     overflow the in-place relocatable field if recalculated against the
+     start address of the symbol's containing section.  */
   if (HAVE_IN_PLACE_ADDENDS
-      && (fixp->fx_pcrel || jalr_reloc_p (fixp->fx_r_type)))
+      && (limited_pcrel_reloc_p (fixp->fx_r_type)
+	  || jalr_reloc_p (fixp->fx_r_type)))
     return 0;
 
 #ifdef OBJ_ELF
@@ -17887,7 +18007,8 @@
       gas_assert (fixp->fx_r_type == BFD_RELOC_16_PCREL_S2
 		  || fixp->fx_r_type == BFD_RELOC_MICROMIPS_7_PCREL_S1
 		  || fixp->fx_r_type == BFD_RELOC_MICROMIPS_10_PCREL_S1
-		  || fixp->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1);
+		  || fixp->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1
+		  || fixp->fx_r_type == BFD_RELOC_32_PCREL);
 
       /* At this point, fx_addnumber is "symbol offset - pcrel address".
 	 Relocations want only the symbol offset.  */
@@ -18678,12 +18799,8 @@
   if (mips_abicalls)
     elf_elfheader (stdoutput)->e_flags |= EF_MIPS_CPIC;
 
-  /* Set MIPS ELF flags for ASEs.  */
-  /* We may need to define a new flag for DSP ASE, and set this flag when
-     file_ase_dsp is true.  */
-  /* Same for DSP R2.  */
-  /* We may need to define a new flag for MT ASE, and set this flag when
-     file_ase_mt is true.  */
+  /* Set MIPS ELF flags for ASEs.  Note that not all ASEs have flags
+     defined at present; this might need to change in future.  */
   if (file_ase_mips16)
     elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_M16;
   if (file_ase_micromips)
@@ -19554,6 +19671,9 @@
 -mmcu			generate MCU instructions\n\
 -mno-mcu		do not generate MCU instructions\n"));
   fprintf (stream, _("\
+-mvirt			generate Virtualization instructions\n\
+-mno-virt		do not generate Virtualization instructions\n"));
+  fprintf (stream, _("\
 -mfix-loongson2f-jump	work around Loongson2F JUMP instructions\n\
 -mfix-loongson2f-nop	work around Loongson2F NOP errata\n\
 -mfix-vr4120		work around certain VR4120 errata\n\
diff --git a/gas/config/tc-msp430.c b/gas/config/tc-msp430.c
index 8ec7546..f319b23 100644
--- a/gas/config/tc-msp430.c
+++ b/gas/config/tc-msp430.c
@@ -1,7 +1,6 @@
 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
 
-  Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2012
-  Free Software Foundation, Inc.
+  Copyright (C) 2002-2013 Free Software Foundation, Inc.
   Contributed by Dmitry Diky <diwil@mail.ru>
 
   This file is part of GAS, the GNU Assembler.
@@ -28,6 +27,7 @@
 #include "opcode/msp430.h"
 #include "safe-ctype.h"
 #include "dwarf2dbg.h"
+#include "elf/msp430.h"
 
 /* We will disable polymorphs by default because it is dangerous.
    The potential problem here is the following: assume we got the
@@ -39,7 +39,7 @@
       .l1:
 	nop
 	ret
-   
+
    In case of assembly time relaxation we'll get:
 	0: jmp .l1 <.text +0x08> (reloc deleted)
 	2: nop
@@ -63,15 +63,18 @@
 
    If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
    do not delete any relocs and leave them for linker.
-   
+
    If relax is enabled, relax at assembly time and kill relocs as necessary.  */
 
 int msp430_enable_relax;
 int msp430_enable_polys;
 
+/*  Set linkrelax here to avoid fixups in most sections.  */
+int linkrelax = 1;
+
 /* GCC uses the some condition codes which we'll
    implement as new polymorph instructions.
-  
+
    COND	EXPL	   SHORT JUMP	LONG JUMP
    ===============================================
    eq	==	   jeq 		jne +4; br lab
@@ -80,7 +83,7 @@
    ltn honours no-overflow flag
    ltn	<	   jn 		jn +2;  jmp +4; br lab
 
-   lt	<	   jl 		jge +4;	br lab 
+   lt	<	   jl 		jge +4;	br lab
    ltu	<	   jlo 		lhs +4; br lab
    le	<= see below
    leu	<= see below
@@ -93,14 +96,14 @@
 
    Therefore, new opcodes are (BranchEQ -> beq; and so on...)
    beq,bne,blt,bltn,bltu,bge,bgeu
-   'u' means unsigned compares 
-  
+   'u' means unsigned compares
+
    Also, we add 'jump' instruction:
    jump	UNCOND	-> jmp		br lab
 
    They will have fmt == 4, and insn_opnumb == number of instruction.  */
 
-struct rcodes_s 
+struct rcodes_s
 {
   char * name;
   int    index;	/* Corresponding insn_opnumb.  */
@@ -114,7 +117,7 @@
 #define MSP430_RLC(n,i,sop,o1) \
   {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
 
-static struct rcodes_s msp430_rcodes[] = 
+static struct rcodes_s msp430_rcodes[] =
 {
   MSP430_RLC (beq,  0, 0x2400, 0x2000),
   MSP430_RLC (bne,  1, 0x2000, 0x2400),
@@ -126,11 +129,27 @@
   {"jump",          7, 0x3c00, 1, 0x4010, 0, 0},
   {0,0,0,0,0,0,0}
 };
+
+#undef  MSP430_RLC
+#define MSP430_RLC(n,i,sop,o1) \
+  {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
+
+static struct rcodes_s msp430x_rcodes[] =
+{
+  MSP430_RLC (beq,  0, 0x2400,    0x2000),
+  MSP430_RLC (bne,  1, 0x2000,    0x2400),
+  MSP430_RLC (blt,  2, 0x3800,    0x3400),
+  MSP430_RLC (bltu, 3, 0x2800,    0x2c00),
+  MSP430_RLC (bge,  4, 0x3400,    0x3800),
+  MSP430_RLC (bgeu, 5, 0x2c00,    0x2800),
+  {"bltn",          6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000},
+  {"jump",          7, 0x3c00, 1, 0x0030,     0,          0},
+  {0,0,0,0,0,0,0}
+};
 #undef MSP430_RLC
 
-
 /* More difficult than above and they have format 5.
-   
+
    COND	EXPL	SHORT			LONG
    =================================================================
    gt	>	jeq +2; jge label	jeq +6; jl  +4; br label
@@ -139,9 +158,9 @@
    le	<=	jeq label; jl  label	jeq +2; jge +4; br label
    =================================================================  */
 
-struct hcodes_s 
+struct hcodes_s
 {
-  char * name;	
+  char * name;
   int    index;		/* Corresponding insn_opnumb.  */
   int    tlab;		/* Number of labels in short mode.  */
   int    op0;		/* Opcode for first word of short jump.  */
@@ -151,7 +170,7 @@
   int    lop2;
 };
 
-static struct hcodes_s msp430_hcodes[] = 
+static struct hcodes_s msp430_hcodes[] =
 {
   {"bgt",  0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
   {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
@@ -160,6 +179,15 @@
   {0,0,0,0,0,0,0,0}
 };
 
+static struct hcodes_s msp430x_hcodes[] =
+{
+  {"bgt",  0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 },
+  {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 },
+  {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 },
+  {"ble",  3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 },
+  {0,0,0,0,0,0,0,0}
+};
+
 const char comment_chars[] = ";";
 const char line_comment_chars[] = "#";
 const char line_separator_chars[] = "{";
@@ -229,115 +257,506 @@
 
 #define MAX_OP_LEN	256
 
+typedef enum msp_isa
+{
+  MSP_ISA_430,
+  MSP_ISA_430X,
+  MSP_ISA_430Xv2
+} msp_isa;
+
 struct mcu_type_s
 {
-  char * name;
-  int isa;
-  int mach;
+  char *  name;
+  msp_isa isa;
 };
 
-#define MSP430_ISA_11   11
-#define MSP430_ISA_110	110
-#define MSP430_ISA_12   12
-#define MSP430_ISA_13   13
-#define MSP430_ISA_14   14
-#define MSP430_ISA_15   15
-#define MSP430_ISA_16   16
-#define MSP430_ISA_21   21
-#define MSP430_ISA_31   31
-#define MSP430_ISA_32   32
-#define MSP430_ISA_33   33
-#define MSP430_ISA_41   41
-#define MSP430_ISA_42   42
-#define MSP430_ISA_43   43
-#define MSP430_ISA_44   44
-
-#define CHECK_RELOC_MSP430 		((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
-#define CHECK_RELOC_MSP430_PCREL	((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
-
 static struct mcu_type_s mcu_types[] =
 {
-  {"msp1",        MSP430_ISA_11, bfd_mach_msp11},
-  {"msp2",        MSP430_ISA_14, bfd_mach_msp14},
-  {"msp430x110",  MSP430_ISA_11, bfd_mach_msp11},
-  {"msp430x112",  MSP430_ISA_11, bfd_mach_msp11},
-  {"msp430x1101", MSP430_ISA_110, bfd_mach_msp110},
-  {"msp430x1111", MSP430_ISA_110, bfd_mach_msp110},
-  {"msp430x1121", MSP430_ISA_110, bfd_mach_msp110},
-  {"msp430x1122", MSP430_ISA_11, bfd_mach_msp110},
-  {"msp430x1132", MSP430_ISA_11, bfd_mach_msp110},
+  {"msp430afe221", MSP_ISA_430},
+  {"msp430afe222", MSP_ISA_430},
+  {"msp430afe223", MSP_ISA_430},
+  {"msp430afe231", MSP_ISA_430},
+  {"msp430afe232", MSP_ISA_430},
+  {"msp430afe233", MSP_ISA_430},
+  {"msp430afe251", MSP_ISA_430},
+  {"msp430afe252", MSP_ISA_430},
+  {"msp430afe253", MSP_ISA_430},
+  {"msp430c091",   MSP_ISA_430},
+  {"msp430c092",   MSP_ISA_430},
+  {"msp430c111",   MSP_ISA_430},
+  {"msp430c1111",  MSP_ISA_430},
+  {"msp430c112",   MSP_ISA_430},
+  {"msp430c1121",  MSP_ISA_430},
+  {"msp430e112",   MSP_ISA_430},
+  {"msp430c1331", MSP_ISA_430},
+  {"msp430c1351", MSP_ISA_430},
+  {"msp430c311s", MSP_ISA_430},
+  {"msp430c312",  MSP_ISA_430},
+  {"msp430c313",  MSP_ISA_430},
+  {"msp430c314",  MSP_ISA_430},
+  {"msp430c315", MSP_ISA_430},
+  {"msp430c323", MSP_ISA_430},
+  {"msp430c325", MSP_ISA_430},
+  {"msp430c336", MSP_ISA_430},
+  {"msp430c337", MSP_ISA_430},
+  {"msp430c412", MSP_ISA_430},
+  {"msp430c413", MSP_ISA_430},
+  {"msp430e313", MSP_ISA_430},
+  {"msp430e315", MSP_ISA_430},
+  {"msp430e325", MSP_ISA_430},
+  {"msp430e337", MSP_ISA_430},
+  {"msp430f110", MSP_ISA_430},
+  {"msp430f1101", MSP_ISA_430},
+  {"msp430f1101a", MSP_ISA_430},
+  {"msp430f1111", MSP_ISA_430},
+  {"msp430f1111a", MSP_ISA_430},
+  {"msp430f112", MSP_ISA_430},
+  {"msp430f1121", MSP_ISA_430},
+  {"msp430f1121a", MSP_ISA_430},
+  {"msp430f1122", MSP_ISA_430},
+  {"msp430f1132", MSP_ISA_430},
+  {"msp430f122", MSP_ISA_430},
+  {"msp430f1222", MSP_ISA_430},
+  {"msp430f123", MSP_ISA_430},
+  {"msp430f1232", MSP_ISA_430},
+  {"msp430f133", MSP_ISA_430},
+  {"msp430f135", MSP_ISA_430},
+  {"msp430f147", MSP_ISA_430},
+  {"msp430f1471", MSP_ISA_430},
+  {"msp430f148", MSP_ISA_430},
+  {"msp430f1481", MSP_ISA_430},
+  {"msp430f149", MSP_ISA_430},
+  {"msp430f1491", MSP_ISA_430},
+  {"msp430f155", MSP_ISA_430},
+  {"msp430f156", MSP_ISA_430},
+  {"msp430f157", MSP_ISA_430},
+  {"msp430f1610", MSP_ISA_430},
+  {"msp430f1611", MSP_ISA_430},
+  {"msp430f1612", MSP_ISA_430},
+  {"msp430f167", MSP_ISA_430},
+  {"msp430f168", MSP_ISA_430},
+  {"msp430f169", MSP_ISA_430},
+  {"msp430f2001", MSP_ISA_430},
+  {"msp430f2002", MSP_ISA_430},
+  {"msp430f2003", MSP_ISA_430},
+  {"msp430f2011", MSP_ISA_430},
+  {"msp430f2012", MSP_ISA_430},
+  {"msp430f2013", MSP_ISA_430},
+  {"msp430f2101", MSP_ISA_430},
+  {"msp430f2111", MSP_ISA_430},
+  {"msp430f2112", MSP_ISA_430},
+  {"msp430f2121", MSP_ISA_430},
+  {"msp430f2122", MSP_ISA_430},
+  {"msp430f2131", MSP_ISA_430},
+  {"msp430f2132", MSP_ISA_430},
+  {"msp430f2232", MSP_ISA_430},
+  {"msp430f2234", MSP_ISA_430},
+  {"msp430f2252", MSP_ISA_430},
+  {"msp430f2254", MSP_ISA_430},
+  {"msp430f2272", MSP_ISA_430},
+  {"msp430f2274", MSP_ISA_430},
+  {"msp430f233", MSP_ISA_430},
+  {"msp430f2330", MSP_ISA_430},
+  {"msp430f235", MSP_ISA_430},
+  {"msp430f2350", MSP_ISA_430},
+  {"msp430f2370", MSP_ISA_430},
+  {"msp430f2410", MSP_ISA_430},
+  {"msp430f247", MSP_ISA_430},
+  {"msp430f2471", MSP_ISA_430},
+  {"msp430f248", MSP_ISA_430},
+  {"msp430f2481", MSP_ISA_430},
+  {"msp430f249", MSP_ISA_430},
+  {"msp430f2491", MSP_ISA_430},
+  {"msp430f412", MSP_ISA_430},
+  {"msp430f413", MSP_ISA_430},
+  {"msp430f4132", MSP_ISA_430},
+  {"msp430f415", MSP_ISA_430},
+  {"msp430f4152", MSP_ISA_430},
+  {"msp430f417", MSP_ISA_430},
+  {"msp430f423", MSP_ISA_430},
+  {"msp430f423a", MSP_ISA_430},
+  {"msp430f425",  MSP_ISA_430},
+  {"msp430f4250", MSP_ISA_430},
+  {"msp430f425a", MSP_ISA_430},
+  {"msp430f4260", MSP_ISA_430},
+  {"msp430f427",  MSP_ISA_430},
+  {"msp430f4270", MSP_ISA_430},
+  {"msp430f427a", MSP_ISA_430},
+  {"msp430f435", MSP_ISA_430},
+  {"msp430f4351", MSP_ISA_430},
+  {"msp430f436", MSP_ISA_430},
+  {"msp430f4361", MSP_ISA_430},
+  {"msp430f437", MSP_ISA_430},
+  {"msp430f4371", MSP_ISA_430},
+  {"msp430f438", MSP_ISA_430},
+  {"msp430f439", MSP_ISA_430},
+  {"msp430f447", MSP_ISA_430},
+  {"msp430f448", MSP_ISA_430},
+  {"msp430f4481", MSP_ISA_430},
+  {"msp430f449", MSP_ISA_430},
+  {"msp430f4491", MSP_ISA_430},
+  {"msp430f477", MSP_ISA_430},
+  {"msp430f478", MSP_ISA_430},
+  {"msp430f4783", MSP_ISA_430},
+  {"msp430f4784", MSP_ISA_430},
+  {"msp430f479", MSP_ISA_430},
+  {"msp430f4793", MSP_ISA_430},
+  {"msp430f4794", MSP_ISA_430},
+  {"msp430fe423", MSP_ISA_430},
+  {"msp430fe4232", MSP_ISA_430},
+  {"msp430fe423a", MSP_ISA_430},
+  {"msp430fe4242", MSP_ISA_430},
+  {"msp430fe425", MSP_ISA_430},
+  {"msp430fe4252", MSP_ISA_430},
+  {"msp430fe425a", MSP_ISA_430},
+  {"msp430fe427", MSP_ISA_430},
+  {"msp430fe4272", MSP_ISA_430},
+  {"msp430fe427a", MSP_ISA_430},
+  {"msp430fg4250", MSP_ISA_430},
+  {"msp430fg4260", MSP_ISA_430},
+  {"msp430fg4270", MSP_ISA_430},
+  {"msp430fg437", MSP_ISA_430},
+  {"msp430fg438", MSP_ISA_430},
+  {"msp430fg439", MSP_ISA_430},
+  {"msp430fg477", MSP_ISA_430},
+  {"msp430fg478", MSP_ISA_430},
+  {"msp430fg479", MSP_ISA_430},
+  {"msp430fw423", MSP_ISA_430},
+  {"msp430fw425", MSP_ISA_430},
+  {"msp430fw427", MSP_ISA_430},
+  {"msp430fw428", MSP_ISA_430},
+  {"msp430fw429", MSP_ISA_430},
+  {"msp430g2001", MSP_ISA_430},
+  {"msp430g2101", MSP_ISA_430},
+  {"msp430g2102", MSP_ISA_430},
+  {"msp430g2111", MSP_ISA_430},
+  {"msp430g2112", MSP_ISA_430},
+  {"msp430g2113", MSP_ISA_430},
+  {"msp430g2121", MSP_ISA_430},
+  {"msp430g2131", MSP_ISA_430},
+  {"msp430g2132", MSP_ISA_430},
+  {"msp430g2152", MSP_ISA_430},
+  {"msp430g2153", MSP_ISA_430},
+  {"msp430g2201", MSP_ISA_430},
+  {"msp430g2202", MSP_ISA_430},
+  {"msp430g2203", MSP_ISA_430},
+  {"msp430g2210", MSP_ISA_430},
+  {"msp430g2211", MSP_ISA_430},
+  {"msp430g2212", MSP_ISA_430},
+  {"msp430g2213", MSP_ISA_430},
+  {"msp430g2221", MSP_ISA_430},
+  {"msp430g2230", MSP_ISA_430},
+  {"msp430g2231", MSP_ISA_430},
+  {"msp430g2232", MSP_ISA_430},
+  {"msp430g2233", MSP_ISA_430},
+  {"msp430g2252", MSP_ISA_430},
+  {"msp430g2253", MSP_ISA_430},
+  {"msp430g2302", MSP_ISA_430},
+  {"msp430g2303", MSP_ISA_430},
+  {"msp430g2312", MSP_ISA_430},
+  {"msp430g2313", MSP_ISA_430},
+  {"msp430g2332", MSP_ISA_430},
+  {"msp430g2333", MSP_ISA_430},
+  {"msp430g2352", MSP_ISA_430},
+  {"msp430g2353", MSP_ISA_430},
+  {"msp430g2402", MSP_ISA_430},
+  {"msp430g2403", MSP_ISA_430},
+  {"msp430g2412", MSP_ISA_430},
+  {"msp430g2413", MSP_ISA_430},
+  {"msp430g2432", MSP_ISA_430},
+  {"msp430g2433", MSP_ISA_430},
+  {"msp430g2444", MSP_ISA_430},
+  {"msp430g2452", MSP_ISA_430},
+  {"msp430g2453", MSP_ISA_430},
+  {"msp430g2513", MSP_ISA_430},
+  {"msp430g2533", MSP_ISA_430},
+  {"msp430g2544", MSP_ISA_430},
+  {"msp430g2553", MSP_ISA_430},
+  {"msp430g2744", MSP_ISA_430},
+  {"msp430g2755", MSP_ISA_430},
+  {"msp430g2855", MSP_ISA_430},
+  {"msp430g2955", MSP_ISA_430},
+  {"msp430l092",  MSP_ISA_430},
+  {"msp430p112",  MSP_ISA_430},
+  {"msp430p313",  MSP_ISA_430},
+  {"msp430p315",  MSP_ISA_430},
+  {"msp430p315s", MSP_ISA_430},
+  {"msp430p325",  MSP_ISA_430},
+  {"msp430p337",  MSP_ISA_430},
+  {"msp430tch5e", MSP_ISA_430},
 
-  {"msp430x122",  MSP430_ISA_12, bfd_mach_msp12},
-  {"msp430x123",  MSP430_ISA_12, bfd_mach_msp12},
-  {"msp430x1222", MSP430_ISA_12, bfd_mach_msp12},
-  {"msp430x1232", MSP430_ISA_12, bfd_mach_msp12},
+  {"msp430cg4616", MSP_ISA_430X},
+  {"msp430cg4617", MSP_ISA_430X},
+  {"msp430cg4618", MSP_ISA_430X},
+  {"msp430cg4619", MSP_ISA_430X},
+  {"msp430f2416", MSP_ISA_430X},
+  {"msp430f2417", MSP_ISA_430X},
+  {"msp430f2418", MSP_ISA_430X},
+  {"msp430f2419", MSP_ISA_430X},
+  {"msp430f2616", MSP_ISA_430X},
+  {"msp430f2617", MSP_ISA_430X},
+  {"msp430f2618", MSP_ISA_430X},
+  {"msp430f2619", MSP_ISA_430X},
+  {"msp430f47126", MSP_ISA_430X},
+  {"msp430f47127", MSP_ISA_430X},
+  {"msp430f47163", MSP_ISA_430X},
+  {"msp430f47173", MSP_ISA_430X},
+  {"msp430f47183", MSP_ISA_430X},
+  {"msp430f47193", MSP_ISA_430X},
+  {"msp430f47166", MSP_ISA_430X},
+  {"msp430f47176", MSP_ISA_430X},
+  {"msp430f47186", MSP_ISA_430X},
+  {"msp430f47196", MSP_ISA_430X},
+  {"msp430f47167", MSP_ISA_430X},
+  {"msp430f47177", MSP_ISA_430X},
+  {"msp430f47187", MSP_ISA_430X},
+  {"msp430f47197", MSP_ISA_430X},
+  {"msp430f46161", MSP_ISA_430X},
+  {"msp430f46171", MSP_ISA_430X},
+  {"msp430f46181", MSP_ISA_430X},
+  {"msp430f46191", MSP_ISA_430X},
+  {"msp430f4616", MSP_ISA_430X},
+  {"msp430f4617", MSP_ISA_430X},
+  {"msp430f4618", MSP_ISA_430X},
+  {"msp430f4619", MSP_ISA_430X},
+  {"msp430fg4616", MSP_ISA_430X},
+  {"msp430fg4617", MSP_ISA_430X},
+  {"msp430fg4618", MSP_ISA_430X},
+  {"msp430fg4619", MSP_ISA_430X},
 
-  {"msp430x133",  MSP430_ISA_13, bfd_mach_msp13},
-  {"msp430x135",  MSP430_ISA_13, bfd_mach_msp13},
-  {"msp430x1331", MSP430_ISA_13, bfd_mach_msp13},
-  {"msp430x1351", MSP430_ISA_13, bfd_mach_msp13},
-  {"msp430x147",  MSP430_ISA_14, bfd_mach_msp14},
-  {"msp430x148",  MSP430_ISA_14, bfd_mach_msp14},
-  {"msp430x149",  MSP430_ISA_14, bfd_mach_msp14},
+  {"msp430f5418", MSP_ISA_430Xv2},
+  {"msp430f5419", MSP_ISA_430Xv2},
+  {"msp430f5435", MSP_ISA_430Xv2},
+  {"msp430f5436", MSP_ISA_430Xv2},
+  {"msp430f5437", MSP_ISA_430Xv2},
+  {"msp430f5438", MSP_ISA_430Xv2},
+  {"msp430f5418a", MSP_ISA_430Xv2},
+  {"msp430f5419a", MSP_ISA_430Xv2},
+  {"msp430f5435a", MSP_ISA_430Xv2},
+  {"msp430f5436a", MSP_ISA_430Xv2},
+  {"msp430f5437a", MSP_ISA_430Xv2},
+  {"msp430f5438a", MSP_ISA_430Xv2},
+  {"msp430f5212", MSP_ISA_430Xv2},
+  {"msp430f5213", MSP_ISA_430Xv2},
+  {"msp430f5214", MSP_ISA_430Xv2},
+  {"msp430f5217", MSP_ISA_430Xv2},
+  {"msp430f5218", MSP_ISA_430Xv2},
+  {"msp430f5219", MSP_ISA_430Xv2},
+  {"msp430f5222", MSP_ISA_430Xv2},
+  {"msp430f5223", MSP_ISA_430Xv2},
+  {"msp430f5224", MSP_ISA_430Xv2},
+  {"msp430f5227", MSP_ISA_430Xv2},
+  {"msp430f5228", MSP_ISA_430Xv2},
+  {"msp430f5229", MSP_ISA_430Xv2},
+  {"msp430f5304", MSP_ISA_430Xv2},
+  {"msp430f5308", MSP_ISA_430Xv2},
+  {"msp430f5309", MSP_ISA_430Xv2},
+  {"msp430f5310", MSP_ISA_430Xv2},
+  {"msp430f5340", MSP_ISA_430Xv2},
+  {"msp430f5341", MSP_ISA_430Xv2},
+  {"msp430f5342", MSP_ISA_430Xv2},
+  {"msp430f5324", MSP_ISA_430Xv2},
+  {"msp430f5325", MSP_ISA_430Xv2},
+  {"msp430f5326", MSP_ISA_430Xv2},
+  {"msp430f5327", MSP_ISA_430Xv2},
+  {"msp430f5328", MSP_ISA_430Xv2},
+  {"msp430f5329", MSP_ISA_430Xv2},
+  {"msp430f5500", MSP_ISA_430Xv2},
+  {"msp430f5501", MSP_ISA_430Xv2},
+  {"msp430f5502", MSP_ISA_430Xv2},
+  {"msp430f5503", MSP_ISA_430Xv2},
+  {"msp430f5504", MSP_ISA_430Xv2},
+  {"msp430f5505", MSP_ISA_430Xv2},
+  {"msp430f5506", MSP_ISA_430Xv2},
+  {"msp430f5507", MSP_ISA_430Xv2},
+  {"msp430f5508", MSP_ISA_430Xv2},
+  {"msp430f5509", MSP_ISA_430Xv2},
+  {"msp430f5510", MSP_ISA_430Xv2},
+  {"msp430f5513", MSP_ISA_430Xv2},
+  {"msp430f5514", MSP_ISA_430Xv2},
+  {"msp430f5515", MSP_ISA_430Xv2},
+  {"msp430f5517", MSP_ISA_430Xv2},
+  {"msp430f5519", MSP_ISA_430Xv2},
+  {"msp430f5521", MSP_ISA_430Xv2},
+  {"msp430f5522", MSP_ISA_430Xv2},
+  {"msp430f5524", MSP_ISA_430Xv2},
+  {"msp430f5525", MSP_ISA_430Xv2},
+  {"msp430f5526", MSP_ISA_430Xv2},
+  {"msp430f5527", MSP_ISA_430Xv2},
+  {"msp430f5528", MSP_ISA_430Xv2},
+  {"msp430f5529", MSP_ISA_430Xv2},
+  {"cc430f5133", MSP_ISA_430Xv2},
+  {"cc430f5135", MSP_ISA_430Xv2},
+  {"cc430f5137", MSP_ISA_430Xv2},
+  {"cc430f6125", MSP_ISA_430Xv2},
+  {"cc430f6126", MSP_ISA_430Xv2},
+  {"cc430f6127", MSP_ISA_430Xv2},
+  {"cc430f6135", MSP_ISA_430Xv2},
+  {"cc430f6137", MSP_ISA_430Xv2},
+  {"cc430f5123", MSP_ISA_430Xv2},
+  {"cc430f5125", MSP_ISA_430Xv2},
+  {"cc430f5143", MSP_ISA_430Xv2},
+  {"cc430f5145", MSP_ISA_430Xv2},
+  {"cc430f5147", MSP_ISA_430Xv2},
+  {"cc430f6143", MSP_ISA_430Xv2},
+  {"cc430f6145", MSP_ISA_430Xv2},
+  {"cc430f6147", MSP_ISA_430Xv2},
+  {"msp430f5333", MSP_ISA_430Xv2},
+  {"msp430f5335", MSP_ISA_430Xv2},
+  {"msp430f5336", MSP_ISA_430Xv2},
+  {"msp430f5338", MSP_ISA_430Xv2},
+  {"msp430f5630", MSP_ISA_430Xv2},
+  {"msp430f5631", MSP_ISA_430Xv2},
+  {"msp430f5632", MSP_ISA_430Xv2},
+  {"msp430f5633", MSP_ISA_430Xv2},
+  {"msp430f5634", MSP_ISA_430Xv2},
+  {"msp430f5635", MSP_ISA_430Xv2},
+  {"msp430f5636", MSP_ISA_430Xv2},
+  {"msp430f5637", MSP_ISA_430Xv2},
+  {"msp430f5638", MSP_ISA_430Xv2},
+  {"msp430f6433", MSP_ISA_430Xv2},
+  {"msp430f6435", MSP_ISA_430Xv2},
+  {"msp430f6436", MSP_ISA_430Xv2},
+  {"msp430f6438", MSP_ISA_430Xv2},
+  {"msp430f6630", MSP_ISA_430Xv2},
+  {"msp430f6631", MSP_ISA_430Xv2},
+  {"msp430f6632", MSP_ISA_430Xv2},
+  {"msp430f6633", MSP_ISA_430Xv2},
+  {"msp430f6634", MSP_ISA_430Xv2},
+  {"msp430f6635", MSP_ISA_430Xv2},
+  {"msp430f6636", MSP_ISA_430Xv2},
+  {"msp430f6637", MSP_ISA_430Xv2},
+  {"msp430f6638", MSP_ISA_430Xv2},
+  {"msp430f5358", MSP_ISA_430Xv2},
+  {"msp430f5359", MSP_ISA_430Xv2},
+  {"msp430f5658", MSP_ISA_430Xv2},
+  {"msp430f5659", MSP_ISA_430Xv2},
+  {"msp430f6458", MSP_ISA_430Xv2},
+  {"msp430f6459", MSP_ISA_430Xv2},
+  {"msp430f6658", MSP_ISA_430Xv2},
+  {"msp430f6659", MSP_ISA_430Xv2},
+  {"msp430f5131", MSP_ISA_430Xv2},
+  {"msp430f5151", MSP_ISA_430Xv2},
+  {"msp430f5171", MSP_ISA_430Xv2},
+  {"msp430f5132", MSP_ISA_430Xv2},
+  {"msp430f5152", MSP_ISA_430Xv2},
+  {"msp430f5172", MSP_ISA_430Xv2},
+  {"msp430f6720", MSP_ISA_430Xv2},
+  {"msp430f6721", MSP_ISA_430Xv2},
+  {"msp430f6723", MSP_ISA_430Xv2},
+  {"msp430f6724", MSP_ISA_430Xv2},
+  {"msp430f6725", MSP_ISA_430Xv2},
+  {"msp430f6726", MSP_ISA_430Xv2},
+  {"msp430f6730", MSP_ISA_430Xv2},
+  {"msp430f6731", MSP_ISA_430Xv2},
+  {"msp430f6733", MSP_ISA_430Xv2},
+  {"msp430f6734", MSP_ISA_430Xv2},
+  {"msp430f6735", MSP_ISA_430Xv2},
+  {"msp430f6736", MSP_ISA_430Xv2},
+  {"msp430f67451", MSP_ISA_430Xv2},
+  {"msp430f67651", MSP_ISA_430Xv2},
+  {"msp430f67751", MSP_ISA_430Xv2},
+  {"msp430f67461", MSP_ISA_430Xv2},
+  {"msp430f67661", MSP_ISA_430Xv2},
+  {"msp430f67761", MSP_ISA_430Xv2},
+  {"msp430f67471", MSP_ISA_430Xv2},
+  {"msp430f67671", MSP_ISA_430Xv2},
+  {"msp430f67771", MSP_ISA_430Xv2},
+  {"msp430f67481", MSP_ISA_430Xv2},
+  {"msp430f67681", MSP_ISA_430Xv2},
+  {"msp430f67781", MSP_ISA_430Xv2},
+  {"msp430f67491", MSP_ISA_430Xv2},
+  {"msp430f67691", MSP_ISA_430Xv2},
+  {"msp430f67791", MSP_ISA_430Xv2},
+  {"msp430f6745", MSP_ISA_430Xv2},
+  {"msp430f6765", MSP_ISA_430Xv2},
+  {"msp430f6775", MSP_ISA_430Xv2},
+  {"msp430f6746", MSP_ISA_430Xv2},
+  {"msp430f6766", MSP_ISA_430Xv2},
+  {"msp430f6776", MSP_ISA_430Xv2},
+  {"msp430f6747", MSP_ISA_430Xv2},
+  {"msp430f6767", MSP_ISA_430Xv2},
+  {"msp430f6777", MSP_ISA_430Xv2},
+  {"msp430f6748", MSP_ISA_430Xv2},
+  {"msp430f6768", MSP_ISA_430Xv2},
+  {"msp430f6778", MSP_ISA_430Xv2},
+  {"msp430f6749", MSP_ISA_430Xv2},
+  {"msp430f6769", MSP_ISA_430Xv2},
+  {"msp430f6779", MSP_ISA_430Xv2},
+  {"msp430fr5720", MSP_ISA_430Xv2},
+  {"msp430fr5721", MSP_ISA_430Xv2},
+  {"msp430fr5722", MSP_ISA_430Xv2},
+  {"msp430fr5723", MSP_ISA_430Xv2},
+  {"msp430fr5724", MSP_ISA_430Xv2},
+  {"msp430fr5725", MSP_ISA_430Xv2},
+  {"msp430fr5726", MSP_ISA_430Xv2},
+  {"msp430fr5727", MSP_ISA_430Xv2},
+  {"msp430fr5728", MSP_ISA_430Xv2},
+  {"msp430fr5729", MSP_ISA_430Xv2},
+  {"msp430fr5730", MSP_ISA_430Xv2},
+  {"msp430fr5731", MSP_ISA_430Xv2},
+  {"msp430fr5732", MSP_ISA_430Xv2},
+  {"msp430fr5733", MSP_ISA_430Xv2},
+  {"msp430fr5734", MSP_ISA_430Xv2},
+  {"msp430fr5735", MSP_ISA_430Xv2},
+  {"msp430fr5736", MSP_ISA_430Xv2},
+  {"msp430fr5737", MSP_ISA_430Xv2},
+  {"msp430fr5738", MSP_ISA_430Xv2},
+  {"msp430fr5739", MSP_ISA_430Xv2},
+  {"msp430bt5190", MSP_ISA_430Xv2},
+  {"msp430fr5949", MSP_ISA_430Xv2},
+  {"msp430fr5969", MSP_ISA_430Xv2},
+  {"msp430sl5438a", MSP_ISA_430Xv2},
 
-  {"msp430x155",  MSP430_ISA_15, bfd_mach_msp15},
-  {"msp430x156",  MSP430_ISA_15, bfd_mach_msp15},
-  {"msp430x157",  MSP430_ISA_15, bfd_mach_msp15},
-  {"msp430x167",  MSP430_ISA_16, bfd_mach_msp16},
-  {"msp430x168",  MSP430_ISA_16, bfd_mach_msp16},
-  {"msp430x169",  MSP430_ISA_16, bfd_mach_msp16},
-  {"msp430x1610", MSP430_ISA_16, bfd_mach_msp16},
-  {"msp430x1611", MSP430_ISA_16, bfd_mach_msp16},
-  {"msp430x1612", MSP430_ISA_16, bfd_mach_msp16},
-
-  {"msp430x2101", MSP430_ISA_21, bfd_mach_msp21},
-  {"msp430x2111", MSP430_ISA_21, bfd_mach_msp21},
-  {"msp430x2121", MSP430_ISA_21, bfd_mach_msp21},
-  {"msp430x2131", MSP430_ISA_21, bfd_mach_msp21},
-  
-  {"msp430x311",  MSP430_ISA_31, bfd_mach_msp31},
-  {"msp430x312",  MSP430_ISA_31, bfd_mach_msp31},
-  {"msp430x313",  MSP430_ISA_31, bfd_mach_msp31},
-  {"msp430x314",  MSP430_ISA_31, bfd_mach_msp31},
-  {"msp430x315",  MSP430_ISA_31, bfd_mach_msp31},
-  {"msp430x323",  MSP430_ISA_32, bfd_mach_msp32},
-  {"msp430x325",  MSP430_ISA_32, bfd_mach_msp32},
-  {"msp430x336",  MSP430_ISA_33, bfd_mach_msp33},
-  {"msp430x337",  MSP430_ISA_33, bfd_mach_msp33},
-
-  {"msp430x412",  MSP430_ISA_41, bfd_mach_msp41},
-  {"msp430x413",  MSP430_ISA_41, bfd_mach_msp41},
-  {"msp430x415",  MSP430_ISA_41, bfd_mach_msp41},
-  {"msp430x417",  MSP430_ISA_41, bfd_mach_msp41},
-
-  {"msp430xE423", MSP430_ISA_42, bfd_mach_msp42},
-  {"msp430xE425", MSP430_ISA_42, bfd_mach_msp42},
-  {"msp430xE427", MSP430_ISA_42, bfd_mach_msp42},
-
-  {"msp430xW423", MSP430_ISA_42, bfd_mach_msp42},
-  {"msp430xW425", MSP430_ISA_42, bfd_mach_msp42},
-  {"msp430xW427", MSP430_ISA_42, bfd_mach_msp42},
-
-  {"msp430xG437", MSP430_ISA_43, bfd_mach_msp43},
-  {"msp430xG438", MSP430_ISA_43, bfd_mach_msp43},
-  {"msp430xG439", MSP430_ISA_43, bfd_mach_msp43},
-
-  {"msp430x435",  MSP430_ISA_43, bfd_mach_msp43},
-  {"msp430x436",  MSP430_ISA_43, bfd_mach_msp43},
-  {"msp430x437",  MSP430_ISA_43, bfd_mach_msp43},
-  {"msp430x447",  MSP430_ISA_44, bfd_mach_msp44},
-  {"msp430x448",  MSP430_ISA_44, bfd_mach_msp44},
-  {"msp430x449",  MSP430_ISA_44, bfd_mach_msp44},
-
-  {NULL, 0, 0}
+  /* Generic names.  */
+  {"msp430",    MSP_ISA_430},
+  {"msp430X",   MSP_ISA_430X},
+  {"msp430Xv2", MSP_ISA_430Xv2},
+    
+  {NULL, 0}
 };
 
-
-static struct mcu_type_s default_mcu =
-    { "msp430x11", MSP430_ISA_11, bfd_mach_msp11 };
+static struct mcu_type_s default_mcu   = { "msp430x11", MSP_ISA_430 };
+static struct mcu_type_s msp430x_mcu   = { "msp430x",   MSP_ISA_430X };
+static struct mcu_type_s msp430xv2_mcu = { "msp430xv2", MSP_ISA_430Xv2 };
 
 static struct mcu_type_s * msp430_mcu = & default_mcu;
 
+static inline bfd_boolean
+target_is_430x (void)
+{
+  return msp430_mcu->isa >= MSP_ISA_430X;
+}
+
+static inline bfd_boolean
+target_is_430xv2 (void)
+{
+  return msp430_mcu->isa == MSP_ISA_430Xv2;
+}
+
+/* Generate a 16-bit relocation.
+   For the 430X we generate a relocation without linkwer range checking
+   if the value is being used in an extended (ie 20-bit) instruction.
+   For the 430 we generate a relocation without assembler range checking
+   if we are handling an immediate value or a byte-width instruction.  */
+#undef  CHECK_RELOC_MSP430
+#define CHECK_RELOC_MSP430				     \
+  (target_is_430x ()					     \
+   ? (extended_op ? BFD_RELOC_16 : BFD_RELOC_MSP430X_ABS16)  \
+   : ((imm_op || byte_op)				     \
+      ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
+
+/* Generate a 16-bit pc-relative relocation.
+   For the 430X we generate a relocation without linkwer range checking.
+   For the 430 we generate a relocation without assembler range checking
+   if we are handling an immediate value or a byte-width instruction.  */
+#undef  CHECK_RELOC_MSP430_PCREL
+#define CHECK_RELOC_MSP430_PCREL			     \
+  (target_is_430x ()					     \
+   ? BFD_RELOC_MSP430X_PCR16				     \
+   : (imm_op || byte_op)				     \
+   ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
+
 /* Profiling capability:
    It is a performance hit to use gcc's profiling approach for this tiny target.
    Even more -- jtag hardware facility does not perform any profiling functions.
@@ -699,16 +1118,22 @@
 #define OPTION_MMCU 'm'
 #define OPTION_RELAX 'Q'
 #define OPTION_POLYMORPHS 'P'
+#define OPTION_LARGE 'l'
+static bfd_boolean large_model = FALSE;
+#define OPTION_NO_INTR_NOPS 'N'
+static bfd_boolean gen_interrupt_nops = TRUE;
+#define OPTION_MCPU 'c'
 
 static void
-msp430_set_arch (int dummy ATTRIBUTE_UNUSED)
+msp430_set_arch (int option)
 {
   char *str = (char *) alloca (32);	/* 32 for good measure.  */
 
   input_line_pointer = extract_word (input_line_pointer, str, 32);
 
-  md_parse_option (OPTION_MMCU, str);
-  bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
+  md_parse_option (option, str);
+  bfd_set_arch_mach (stdoutput, TARGET_ARCH,
+		     target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
 }
 
 static void
@@ -719,7 +1144,11 @@
   fprintf (stream, _("Known MCU names:\n"));
 
   for (i = 0; mcu_types[i].name; i++)
-    fprintf (stream, _("\t %s\n"), mcu_types[i].name);
+    {
+      fprintf (stream, "%14.14s", mcu_types[i].name);
+      if ((i % 6) == 5)
+	fprintf (stream, "\n");
+    }
 
   fprintf (stream, "\n");
 }
@@ -732,33 +1161,55 @@
   switch (c)
     {
     case OPTION_MMCU:
+      if (arg == NULL)
+	as_fatal (_("MCU option requires a name\n"));
+
       for (i = 0; mcu_types[i].name; ++i)
-	if (strcmp (mcu_types[i].name, arg) == 0)
+	if (strcasecmp (mcu_types[i].name, arg) == 0)
 	  break;
 
-      if (!mcu_types[i].name)
+      if (mcu_types[i].name == NULL)
 	{
 	  show_mcu_list (stderr);
 	  as_fatal (_("unknown MCU: %s\n"), arg);
 	}
 
-      if (msp430_mcu == &default_mcu || msp430_mcu->mach == mcu_types[i].mach)
-	msp430_mcu = &mcu_types[i];
+      /* Allow switching to the same or a lesser architecture.  */
+      if (msp430_mcu == &default_mcu || msp430_mcu->isa >= mcu_types[i].isa)
+	msp430_mcu = mcu_types + i;
       else
-	as_fatal (_("redefinition of mcu type %s' to %s'"),
+	as_fatal (_("redefinition of mcu type '%s' to '%s'"),
 		  msp430_mcu->name, mcu_types[i].name);
       return 1;
-      break;
+
+    case OPTION_MCPU:
+      if (strcmp (arg, "430") == 0)
+	msp430_mcu = & default_mcu;
+      else if (strcmp (arg, "430x") == 0
+	       || strcmp (arg, "430X") == 0)
+	msp430_mcu = & msp430x_mcu;
+      else if (strcasecmp (arg, "430xv2") == 0)
+	msp430_mcu = & msp430xv2_mcu;
+      else
+	as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg);
+
+      return 1;
       
     case OPTION_RELAX:
-      msp430_enable_relax = 1; 
+      msp430_enable_relax = 1;
       return 1;
-      break;
-      
+
     case OPTION_POLYMORPHS:
       msp430_enable_polys = 1;
       return 1;
-      break;
+
+    case OPTION_LARGE:
+      large_model = TRUE;
+      return 1;
+
+    case OPTION_NO_INTR_NOPS:
+      gen_interrupt_nops = FALSE;
+      return 1;
     }
 
   return 0;
@@ -767,18 +1218,22 @@
 
 const pseudo_typeS md_pseudo_table[] =
 {
-  {"arch", msp430_set_arch, 0},
+  {"arch", msp430_set_arch, OPTION_MMCU},
+  {"cpu", msp430_set_arch, OPTION_MCPU},
   {"profiler", msp430_profiler, 0},
   {NULL, NULL, 0}
 };
 
-const char *md_shortopts = "m:";
+const char *md_shortopts = "mm:,mP,mQ,ml,mN";
 
 struct option md_longopts[] =
 {
   {"mmcu", required_argument, NULL, OPTION_MMCU},
+  {"mcpu", required_argument, NULL, OPTION_MCPU},
   {"mP", no_argument, NULL, OPTION_POLYMORPHS},
   {"mQ", no_argument, NULL, OPTION_RELAX},
+  {"ml", no_argument, NULL, OPTION_LARGE},
+  {"mN", no_argument, NULL, OPTION_NO_INTR_NOPS},
   {NULL, no_argument, NULL, 0}
 };
 
@@ -789,30 +1244,15 @@
 {
   fprintf (stream,
 	   _("MSP430 options:\n"
-	     "  -mmcu=[msp430-name] select microcontroller type\n"
-	     "                  msp430x110  msp430x112\n"
-	     "                  msp430x1101 msp430x1111\n"
-	     "                  msp430x1121 msp430x1122 msp430x1132\n"
-	     "                  msp430x122  msp430x123\n"
-	     "                  msp430x1222 msp430x1232\n"
-	     "                  msp430x133  msp430x135\n"
-	     "                  msp430x1331 msp430x1351\n"
-	     "                  msp430x147  msp430x148  msp430x149\n"
-	     "                  msp430x155  msp430x156  msp430x157\n"
-	     "                  msp430x167  msp430x168  msp430x169\n"
-	     "                  msp430x1610 msp430x1611 msp430x1612\n"
-	     "                  msp430x311  msp430x312  msp430x313  msp430x314  msp430x315\n"
-	     "                  msp430x323  msp430x325\n"
-	     "                  msp430x336  msp430x337\n"
-	     "                  msp430x412  msp430x413  msp430x415  msp430x417\n"
-	     "                  msp430xE423 msp430xE425 msp430E427\n"
-	     "                  msp430xW423 msp430xW425 msp430W427\n"
-	     "                  msp430xG437 msp430xG438 msp430G439\n"
-	     "                  msp430x435  msp430x436  msp430x437\n"
-	     "                  msp430x447  msp430x448  msp430x449\n"));
+	     "  -mmcu=<msp430-name>     - select microcontroller type\n"
+             "  -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
   fprintf (stream,
 	   _("  -mQ - enable relaxation at assembly time. DANGEROUS!\n"
 	     "  -mP - enable polymorph instructions\n"));
+  fprintf (stream,
+	   _("  -ml - enable large code model\n"));
+  fprintf (stream,
+	   _("  -mN - disable generation of NOP after changing interrupts\n"));
 
   show_mcu_list (stream);
 }
@@ -820,7 +1260,7 @@
 symbolS *
 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
 {
-  return 0;
+  return NULL;
 }
 
 static char *
@@ -855,34 +1295,53 @@
   for (opcode = msp430_opcodes; opcode->name; opcode++)
     hash_insert (msp430_hash, opcode->name, (char *) opcode);
 
-  bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
+  bfd_set_arch_mach (stdoutput, TARGET_ARCH,
+		     target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
 }
 
-static int
+/* Returns the register number equivalent to the string T.
+   Returns -1 if there is no such register.
+   Skips a leading 'r' or 'R' character if there is one.
+   Handles the register aliases PC and SP.  */
+
+static signed int
 check_reg (char * t)
 {
-  /* If this is a reg numb, str 't' must be a number from 0 - 15.  */
+  signed int val;
 
-  if (strlen (t) > 2 && *(t + 2) != '+')
+  if (t == NULL)
+    return -1;
+
+  if (*t == 'r' || *t == 'R')
+    ++t;
+
+  if (strncasecmp (t, "pc", 2) == 0)
+    return 0;
+
+  if (strncasecmp (t, "sp", 2) == 0)
     return 1;
 
-  while (*t)
-    {
-      if ((*t < '0' || *t > '9') && *t != '+')
-	break;
-      t++;
-    }
+  if (strncasecmp (t, "sr", 2) == 0)
+    return 2;
 
-  if (*t)
-    return 1;
+  if (*t == '0')
+    return 0;
 
-  return 0;
+  val = atoi (t);
+
+  if (val < 1 || val > 15)
+    return -1;
+
+  return val;
 }
 
-
 static int
 msp430_srcoperand (struct msp430_operand_s * op,
-		   char * l, int bin, int * imm_op)
+		   char * l,
+		   int bin,
+		   int * imm_op,
+		   bfd_boolean allow_20bit_values,
+		   bfd_boolean constants_allowed)
 {
   char *__tl = l;
 
@@ -963,7 +1422,15 @@
 	      x = op->exp.X_add_number;
 	    }
 
-	  if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
+	  if (allow_20bit_values)
+	    {
+	      if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < - (0x7ffff))
+		{
+		  as_bad (_("value 0x%x out of extended range."), x);
+		  return 1;
+		}
+	    }
+	  else if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
 	    {
 	      as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
 	      return 1;
@@ -972,9 +1439,12 @@
 	  /* Now check constants.  */
 	  /* Substitute register mode with a constant generator if applicable.  */
 
-	  x = (short) x;	/* Extend sign.  */
+	  if (!allow_20bit_values)
+	    x = (short) x;	/* Extend sign.  */
 
-	  if (x == 0)
+	  if (! constants_allowed)
+	    ;
+	  else if (x == 0)
 	    {
 	      op->reg = 3;
 	      op->am = 0;
@@ -1126,9 +1596,17 @@
 	{
 	  int x = op->exp.X_add_number;
 
-	  if (x > 65535 || x < -32768)
+	  if (allow_20bit_values)
 	    {
-	      as_bad (_("value out of range: %d"), x);
+	      if (x > 0xfffff || x < -(0x7ffff))
+		{
+		  as_bad (_("value 0x%x out of extended range."), x);
+		  return 1;
+		}
+	    }
+	  else if (x > 65535 || x < -32768)
+	    {
+	      as_bad (_("value out of range: 0x%x"), x);
 	      return 1;
 	    }
 	}
@@ -1160,31 +1638,16 @@
 	}
 
       t++;
-      if (*t != 'r' && *t != 'R')
-	{
-	  as_bad (_("unknown addressing mode %s"), l);
-	  return 1;
-	}
 
-      t++;	/* Points to the reg value.  */
-
-      if (check_reg (t))
+      if ((op->reg = check_reg (t)) == -1)
 	{
-	  as_bad (_("Bad register name r%s"), t);
+	  as_bad (_("Bad register name %s"), t);
 	  return 1;
 	}
 
       op->mode = OP_REG;
       op->am = m ? 3 : 2;
       op->ol = 0;
-      if (m)
-	*m = 0;			/* strip '+' */
-      op->reg = atoi (t);
-      if (op->reg < 0 || op->reg > 15)
-	{
-	  as_bad (_("MSP430 does not have %d registers"), op->reg);
-	  return 1;
-	}
 
       return 0;
     }
@@ -1209,48 +1672,21 @@
       t = h;
       op->am = 1;
       op->ol = 1;
-      /* Extract a register.  */
-      t++;	/* Advance pointer.  */
 
-      if (*t != 'r' && *t != 'R')
+      /* Extract a register.  */
+      if ((op->reg = check_reg (t + 1)) == -1)
 	{
 	  as_bad (_
 		  ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
 		  l);
 	  return 1;
 	}
-      t++;
 
-      op->reg = *t - '0';
-      if (op->reg > 9 || op->reg < 0)
+      if (op->reg == 2)
 	{
-	  as_bad (_("unknown operator (r%s substituted as a register name"),
-		  t);
+	  as_bad (_("r2 should not be used in indexed addressing mode"));
 	  return 1;
 	}
-      t++;
-      if (*t != ')')
-	{
-	  op->reg = op->reg * 10;
-	  op->reg += *t - '0';
-
-	  if (op->reg > 15)
-	    {
-	      as_bad (_("unknown operator %s"), l);
-	      return 1;
-	    }
-	  if (op->reg == 2)
-	    {
-	      as_bad (_("r2 should not be used in indexed addressing mode"));
-	      return 1;
-	    }
-
-	  if (*(t + 1) != ')')
-	    {
-	      as_bad (_("unknown operator %s"), l);
-	      return 1;
-	    }
-	}
 
       /* Extract constant.  */
       __tl = l;
@@ -1261,9 +1697,17 @@
 	{
 	  int x = op->exp.X_add_number;
 
-	  if (x > 65535 || x < -32768)
+	  if (allow_20bit_values)
 	    {
-	      as_bad (_("value out of range: %d"), x);
+	      if (x > 0xfffff || x < - (0x7ffff))
+		{
+		  as_bad (_("value 0x%x out of extended range."), x);
+		  return 1;
+		}
+	    }
+	  else if (x > 65535 || x < -32768)
+	    {
+	      as_bad (_("value out of range: 0x%x"), x);
 	      return 1;
 	    }
 
@@ -1292,37 +1736,22 @@
     }
   while (0);
 
-  /* Register mode 'mov r1,r2'.  */
-  do
+  /* Possibly register mode 'mov r1,r2'.  */
+  if ((op->reg = check_reg (l)) != -1)
     {
-      char *t = l;
-
-      /* Operand should be a register.  */
-      if (*t == 'r' || *t == 'R')
-	{
-	  int x = atoi (t + 1);
-
-	  if (check_reg (t + 1))
-	    break;
-
-	  if (x < 0 || x > 15)
-	    break;		/* Symbolic mode.  */
-
-	  op->mode = OP_REG;
-	  op->am = 0;
-	  op->ol = 0;
-	  op->reg = x;
-	  return 0;
-	}
+      op->mode = OP_REG;
+      op->am = 0;
+      op->ol = 0;
+      return 0;
     }
-  while (0);
 
   /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'.  */
   do
     {
       op->mode = OP_EXP;
       op->reg = 0;		/* PC relative... be careful.  */
-      op->am = 1;
+      /* An expression starting with a minus sign is a constant, not an address.  */
+      op->am = (*l == '-' ? 3 : 1);
       op->ol = 1;
       __tl = l;
       parse_exp (__tl, &(op->exp));
@@ -1337,10 +1766,16 @@
 
 
 static int
-msp430_dstoperand (struct msp430_operand_s * op, char * l, int bin)
+msp430_dstoperand (struct msp430_operand_s * op,
+		   char * l,
+		   int bin,
+		   bfd_boolean allow_20bit_values,
+		   bfd_boolean constants_allowed)
 {
   int dummy;
-  int ret = msp430_srcoperand (op, l, bin, & dummy);
+  int ret = msp430_srcoperand (op, l, bin, & dummy,
+			       allow_20bit_values,
+			       constants_allowed);
 
   if (ret)
     return ret;
@@ -1373,6 +1808,267 @@
 }
 
 
+/* Attempt to encode a MOVA instruction with the given operands.
+   Returns the length of the encoded instruction if successful
+   or 0 upon failure.  If the encoding fails, an error message
+   will be returned if a pointer is provided.  */
+
+static int
+try_encode_mova (bfd_boolean imm_op,
+		 int bin,
+		 struct msp430_operand_s * op1,
+		 struct msp430_operand_s * op2,
+		 const char ** error_message_return)
+{
+  short ZEROS = 0;
+  char *frag;
+  int where;
+
+  /* Only a restricted subset of the normal MSP430 addressing modes
+     are supported here, so check for the ones that are allowed.  */
+  if (imm_op)
+    {
+      if (op1->mode == OP_EXP)
+	{
+	  if (op2->mode != OP_REG)
+	    {
+	      if (error_message_return != NULL)
+		* error_message_return = _("expected register as second argument of %s");
+	      return 0;
+	    }
+
+	  if (op1->am == 3)
+	    {
+	      /* MOVA #imm20, Rdst.  */
+	      bin |= 0x80 | op2->reg;
+	      frag = frag_more (4);
+	      where = frag - frag_now->fr_literal;
+	      if (op1->exp.X_op == O_constant)
+		{
+		  bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
+		  bfd_putl16 ((bfd_vma) bin, frag);
+		  bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
+		}
+	      else
+		{
+		  bfd_putl16 ((bfd_vma) bin, frag);
+		  fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
+			       BFD_RELOC_MSP430X_ABS20_ADR_SRC);
+		  bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+		}
+
+	      return 4;
+	    }
+	  else if (op1->am == 1)
+	    {
+	      /* MOVA z16(Rsrc), Rdst.  */
+	      bin |= 0x30 | (op1->reg << 8) | op2->reg;
+	      frag = frag_more (4);
+	      where = frag - frag_now->fr_literal;
+	      bfd_putl16 ((bfd_vma) bin, frag);
+	      if (op1->exp.X_op == O_constant)
+		{
+		  if (op1->exp.X_add_number > 0xffff
+		      || op1->exp.X_add_number < -(0x7fff))
+		    {
+		      if (error_message_return != NULL)
+			* error_message_return = _("index value too big for %s");
+		      return 0;
+		    }
+		  bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
+		}
+	      else
+		{
+		  bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+		  fix_new_exp (frag_now, where + 2, 2, &(op1->exp), FALSE,
+			       op1->reg == 0 ?
+			       BFD_RELOC_MSP430X_PCR16 :
+			       BFD_RELOC_MSP430X_ABS16);
+		}
+	      return 4;
+	    }
+
+	  if (error_message_return != NULL)
+	    * error_message_return = _("unexpected addressing mode for %s");
+	  return 0;
+	}
+      else if (op1->am == 0)
+	{
+	  /* MOVA Rsrc, ... */
+	  if (op2->mode == OP_REG)
+	    {
+	      bin |= 0xc0 | (op1->reg << 8) | op2->reg;
+	      frag = frag_more (2);
+	      where = frag - frag_now->fr_literal;
+	      bfd_putl16 ((bfd_vma) bin, frag);
+	      return 2;
+	    }
+	  else if (op2->am == 1)
+	    {
+	      if (op2->reg == 2)
+		{
+		  /* MOVA Rsrc, &abs20.  */
+		  bin |= 0x60 | (op1->reg << 8);
+		  frag = frag_more (4);
+		  where = frag - frag_now->fr_literal;
+		  if (op2->exp.X_op == O_constant)
+		    {
+		      bin |= (op2->exp.X_add_number >> 16) & 0xf;
+		      bfd_putl16 ((bfd_vma) bin, frag);
+		      bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
+		    }
+		  else
+		    {
+		      bfd_putl16 ((bfd_vma) bin, frag);
+		      bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+		      fix_new_exp (frag_now, where, 4, &(op2->exp), FALSE,
+				   BFD_RELOC_MSP430X_ABS20_ADR_DST);
+		    }
+		  return 4;
+		}
+
+	      /* MOVA Rsrc, z16(Rdst).  */
+	      bin |= 0x70 | (op1->reg << 8) | op2->reg;
+	      frag = frag_more (4);
+	      where = frag - frag_now->fr_literal;
+	      bfd_putl16 ((bfd_vma) bin, frag);
+	      if (op2->exp.X_op == O_constant)
+		{
+		  if (op2->exp.X_add_number > 0xffff
+		      || op2->exp.X_add_number < -(0x7fff))
+		    {
+		      if (error_message_return != NULL)
+			* error_message_return = _("index value too big for %s");
+		      return 0;
+		    }
+		  bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
+		}
+	      else
+		{
+		  bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+		  fix_new_exp (frag_now, where + 2, 2, &(op2->exp), FALSE,
+			       op2->reg == 0 ?
+			       BFD_RELOC_MSP430X_PCR16 :
+			       BFD_RELOC_MSP430X_ABS16);
+		}
+	      return 4;
+	    }
+
+	  if (error_message_return != NULL)
+	    * error_message_return = _("unexpected addressing mode for %s");
+	  return 0;
+	}
+    }
+
+  /* imm_op == FALSE.  */
+
+  if (op1->reg == 2 && op1->am == 1 && op1->mode == OP_EXP)
+    {
+      /* MOVA &abs20, Rdst.  */
+      if (op2->mode != OP_REG)
+	{
+	  if (error_message_return != NULL)
+	    * error_message_return = _("expected register as second argument of %s");
+	  return 0;
+	}
+
+      if (op2->reg == 2 || op2->reg == 3)
+	{
+	  if (error_message_return != NULL)
+	    * error_message_return = _("constant generator destination register found in %s");
+	  return 0;
+	}
+
+      bin |= 0x20 | op2->reg;
+      frag = frag_more (4);
+      where = frag - frag_now->fr_literal;
+      if (op1->exp.X_op == O_constant)
+	{
+	  bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
+	  bfd_putl16 ((bfd_vma) bin, frag);
+	  bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
+	}
+      else
+	{
+	  bfd_putl16 ((bfd_vma) bin, frag);
+	  bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+	  fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
+		       BFD_RELOC_MSP430X_ABS20_ADR_SRC);
+	}
+      return 4;
+    }
+  else if (op1->mode == OP_REG)
+    {
+      if (op1->am == 3)
+	{
+	  /* MOVA @Rsrc+, Rdst.  */
+	  if (op2->mode != OP_REG)
+	    {
+	      if (error_message_return != NULL)
+		* error_message_return = _("expected register as second argument of %s");
+	      return 0;
+	    }
+
+	  if (op2->reg == 2 || op2->reg == 3)
+	    {
+	      if (error_message_return != NULL)
+		* error_message_return = _("constant generator destination register found in %s");
+	      return 0;
+	    }
+
+	  if (op1->reg == 2 || op1->reg == 3)
+	    {
+	      if (error_message_return != NULL)
+		* error_message_return = _("constant generator source register found in %s");
+	      return 0;
+	    }
+
+	  bin |= 0x10 | (op1->reg << 8) | op2->reg;
+	  frag = frag_more (2);
+	  where = frag - frag_now->fr_literal;
+	  bfd_putl16 ((bfd_vma) bin, frag);
+	  return 2;
+	}
+      else if (op1->am == 2)
+	{
+	  /* MOVA @Rsrc,Rdst */
+	  if (op2->mode != OP_REG)
+	    {
+	      if (error_message_return != NULL)
+		* error_message_return = _("expected register as second argument of %s");
+	      return 0;
+	    }
+
+	  if (op2->reg == 2 || op2->reg == 3)
+	    {
+	      if (error_message_return != NULL)
+		* error_message_return = _("constant generator destination register found in %s");
+	      return 0;
+	    }
+
+	  if (op1->reg == 2 || op1->reg == 3)
+	    {
+	      if (error_message_return != NULL)
+		* error_message_return = _("constant generator source register found in %s");
+	      return 0;
+	    }
+
+	  bin |= (op1->reg << 8) | op2->reg;
+	  frag = frag_more (2);
+	  where = frag - frag_now->fr_literal;
+	  bfd_putl16 ((bfd_vma) bin, frag);
+	  return 2;
+	}
+    }
+
+  if (error_message_return != NULL)
+    * error_message_return = _("unexpected addressing mode for %s");
+
+  return 0;
+}
+
+#define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
+
 /* Parse instruction operands.
    Return binary opcode.  */
 
@@ -1380,7 +2076,7 @@
 msp430_operands (struct msp430_opcode_s * opcode, char * line)
 {
   int bin = opcode->bin_opcode;	/* Opcode mask.  */
-  int __is = 0;
+  int insn_length = 0;
   char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
   char *frag;
   int where;
@@ -1388,6 +2084,14 @@
   int res = 0;
   static short ZEROS = 0;
   int byte_op, imm_op;
+  int op_length = 0;
+  int fmt;
+  int extended = 0x1800;
+  bfd_boolean extended_op = FALSE;
+  bfd_boolean addr_op;
+  const char * error_message;
+  static signed int repeat_count = 0;
+  bfd_boolean fix_emitted;
 
   /* Opcode is the one from opcodes table
      line contains something like
@@ -1404,11 +2108,22 @@
   else
     byte_op = 0;
 
-  /* skip .[bwBW].  */
+  /* "Address" ops work on 20-bit values.  */
+  if (*line == '.' && TOLOWER (*(line + 1)) == 'a')
+    {
+      addr_op = TRUE;
+      bin |= BYTE_OPERATION;
+    }
+  else
+    addr_op = FALSE;
+
+  /* skip .[aAbwBW].  */
   while (! ISSPACE (*line) && *line)
     line++;
 
-  if (opcode->insn_opnumb && (!*line || *line == '\n'))
+  if (opcode->fmt != -1
+      && opcode->insn_opnumb
+      && (!*line || *line == '\n'))
     {
       as_bad (_("instruction %s requires %d operand(s)"),
 	      opcode->name, opcode->insn_opnumb);
@@ -1422,123 +2137,759 @@
 
   imm_op = 0;
 
-  switch (opcode->fmt)
+  if ((fmt = opcode->fmt) < 0)
+    {
+      if (! target_is_430x ())
+	{
+	  as_bad (_("instruction %s requires MSP430X mcu"),
+		  opcode->name);
+	  return 0;
+	}
+	
+      fmt = (-fmt) - 1;
+      extended_op = TRUE;
+    }
+
+  if (repeat_count)
+    {
+      /* If requested set the extended instruction repeat count.  */
+      if (extended_op)
+	{
+	  if (repeat_count > 0)
+	    extended |= (repeat_count - 1);
+	  else
+	    extended |= (1 << 7) | (- repeat_count);
+	}
+      else
+	as_bad (_("unable to repeat %s insn"), opcode->name);
+
+      repeat_count = 0;
+    }
+
+  switch (fmt)
     {
     case 0:			/* Emulated.  */
       switch (opcode->insn_opnumb)
 	{
 	case 0:
 	  /* Set/clear bits instructions.  */
-	  __is = 2;
-	  frag = frag_more (__is);
+	  if (extended_op)
+	    {
+	      if (!addr_op)
+		extended |= BYTE_OPERATION;
+
+	      /* Emit the extension word.  */
+	      insn_length += 2;
+	      frag = frag_more (insn_length);
+	      bfd_putl16 (extended, frag);
+	    }
+
+	  insn_length += 2;
+	  frag = frag_more (insn_length);
 	  bfd_putl16 ((bfd_vma) bin, frag);
-	  dwarf2_emit_insn (__is);
+
+	  if (gen_interrupt_nops
+	      && target_is_430xv2 ()
+	      && (is_opcode ("eint") || is_opcode ("dint")))
+	    {
+	      /* Emit a NOP following interrupt enable/disable.
+		 See 1.3.4.1 of the MSP430x5xx User Guide.  */
+	      insn_length += 2;
+	      frag = frag_more (2);
+	      bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
+	    }
+	  dwarf2_emit_insn (insn_length);
 	  break;
+
 	case 1:
 	  /* Something which works with destination operand.  */
 	  line = extract_operand (line, l1, sizeof (l1));
-	  res = msp430_dstoperand (&op1, l1, opcode->bin_opcode);
+	  res = msp430_dstoperand (&op1, l1, opcode->bin_opcode, extended_op, TRUE);
 	  if (res)
 	    break;
 
-	  bin |= (op1.reg | (op1.am << 7));
-	  __is = 1 + op1.ol;
-	  frag = frag_more (2 * __is);
+	  /* Compute the entire instruction length, in bytes.  */
+	  insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
+	  frag = frag_more (insn_length);
 	  where = frag - frag_now->fr_literal;
+	  
+	  if (extended_op)
+	    {
+	      if (!addr_op)
+		extended |= BYTE_OPERATION;
+
+	      if (op1.ol != 0 && ((extended & 0xf) != 0))
+		{
+		  as_bad (_("repeat instruction used with non-register mode instruction"));
+		  extended &= ~ 0xf;
+		}
+	      
+	      if (op1.mode == OP_EXP)
+		{
+		  if (op1.exp.X_op == O_constant)
+		    extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
+
+		  else if (op1.reg || (op1.reg == 0 && op1.am == 3))	/* Not PC relative.  */
+		    fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+				 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
+		  else
+		    fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+				 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
+		}
+	  
+	      /* Emit the extension word.  */
+	      bfd_putl16 (extended, frag);
+	      frag += 2;
+	      where += 2;
+	    }
+
+	  bin |= (op1.reg | (op1.am << 7));
 	  bfd_putl16 ((bfd_vma) bin, frag);
-	  dwarf2_emit_insn (2 * __is);
+	  frag += 2;
+	  where += 2;
 
 	  if (op1.mode == OP_EXP)
 	    {
-	      where += 2;
-	      bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
-
-	      if (op1.reg)
-		fix_new_exp (frag_now, where, 2,
-			     &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+	      if (op1.exp.X_op == O_constant)
+		{
+		  bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
+		}
 	      else
-		fix_new_exp (frag_now, where, 2,
-			     &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+		{
+		  bfd_putl16 ((bfd_vma) ZEROS, frag);
+
+		  if (!extended_op)
+		    {
+		      if (op1.reg)
+			fix_new_exp (frag_now, where, 2,
+				     &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+		      else
+			fix_new_exp (frag_now, where, 2,
+				     &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+		    }
+		}
 	    }
+
+	  if (gen_interrupt_nops
+	      && target_is_430xv2 ()
+	      && is_opcode ("clr")
+	      && bin == 0x4302 /* CLR R2*/)
+	    {
+	      /* Emit a NOP following interrupt enable/disable.
+		 See 1.3.4.1 of the MSP430x5xx User Guide.  */
+	      insn_length += 2;
+	      frag = frag_more (2);
+	      bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
+	    }
+
+	  dwarf2_emit_insn (insn_length);
 	  break;
 
 	case 2:
-	  {
-	    /* Shift instruction.  */
-	    line = extract_operand (line, l1, sizeof (l1));
-	    strncpy (l2, l1, sizeof (l2));
-	    l2[sizeof (l2) - 1] = '\0';
-	    res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
-	    res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
+	  /* Shift instruction.  */
+	  line = extract_operand (line, l1, sizeof (l1));
+	  strncpy (l2, l1, sizeof (l2));
+	  l2[sizeof (l2) - 1] = '\0';
+	  res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
+	  res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
 
-	    if (res)
-	      break;	/* An error occurred.  All warnings were done before.  */
+	  if (res)
+	    break;	/* An error occurred.  All warnings were done before.  */
 
-	    bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
+	  insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2) + (op2.ol * 2);
+	  frag = frag_more (insn_length);
+	  where = frag - frag_now->fr_literal;
 
-	    __is = 1 + op1.ol + op2.ol;	/* insn size in words.  */
-	    frag = frag_more (2 * __is);
-	    where = frag - frag_now->fr_literal;
-	    bfd_putl16 ((bfd_vma) bin, frag);
-	    dwarf2_emit_insn (2 * __is);
-	    
-	    if (op1.mode == OP_EXP)
-	      {
-		where += 2;	/* Advance 'where' as we do not know _where_.  */
-		bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+	  /* Issue 3831743.  */
+	  if (op1.mode == OP_REG
+	      && op1.reg == 0 
+	      && (is_opcode ("rlax")
+		  || is_opcode ("rlcx")
+		  || is_opcode ("rla")
+		  || is_opcode ("rlc")))
+	    {
+	      as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
+	      return 0;
+	    }
+	  
+	  if (extended_op)
+	    {
+	      if (!addr_op)
+		extended |= BYTE_OPERATION;
 
-		if (op1.reg || (op1.reg == 0 && op1.am == 3))	/* Not PC relative.  */
-		  fix_new_exp (frag_now, where, 2,
-			       &(op1.exp), FALSE, CHECK_RELOC_MSP430);
-		else
-		  fix_new_exp (frag_now, where, 2,
-			       &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
-	      }
+	      if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
+		{
+		  as_bad (_("repeat instruction used with non-register mode instruction"));
+		  extended &= ~ 0xf;
+		}
+	      
+	      if (op1.mode == OP_EXP)
+		{
+		  if (op1.exp.X_op == O_constant)
+		    extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
 
-	    if (op2.mode == OP_EXP)
-	      {
-		imm_op = 0;
-		bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
+		  else if (op1.reg || (op1.reg == 0 && op1.am == 3))	/* Not PC relative.  */
+		    fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+				 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
+		  else
+		    fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+				 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
+		}
 
-		if (op2.reg)	/* Not PC relative.  */
-		  fix_new_exp (frag_now, where + 2, 2,
-			       &(op2.exp), FALSE, CHECK_RELOC_MSP430);
-		else
-		  fix_new_exp (frag_now, where + 2, 2,
-			       &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
-	      }
-	    break;
-	  }
+	      if (op2.mode == OP_EXP)
+		{
+		  if (op2.exp.X_op == O_constant)
+		    extended |= (op2.exp.X_add_number >> 16) & 0xf;
+
+		  else if (op1.mode == OP_EXP)
+		    fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
+				 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
+				 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
+		  else
+		    fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
+				 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
+				 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
+		}
+
+	      /* Emit the extension word.  */
+	      bfd_putl16 (extended, frag);
+	      frag += 2;
+	      where += 2;
+	    }
+
+	  bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
+	  bfd_putl16 ((bfd_vma) bin, frag);
+	  frag += 2;
+	  where += 2;
+
+	  if (op1.mode == OP_EXP)
+	    {
+	      if (op1.exp.X_op == O_constant)
+		{
+		  bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
+		}
+	      else
+		{
+		  bfd_putl16 ((bfd_vma) ZEROS, frag);
+
+		  if (!extended_op)
+		    {
+		      if (op1.reg || (op1.reg == 0 && op1.am == 3))	/* Not PC relative.  */
+			fix_new_exp (frag_now, where, 2,
+				     &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+		      else
+			fix_new_exp (frag_now, where, 2,
+				     &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+		    }
+		}
+	      frag += 2;
+	      where += 2;
+	    }
+
+	  if (op2.mode == OP_EXP)
+	    {
+	      if (op2.exp.X_op == O_constant)
+		{
+		  bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
+		}
+	      else
+		{
+		  bfd_putl16 ((bfd_vma) ZEROS, frag);
+
+		  if (!extended_op)
+		    {
+		      if (op2.reg)	/* Not PC relative.  */
+			fix_new_exp (frag_now, where, 2,
+				     &(op2.exp), FALSE, CHECK_RELOC_MSP430);
+		      else
+			fix_new_exp (frag_now, where, 2,
+				     &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+		    }
+		}
+	    }
+
+	  dwarf2_emit_insn (insn_length);
+	  break;
+
 	case 3:
 	  /* Branch instruction => mov dst, r0.  */
-	  line = extract_operand (line, l1, sizeof (l1));
+	  if (extended_op)
+	    {
+	      as_bad ("Internal error: state 0/3 not coded for extended instructions");
+	      return 0;
+	    }
 
-	  res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
+	  line = extract_operand (line, l1, sizeof (l1));
+	  res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, FALSE);
 	  if (res)
 	    break;
 
 	  byte_op = 0;
 	  imm_op = 0;
-
 	  bin |= ((op1.reg << 8) | (op1.am << 4));
-	  __is = 1 + op1.ol;
-	  frag = frag_more (2 * __is);
+	  op_length = 2 + 2 * op1.ol;
+	  frag = frag_more (op_length);
 	  where = frag - frag_now->fr_literal;
 	  bfd_putl16 ((bfd_vma) bin, frag);
-	  dwarf2_emit_insn (2 * __is);
 
 	  if (op1.mode == OP_EXP)
 	    {
-	      where += 2;
+	      if (op1.exp.X_op == O_constant)
+		{
+		  bfd_putl16 (op1.exp.X_add_number & 0xffff, frag + 2);
+		}
+	      else
+		{
+		  where += 2;
+	      
+		  bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+
+		  if (op1.reg || (op1.reg == 0 && op1.am == 3))
+		    fix_new_exp (frag_now, where, 2,
+				 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+		  else
+		    fix_new_exp (frag_now, where, 2,
+				 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+		}
+	    }
+
+	  dwarf2_emit_insn (insn_length + op_length);
+	  break;
+
+	case 4:
+	  /* CALLA instructions.  */
+	  fix_emitted = FALSE;
+
+	  line = extract_operand (line, l1, sizeof (l1));
+	  imm_op = 0;
+
+	  res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op,
+				   extended_op, FALSE);
+	  if (res)
+	    break;
+
+	  byte_op = 0;
+
+	  op_length = 2 + 2 * op1.ol;
+	  frag = frag_more (op_length);
+	  where = frag - frag_now->fr_literal;
+
+	  if (imm_op)
+	    {
+	      if (op1.am == 3)
+		{
+		  bin |= 0xb0;
+
+		  fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
+			       BFD_RELOC_MSP430X_ABS20_ADR_DST);
+		  fix_emitted = TRUE;
+		}
+	      else if (op1.am == 1)
+		{
+		  if (op1.reg == 0)
+		    {
+		      bin |=  0x90;
+
+		      fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
+				   BFD_RELOC_MSP430X_PCR20_CALL);
+		      fix_emitted = TRUE;
+		    }
+		  else
+		    bin |=  0x50 | op1.reg;
+		}
+	      else if (op1.am == 0)
+		bin |= 0x40 | op1.reg;
+	    }
+	  else if (op1.am == 1)
+	    {
+	      bin |= 0x80;
+
+	      fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
+			   BFD_RELOC_MSP430X_ABS20_ADR_DST);
+	      fix_emitted = TRUE;
+	    }
+	  else if (op1.am == 2)
+	    bin |= 0x60 | op1.reg;
+	  else if (op1.am == 3)
+	    bin |= 0x70 | op1.reg;
+	  
+	  bfd_putl16 ((bfd_vma) bin, frag);
+
+	  if (op1.mode == OP_EXP)
+	    {
+	      if (op1.ol != 1)
+		{
+		  as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
+		  return 0;
+		}
+
 	      bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
 
-	      if (op1.reg || (op1.reg == 0 && op1.am == 3))
-		fix_new_exp (frag_now, where, 2,
-			     &(op1.exp), FALSE, CHECK_RELOC_MSP430);
-	      else
-		fix_new_exp (frag_now, where, 2,
-			     &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+	      if (! fix_emitted)
+		fix_new_exp (frag_now, where + 2, 2,
+			     &(op1.exp), FALSE, BFD_RELOC_16);
 	    }
+
+	  dwarf2_emit_insn (insn_length + op_length);
+	  break;
+
+	case 5:
+	  {
+	    int n;
+	    int reg;
+
+	    /* [POP|PUSH]M[.A] #N, Rd */
+	    line = extract_operand (line, l1, sizeof (l1));
+	    line = extract_operand (line, l2, sizeof (l2));
+
+	    if (*l1 != '#')
+	      {
+		as_bad (_("expected #n as first argument of %s"), opcode->name);
+		return 0;
+	      }
+	    parse_exp (l1 + 1, &(op1.exp));
+	    if (op1.exp.X_op != O_constant)
+	      {
+		as_bad (_("expected constant expression for first argument of %s"),
+			opcode->name);
+		return 0;
+	      }
+
+	    if ((reg = check_reg (l2)) == -1)
+	      {
+		as_bad (_("expected register as second argument of %s"),
+			opcode->name);
+		return 0;
+	      }
+
+	    op_length = 2;
+	    frag = frag_more (op_length);
+	    where = frag - frag_now->fr_literal;
+	    bin = opcode->bin_opcode;
+	    if (! addr_op)
+	      bin |= 0x100;
+	    n = op1.exp.X_add_number;
+	    bin |= (n - 1) << 4;
+	    if (is_opcode ("pushm"))
+	      bin |= reg;
+	    else
+	      {
+		if (reg - n + 1 < 0)
+		  {
+		    as_bad (_("Too many registers popped"));
+		    return 0;
+		  }
+
+		/* Issue 3831713:  CPU21 parts cannot use POPM to restore the SR register.  */
+		if (target_is_430x ()
+		    && (reg - n + 1 < 3)
+		    && reg >= 2
+		    && is_opcode ("popm"))
+		  {
+		    as_bad (_("Cannot use POPM to restore the SR register"));
+		    return 0;
+		  }
+
+		bin |= (reg - n + 1);
+	      }
+
+	    bfd_putl16 ((bfd_vma) bin, frag);
+	    dwarf2_emit_insn (op_length);
+	    break;
+	  }
+
+	case 6:
+	  {
+	    int n;
+	    int reg;
+
+	    /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM.  */
+	    if (extended & 0xff)
+	      {
+		as_bad (_("repeat count cannot be used with %s"), opcode->name);
+		return 0;
+	      }
+
+	    line = extract_operand (line, l1, sizeof (l1));
+	    line = extract_operand (line, l2, sizeof (l2));
+
+	    if (*l1 != '#')
+	      {
+		as_bad (_("expected #n as first argument of %s"), opcode->name);
+		return 0;
+	      }
+	    parse_exp (l1 + 1, &(op1.exp));
+	    if (op1.exp.X_op != O_constant)
+	      {
+		as_bad (_("expected constant expression for first argument of %s"),
+			opcode->name);
+		return 0;
+	      }
+	    n = op1.exp.X_add_number;
+	    if (n > 4 || n < 1)
+	      {
+		as_bad (_("expected first argument of %s to be in the range 1-4"),
+			opcode->name);
+		return 0;
+	      }
+
+	    if ((reg = check_reg (l2)) == -1)
+	      {
+		as_bad (_("expected register as second argument of %s"),
+			opcode->name);
+		return 0;
+	      }
+
+	    /* Issue 3831743.  */
+	    if (reg == 0)
+	      {
+		as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
+		return 0;
+	      }
+
+	    op_length = 2;
+	    frag = frag_more (op_length);
+	    where = frag - frag_now->fr_literal;
+
+	    bin = opcode->bin_opcode;
+	    if (! addr_op)
+	      bin |= 0x10;
+	    bin |= (n - 1) << 10;
+	    bin |= reg;
+
+	    bfd_putl16 ((bfd_vma) bin, frag);
+	    dwarf2_emit_insn (op_length);
+	    break;
+	  }
+
+	case 7:
+	  {
+	    int reg;
+
+	    /* RRUX: Synthetic unsigned right shift of a register by one bit.  */
+	    if (extended & 0xff)
+	      {
+		as_bad (_("repeat count cannot be used with %s"), opcode->name);
+		return 0;
+	      }
+
+	    line = extract_operand (line, l1, sizeof (l1));
+	    if ((reg = check_reg (l1)) == -1)
+	      {
+		as_bad (_("expected register as argument of %s"),
+			opcode->name);
+		return 0;
+	      }
+
+	    /* Issue 3831743.  */
+	    if (reg == 0)
+	      {
+		as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
+		return 0;
+	      }
+
+	    if (byte_op)
+	      {
+		/* Tricky - there is no single instruction that will do this.
+		   Encode as: RRA.B rN { BIC.B #0x80, rN  */
+		op_length = 6;
+		frag = frag_more (op_length);
+		where = frag - frag_now->fr_literal;
+		bin = 0x1140 | reg;
+		bfd_putl16 ((bfd_vma) bin, frag);
+		dwarf2_emit_insn (2);
+		bin = 0xc070 | reg;
+		bfd_putl16 ((bfd_vma) bin, frag + 2);
+		bin = 0x0080;
+		bfd_putl16 ((bfd_vma) bin, frag + 4);
+		dwarf2_emit_insn (4);
+	      }
+	    else
+	      {
+		/* Encode as RRUM[.A] rN.  */
+		bin = opcode->bin_opcode;
+		if (! addr_op)
+		  bin |= 0x10;
+		bin |= reg;
+		op_length = 2;
+		frag = frag_more (op_length);
+		where = frag - frag_now->fr_literal;
+		bfd_putl16 ((bfd_vma) bin, frag);
+		dwarf2_emit_insn (op_length);
+	      }	    
+	    break;
+	  }
+
+	case 8:
+	  {
+	    bfd_boolean need_reloc = FALSE;
+	    int n;
+	    int reg;
+
+	    /* ADDA, CMPA and SUBA address instructions.  */
+	    if (extended & 0xff)
+	      {
+		as_bad (_("repeat count cannot be used with %s"), opcode->name);
+		return 0;
+	      }
+
+	    line = extract_operand (line, l1, sizeof (l1));
+	    line = extract_operand (line, l2, sizeof (l2));
+
+	    bin = opcode->bin_opcode;
+
+	    if (*l1 == '#')
+	      {
+		parse_exp (l1 + 1, &(op1.exp));
+
+		if (op1.exp.X_op == O_constant)
+		  {
+		    n = op1.exp.X_add_number;
+		    if (n > 0xfffff || n < - (0x7ffff))
+		      {
+			as_bad (_("expected value of first argument of %s to fit into 20-bits"),
+				opcode->name);
+			return 0;
+		      }
+
+		    bin |= ((n >> 16) & 0xf) << 8;
+		  }
+		else
+		  {
+		    n = 0;
+		    need_reloc = TRUE;
+		  }
+
+		op_length = 4;
+	      }
+	    else
+	      {
+		if ((n = check_reg (l1)) == -1)
+		  {
+		    as_bad (_("expected register name or constant as first argument of %s"),
+			    opcode->name);
+		    return 0;
+		  }
+
+		bin |= (n << 8) | (1 << 6);
+		op_length = 2;
+	      }
+
+	    if ((reg = check_reg (l2)) == -1)
+	      {
+		as_bad (_("expected register as second argument of %s"),
+			opcode->name);
+		return 0;
+	      }
+
+	    frag = frag_more (op_length);
+	    where = frag - frag_now->fr_literal;
+	    bin |= reg;
+	    if (need_reloc)
+	      fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
+			   BFD_RELOC_MSP430X_ABS20_ADR_SRC);
+
+	    bfd_putl16 ((bfd_vma) bin, frag);
+	    if (op_length == 4)
+	      bfd_putl16 ((bfd_vma) (n & 0xffff), frag + 2);
+	    dwarf2_emit_insn (op_length);
+	    break;
+	  }
+	  
+	case 9: /* MOVA, BRA, RETA.  */
+	  imm_op = 0;
+	  bin = opcode->bin_opcode;
+
+	  if (is_opcode ("reta"))
+	    {
+	      /* The RETA instruction does not take any arguments.
+		 The implicit first argument is @SP+.
+		 The implicit second argument is PC.  */
+	      op1.mode = OP_REG;
+	      op1.am = 3;
+	      op1.reg = 1;
+
+	      op2.mode = OP_REG;
+	      op2.reg = 0;
+	    }
+	  else
+	    {
+	      line = extract_operand (line, l1, sizeof (l1));
+	      res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
+				       &imm_op, extended_op, FALSE);
+
+	      if (is_opcode ("bra"))
+		{
+		  /* This is the BRA synthetic instruction.
+		     The second argument is always PC.  */
+		  op2.mode = OP_REG;
+		  op2.reg = 0;
+		}
+	      else
+		{
+		  line = extract_operand (line, l2, sizeof (l2));
+		  res += msp430_dstoperand (&op2, l2, opcode->bin_opcode,
+					    extended_op, TRUE);
+		}
+	  
+	      if (res)
+		break;	/* Error occurred.  All warnings were done before.  */
+	    }
+
+	  /* Only a restricted subset of the normal MSP430 addressing modes
+	     are supported here, so check for the ones that are allowed.  */
+	  if ((op_length = try_encode_mova (imm_op, bin, & op1, & op2,
+					    & error_message)) == 0)
+	    {
+	      as_bad (error_message, opcode->name);
+	      return 0;
+	    }
+	  dwarf2_emit_insn (op_length);
+	  break;
+
+	case 10: /* RPT */
+	  line = extract_operand (line, l1, sizeof l1);
+	  /* The RPT instruction only accepted immediates and registers.  */
+	  if (*l1 == '#')
+	    {
+	      parse_exp (l1 + 1, &(op1.exp));
+	      if (op1.exp.X_op != O_constant)
+		{
+		  as_bad (_("expected constant value as argument to RPT"));
+		  return 0;
+		}
+	      if (op1.exp.X_add_number < 1
+		  || op1.exp.X_add_number > (1 << 4))
+		{
+		  as_bad (_("expected constant in the range 2..16"));
+		  return 0;
+		}
+
+	      /* We silently accept and ignore a repeat count of 1.  */
+	      if (op1.exp.X_add_number > 1)
+		repeat_count = op1.exp.X_add_number;
+	    }
+	  else
+	    {
+	      int reg;
+
+	      if ((reg = check_reg (l1)) != -1)
+		{
+		  if (reg == 0)
+		    as_warn (_("PC used as an argument to RPT"));
+		  else
+		    repeat_count = - reg;
+		}
+	      else
+		{
+		  as_bad (_("expected constant or register name as argument to RPT insn"));
+		  return 0;
+		}
+	    }
+	  break;
+
+	default:
+	  as_bad (_("Illegal emulated instruction "));
 	  break;
 	}
       break;
@@ -1546,80 +2897,258 @@
     case 1:			/* Format 1, double operand.  */
       line = extract_operand (line, l1, sizeof (l1));
       line = extract_operand (line, l2, sizeof (l2));
-      res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
-      res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
+      res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
+      res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
 
       if (res)
 	break;			/* Error occurred.  All warnings were done before.  */
 
-      bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
+      if (extended_op
+	  && is_opcode ("movx")
+	  && addr_op
+	  && msp430_enable_relax)
+	{
+	  /* This is the MOVX.A instruction.  See if we can convert
+	     it into the MOVA instruction instead.  This saves 2 bytes.  */
+	  if ((op_length = try_encode_mova (imm_op, 0x0000, & op1, & op2,
+					    NULL)) != 0)
+	    {
+	      dwarf2_emit_insn (op_length);
+	      break;
+	    }
+	}
 
-      __is = 1 + op1.ol + op2.ol;	/* insn size in words.  */
-      frag = frag_more (2 * __is);
+      /* Compute the entire length of the instruction in bytes.  */
+      insn_length =
+	(extended_op ? 2 : 0)	/* The extension word.  */
+	+ 2 			/* The opcode */
+	+ (2 * op1.ol)		/* The first operand. */
+	+ (2 * op2.ol);		/* The second operand.  */
+
+      frag = frag_more (insn_length);
       where = frag - frag_now->fr_literal;
+      
+      if (extended_op)
+	{
+	  if (!addr_op)
+	    extended |= BYTE_OPERATION;
+
+	  if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
+	    {
+	      as_bad (_("repeat instruction used with non-register mode instruction"));
+	      extended &= ~ 0xf;
+	    }
+
+	  /* If necessary, emit a reloc to update the extension word.  */
+	  if (op1.mode == OP_EXP)
+	    {
+	      if (op1.exp.X_op == O_constant)
+		extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
+
+	      else  if (op1.reg || (op1.reg == 0 && op1.am == 3))	/* Not PC relative.  */
+		fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+			     BFD_RELOC_MSP430X_ABS20_EXT_SRC);
+	      else
+		fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+			     BFD_RELOC_MSP430X_PCR20_EXT_SRC);
+	    }
+	  
+	  if (op2.mode == OP_EXP)
+	    {
+	      if (op2.exp.X_op == O_constant)
+		extended |= (op2.exp.X_add_number >> 16) & 0xf;
+
+	      else if (op1.mode == OP_EXP)
+		fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
+			     op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
+			     : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
+	    
+	      else
+		fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
+			     op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
+			     : BFD_RELOC_MSP430X_PCR20_EXT_DST);
+	    }
+
+	  /* Emit the extension word.  */
+	  bfd_putl16 (extended, frag);
+	  where += 2;
+	  frag += 2;
+	}
+
+      bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
       bfd_putl16 ((bfd_vma) bin, frag);
-      dwarf2_emit_insn (2 * __is);
+      where += 2;
+      frag += 2;
 
       if (op1.mode == OP_EXP)
 	{
-	  where += 2;		/* Advance where as we do not know _where_.  */
-	  bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
-
-	  if (op1.reg || (op1.reg == 0 && op1.am == 3))	/* Not PC relative.  */
-	    fix_new_exp (frag_now, where, 2,
-			 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+	  if (op1.exp.X_op == O_constant)
+	    {
+	      bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
+	    }
 	  else
-	    fix_new_exp (frag_now, where, 2,
-			 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+	    {
+	      bfd_putl16 ((bfd_vma) ZEROS, frag);
+
+	      if (!extended_op)
+		{
+		  if (op1.reg || (op1.reg == 0 && op1.am == 3))	/* Not PC relative.  */
+		    fix_new_exp (frag_now, where, 2,
+				 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+		  else
+		    fix_new_exp (frag_now, where, 2,
+				 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+		}
+	    }
+
+	  where += 2;
+	  frag += 2;
 	}
 
       if (op2.mode == OP_EXP)
 	{
-	  imm_op = 0;
-	  bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
-
-	  if (op2.reg)		/* Not PC relative.  */
-	    fix_new_exp (frag_now, where + 2, 2,
-			 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
+	  if (op2.exp.X_op == O_constant)
+	    {
+	      bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
+	    }
 	  else
-	    fix_new_exp (frag_now, where + 2, 2,
-			 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+	    {
+	      bfd_putl16 ((bfd_vma) ZEROS, frag);
+
+	      if (!extended_op)
+		{
+		  if (op2.reg)		/* Not PC relative.  */
+		    fix_new_exp (frag_now, where, 2,
+			     &(op2.exp), FALSE, CHECK_RELOC_MSP430);
+		  else
+		    fix_new_exp (frag_now, where, 2,
+				 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+		}
+	    }
 	}
+
+      if (gen_interrupt_nops
+	  && target_is_430xv2 ()
+	  && (   (is_opcode ("bic") && bin == 0xc232)
+	      || (is_opcode ("bis") && bin == 0xd232)
+	      || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2)))
+	{
+	  /* Emit a NOP following interrupt enable/disable.
+	     See 1.3.4.1 of the MSP430x5xx User Guide.  */
+	  insn_length += 2;
+	  frag = frag_more (2);
+	  bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
+	}
+
+      dwarf2_emit_insn (insn_length);
       break;
 
     case 2:			/* Single-operand mostly instr.  */
       if (opcode->insn_opnumb == 0)
 	{
 	  /* reti instruction.  */
+	  insn_length += 2;
 	  frag = frag_more (2);
 	  bfd_putl16 ((bfd_vma) bin, frag);
-	  dwarf2_emit_insn (2);
+	  dwarf2_emit_insn (insn_length);
 	  break;
 	}
 
       line = extract_operand (line, l1, sizeof (l1));
-      res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
+      res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
+			       &imm_op, extended_op, TRUE);
       if (res)
 	break;		/* Error in operand.  */
 
-      bin |= op1.reg | (op1.am << 4);
-      __is = 1 + op1.ol;
-      frag = frag_more (2 * __is);
+      /* Issue 3831743.  */
+      if (op1.mode == OP_REG
+	  && op1.reg == 0 
+	  && (is_opcode ("rrax")
+	      || is_opcode ("rrcx")
+	      || is_opcode ("rra")
+	      || is_opcode ("rrc")))
+	{
+	  as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
+	  return 0;
+	}
+      
+      insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
+      frag = frag_more (insn_length);
       where = frag - frag_now->fr_literal;
+      
+      if (extended_op)
+	{
+	  if (is_opcode ("swpbx") || is_opcode ("sxtx"))
+	    {
+	      /* These two instructions use a special
+		 encoding of the A/L and B/W bits.  */
+	      bin &= ~ BYTE_OPERATION;
+
+	      if (byte_op)
+		{
+		  as_bad (_("%s instruction does not accept a .b suffix"),
+			  opcode->name);
+		  return 0;
+		}
+	      else if (! addr_op)
+		extended |= BYTE_OPERATION;
+	    }
+	  else if (! addr_op)
+	    extended |= BYTE_OPERATION;
+
+	  if (op1.ol != 0 && ((extended & 0xf) != 0))
+	    {
+	      as_bad (_("repeat instruction used with non-register mode instruction"));
+	      extended &= ~ 0xf;
+	    }
+
+	  if (op1.mode == OP_EXP)
+	    {
+	      if (op1.exp.X_op == O_constant)
+		extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
+	  
+	      else if (op1.reg || (op1.reg == 0 && op1.am == 3))	/* Not PC relative.  */
+		fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+			     BFD_RELOC_MSP430X_ABS20_EXT_SRC);
+	      else
+		fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+			     BFD_RELOC_MSP430X_PCR20_EXT_SRC);
+	    }
+	  
+	  /* Emit the extension word.  */
+	  bfd_putl16 (extended, frag);
+	  frag += 2;
+	  where += 2;
+	}
+
+      bin |= op1.reg | (op1.am << 4);
       bfd_putl16 ((bfd_vma) bin, frag);
-      dwarf2_emit_insn (2 * __is);
+      frag += 2;
+      where += 2;
 
       if (op1.mode == OP_EXP)
 	{
-	  bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
-
-	  if (op1.reg || (op1.reg == 0 && op1.am == 3))	/* Not PC relative.  */
-	    fix_new_exp (frag_now, where + 2, 2,
-			 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+	  if (op1.exp.X_op == O_constant)
+	    {
+	      bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
+	    }
 	  else
-	    fix_new_exp (frag_now, where + 2, 2,
-			 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+	    {
+	      bfd_putl16 ((bfd_vma) ZEROS, frag);
+
+	      if (!extended_op)
+		{
+		  if (op1.reg || (op1.reg == 0 && op1.am == 3))	/* Not PC relative.  */
+		    fix_new_exp (frag_now, where, 2,
+				 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+		  else
+		    fix_new_exp (frag_now, where, 2,
+				 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+		}
+	    }
 	}
+
+      dwarf2_emit_insn (insn_length);
       break;
 
     case 3:			/* Conditional jumps instructions.  */
@@ -1634,7 +3163,6 @@
 	    m++;
 
 	  parse_exp (m, &exp);
-	  frag = frag_more (2);	/* Instr size is 1 word.  */
 
 	  /* In order to handle something like:
 
@@ -1678,11 +3206,16 @@
 		  break;
 		}
 
+	      insn_length += 2;
+	      frag = frag_more (2);	/* Instr size is 1 word.  */
+
 	      bin |= x & 0x3ff;
 	      bfd_putl16 ((bfd_vma) bin, frag);
 	    }
 	  else if (exp.X_op == O_symbol && *l1 != '$')
 	    {
+	      insn_length += 2;
+	      frag = frag_more (2);	/* Instr size is 1 word.  */
 	      where = frag - frag_now->fr_literal;
 	      fix_new_exp (frag_now, where, 2,
 			   &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
@@ -1694,11 +3227,9 @@
 	      as_bad (_("instruction requires label sans '$'"));
 	    }
 	  else
-	    {
-	      as_bad (_
-		      ("instruction requires label or value in range -511:512"));
-	    }
-	  dwarf2_emit_insn (2 * __is);
+	    as_bad (_
+		    ("instruction requires label or value in range -511:512"));
+	  dwarf2_emit_insn (insn_length);
 	  break;
 	}
       else
@@ -1731,15 +3262,20 @@
 	      /* Relaxation required.  */
 	      struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
 
-	      /* The parameter to dwarf2_emit_insn is actually the offset to the start
-		 of the insn from the fix piece of instruction that was emitted.
-		 Since next fragments may have variable size we tie debug info
-	         to the beginning of the instruction. */
+	      if (target_is_430x ())
+		rc = msp430x_rcodes[opcode->insn_opnumb];
+
+	      /* The parameter to dwarf2_emit_insn is actually the offset to
+		 the start of the insn from the fix piece of instruction that
+		 was emitted.  Since next fragments may have variable size we
+		 tie debug info to the beginning of the instruction.  */
+	      insn_length += 8;
 	      frag = frag_more (8);
 	      dwarf2_emit_insn (0);
 	      bfd_putl16 ((bfd_vma) rc.sop, frag);
 	      frag = frag_variant (rs_machine_dependent, 8, 2,
-				   ENCODE_RELAX (rc.lpos, STATE_BITS10), /* Wild guess.  */
+				    /* Wild guess.  */
+				   ENCODE_RELAX (rc.lpos, STATE_BITS10),
 				   exp.X_add_symbol,
 				   0,	/* Offset is zero if jump dist less than 1K.  */
 				   (char *) frag);
@@ -1772,6 +3308,10 @@
 	      /* Relaxation required.  */
 	      struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
 
+	      if (target_is_430x ())
+		hc = msp430x_hcodes[opcode->insn_opnumb];
+
+	      insn_length += 8;
 	      frag = frag_more (8);
 	      dwarf2_emit_insn (0);
 	      bfd_putl16 ((bfd_vma) hc.op0, frag);
@@ -1866,16 +3406,20 @@
 
 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
    Now it handles the situation when relocations
-   have to be passed to linker. */
+   have to be passed to linker.  */
 int
-msp430_force_relocation_local(fixS *fixp)
+msp430_force_relocation_local (fixS *fixp)
 {
+  if (fixp->fx_r_type == BFD_RELOC_MSP430_10_PCREL)
+    return 1;
+  if (fixp->fx_pcrel)
+    return 1;
   if (msp430_enable_polys
         && !msp430_enable_relax)
     return 1;
-  else
-    return (!fixp->fx_pcrel
-	    || generic_force_reloc(fixp));
+
+  return (!fixp->fx_pcrel
+	  || generic_force_reloc (fixp));
 }
 
 
@@ -1928,19 +3472,13 @@
 	      value -= S_GET_VALUE (fixp->fx_subsy);
 	      fixp->fx_done = 1;
 	    }
-	  else
-	    {
-	      /* We don't actually support subtracting a symbol.  */
-	      as_bad_where (fixp->fx_file, fixp->fx_line,
-			    _("expression too complex"));
-	    }
 	}
     }
 
   fixp->fx_no_overflow = 1;
 
-  /* if polymorphs are enabled and relax disabled. 
-     do not kill any relocs and pass them to linker. */
+  /* If polymorphs are enabled and relax disabled. 
+     do not kill any relocs and pass them to linker.  */
   if (msp430_enable_polys 
       && !msp430_enable_relax)
     {
@@ -1955,7 +3493,6 @@
     {
       /* Fetch the instruction, insert the fully resolved operand
 	 value, and stuff the instruction back again.  */
-
       where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
 
       insn = bfd_getl16 (where);
@@ -1979,27 +3516,25 @@
 	  bfd_putl16 ((bfd_vma) (value | insn), where);
 	  break;
 
+	case BFD_RELOC_MSP430X_PCR16:
 	case BFD_RELOC_MSP430_RL_PCREL:
 	case BFD_RELOC_MSP430_16_PCREL:
 	  if (value & 1)
 	    as_bad_where (fixp->fx_file, fixp->fx_line,
 			  _("odd address operand: %ld"), value);
-
-	  /* Nothing to be corrected here.  */
-	  if (value < -32768 || value > 65536)
-	    as_bad_where (fixp->fx_file, fixp->fx_line,
-			  _("operand out of range: %ld"), value);
-
-	  value &= 0xffff;	/* Get rid of extended sign.  */
-	  bfd_putl16 ((bfd_vma) value, where);
-	  break;
+	  /* Fall through.  */
 
 	case BFD_RELOC_MSP430_16_PCREL_BYTE:
 	  /* Nothing to be corrected here.  */
 	  if (value < -32768 || value > 65536)
 	    as_bad_where (fixp->fx_file, fixp->fx_line,
 			  _("operand out of range: %ld"), value);
+	  /* Fall through.  */
 
+	case BFD_RELOC_MSP430X_ABS16:
+	case BFD_RELOC_MSP430_16:
+	case BFD_RELOC_16:
+	case BFD_RELOC_MSP430_16_BYTE:
 	  value &= 0xffff;	/* Get rid of extended sign.  */
 	  bfd_putl16 ((bfd_vma) value, where);
 	  break;
@@ -2008,13 +3543,55 @@
 	  bfd_putl16 ((bfd_vma) value, where);
 	  break;
 
-	case BFD_RELOC_MSP430_16:
-	case BFD_RELOC_16:
-	case BFD_RELOC_MSP430_16_BYTE:
-	  value &= 0xffff;
-	  bfd_putl16 ((bfd_vma) value, where);
+	case BFD_RELOC_MSP430_ABS8:
+	case BFD_RELOC_8:
+	  bfd_put_8 (NULL, (bfd_vma) value, where);
 	  break;
 
+	case BFD_RELOC_MSP430X_ABS20_EXT_SRC:
+	case BFD_RELOC_MSP430X_PCR20_EXT_SRC:
+	  bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
+	  value >>= 16;	  
+	  bfd_putl16 ((bfd_vma) (((value & 0xf) << 7) | insn), where);
+	  break;
+
+	case BFD_RELOC_MSP430X_ABS20_ADR_SRC:
+	  bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
+	  value >>= 16;	  
+	  bfd_putl16 ((bfd_vma) (((value & 0xf) << 8) | insn), where);
+	  break;
+
+	case BFD_RELOC_MSP430X_ABS20_EXT_ODST:
+	  bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
+	  value >>= 16;
+	  bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
+	  break;
+
+	case BFD_RELOC_MSP430X_PCR20_CALL:
+	  bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
+	  value >>= 16;
+	  bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
+	  break;
+
+	case BFD_RELOC_MSP430X_ABS20_EXT_DST:
+	case BFD_RELOC_MSP430X_PCR20_EXT_DST:
+	  bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
+	  value >>= 16;
+	  bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
+	  break;
+
+	case BFD_RELOC_MSP430X_PCR20_EXT_ODST:
+	  bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
+	  value >>= 16;
+	  bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
+	  break;
+
+	case BFD_RELOC_MSP430X_ABS20_ADR_DST:
+	  bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
+	  value >>= 16;
+	  bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
+	  break;
+	  
 	default:
 	  as_fatal (_("line %d: unknown relocation type: 0x%x"),
 		    fixp->fx_line, fixp->fx_r_type);
@@ -2027,6 +3604,20 @@
     }
 }
 
+static bfd_boolean
+S_IS_GAS_LOCAL (symbolS * s)
+{
+  const char * name;
+  unsigned int len;
+
+  if (s == NULL)
+    return FALSE;
+  name = S_GET_NAME (s);
+  len = strlen (name) - 1;
+  
+  return name[len] == 1 || name[len] == 2;
+}
+
 /* GAS will call this to generate a reloc, passing the resulting reloc
    to `bfd_install_relocation'.  This currently works poorly, as
    `bfd_install_relocation' often does the wrong thing, and instances of
@@ -2036,33 +3627,157 @@
 /* If while processing a fixup, a reloc really needs to be created
    then it is done here.  */
 
-arelent *
+arelent **
 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
 {
-  arelent * reloc;
+  static arelent * no_relocs = NULL;
+  static arelent * relocs[MAX_RELOC_EXPANSION + 1];
+  arelent *reloc;
 
   reloc = xmalloc (sizeof (arelent));
-
-  reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
-  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
-
   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+
   if (reloc->howto == (reloc_howto_type *) NULL)
     {
       as_bad_where (fixp->fx_file, fixp->fx_line,
 		    _("reloc %d not supported by object file format"),
 		    (int) fixp->fx_r_type);
-      return NULL;
+      free (reloc);
+      return & no_relocs;
     }
 
-  if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
-      || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
-    reloc->address = fixp->fx_offset;
+  relocs[0] = reloc;
+  relocs[1] = NULL;
 
-  reloc->addend = fixp->fx_offset;
+  if (fixp->fx_subsy
+      && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
+    {
+      fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
+      fixp->fx_subsy = NULL;
+    }
 
-  return reloc;
+  if (fixp->fx_addsy && fixp->fx_subsy)
+    {
+      asection *asec, *ssec;
+
+      asec = S_GET_SEGMENT (fixp->fx_addsy);
+      ssec = S_GET_SEGMENT (fixp->fx_subsy);
+
+      /* If we have a difference between two different, non-absolute symbols
+	 we must generate two relocs (one for each symbol) and allow the
+	 linker to resolve them - relaxation may change the distances between
+	 symbols, even local symbols defined in the same section.
+
+	 Unfortunately we cannot do this with assembler generated local labels
+	 because there can be multiple incarnations of the same label, with
+	 exactly the same name, in any given section and the linker will have
+	 no way to identify the correct one.  Instead we just have to hope
+	 that no relaxtion will occur between the local label and the other
+	 symbol in the expression.
+
+	 Similarly we have to compute differences between symbols in the .eh_frame
+	 section as the linker is not smart enough to apply relocations there
+	 before attempting to process it.  */
+      if ((ssec != absolute_section || asec != absolute_section)
+	  && (fixp->fx_addsy != fixp->fx_subsy)
+	  && strcmp (ssec->name, ".eh_frame") != 0
+	  && ! S_IS_GAS_LOCAL (fixp->fx_addsy)
+	  && ! S_IS_GAS_LOCAL (fixp->fx_subsy))
+	{
+	  arelent * reloc2 = xmalloc (sizeof * reloc);
+
+	  relocs[0] = reloc2;
+	  relocs[1] = reloc;
+
+	  reloc2->address = reloc->address;
+	  reloc2->howto = bfd_reloc_type_lookup (stdoutput,
+						 BFD_RELOC_MSP430_SYM_DIFF);
+	  reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
+
+	  if (ssec == absolute_section)
+	    reloc2->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+	  else
+	    {
+	      reloc2->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+	      *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
+	    }
+
+	  reloc->addend = fixp->fx_offset; 
+	  if (asec == absolute_section)
+	    {
+	      reloc->addend += S_GET_VALUE (fixp->fx_addsy);
+	      reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+	    }
+	  else
+	    {
+	      reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+	      *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+	    }
+
+	  fixp->fx_pcrel = 0;
+	  fixp->fx_done = 1;
+	  return relocs;
+	}
+      else
+	{
+	  char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
+
+	  reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
+			   - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
+
+	  switch (fixp->fx_r_type)
+	    {
+	    case BFD_RELOC_8:
+	      md_number_to_chars (fixpos, reloc->addend, 1);
+	      break;
+
+	    case BFD_RELOC_16:
+	      md_number_to_chars (fixpos, reloc->addend, 2);
+	      break;
+
+	    case BFD_RELOC_24:
+	      md_number_to_chars (fixpos, reloc->addend, 3);
+	      break;
+
+	    case BFD_RELOC_32:
+	      md_number_to_chars (fixpos, reloc->addend, 4);
+	      break;
+
+	    default:
+	      reloc->sym_ptr_ptr
+		= (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
+	      return relocs;
+	    }
+
+	  free (reloc);
+	  return & no_relocs;
+	}
+    }
+  else
+    {
+#if 0
+      if (fixp->fx_r_type == BFD_RELOC_MSP430X_ABS16
+	  && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
+	{
+	  bfd_vma amount = S_GET_VALUE (fixp->fx_addsy);
+	  char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
+
+	  md_number_to_chars (fixpos, amount, 2);
+	  free (reloc);
+	  return & no_relocs;
+	}
+#endif
+      reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+      *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+      reloc->addend = fixp->fx_offset;
+
+      if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+	  || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+	reloc->address = fixp->fx_offset;
+    }
+
+  return relocs;
 }
 
 int
@@ -2121,7 +3836,10 @@
     case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
     case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
       /* Convert uncond branch jmp lab -> br lab.  */
-      cc = & msp430_rcodes[7];
+      if (target_is_430x ())
+	cc = msp430x_rcodes + 7;
+      else
+	cc = msp430_rcodes + 7;
       where = fragP->fr_literal + fragP->fr_fix;
       bfd_putl16 (cc->lop0, where);
       rela = BFD_RELOC_MSP430_RL_PCREL;
@@ -2136,9 +3854,19 @@
 
 	insn &= 0xffff;
 	/* Find actual instruction.  */
-	for (i = 0; i < 7 && !cc; i++)
-	  if (msp430_rcodes[i].sop == insn)
-	    cc = & msp430_rcodes[i];
+	if (target_is_430x ())
+	  {
+	    for (i = 0; i < 7 && !cc; i++)
+	      if (msp430x_rcodes[i].sop == insn)
+		cc = msp430x_rcodes + i;
+	  }
+	else
+	  {
+	    for (i = 0; i < 7 && !cc; i++)
+	      if (msp430_rcodes[i].sop == insn)
+		cc = & msp430_rcodes[i];
+	  }
+
 	if (!cc || !cc->name)
 	  as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
 		    __FUNCTION__, (long) insn);
@@ -2152,7 +3880,10 @@
 
     case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
     case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
-      cc = & msp430_rcodes[6];
+      if (target_is_430x ())
+	cc = msp430x_rcodes + 6;
+      else
+	cc = msp430_rcodes + 6;
       where = fragP->fr_literal + fragP->fr_fix;
       bfd_putl16 (cc->lop0, where);
       bfd_putl16 (cc->lop1, where + 2);
@@ -2166,9 +3897,18 @@
 	int insn = bfd_getl16 (fragP->fr_opcode + 2);
 
 	insn &= 0xffff;
-	for (i = 0; i < 4 && !hc; i++)
-	  if (msp430_hcodes[i].op1 == insn)
-	    hc = &msp430_hcodes[i];
+	if (target_is_430x ())
+	  {
+	    for (i = 0; i < 4 && !hc; i++)
+	      if (msp430x_hcodes[i].op1 == insn)
+		hc = msp430x_hcodes + i;
+	  }
+	else
+	  {
+	    for (i = 0; i < 4 && !hc; i++)
+	      if (msp430_hcodes[i].op1 == insn)
+		hc = &msp430_hcodes[i];
+	  }
 	if (!hc || !hc->name)
 	  as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
 	      __FUNCTION__, (long) insn);
@@ -2177,7 +3917,7 @@
 	   another fix will be applied to the next word of insn anyway.  */
 	if (hc->tlab == 2)
 	  fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
-	      fragP->fr_offset, TRUE, rela);
+		   fragP->fr_offset, TRUE, rela);
 	fragP->fr_fix += 2;
       }
 
@@ -2189,9 +3929,18 @@
 	int insn = bfd_getl16 (fragP->fr_opcode + 2);
 
 	insn &= 0xffff;
-	for (i = 0; i < 4 && !hc; i++)
-	  if (msp430_hcodes[i].op1 == insn)
-	    hc = & msp430_hcodes[i];
+	if (target_is_430x ())
+	  {
+	    for (i = 0; i < 4 && !hc; i++)
+	      if (msp430x_hcodes[i].op1 == insn)
+		hc = msp430x_hcodes + i;
+	  }
+	else
+	  {
+	    for (i = 0; i < 4 && !hc; i++)
+	      if (msp430_hcodes[i].op1 == insn)
+		hc = & msp430_hcodes[i];
+	  }
 	if (!hc || !hc->name)
 	  as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
 	      __FUNCTION__, (long) insn);
@@ -2251,7 +4000,7 @@
   if (!msp430_enable_relax)
     {
       /* Relaxation is not enabled. So, make all jump as long ones
-         by setting 'aim' to quite high value. */
+         by setting 'aim' to quite high value.  */
       aim = 0x7fff;
     }
   
@@ -2292,3 +4041,58 @@
     fragP->fr_subtype = this_state;
   return growth;
 }
+
+/* Return FALSE if the fixup in fixp should be left alone and not
+   adjusted.   We return FALSE here so that linker relaxation will
+   work.  */
+
+bfd_boolean
+msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
+{
+  /* If the symbol is in a non-code section then it should be OK.  */
+  if (fixp->fx_addsy
+      && ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) == 0))
+    return TRUE;
+	   
+  return FALSE;
+}
+
+/* Set the contents of the .MSP430.attributes section.  */
+
+void
+msp430_md_end (void)
+{
+  bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
+			     target_is_430x () ? 2 : 1);
+
+  bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model,
+			     large_model ? 2 : 1);
+
+  bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model,
+			     large_model ? 2 : 1);
+}
+
+/* Returns FALSE if there is a msp430 specific reason why the
+   subtraction of two same-section symbols cannot be computed by
+   the assembler.  */
+
+bfd_boolean
+msp430_allow_local_subtract (expressionS * left,
+			     expressionS * right,
+			     segT section)
+{
+  /* If the symbols are not in a code section then they are OK.  */
+  if ((section->flags & SEC_CODE) == 0)
+    return TRUE;
+
+  if (S_IS_GAS_LOCAL (left->X_add_symbol) || S_IS_GAS_LOCAL (right->X_add_symbol))
+    return TRUE;
+
+  if (left->X_add_symbol == right->X_add_symbol)
+    return TRUE;
+
+  /* We have to assume that there may be instructions between the
+     two symbols and that relaxation may increase the distance between
+     them.  */
+  return FALSE;
+}
diff --git a/gas/config/tc-msp430.h b/gas/config/tc-msp430.h
index 118b46d..f805f66 100644
--- a/gas/config/tc-msp430.h
+++ b/gas/config/tc-msp430.h
@@ -1,5 +1,5 @@
 /* This file is tc-msp430.h
-   Copyright (C) 2002, 2004, 2005, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2002-2013 Free Software Foundation, Inc.
 
    Contributed by Dmitry Diky <diwil@mail.ru>
 
@@ -99,8 +99,9 @@
      example, a value of 2 might print `1234 5678' where a value of 1
      would print `12 34 56 78'.  The default value is 4.  */
 
-#define LEX_DOLLAR 0
-/* MSP430 port does not use `$' as a logical line separator */
+/* Support symbols like: C$$IO$$.  */
+#undef  LEX_DOLLAR
+#define LEX_DOLLAR 1
 
 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) (P2VAR) = 0
 /*   An `.lcomm' directive with no explicit alignment parameter will
@@ -116,9 +117,52 @@
 extern long msp430_relax_frag (segT, fragS *, long);
 
 #define TC_FORCE_RELOCATION_LOCAL(FIX)	\
-   msp430_force_relocation_local(FIX)
-extern int msp430_force_relocation_local(struct fix *);
-
+   msp430_force_relocation_local (FIX)
+extern int msp430_force_relocation_local (struct fix *);
 
 extern int msp430_enable_relax;
 extern int msp430_enable_polys;
+
+#define tc_fix_adjustable(FIX) msp430_fix_adjustable (FIX)
+extern bfd_boolean             msp430_fix_adjustable (struct fix *);
+
+/* Allow hexadeciaml numbers with 'h' suffix.  Note that if the number
+   starts with a letter it will be interpreted as a symbol name not a
+   constant.  Thus "beach" is a symbol not the hex value 0xbeac.  So
+   is A5A5h...  */
+#define NUMBERS_WITH_SUFFIX 1
+
+#define md_end msp430_md_end
+extern void    msp430_md_end (void);
+
+/* Do not allow call frame debug info optimization as otherwise we could
+   generate the DWARF directives without the relocs necessary to patch
+   them up.  */
+#define md_allow_eh_opt 0
+
+/* The difference between same-section symbols may be affected by linker
+   relaxation, so do not resolve such expressions in the assembler.  */
+#define md_allow_local_subtract(l,r,s) msp430_allow_local_subtract (l, r, s)
+extern bfd_boolean msp430_allow_local_subtract (expressionS *, expressionS *, segT);
+
+#define RELOC_EXPANSION_POSSIBLE
+#define MAX_RELOC_EXPANSION 2
+
+#define DIFF_EXPR_OK
+
+/* Do not adjust relocations involving symbols in code sections,
+   because it breaks linker relaxations.  This could be fixed in the
+   linker, but this fix is simpler, and it pretty much only affects
+   object size a little bit.  */
+#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEC)	\
+  (((SEC)->flags & SEC_CODE) != 0		\
+   || ! SEG_NORMAL (SEC)			\
+   || TC_FORCE_RELOCATION (FIX))
+
+/* We validate subtract arguments within tc_gen_reloc(),
+   so don't report errors at this point.  */
+#define TC_VALIDATE_FIX_SUB(FIX, SEG) 1
+
+#define DWARF2_USE_FIXED_ADVANCE_PC 1
+
+#define TC_LINKRELAX_FIXUP(seg) (seg->flags & SEC_CODE)
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 0929e52..d4f6b71 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -64,40 +64,14 @@
 /* #lo(value) denotes the least significant 16 bits of the indicated.  */
 #define PPC_LO(v) ((v) & 0xffff)
 
-/* Split the indicated value with the msbs in bits 11-15
-   and the lsbs in bits 21-31.  */
-#define PPC_VLE_SPLIT16A(v) ((v & 0xf800) << 11) | (v & 0x7ff)
-
-/* Split the indicated value with the msbs in bits 6-10
-   and the lsbs in bits 21-31.  */
-#define PPC_VLE_SPLIT16D(v) ((v & 0xf800) << 5) | (v & 0x7ff)
-
-/* #lo(value) denotes the lsb 16 bits in split16a format.  */
-#define PPC_VLE_LO16A(v) PPC_VLE_SPLIT16A(PPC_LO(v))
-
-/* #lo(value) denotes the lsb 16 bits in split16d format.  */
-#define PPC_VLE_LO16D(v) PPC_VLE_SPLIT16D(PPC_LO(v))
-
 /* #hi(value) denotes bits 16 through 31 of the indicated value.  */
 #define PPC_HI(v) (((v) >> 16) & 0xffff)
 
-/* #lo(value) denotes the msb 16 bits in split16a format.  */
-#define PPC_VLE_HI16A(v) PPC_VLE_SPLIT16A(PPC_HI(v))
-
-/* #lo(value) denotes the msb 16 bits in split16d format.  */
-#define PPC_VLE_HI16D(v) PPC_VLE_SPLIT16D(PPC_HI(v))
-
 /* #ha(value) denotes the high adjusted value: bits 16 through 31 of
   the indicated value, compensating for #lo() being treated as a
   signed number.  */
 #define PPC_HA(v) PPC_HI ((v) + 0x8000)
 
-/* #ha(value) denotes the high adjusted value in split16a format.  */
-#define PPC_VLE_HA16A(v) PPC_VLE_SPLIT16A(PPC_HA(v))
-
-/* #ha(value) denotes the high adjusted value in split16d format.  */
-#define PPC_VLE_HA16D(v) PPC_VLE_SPLIT16D(PPC_HA(v))
-
 /* #higher(value) denotes bits 32 through 47 of the indicated value.  */
 #define PPC_HIGHER(v) (((v) >> 16 >> 16) & 0xffff)
 
@@ -1552,10 +1526,10 @@
 	      int new_opcode = PPC_OP (op[0].opcode);
 
 #ifdef PRINT_OPCODE_TABLE
-	      printf ("%-14s\t#%04d\tmajor op: 0x%x\top: 0x%x\tmask: 0x%x\tflags: 0x%llx\n",
-		      op->name, op - powerpc_opcodes, (unsigned int) new_opcode,
-		      (unsigned int) op->opcode, (unsigned int) op->mask,
-		      (unsigned long long) op->flags);
+	      printf ("%-14s\t#%04u\tmajor op: 0x%x\top: 0x%x\tmask: 0x%x\tflags: 0x%llx\n",
+		      op->name, (unsigned int) (op - powerpc_opcodes),
+		      (unsigned int) new_opcode, (unsigned int) op->opcode,
+		      (unsigned int) op->mask, (unsigned long long) op->flags);
 #endif
 
 	      /* The major opcodes had better be sorted.  Code in the
@@ -1605,10 +1579,10 @@
 	      new_seg = VLE_OP_TO_SEG (new_seg);
 
 #ifdef PRINT_OPCODE_TABLE
-	      printf ("%-14s\t#%04d\tmajor op: 0x%x\top: 0x%x\tmask: 0x%x\tflags: 0x%llx\n",
-		      op->name, op - powerpc_opcodes, (unsigned int) new_opcode,
-		      (unsigned int) op->opcode, (unsigned int) op->mask,
-		      (unsigned long long) op->flags);
+	      printf ("%-14s\t#%04u\tmajor op: 0x%x\top: 0x%x\tmask: 0x%x\tflags: 0x%llx\n",
+		      op->name, (unsigned int) (op - powerpc_opcodes),
+		      (unsigned int) new_seg, (unsigned int) op->opcode,
+		      (unsigned int) op->mask, (unsigned long long) op->flags);
 #endif
 	      /* The major opcodes had better be sorted.  Code in the
 		 disassembler assumes the insns are sorted according to
@@ -2454,7 +2428,8 @@
 ppc_is_toc_sym (symbolS *sym)
 {
 #ifdef OBJ_XCOFF
-  return symbol_get_tc (sym)->symbol_class == XMC_TC;
+  return (symbol_get_tc (sym)->symbol_class == XMC_TC
+	  || symbol_get_tc (sym)->symbol_class == XMC_TC0);
 #endif
 #ifdef OBJ_ELF
   const char *sname = segment_name (S_GET_SEGMENT (sym));
@@ -6312,6 +6287,8 @@
 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 {
   valueT value = * valP;
+  offsetT fieldval;
+  const struct powerpc_operand *operand;
 
 #ifdef OBJ_ELF
   if (fixP->fx_addsy != NULL)
@@ -6350,16 +6327,13 @@
       as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
     }
 
+  operand = NULL;
   if (fixP->fx_pcrel_adjust != 0)
     {
-      /* Handle relocs in an insn.  */
-
+      /* This is a fixup on an instruction.  */
       int opindex = fixP->fx_pcrel_adjust & 0xff;
-      const struct powerpc_operand *operand = &powerpc_operands[opindex];
-      char *where;
-      unsigned long insn;
-      offsetT fieldval;
 
+      operand = &powerpc_operands[opindex];
 #ifdef OBJ_XCOFF
       /* An instruction like `lwz 9,sym(30)' when `sym' is not a TOC symbol
 	 does not generate a reloc.  It uses the offset of `sym' within its
@@ -6379,64 +6353,75 @@
 	  fixP->fx_done = 1;
 	}
 #endif
-      fieldval = value;
+    }
+
+  /* Calculate value to be stored in field.  */
+  fieldval = value;
+  switch (fixP->fx_r_type)
+    {
+#ifdef OBJ_ELF
+    case BFD_RELOC_PPC64_ADDR16_LO_DS:
+    case BFD_RELOC_PPC_VLE_LO16A:
+    case BFD_RELOC_PPC_VLE_LO16D:
+#endif
+    case BFD_RELOC_LO16:
+    case BFD_RELOC_LO16_PCREL:
+      fieldval = value & 0xffff;
+    sign_extend_16:
+      if (operand != NULL && (operand->flags & PPC_OPERAND_SIGNED) != 0)
+	fieldval = (fieldval ^ 0x8000) - 0x8000;
+      fixP->fx_no_overflow = 1;
+      break;
+
+#ifdef OBJ_ELF
+    case BFD_RELOC_PPC_VLE_HI16A:
+    case BFD_RELOC_PPC_VLE_HI16D:
+#endif
+    case BFD_RELOC_HI16:
+    case BFD_RELOC_HI16_PCREL:
+      fieldval = PPC_HI (value);
+      goto sign_extend_16;
+
+#ifdef OBJ_ELF
+    case BFD_RELOC_PPC_VLE_HA16A:
+    case BFD_RELOC_PPC_VLE_HA16D:
+#endif
+    case BFD_RELOC_HI16_S:
+    case BFD_RELOC_HI16_S_PCREL:
+      fieldval = PPC_HA (value);
+      goto sign_extend_16;
+
+#ifdef OBJ_ELF
+    case BFD_RELOC_PPC64_HIGHER:
+      fieldval = PPC_HIGHER (value);
+      goto sign_extend_16;
+
+    case BFD_RELOC_PPC64_HIGHER_S:
+      fieldval = PPC_HIGHERA (value);
+      goto sign_extend_16;
+
+    case BFD_RELOC_PPC64_HIGHEST:
+      fieldval = PPC_HIGHEST (value);
+      goto sign_extend_16;
+
+    case BFD_RELOC_PPC64_HIGHEST_S:
+      fieldval = PPC_HIGHESTA (value);
+      goto sign_extend_16;
+#endif
+
+    default:
+      break;
+    }
+
+  if (operand != NULL)
+    {
+      /* Handle relocs in an insn.  */
+      char *where;
+      unsigned long insn;
+
+#ifdef OBJ_ELF
       switch (fixP->fx_r_type)
 	{
-#ifdef OBJ_ELF
-	case BFD_RELOC_PPC64_ADDR16_LO_DS:
-	  if (fixP->fx_pcrel)
-	    goto bad_pcrel;
-	  /* fall through */
-#endif
-	case BFD_RELOC_LO16:
-	  if (fixP->fx_pcrel)
-	    fixP->fx_r_type = BFD_RELOC_LO16_PCREL;
-	  /* fall through */
-	case BFD_RELOC_LO16_PCREL:
-	  fieldval = SEX16 (value);
-	  break;
-
-	case BFD_RELOC_HI16:
-	  if (fixP->fx_pcrel)
-	    fixP->fx_r_type = BFD_RELOC_HI16_PCREL;
-	  /* fall through */
-	case BFD_RELOC_HI16_PCREL:
-	  fieldval = SEX16 (PPC_HI (value));
-	  break;
-
-	case BFD_RELOC_HI16_S:
-	  if (fixP->fx_pcrel)
-	    fixP->fx_r_type = BFD_RELOC_HI16_S_PCREL;
-	  /* fall through */
-	case BFD_RELOC_HI16_S_PCREL:
-	  fieldval = SEX16 (PPC_HA (value));
-	  break;
-
-#ifdef OBJ_ELF
-	case BFD_RELOC_PPC64_HIGHER:
-	  if (fixP->fx_pcrel)
-	    goto bad_pcrel;
-	  fieldval = SEX16 (PPC_HIGHER (value));
-	  break;
-
-	case BFD_RELOC_PPC64_HIGHER_S:
-	  if (fixP->fx_pcrel)
-	    goto bad_pcrel;
-	  fieldval = SEX16 (PPC_HIGHERA (value));
-	  break;
-
-	case BFD_RELOC_PPC64_HIGHEST:
-	  if (fixP->fx_pcrel)
-	    goto bad_pcrel;
-	  fieldval = SEX16 (PPC_HIGHEST (value));
-	  break;
-
-	case BFD_RELOC_PPC64_HIGHEST_S:
-	  if (fixP->fx_pcrel)
-	    goto bad_pcrel;
-	  fieldval = SEX16 (PPC_HIGHESTA (value));
-	  break;
-
 	  /* The following relocs can't be calculated by the assembler.
 	     Leave the field zero.  */
 	case BFD_RELOC_PPC_TPREL16:
@@ -6478,8 +6463,6 @@
 	  gas_assert (fixP->fx_addsy != NULL);
 	  S_SET_THREAD_LOCAL (fixP->fx_addsy);
 	  fieldval = 0;
-	  if (fixP->fx_pcrel)
-	    goto bad_pcrel;
 	  break;
 
 	  /* These also should leave the field zero for the same
@@ -6546,14 +6529,12 @@
 	case BFD_RELOC_PPC_TLSGD:
 	case BFD_RELOC_PPC_TLSLD:
 	  fieldval = 0;
-	  if (fixP->fx_pcrel)
-	    goto bad_pcrel;
 	  break;
-#endif
 
 	default:
 	  break;
 	}
+#endif
 
 #ifdef OBJ_ELF
 /* powerpc uses RELA style relocs, so if emitting a reloc the field
@@ -6625,79 +6606,9 @@
     }
   else
     {
-      int size = 0;
-      offsetT fieldval = value;
-
       /* Handle relocs in data.  */
       switch (fixP->fx_r_type)
 	{
-	case BFD_RELOC_CTOR:
-	  if (ppc_obj64)
-	    goto ctor64;
-	  /* fall through */
-
-	case BFD_RELOC_32:
-	  if (fixP->fx_pcrel)
-	    fixP->fx_r_type = BFD_RELOC_32_PCREL;
-	  /* fall through */
-
-	case BFD_RELOC_32_PCREL:
-	case BFD_RELOC_RVA:
-	  size = 4;
-	  break;
-
-	case BFD_RELOC_64:
-	ctor64:
-	  if (fixP->fx_pcrel)
-	    fixP->fx_r_type = BFD_RELOC_64_PCREL;
-	  /* fall through */
-
-	case BFD_RELOC_64_PCREL:
-	  size = 8;
-	  break;
-
-	case BFD_RELOC_16:
-	  if (fixP->fx_pcrel)
-	    fixP->fx_r_type = BFD_RELOC_16_PCREL;
-	  /* fall through */
-
-	case BFD_RELOC_16_PCREL:
-	  size = 2;
-	  break;
-
-	case BFD_RELOC_8:
-	  if (fixP->fx_pcrel)
-	    {
-#ifdef OBJ_ELF
-	    bad_pcrel:
-#endif
-	      if (fixP->fx_addsy)
-		{
-		  char *sfile;
-		  unsigned int sline;
-
-		  /* Use expr_symbol_where to see if this is an
-		     expression symbol.  */
-		  if (expr_symbol_where (fixP->fx_addsy, &sfile, &sline))
-		    as_bad_where (fixP->fx_file, fixP->fx_line,
-				  _("unresolved expression that must"
-				    " be resolved"));
-		  else
-		    as_bad_where (fixP->fx_file, fixP->fx_line,
-				  _("cannot emit PC relative %s relocation"
-				    " against %s"),
-				  bfd_get_reloc_code_name (fixP->fx_r_type),
-				  S_GET_NAME (fixP->fx_addsy));
-		}
-	      else
-		as_bad_where (fixP->fx_file, fixP->fx_line,
-			      _("unable to resolve expression"));
-	      fixP->fx_done = 1;
-	    }
-	  else
-	    size = 1;
-	  break;
-
 	case BFD_RELOC_VTABLE_INHERIT:
 	  if (fixP->fx_addsy
 	      && !S_IS_DEFINED (fixP->fx_addsy)
@@ -6712,54 +6623,15 @@
 #ifdef OBJ_ELF
 	  /* These can appear with @l etc. in data.  */
 	case BFD_RELOC_LO16:
-	  if (fixP->fx_pcrel)
-	    fixP->fx_r_type = BFD_RELOC_LO16_PCREL;
 	case BFD_RELOC_LO16_PCREL:
-	  size = 2;
-	  break;
-
 	case BFD_RELOC_HI16:
-	  if (fixP->fx_pcrel)
-	    fixP->fx_r_type = BFD_RELOC_HI16_PCREL;
 	case BFD_RELOC_HI16_PCREL:
-	  size = 2;
-	  fieldval = PPC_HI (value);
-	  break;
-
 	case BFD_RELOC_HI16_S:
-	  if (fixP->fx_pcrel)
-	    fixP->fx_r_type = BFD_RELOC_HI16_S_PCREL;
 	case BFD_RELOC_HI16_S_PCREL:
-	  size = 2;
-	  fieldval = PPC_HA (value);
-	  break;
-
 	case BFD_RELOC_PPC64_HIGHER:
-	  if (fixP->fx_pcrel)
-	    goto bad_pcrel;
-	  size = 2;
-	  fieldval = PPC_HIGHER (value);
-	  break;
-
 	case BFD_RELOC_PPC64_HIGHER_S:
-	  if (fixP->fx_pcrel)
-	    goto bad_pcrel;
-	  size = 2;
-	  fieldval = PPC_HIGHERA (value);
-	  break;
-
 	case BFD_RELOC_PPC64_HIGHEST:
-	  if (fixP->fx_pcrel)
-	    goto bad_pcrel;
-	  size = 2;
-	  fieldval = PPC_HIGHEST (value);
-	  break;
-
 	case BFD_RELOC_PPC64_HIGHEST_S:
-	  if (fixP->fx_pcrel)
-	    goto bad_pcrel;
-	  size = 2;
-	  fieldval = PPC_HIGHESTA (value);
 	  break;
 
 	case BFD_RELOC_PPC_DTPMOD:
@@ -6850,8 +6722,17 @@
 
 #ifdef OBJ_XCOFF
 	case BFD_RELOC_NONE:
-	  break;
 #endif
+	case BFD_RELOC_CTOR:
+	case BFD_RELOC_32:
+	case BFD_RELOC_32_PCREL:
+	case BFD_RELOC_RVA:
+	case BFD_RELOC_64:
+	case BFD_RELOC_64_PCREL:
+	case BFD_RELOC_16:
+	case BFD_RELOC_16_PCREL:
+	case BFD_RELOC_8:
+	  break;
 
 	default:
 	  fprintf (stderr,
@@ -6860,9 +6741,85 @@
 	  abort ();
 	}
 
-      if (size && APPLY_RELOC)
+      if (fixP->fx_size && APPLY_RELOC)
 	md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
-			    fieldval, size);
+			    fieldval, fixP->fx_size);
+    }
+
+  /* We are only able to convert some relocs to pc-relative.  */
+  if (!fixP->fx_done && fixP->fx_pcrel)
+    {
+      switch (fixP->fx_r_type)
+	{
+	case BFD_RELOC_LO16:
+	  fixP->fx_r_type = BFD_RELOC_LO16_PCREL;
+	  break;
+
+	case BFD_RELOC_HI16:
+	  fixP->fx_r_type = BFD_RELOC_HI16_PCREL;
+	  break;
+
+	case BFD_RELOC_HI16_S:
+	  fixP->fx_r_type = BFD_RELOC_HI16_S_PCREL;
+	  break;
+
+	case BFD_RELOC_64:
+	  fixP->fx_r_type = BFD_RELOC_64_PCREL;
+	  break;
+
+	case BFD_RELOC_32:
+	  fixP->fx_r_type = BFD_RELOC_32_PCREL;
+	  break;
+
+	case BFD_RELOC_16:
+	  fixP->fx_r_type = BFD_RELOC_16_PCREL;
+	  break;
+
+	  /* Some of course are already pc-relative.  */
+	case BFD_RELOC_LO16_PCREL:
+	case BFD_RELOC_HI16_PCREL:
+	case BFD_RELOC_HI16_S_PCREL:
+	case BFD_RELOC_64_PCREL:
+	case BFD_RELOC_32_PCREL:
+	case BFD_RELOC_16_PCREL:
+	case BFD_RELOC_PPC_B16:
+	case BFD_RELOC_PPC_B16_BRTAKEN:
+	case BFD_RELOC_PPC_B16_BRNTAKEN:
+	case BFD_RELOC_PPC_B26:
+	case BFD_RELOC_PPC_LOCAL24PC:
+	case BFD_RELOC_24_PLT_PCREL:
+	case BFD_RELOC_32_PLT_PCREL:
+	case BFD_RELOC_64_PLT_PCREL:
+	case BFD_RELOC_PPC_VLE_REL8:
+	case BFD_RELOC_PPC_VLE_REL15:
+	case BFD_RELOC_PPC_VLE_REL24:
+	  break;
+
+	default:
+	  if (fixP->fx_addsy)
+	    {
+	      char *sfile;
+	      unsigned int sline;
+
+	      /* Use expr_symbol_where to see if this is an
+		 expression symbol.  */
+	      if (expr_symbol_where (fixP->fx_addsy, &sfile, &sline))
+		as_bad_where (fixP->fx_file, fixP->fx_line,
+			      _("unresolved expression that must"
+				" be resolved"));
+	      else
+		as_bad_where (fixP->fx_file, fixP->fx_line,
+			      _("cannot emit PC relative %s relocation"
+				" against %s"),
+			      bfd_get_reloc_code_name (fixP->fx_r_type),
+			      S_GET_NAME (fixP->fx_addsy));
+	    }
+	  else
+	    as_bad_where (fixP->fx_file, fixP->fx_line,
+			  _("unable to resolve expression"));
+	  fixP->fx_done = 1;
+	  break;
+	}
     }
 
 #ifdef OBJ_ELF
diff --git a/gas/configure.tgt b/gas/configure.tgt
index da6f65a..f416149 100644
--- a/gas/configure.tgt
+++ b/gas/configure.tgt
@@ -121,7 +121,7 @@
 
   alpha-*-*vms*)			fmt=evax ;;
   alpha-*-osf*)				fmt=ecoff ;;
-  alpha-*-linuxecoff*)			fmt=ecoff ;;
+  alpha-*-linux*ecoff*)			fmt=ecoff ;;
   alpha-*-linux-*)			fmt=elf em=linux ;;
   alpha-*-netbsd*)			fmt=elf em=nbsd ;;
   alpha-*-openbsd*)			fmt=elf em=obsd ;;
diff --git a/gas/doc/c-mips.texi b/gas/doc/c-mips.texi
index 7df5f79..b8953be 100644
--- a/gas/doc/c-mips.texi
+++ b/gas/doc/c-mips.texi
@@ -181,6 +181,12 @@
 This tells the assembler to accept MCU instructions.
 @samp{-mno-mcu} turns off this option.
 
+@item -mvirt
+@itemx -mno-virt
+Generate code for the Virtualization Application Specific Extension.
+This tells the assembler to accept Virtualization instructions.
+@samp{-mno-virt} turns off this option.
+
 @item -mfix7000
 @itemx -mno-fix7000
 Cause nops to be inserted if the read of the destination register
@@ -684,6 +690,14 @@
 in the assembly.  The @code{.set nomcu} directive prevents MCU
 instructions from being accepted.
 
+@cindex Virtualization instruction generation override
+@kindex @code{.set virt}
+@kindex @code{.set novirt}
+The directive @code{.set virt} makes the assembler accept instructions
+from the Virtualization Application Specific Extension from that point
+on in the assembly.  The @code{.set novirt} directive prevents Virtualization
+instructions from being accepted.
+
 Traditional @sc{mips} assemblers do not support these directives.
 
 @node MIPS floating-point
diff --git a/gas/doc/c-msp430.texi b/gas/doc/c-msp430.texi
index 4beb90a..538133a 100644
--- a/gas/doc/c-msp430.texi
+++ b/gas/doc/c-msp430.texi
@@ -1,4 +1,4 @@
-@c Copyright 2002, 2004, 2005, 2011 Free Software Foundation, Inc.
+@c Copyright 2002-2013 Free Software Foundation, Inc.
 @c This is part of the GAS manual.
 @c For copying conditions, see the file as.texinfo.
 @ifset GENERIC
@@ -28,14 +28,35 @@
 @cindex options for MSP430 (none)
 @table @code
 
-@item -m
-select the mpu arch. Currently has no effect.
+@item -mmcu
+selects the mpu arch.  If the architecture is 430Xv2 then this also
+enables NOP generation unless the @option{-mN} is also specified.
+
+@item -mcpu
+selects the cpu architecture.  If the architecture is 430Xv2 then this
+also enables NOP generation unless the @option{-mN} is also
+specified.
+
 @item -mP
 enables polymorph instructions handler.
 
 @item -mQ
 enables relaxation at assembly time. DANGEROUS!
 
+@item -ml
+indicates that the input uses the large code model.
+
+@item -mN
+disables the generation of a NOP instruction following any instruction
+that might change the interrupts enabled/disabled state.  For the
+430Xv2 architecture the instructions: @code{EINT}, @code{DINT},
+@code{BIC #8, SR}, @code{BIS #8, SR} and @code{MOV.W <>, SR} must be
+followed by a NOP instruction in order to ensure the correct
+processing of interrupts.  By default generation of the NOP
+instruction happens automatically, but this command line option
+disables this behaviour.  It is then up to the programmer to ensure
+that interrupts are enabled and disabled correctly.
+
 @end table
 
 @node MSP430 Syntax
@@ -215,10 +236,15 @@
 This directive is ignored; it is accepted for compatibility with other
 MSP 430 assemblers.
 
-@cindex @code{sect} directive, MSP 430
+@cindex @code{arch} directive, MSP 430
 @item .arch
-Currently this directive is ignored; it is accepted for compatibility with other
-MSP 430 assemblers.
+Sets the target microcontroller in the same way as the @option{-mmcu}
+command line option.
+
+@cindex @code{cpu} directive, MSP 430
+@item .cpu
+Sets the target architecture in the same way as the @option{-mcpu}
+command line option.
 
 @cindex @code{profiler} directive, MSP 430
 @item .profiler
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index ed42859..faa07c1 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,113 @@
+2013-05-23  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
+	* gas/s390/zarch-zEC12.d: Adjust length operands for cdzt, cxzt,
+	czdt, and czxt.
+	* gas/s390/zarch-zEC12.d: Likewise.
+
+2013-05-22  Jürgen Urban  <JuergenUrban@gmx.de>
+
+	* gas/mips/r5900-full.s, gas/mips/r5900-full.d: Add tests for LQ
+	and SQ macros.
+	* gas/mips/r5900-vu0.s, gas/mips/r5900-vu0.d: New test.
+	* gas/mips/mips.exp: Run it.
+
+2013-05-21  Alan Modra  <amodra@gmail.com>
+
+	* gas/ppc/vsx2.d: Ignore trailing padding.
+
+2013-05-20  Peter Bergner <bergner@vnet.ibm.com>
+
+	* gas/ppc/altivec2.d <bcdadd., bcdadd., vaddcuq, vaddecuq, vaddeuqm,
+	vaddudm, vadduqm, vbpermq, vcipher, vcipherlast, vclzb, vclzd, vclzh,
+	vclzw, vcmpequd, vcmpequd., vcmpgtsd, vcmpgtsd., vcmpgtud, vcmpgtud.,
+	veqv, vgbbd, vmaxsd, vmaxud, vminsd, vminud, vmrgew, vmrgow, vmulesw,
+	vmuleuw, vmulosw, vmulouw, vmuluwm, vnand, vncipher, vncipherlast,
+	vorc, vpermxor, vpksdss, vpksdus, vpkudum, vpkudus, vpmsumb, vpmsumd,
+	vpmsumh, vpmsumw, vpopcntb, vpopcntd, vpopcnth, vpopcntw, vrld, vsbox,
+	vshasigmad, vshasigmaw, vsld, vsrad, vsrd, vsubcuq, vsubecuq, vsubeuqm,
+	vsubudm, vsubuqm, vupkhsw, vupklsw>: Add new tests.
+	* gas/ppc/altivec2.s: Likewise.
+	* gas/ppc/power8.d <bcdadd., bcdsub., bctar, bctarl, clrbhrb, fmrgew,
+	fmrgow, lqarx, lxsiwax, lxsiwzx, lxsspx, mfbhrbe, mfvsrd, mfvsrwz,
+	msgclrp, msgsndp, mtsle, mtvsrd, mtvsrwa, mtvsrwz, pbt., rfebb,
+	stqcx., stxsiwx, stxsspx, vaddcuq, vaddecuq, vaddeuqm, vaddudm,
+	vadduqm, vbpermq, vcipher, vcipherlast, vclzb, vclzd, vclzh, vclzw,
+	vcmpequd, vcmpequd., vcmpgtsd, vcmpgtsd., vcmpgtud, vcmpgtud., veqv,
+	vgbbd, vmaxsd, vmaxud, vminsd, vminud, vmrgow, vmulesw, vmuleuw,
+	vmulosw, vmulouw, vmuluwm, vnand, vncipher, vncipherlast, vorc,
+	vpermxor, vpksdss, vpksdus, vpkudum, vpkudus, vpmsumb, vpmsumd,
+	vpmsumh, vpmsumw, vpopcntb, vpopcntd, vpopcnth, vpopcntw, vrld, vsbox,
+	vshasigmad, vshasigmaw, vsld, vsrad, vsrd, vsubcuq, vsubecuq, vsubeuqm,
+	vsubuqm, vupkhsw, vupklsw, waitasec, xsaddsp, xscvdpspn, xscvspdpn,
+	xscvsxdsp, xscvuxdsp, xsdivsp, xsmaddasp, xsmaddmsp, xsmsubasp,
+	xsmsubmsp, xsmulsp, xsnmaddasp, xsnmaddmsp, xsnmsubasp, xsnmsubmsp,
+	xsresp, xsrsp, xsrsqrtesp, xssqrtsp, xssubsp, xxleqv, xxlnand,
+	xxlorc>: Add new tests.
+	* gas/ppc/power8.s Likewise.
+	* gas/ppc/vsx.d <lxvd2x, stxvd2x>: Add new tests.
+	* gas/ppc/vsx.s Likewise.
+	* gas/ppc/vsx2.d: New test file.
+	* gas/ppc/vsx2.s: Likewise.
+	* gas/ppc/ppc.exp: Run it.
+
+2013-05-16  Tristan Gingold  <gingold@adacore.com>
+
+	* gas/ppc/ppc.exp: Do not run simpshft on aix.
+
+2013-05-16  Nick Clifton  <nickc@redhat.com>
+
+	* gas/msp430/opcodes.s: Use correct value for .arch pseudo.
+	* gas/msp430/msp430x.d: Use correct value for -mcpu option.
+
+2013-05-13  Yufeng Zhang  <yufeng.zhang@arm.com>
+
+	* gas/aarch64/diagnostic.s: Update.
+	* gas/aarch64/diagnostic.l: Ditto.
+	* gas/aarch64/movi.s: Add new tests.
+	* gas/aarch64/movi.d: Update.
+
+2013-05-09  Andrew Pinski  <apinski@cavium.com>
+
+	* gas/mips/mips.exp: Run virt and virt64 testcases.
+	* gas/mips/virt.d: New file.
+	* gas/mips/virt.s: New file.
+	* gas/mips/virt64.d: New file.
+	* gas/mips/virt64.s: New file.
+
+2013-05-04  Richard Sandiford  <rdsandiford@googlemail.com>
+
+	* gas/mips/micromips-warn-branch-delay.d: Use numeric registers.
+
+2013-05-02  Richard Sandiford  <rdsandiford@googlemail.com>
+
+	* gas/mips/mips16-stabs.s, gas/mips/mips16-stabs.d: New test.
+	* gas/mips/mips.exp: Run it.
+
+2013-05-02  Nick Clifton  <nickc@redhat.com>
+
+	* gas/all/gas.exp: Skip the DIFF1 test for the MSP430.
+	Expect the FORWARD test to pass for the MSP430.
+	Skip the REDEF tests for the MSP430.
+	Expect the 930509A test to fail for the MSP430.
+	* gas/all/sleb128-4.d: Skip for the MSP430.
+	* gas/elf/elf.exp: Set target_machine to msp430 for the MSP430.
+	Skip the EHOPT0 test for the MSP430.
+	Skip the REDEF and EQU-RELOC tests for the MSP430.
+	* gas/elf/section2.e-msp430: New file.
+	* gas/lns/lns-big-delta.d: Remove expectation of 20-bit
+	addresses.
+	* gas/lns/lns.exp: Use alternate LNS COMMON test for the MSP430.
+	* gas/msp430/msp430x.s: New test.
+	* gas/msp430/msp430x.d: Expected disassembly.
+	* gas/msp430/msp430.exp: Run new test.
+	* gas/msp430/opcode.d: Update expected disassembly.
+
+2013-04-30  Chao-ying Fu  <Chao-ying.Fu@imgtec.com>
+
+	* gas/mips/ext-ill.s: New file.
+	* gas/mips/ext-ill.l: New file.
+	* gas/mips/mips.exp: Run new tests.
+
 2013-04-29  Nick Clifton  <nickc@redhat.com>
 
 	* gas/elf/dwarf2-3.d: Fix expected readelf output.
diff --git a/gas/testsuite/gas/aarch64/diagnostic.l b/gas/testsuite/gas/aarch64/diagnostic.l
index 0a08011..cca8881 100644
--- a/gas/testsuite/gas/aarch64/diagnostic.l
+++ b/gas/testsuite/gas/aarch64/diagnostic.l
@@ -38,8 +38,8 @@
 [^:]*:40: Error: invalid shift amount at operand 3 -- `shll v1.4s,v2.4h,#32'
 [^:]*:41: Error: immediate value out of range 0 to 31 at operand 3 -- `shl v1.2s,v2.2s,32'
 [^:]*:42: Error: immediate value out of range 1 to 8 at operand 3 -- `sqshrn2 v2.16b,v3.8h,#17'
-[^:]*:43: Error: immediate value out of range 0 to 255 at operand 2 -- `movi v1.4h,256'
-[^:]*:44: Error: immediate value out of range 0 to 255 at operand 2 -- `movi v1.4h,-1'
+[^:]*:43: Error: immediate value out of range -128 to 255 at operand 2 -- `movi v1.4h,256'
+[^:]*:44: Error: immediate value out of range -128 to 255 at operand 2 -- `movi v1.4h,-129'
 [^:]*:45: Error: invalid shift operator at operand 2 -- `movi v1.4h,255,msl#8'
 [^:]*:46: Error: invalid value for immediate at operand 2 -- `movi d0,256'
 [^:]*:47: Error: immediate value should be a multiple of 8 at operand 2 -- `movi v1.4h,255,lsl#7'
diff --git a/gas/testsuite/gas/aarch64/diagnostic.s b/gas/testsuite/gas/aarch64/diagnostic.s
index 99ebf8f..e5443ab 100644
--- a/gas/testsuite/gas/aarch64/diagnostic.s
+++ b/gas/testsuite/gas/aarch64/diagnostic.s
@@ -41,7 +41,7 @@
 	shl	v1.2s, v2.2s, 32
 	sqshrn2	v2.16b, v3.8h, #17
 	movi	v1.4h, 256
-	movi	v1.4h, -1
+	movi	v1.4h, -129
 	movi	v1.4h, 255, msl #8
 	movi	d0, 256
 	movi	v1.4h, 255, lsl #7
diff --git a/gas/testsuite/gas/aarch64/movi.d b/gas/testsuite/gas/aarch64/movi.d
index cd54cfd..e159e47 100644
--- a/gas/testsuite/gas/aarch64/movi.d
+++ b/gas/testsuite/gas/aarch64/movi.d
@@ -8713,3 +8713,6 @@
     8804:	6f07e7e0 	movi	v0.2d, #0xffffffffffffffff
     8808:	6f07e7e0 	movi	v0.2d, #0xffffffffffffffff
     880c:	2f07e7ff 	movi	d31, #0xffffffffffffffff
+    8810:	0f04e403 	movi	v3.8b, #0x80
+    8814:	0f04e423 	movi	v3.8b, #0x81
+    8818:	0f07e7e3 	movi	v3.8b, #0xff
diff --git a/gas/testsuite/gas/aarch64/movi.s b/gas/testsuite/gas/aarch64/movi.s
index a650790..3a15e3d 100644
--- a/gas/testsuite/gas/aarch64/movi.s
+++ b/gas/testsuite/gas/aarch64/movi.s
@@ -113,3 +113,8 @@
 	movi	v0.2d, bignum
 	movi	d31, 18446744073709551615
 .set    bignum, 0xffffffffffffffff
+
+	// Allow -128 to 255 in #<imm8>
+	movi	v3.8b, -128
+	movi	v3.8b, -127
+	movi	v3.8b, -1
diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp
index 709b448..f604ac9 100644
--- a/gas/testsuite/gas/all/gas.exp
+++ b/gas/testsuite/gas/all/gas.exp
@@ -61,6 +61,7 @@
      && ![istarget alpha*-*-*vms*]
      && ![istarget rx-*-*]
      && ![istarget mn10300-*-*]
+     && ![istarget msp430*-*-*]
      && ![istarget am3*-*-*] } then {
     gas_test_error "diff1.s" "" "difference of two undefined symbols"
 }
@@ -99,7 +100,7 @@
     default {
 	# Some targets don't manage to resolve BFD_RELOC_8 for constants.
 	setup_xfail "alpha*-*-*" "*c30*-*-*" "*c4x*-*-*" \
-	    "d\[13\]0v*-*-*" "i860-*-*" "mips*-*-*" "msp430-*-*" \
+	    "d\[13\]0v*-*-*" "i860-*-*" "mips*-*-*" \
 	    "pdp11-*-*" "xtensa*-*-*"
 	run_dump_test forward
     }
@@ -139,6 +140,7 @@
     { mips*-*-* } { }
     { mn10200-*-* } { }
     { mn10300-*-* } { }
+    { msp430*-*-* } { }
     { pdp11-*-* } { }
     { tic30*-*-* } { }
     { tic4x*-*-* } { }
@@ -266,8 +268,8 @@
      ![istarget *c54x*-*-*] } then {
     # the vax fails because VMS can apparently actually handle this
     # case in relocs, so gas doesn't handle it itself.
-    # mn10300 emits two relocs to handle the difference of two symbols.
-    setup_xfail "mn10300*-*-*" "vax*-*-vms*"
+    # msp430 and mn10300 emit two relocs to handle the difference of two symbols.
+    setup_xfail "mn10300*-*-*" "msp430*-*-*" "vax*-*-vms*"
     do_930509a
 }
 
diff --git a/gas/testsuite/gas/all/sleb128-4.d b/gas/testsuite/gas/all/sleb128-4.d
index 0c56696..89b9565 100644
--- a/gas/testsuite/gas/all/sleb128-4.d
+++ b/gas/testsuite/gas/all/sleb128-4.d
@@ -1,5 +1,6 @@
 #objdump : -s -j .data -j "\$DATA\$"
 #name : .sleb128 tests (4)
+#skip: msp430*-*-*
 
 .*: .*
 
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index 9ffd257..4196fd7 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -1,5 +1,4 @@
-# Copyright 2012
-# Free Software Foundation, Inc.
+# Copyright 2012-2013 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -62,6 +61,9 @@
     if {[istarget m32r*-*-*]} then {
 	set target_machine -m32r
     }
+    if {[istarget "msp430-*-*"]} then {
+	set target_machine -msp430
+    }
     if {[istarget "score-*-*"]} then {
 	set target_machine -score
     }
@@ -91,6 +93,7 @@
     # function prologues.
     if {![istarget "mn10300-*-*"]
 	&& ![istarget "xtensa*-*-*"]
+	&& ![istarget "msp430*-*-*"]
 	&& ![istarget "am3*-*-*"]} then {
       run_dump_test "ehopt0"
     }
@@ -136,6 +139,7 @@
 	{ mips*-*-* } { }
 	{ mn10200-*-* } { }
 	{ mn10300-*-* } { }
+	{ msp43*-*-* } { }
 	{ *c54x*-*-* } { }
 	{ rx-*-* } { }
 	default {
diff --git a/gas/testsuite/gas/elf/section2.e-msp430 b/gas/testsuite/gas/elf/section2.e-msp430
new file mode 100644
index 0000000..115bae2
--- /dev/null
+++ b/gas/testsuite/gas/elf/section2.e-msp430
@@ -0,0 +1,9 @@
+
+Symbol table '.symtab' contains 6 entries:
+ +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +0: 0+0 +0 +NOTYPE +LOCAL +DEFAULT +UND 
+ +1: 0+0 +0 +SECTION +LOCAL +DEFAULT +1 
+ +2: 0+0 +0 +SECTION +LOCAL +DEFAULT +2 
+ +3: 0+0 +0 +SECTION +LOCAL +DEFAULT +3 
+ +4: 0+0 +0 +SECTION +LOCAL +DEFAULT +4 
+ +5: 0+0 +0 +SECTION +LOCAL +DEFAULT +5 
diff --git a/gas/testsuite/gas/lns/lns-big-delta.d b/gas/testsuite/gas/lns/lns-big-delta.d
index b6a113e..f4bdcf4 100644
--- a/gas/testsuite/gas/lns/lns-big-delta.d
+++ b/gas/testsuite/gas/lns/lns-big-delta.d
@@ -10,8 +10,8 @@
   Advance PC by fixed size amount 0 to 0x0
   Copy
   Advance Line by 1 to 3
-  Extended opcode 2: set Address to 0x.....
+  Extended opcode 2: set Address to 0x.*
   Copy
-  Advance PC by fixed size amount . to 0x.....
+  Advance PC by fixed size amount . to 0x.*
   Extended opcode 1: End of Sequence
 #pass
diff --git a/gas/testsuite/gas/lns/lns.exp b/gas/testsuite/gas/lns/lns.exp
index 0febe0b..f1d7f98 100644
--- a/gas/testsuite/gas/lns/lns.exp
+++ b/gas/testsuite/gas/lns/lns.exp
@@ -38,6 +38,7 @@
 	 || [istarget am3*-*-*]
 	 || [istarget cr16-*-*]
 	 || [istarget crx-*-*]
+	 || [istarget msp430-*-*]
 	 || [istarget mn10*-*-*] } {
       run_dump_test "lns-common-1-alt"
       run_dump_test "lns-big-delta"
diff --git a/gas/testsuite/gas/mips/ext-ill.l b/gas/testsuite/gas/mips/ext-ill.l
new file mode 100644
index 0000000..0f4ed35
--- /dev/null
+++ b/gas/testsuite/gas/mips/ext-ill.l
@@ -0,0 +1,6 @@
+.*: Assembler messages:
+.*:5: Error: Improper extract size \(0, position 1\)
+.*:6: Error: Improper extract size \(0, position 1\)
+.*:7: Error: Improper extract size \(2, position 31\)
+.*:8: Error: Improper extract size \(32, position 1\)
+.*:9: Error: Improper extract size \(0, position 33\)
diff --git a/gas/testsuite/gas/mips/ext-ill.s b/gas/testsuite/gas/mips/ext-ill.s
new file mode 100644
index 0000000..e4ce35a
--- /dev/null
+++ b/gas/testsuite/gas/mips/ext-ill.s
@@ -0,0 +1,9 @@
+# source file to test illegal ext, dext, dextm, dextu instructions
+
+	.text
+text_label:
+	ext	$2, $3, 1, 0
+	dext	$2, $3, 1, 0
+	dextm	$2, $3, 31, 2
+	dextm	$2, $3, 1, 32
+	dextu	$2, $3, 33, 0
diff --git a/gas/testsuite/gas/mips/micromips-warn-branch-delay.d b/gas/testsuite/gas/mips/micromips-warn-branch-delay.d
index fde0af5..936dab7 100644
--- a/gas/testsuite/gas/mips/micromips-warn-branch-delay.d
+++ b/gas/testsuite/gas/mips/micromips-warn-branch-delay.d
@@ -1,4 +1,4 @@
-#objdump: -dr --show-raw-insn
+#objdump: -dr --show-raw-insn -M gpr-names=numeric
 #name: microMIPS fixed-size branch delay slots
 #as: -mmicromips
 #source: micromips-warn-branch-delay.s
@@ -9,18 +9,18 @@
 Disassembly of section \.text:
 
 [0-9a-f]+ <foo>:
-[ 0-9a-f]+:	45e2      	jalrs	v0
-[ 0-9a-f]+:	0083 1250 	and	v0,v1,a0
-[ 0-9a-f]+:	45e2      	jalrs	v0
-[ 0-9a-f]+:	6043 9000 	swr	v0,0\(v1\)
-[ 0-9a-f]+:	45e2      	jalrs	v0
-[ 0-9a-f]+:	6043 8000 	swl	v0,0\(v1\)
-[ 0-9a-f]+:	45e2      	jalrs	v0
-[ 0-9a-f]+:	0272 8210 	mul	s0,s2,s3
-[ 0-9a-f]+:	45e2      	jalrs	v0
-[ 0-9a-f]+:	001f 8b90 	sltu	s1,ra,zero
-[ 0-9a-f]+:	45e2      	jalrs	v0
-[ 0-9a-f]+:	0220 8910 	add	s1,zero,s1
-[ 0-9a-f]+:	45e2      	jalrs	v0
-[ 0-9a-f]+:	01b1 8990 	sub	s1,s1,t5
+[ 0-9a-f]+:	45e2      	jalrs	\$2
+[ 0-9a-f]+:	0083 1250 	and	\$2,\$3,\$4
+[ 0-9a-f]+:	45e2      	jalrs	\$2
+[ 0-9a-f]+:	6043 9000 	swr	\$2,0\(\$3\)
+[ 0-9a-f]+:	45e2      	jalrs	\$2
+[ 0-9a-f]+:	6043 8000 	swl	\$2,0\(\$3\)
+[ 0-9a-f]+:	45e2      	jalrs	\$2
+[ 0-9a-f]+:	0272 8210 	mul	\$16,\$18,\$19
+[ 0-9a-f]+:	45e2      	jalrs	\$2
+[ 0-9a-f]+:	001f 8b90 	sltu	\$17,\$31,\$0
+[ 0-9a-f]+:	45e2      	jalrs	\$2
+[ 0-9a-f]+:	0220 8910 	add	\$17,\$0,\$17
+[ 0-9a-f]+:	45e2      	jalrs	\$2
+[ 0-9a-f]+:	01b1 8990 	sub	\$17,\$17,\$13
 #pass
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 145824a..aef771a 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -786,6 +786,9 @@
     run_dump_test "lineno"
     run_dump_test "sync"
 
+    run_dump_test_arches "virt" [mips_arch_list_matching mips32r2 !micromips]
+    run_dump_test_arches "virt64" [mips_arch_list_matching mips64r2 !micromips]
+
     run_dump_test_arches "mips32"	[mips_arch_list_matching mips32]
     run_dump_test_arches "mips32-imm"	[mips_arch_list_matching mips32]
 
@@ -1086,6 +1089,7 @@
 	if $has_newabi {
 	    run_dump_test "mips16-dwarf2-n32"
 	}
+	run_dump_test "mips16-stabs"
     }
     if { !$no_mips16 } { 
         run_dump_test "mips16e-jrc"
@@ -1169,4 +1173,7 @@
     run_dump_test "r5900"
     run_dump_test "r5900-full"
     if $elf { run_list_test "r5900-nollsc" "-mabi=o64 -march=r5900" }
+    run_dump_test "r5900-vu0"
+
+    run_list_test_arches "ext-ill"	[mips_arch_list_matching mips64r2]
 }
diff --git a/gas/testsuite/gas/mips/mips16-stabs.d b/gas/testsuite/gas/mips/mips16-stabs.d
new file mode 100644
index 0000000..db7673a
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips16-stabs.d
@@ -0,0 +1,6 @@
+#as: -mips3 -EB
+#objdump: -dr
+#...
+0+ <foo>:
+   0:	e820      	jr	ra
+#pass
diff --git a/gas/testsuite/gas/mips/mips16-stabs.s b/gas/testsuite/gas/mips/mips16-stabs.s
new file mode 100644
index 0000000..f44ad6a
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips16-stabs.s
@@ -0,0 +1,8 @@
+	.align	2
+	.set	mips16
+	.globl	foo
+	.ent	foo
+foo:
+	.stabs	"foo:F(0,49)",36,0,0,foo
+	jr	$31
+	.end	foo
diff --git a/gas/testsuite/gas/mips/r5900-full.d b/gas/testsuite/gas/mips/r5900-full.d
index 26d97ca..9689209 100644
--- a/gas/testsuite/gas/mips/r5900-full.d
+++ b/gas/testsuite/gas/mips/r5900-full.d
@@ -43,10 +43,28 @@
 [0-9a-f]+ <[^>]*> 7c217fff 	sq	\$1,32767\(\$1\)
 [0-9a-f]+ <[^>]*> 7d088000 	sq	\$8,-32768\(\$8\)
 [0-9a-f]+ <[^>]*> 7fffffff 	sq	\$31,-1\(\$31\)
+[0-9a-f]+ <[^>]*> 3c010001 	lui	\$1,0x1
+[0-9a-f]+ <[^>]*> 00220821 	addu	\$1,\$1,\$2
+[0-9a-f]+ <[^>]*> 7c208000 	sq	\$0,-32768\(\$1\)
+[0-9a-f]+ <[^>]*> 3c01ffff 	lui	\$1,0xffff
+[0-9a-f]+ <[^>]*> 003f0821 	addu	\$1,\$1,\$31
+[0-9a-f]+ <[^>]*> 7c287fff 	sq	\$8,32767\(\$1\)
+[0-9a-f]+ <[^>]*> 3c01f123 	lui	\$1,0xf123
+[0-9a-f]+ <[^>]*> 00240821 	addu	\$1,\$1,\$4
+[0-9a-f]+ <[^>]*> 7c3f4567 	sq	\$31,17767\(\$1\)
 [0-9a-f]+ <[^>]*> 78000000 	lq	\$0,0\(\$0\)
 [0-9a-f]+ <[^>]*> 78217fff 	lq	\$1,32767\(\$1\)
 [0-9a-f]+ <[^>]*> 79088000 	lq	\$8,-32768\(\$8\)
 [0-9a-f]+ <[^>]*> 7bffffff 	lq	\$31,-1\(\$31\)
+[0-9a-f]+ <[^>]*> 3c030001 	lui	\$3,0x1
+[0-9a-f]+ <[^>]*> 00621821 	addu	\$3,\$3,\$2
+[0-9a-f]+ <[^>]*> 78638000 	lq	\$3,-32768\(\$3\)
+[0-9a-f]+ <[^>]*> 3c08ffff 	lui	\$8,0xffff
+[0-9a-f]+ <[^>]*> 011f4021 	addu	\$8,\$8,\$31
+[0-9a-f]+ <[^>]*> 79087fff 	lq	\$8,32767\(\$8\)
+[0-9a-f]+ <[^>]*> 3c1ff123 	lui	\$31,0xf123
+[0-9a-f]+ <[^>]*> 03e4f821 	addu	\$31,\$31,\$4
+[0-9a-f]+ <[^>]*> 7bff4567 	lq	\$31,17767\(\$31\)
 [0-9a-f]+ <[^>]*> cc000000 	pref	0x0,0\(\$0\)
 [0-9a-f]+ <[^>]*> cc217fff 	pref	0x1,32767\(\$1\)
 [0-9a-f]+ <[^>]*> cd088000 	pref	0x8,-32768\(\$8\)
diff --git a/gas/testsuite/gas/mips/r5900-full.s b/gas/testsuite/gas/mips/r5900-full.s
index f3c2454..9560dc7 100644
--- a/gas/testsuite/gas/mips/r5900-full.s
+++ b/gas/testsuite/gas/mips/r5900-full.s
@@ -53,7 +53,7 @@
 	trunc.w.s $f0, $f31
 	trunc.w.s $f31, $f0
 
-	# Test ei/di, but not the R5900 has a bug. ei/di should not be used.
+	# Test ei/di, but the R5900 has a bug. ei/di should not be used.
 	di
 	ei
 
@@ -68,12 +68,20 @@
 	sq $1, 0x7fff($1)
 	sq $8, -0x8000($8)
 	sq $31, -1($31)
+	.set at
+	sq $0, 0x8000($2)
+	sq $8, -0x8001($31)
+	sq $31, 0xF1234567($4)
+	.set noat
 
 	# 128 bit load instruction.
 	lq $0, 0($0)
 	lq $1, 0x7fff($1)
 	lq $8, -0x8000($8)
 	lq $31, -1($31)
+	lq $3, 0x8000($2)
+	lq $8, -0x8001($31)
+	lq $31, 0xF1234567($4)
 
 	# Prefetch cache
 	pref 0, 0($0)
@@ -210,7 +218,7 @@
 	rsqrt.s $f0, $f31, $f0
 	rsqrt.s $f31, $f0, $f31
 
-	# FLoating point subtract to accumulator
+	# Floating point subtract to accumulator
 	suba.s $f0, $f31
 	suba.s $f31, $f0
 
diff --git a/gas/testsuite/gas/mips/r5900-vu0.d b/gas/testsuite/gas/mips/r5900-vu0.d
new file mode 100644
index 0000000..8375946
--- /dev/null
+++ b/gas/testsuite/gas/mips/r5900-vu0.d
@@ -0,0 +1,66 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=numeric -mmips:5900
+#name: MIPS R5900 VU0
+#as: -march=r5900
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> d8000000 	lqc2	\$0,0\(\$0\)
+[0-9a-f]+ <[^>]*> d8217fff 	lqc2	\$1,32767\(\$1\)
+[0-9a-f]+ <[^>]*> d9088000 	lqc2	\$8,-32768\(\$8\)
+[0-9a-f]+ <[^>]*> dbffffff 	lqc2	\$31,-1\(\$31\)
+[0-9a-f]+ <[^>]*> 3c010001 	lui	\$1,0x1
+[0-9a-f]+ <[^>]*> 00220821 	addu	\$1,\$1,\$2
+[0-9a-f]+ <[^>]*> d8208000 	lqc2	\$0,-32768\(\$1\)
+[0-9a-f]+ <[^>]*> 3c01ffff 	lui	\$1,0xffff
+[0-9a-f]+ <[^>]*> 003f0821 	addu	\$1,\$1,\$31
+[0-9a-f]+ <[^>]*> d8287fff 	lqc2	\$8,32767\(\$1\)
+[0-9a-f]+ <[^>]*> 3c01f123 	lui	\$1,0xf123
+[0-9a-f]+ <[^>]*> 00240821 	addu	\$1,\$1,\$4
+[0-9a-f]+ <[^>]*> d83f4567 	lqc2	\$31,17767\(\$1\)
+[0-9a-f]+ <[^>]*> f8000000 	sqc2	\$0,0\(\$0\)
+[0-9a-f]+ <[^>]*> f8217fff 	sqc2	\$1,32767\(\$1\)
+[0-9a-f]+ <[^>]*> f9088000 	sqc2	\$8,-32768\(\$8\)
+[0-9a-f]+ <[^>]*> fbffffff 	sqc2	\$31,-1\(\$31\)
+[0-9a-f]+ <[^>]*> 3c010001 	lui	\$1,0x1
+[0-9a-f]+ <[^>]*> 00220821 	addu	\$1,\$1,\$2
+[0-9a-f]+ <[^>]*> f8208000 	sqc2	\$0,-32768\(\$1\)
+[0-9a-f]+ <[^>]*> 3c01ffff 	lui	\$1,0xffff
+[0-9a-f]+ <[^>]*> 003f0821 	addu	\$1,\$1,\$31
+[0-9a-f]+ <[^>]*> f8287fff 	sqc2	\$8,32767\(\$1\)
+[0-9a-f]+ <[^>]*> 3c01f123 	lui	\$1,0xf123
+[0-9a-f]+ <[^>]*> 00240821 	addu	\$1,\$1,\$4
+[0-9a-f]+ <[^>]*> f83f4567 	sqc2	\$31,17767\(\$1\)
+[0-9a-f]+ <[^>]*> 48400000 	cfc2	\$0,\$0
+[0-9a-f]+ <[^>]*> 4840f800 	cfc2	\$0,\$31
+[0-9a-f]+ <[^>]*> 48400001 	cfc2.i	\$0,\$0
+[0-9a-f]+ <[^>]*> 4840f801 	cfc2.i	\$0,\$31
+[0-9a-f]+ <[^>]*> 48400000 	cfc2	\$0,\$0
+[0-9a-f]+ <[^>]*> 4840f800 	cfc2	\$0,\$31
+[0-9a-f]+ <[^>]*> 48c00000 	ctc2	\$0,\$0
+[0-9a-f]+ <[^>]*> 48c0f800 	ctc2	\$0,\$31
+[0-9a-f]+ <[^>]*> 48c00001 	ctc2.i	\$0,\$0
+[0-9a-f]+ <[^>]*> 48c0f801 	ctc2.i	\$0,\$31
+[0-9a-f]+ <[^>]*> 48c00000 	ctc2	\$0,\$0
+[0-9a-f]+ <[^>]*> 48c0f800 	ctc2	\$0,\$31
+[0-9a-f]+ <[^>]*> 48200000 	qmfc2	\$0,\$0
+[0-9a-f]+ <[^>]*> 4820f800 	qmfc2	\$0,\$31
+[0-9a-f]+ <[^>]*> 48200001 	qmfc2.i	\$0,\$0
+[0-9a-f]+ <[^>]*> 4820f801 	qmfc2.i	\$0,\$31
+[0-9a-f]+ <[^>]*> 48200000 	qmfc2	\$0,\$0
+[0-9a-f]+ <[^>]*> 4820f800 	qmfc2	\$0,\$31
+[0-9a-f]+ <[^>]*> 48a00000 	qmtc2	\$0,\$0
+[0-9a-f]+ <[^>]*> 48a0f800 	qmtc2	\$0,\$31
+[0-9a-f]+ <[^>]*> 48a00001 	qmtc2.i	\$0,\$0
+[0-9a-f]+ <[^>]*> 48a0f801 	qmtc2.i	\$0,\$31
+[0-9a-f]+ <[^>]*> 48a00000 	qmtc2	\$0,\$0
+[0-9a-f]+ <[^>]*> 48a0f800 	qmtc2	\$0,\$31
+[0-9a-f]+ <[^>]*> 4900ffff 	bc2f	[0-9a-f]+ <branch_label>
+[0-9a-f]+ <[^>]*> 00000000 	nop
+[0-9a-f]+ <[^>]*> 4902fffd 	bc2fl	[0-9a-f]+ <branch_label>
+[0-9a-f]+ <[^>]*> 00000000 	nop
+[0-9a-f]+ <[^>]*> 4901fffb 	bc2t	[0-9a-f]+ <branch_label>
+[0-9a-f]+ <[^>]*> 00000000 	nop
+[0-9a-f]+ <[^>]*> 4903fff9 	bc2tl	[0-9a-f]+ <branch_label>
+[0-9a-f]+ <[^>]*> 00000000 	nop
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/r5900-vu0.s b/gas/testsuite/gas/mips/r5900-vu0.s
new file mode 100644
index 0000000..13fe3d8
--- /dev/null
+++ b/gas/testsuite/gas/mips/r5900-vu0.s
@@ -0,0 +1,76 @@
+	.text
+
+	.set noreorder
+	.set noat
+
+	.ent text_label
+	.global text_label
+text_label:
+	# Floating point transfer to VU
+	lqc2	$0,0($0)
+	lqc2	$1, 0x7fff($1)
+	lqc2	$8, -0x8000($8)
+	lqc2	$31, -1($31)
+	.set at
+	lqc2	$0, 0x8000($2)
+	lqc2	$8, -0x8001($31)
+	lqc2	$31, 0xF1234567($4)
+	.set noat
+
+	# Floating point transfer from VU
+	sqc2	$0,0($0)
+	sqc2	$1, 0x7fff($1)
+	sqc2	$8, -0x8000($8)
+	sqc2	$31, -1($31)
+	.set at
+	sqc2	$0, 0x8000($2)
+	sqc2	$8, -0x8001($31)
+	sqc2	$31, 0xF1234567($4)
+	.set noat
+
+	# Integer transfer from VU
+	cfc2	$0,$0
+	cfc2	$0,$31
+	cfc2.i	$0,$0
+	cfc2.i	$0,$31
+	cfc2.ni	$0,$0
+	cfc2.ni	$0,$31
+
+	# Integer transfer to VU
+	ctc2	$0,$0
+	ctc2	$0,$31
+	ctc2.i	$0,$0
+	ctc2.i	$0,$31
+	ctc2.ni	$0,$0
+	ctc2.ni	$0,$31
+
+	# Floating point transfer from VU
+	qmfc2	$0,$0
+	qmfc2	$0,$31
+	qmfc2.i	$0,$0
+	qmfc2.i	$0,$31
+	qmfc2.ni	$0,$0
+	qmfc2.ni	$0,$31
+
+	# Floating point transfer to VU
+	qmtc2	$0,$0
+	qmtc2	$0,$31
+	qmtc2.i	$0,$0
+	qmtc2.i	$0,$31
+	qmtc2.ni	$0,$0
+	qmtc2.ni	$0,$31
+
+	# COP2 conditional branch instructions
+branch_label:
+	bc2f    branch_label
+	nop
+	bc2fl   branch_label
+	nop
+	bc2t    branch_label
+	nop
+	bc2tl   branch_label
+	nop
+
+# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.space  8
+	.end text_label
diff --git a/gas/testsuite/gas/mips/virt.d b/gas/testsuite/gas/mips/virt.d
new file mode 100644
index 0000000..c22f867
--- /dev/null
+++ b/gas/testsuite/gas/mips/virt.d
@@ -0,0 +1,20 @@
+#objdump: -dr --prefix-addresses  --show-raw-insn -Mvirt,cp0-names=mips32r2
+#name: virt instructions
+#as: -32 -mvirt
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 4063e800 	mfgc0	v1,c0_taghi
+[0-9a-f]+ <[^>]*> 406ba005 	mfgc0	t3,\$20,5
+[0-9a-f]+ <[^>]*> 40771200 	mtgc0	s7,c0_entrylo0
+[0-9a-f]+ <[^>]*> 40677202 	mtgc0	a3,\$14,2
+[0-9a-f]+ <[^>]*> 42000028 	hypcall
+[0-9a-f]+ <[^>]*> 4212b028 	hypcall	0x256
+[0-9a-f]+ <[^>]*> 4200000b 	tlbginv
+[0-9a-f]+ <[^>]*> 4200000c 	tlbginvf
+[0-9a-f]+ <[^>]*> 42000010 	tlbgp
+[0-9a-f]+ <[^>]*> 42000009 	tlbgr
+[0-9a-f]+ <[^>]*> 4200000a 	tlbgwi
+[0-9a-f]+ <[^>]*> 4200000e 	tlbgwr
+	...
diff --git a/gas/testsuite/gas/mips/virt.s b/gas/testsuite/gas/mips/virt.s
new file mode 100644
index 0000000..eca5e02
--- /dev/null
+++ b/gas/testsuite/gas/mips/virt.s
@@ -0,0 +1,22 @@
+	.text
+	.set noreorder
+
+foo:
+	mfgc0   $3,$29
+	mfgc0   $11,$20,5
+	mtgc0   $23,$2
+	mtgc0   $7,$14,2
+
+	hypcall
+	hypcall 0x256
+
+	tlbginv
+	tlbginvf
+	tlbgp
+	tlbgr
+	tlbgwi
+	tlbgwr
+
+# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	2
+	.space	8
diff --git a/gas/testsuite/gas/mips/virt64.d b/gas/testsuite/gas/mips/virt64.d
new file mode 100644
index 0000000..7a86ff9
--- /dev/null
+++ b/gas/testsuite/gas/mips/virt64.d
@@ -0,0 +1,12 @@
+#objdump: -dr --prefix-addresses  --show-raw-insn -Mvirt,cp0-names=mips64r2
+#name: virt64 instructions
+#as: -64 -mvirt
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 4063e900 	dmfgc0	v1,c0_taghi
+[0-9a-f]+ <[^>]*> 406ba105 	dmfgc0	a7,\$20,5
+[0-9a-f]+ <[^>]*> 40771300 	dmtgc0	s7,c0_entrylo0
+[0-9a-f]+ <[^>]*> 40677302 	dmtgc0	a3,\$14,2
+	...
diff --git a/gas/testsuite/gas/mips/virt64.s b/gas/testsuite/gas/mips/virt64.s
new file mode 100644
index 0000000..f3cd7b5
--- /dev/null
+++ b/gas/testsuite/gas/mips/virt64.s
@@ -0,0 +1,12 @@
+	.text
+	.set noreorder
+
+foo:
+	dmfgc0   $3,$29
+	dmfgc0   $11,$20,5
+	dmtgc0   $23,$2
+	dmtgc0   $7,$14,2
+
+# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	2
+	.space	8
diff --git a/gas/testsuite/gas/msp430/msp430.exp b/gas/testsuite/gas/msp430/msp430.exp
index 27df900..656ace8 100644
--- a/gas/testsuite/gas/msp430/msp430.exp
+++ b/gas/testsuite/gas/msp430/msp430.exp
@@ -1,5 +1,4 @@
-# Copyright 2012
-# Free Software Foundation, Inc.
+# Copyright 2012-2013 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -21,4 +20,5 @@
 
 if [expr [istarget "msp430-*-*"]]  then {
     run_dump_test "opcode"
+    run_dump_test "msp430x"
 }
diff --git a/gas/testsuite/gas/msp430/msp430x.d b/gas/testsuite/gas/msp430/msp430x.d
new file mode 100644
index 0000000..13fdb0b
--- /dev/null
+++ b/gas/testsuite/gas/msp430/msp430x.d
@@ -0,0 +1,216 @@
+#objdump: -d --prefix-addresses --show-raw-insn
+#name: MSP430X instructions
+#as: -mcpu=430X
+
+.*: +file format .*msp.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> 04 63       	adc	r4		;
+0+0002 <[^>]*> 40 18 04 63 	adcx.w	r4		;
+0+0006 <[^>]*> 00 18 c0 63 00 00 	adcx.a	0x0000		;PC rel. abs addr 0x000a
+0+000c <[^>]*> 40 18 46 63 	adcx.b	r6		;
+0+0010 <[^>]*> 40 18 07 63 	adcx.w	r7		;
+0+0014 <[^>]*> 40 18 09 68 	addcx.w	r8,	r9	;
+0+0018 <[^>]*> 80 18 7a 60 45 23 	addcx.a	#74565,	r10	;0x12345
+0+001e <[^>]*> 40 18 4c 6b 	addcx.b	r11,	r12	;
+0+0022 <[^>]*> 40 18 0e 6d 	addcx.w	r13,	r14	;
+0+0026 <[^>]*> 40 18 20 59 	addx.w	@r9,	r0	;
+0+002a <[^>]*> 40 18 00 59 	addx.w	r9,	r0	;
+0+002e <[^>]*> 00 18 70 50 00 00 	addx.a	#0,	r0	;
+0+0034 <[^>]*> 00 18 50 52 00 00 	addx.a	&0x0000,r0	;0x0000
+0+003a <[^>]*> 00 18 70 59 	addx.a	@r9\+,	r0	;
+0+003e <[^>]*> 00 18 50 50 00 00 	addx.a	0x0000,	r0	;PC rel. 0x0042
+0+0044 <[^>]*> 40 18 42 51 	addx.b	r1,	r2	;
+0+0048 <[^>]*> 40 18 04 53 	addx.w	#0,	r4	;r3 As==00
+0+004c <[^>]*> 40 18 15 54 00 00 	addx.w	0\(r4\),	r5	;
+0+0052 <[^>]*> 40 18 b6 f0 d2 04 04 00 	andx.w	#1234,	4\(r6\)	;#0x04d2
+0+005a <[^>]*> 40 18 96 f7 04 00 04 00 	andx.w	4\(r7\),	4\(r6\)	;
+0+0062 <[^>]*> 40 18 b6 f5 04 00 	andx.w	@r5\+,	4\(r6\)	;
+0+0068 <[^>]*> 40 18 96 f0 00 00 04 00 	andx.w	0x0000,	4\(r6\)	;PC rel. 0x006c
+0+0070 <[^>]*> 40 18 90 f0 00 00 00 00 	andx.w	0x0000,	0x0000	;PC rel. 0x0074, PC rel. 0x0076
+0+0078 <[^>]*> 00 18 e6 f5 04 00 	andx.a	@r5,	4\(r6\)	;
+0+007e <[^>]*> 00 18 c6 f5 04 00 	andx.a	r5,	4\(r6\)	;
+0+0084 <[^>]*> 40 18 d6 f2 00 00 04 00 	andx.b	&0x0000,4\(r6\)	;0x0000
+0+008c <[^>]*> 40 18 02 f1 	andx.w	r1,	r2	;
+0+0090 <[^>]*> 40 18 3e c0 a0 00 	bicx.w	#160,	r14	;#0x00a0
+0+0096 <[^>]*> 00 18 7e c0 a0 00 	bicx.a	#160,	r14	;#0x00a0
+0+009c <[^>]*> 40 18 7e c0 a0 00 	bicx.b	#160,	r14	;#0x00a0
+0+00a2 <[^>]*> 40 18 3e c0 a0 00 	bicx.w	#160,	r14	;#0x00a0
+0+00a8 <[^>]*> 40 18 3b d2 	bisx.w	#8,	r11	;r2 As==11
+0+00ac <[^>]*> 00 18 7b d2 	bisx.a	#8,	r11	;r2 As==11
+0+00b0 <[^>]*> 40 18 7b d2 	bisx.b	#8,	r11	;r2 As==11
+0+00b4 <[^>]*> 40 18 3b d2 	bisx.w	#8,	r11	;r2 As==11
+0+00b8 <[^>]*> 40 18 38 b0 14 00 	bitx.w	#20,	r8	;#0x0014
+0+00be <[^>]*> 40 18 92 b2 00 00 00 00 	bitx.w	&0x0000,&0x0000	;0x0000
+0+00c6 <[^>]*> 40 18 18 b2 00 00 	bitx.w	&0x0000,r8	;0x0000
+0+00cc <[^>]*> 40 18 18 b5 02 00 	bitx.w	2\(r5\),	r8	;
+0+00d2 <[^>]*> 40 18 92 b1 08 00 00 00 	bitx.w	8\(r1\),	&0x0000	;
+0+00da <[^>]*> 40 18 b2 b5 00 00 	bitx.w	@r5\+,	&0x0000	;
+0+00e0 <[^>]*> 40 18 38 b5 	bitx.w	@r5\+,	r8	;
+0+00e4 <[^>]*> 40 18 28 b5 	bitx.w	@r5,	r8	;
+0+00e8 <[^>]*> 40 18 92 b0 00 00 00 00 	bitx.w	0x0000,	&0x0000	;PC rel. 0x00ec
+0+00f0 <[^>]*> 40 18 f2 b0 0c 00 00 00 	bitx.b	#12,	&0x0000	;#0x000c
+0+00f8 <[^>]*> 40 18 e2 b5 00 00 	bitx.b	@r5,	&0x0000	;
+0+00fe <[^>]*> 40 18 58 b0 00 00 	bitx.b	0x0000,	r8	;PC rel. 0x0102
+0+0104 <[^>]*> 40 18 48 b5 	bitx.b	r5,	r8	;
+0+0108 <[^>]*> 40 18 82 b5 00 00 	bitx.w	r5,	&0x0000	;
+0+010e <[^>]*> 40 18 80 43 00 00 	movx.w	#0,	0x0000	;r3 As==00, PC rel. 0x0112
+0+0114 <[^>]*> 00 18 c0 43 00 00 	movx.a	#0,	0x0000	;r3 As==00, PC rel. 0x0118
+0+011a <[^>]*> 40 18 c0 43 00 00 	movx.b	#0,	0x0000	;r3 As==00, PC rel. 0x011e
+0+0120 <[^>]*> 40 18 80 43 00 00 	movx.w	#0,	0x0000	;r3 As==00, PC rel. 0x0124
+0+0126 <[^>]*> 40 18 0f 93 	cmpx.w	#0,	r15	;r3 As==00
+0+012a <[^>]*> 00 18 f0 90 00 18 00 00 	cmpx.a	#6144,	0x0000	;#0x1800, PC rel. 0x0130
+0+0132 <[^>]*> 40 18 6f 91 	cmpx.b	@r1,	r15	;
+0+0136 <[^>]*> 40 18 b2 92 00 00 	cmpx.w	#8,	&0x0000	;r2 As==11
+0+013c <[^>]*> 40 18 80 a3 00 00 	dadcx.w	0x0000		;PC rel. abs addr 0x0140
+0+0142 <[^>]*> 00 18 cc a3 00 00 	dadcx.a	0\(r12\)		;
+0+0148 <[^>]*> 40 18 c0 a3 00 00 	dadcx.b	0x0000		;PC rel. abs addr 0x014c
+0+014e <[^>]*> 40 18 0c a3 	dadcx.w	r12		;
+0+0152 <[^>]*> 40 18 27 a5 	daddx.w	@r5,	r7	;
+0+0156 <[^>]*> 00 18 f2 a0 10 00 00 00 	daddx.a	#16,	&0x0000	;#0x0010
+0+015e <[^>]*> 40 18 54 a6 02 00 	daddx.b	2\(r6\),	r4	;
+0+0164 <[^>]*> 40 18 14 a0 00 00 	daddx.w	0x0000,	r4	;PC rel. 0x0168
+0+016a <[^>]*> 40 18 90 83 00 00 	decx.w	0x0000		;PC rel. abs addr 0x016e
+0+0170 <[^>]*> 00 18 d0 83 00 00 	decx.a	0x0000		;PC rel. abs addr 0x0174
+0+0176 <[^>]*> 40 18 d0 83 00 00 	decx.b	0x0000		;PC rel. abs addr 0x017a
+0+017c <[^>]*> 40 18 90 83 00 00 	decx.w	0x0000		;PC rel. abs addr 0x0180
+0+0182 <[^>]*> 40 18 a0 83 00 00 	decdx.w	0x0000		;PC rel. abs addr 0x0186
+0+0188 <[^>]*> 00 18 e0 83 00 00 	decdx.a	0x0000		;PC rel. abs addr 0x018c
+0+018e <[^>]*> 40 18 e0 83 00 00 	decdx.b	0x0000		;PC rel. abs addr 0x0192
+0+0194 <[^>]*> 40 18 a0 83 00 00 	decdx.w	0x0000		;PC rel. abs addr 0x0198
+0+019a <[^>]*> 40 18 14 53 	incx.w	r4		;
+0+019e <[^>]*> 00 18 55 53 	incx.a	r5		;
+0+01a2 <[^>]*> 40 18 56 53 	incx.b	r6		;
+0+01a6 <[^>]*> 40 18 17 53 	incx.w	r7		;
+0+01aa <[^>]*> 40 18 28 53 	incdx.w	r8		;
+0+01ae <[^>]*> 00 18 69 53 	incdx.a	r9		;
+0+01b2 <[^>]*> 40 18 6a 53 	incdx.b	r10		;
+0+01b6 <[^>]*> 40 18 2b 53 	incdx.w	r11		;
+0+01ba <[^>]*> 40 18 3c e3 	invx.w	r12		;
+0+01be <[^>]*> 00 18 f0 e3 00 00 	xorx.a	#-1,	0x0000	;r3 As==11, PC rel. 0x01c2
+0+01c4 <[^>]*> 40 18 7e e3 	xorx.b	#-1,	r14	;r3 As==11
+0+01c8 <[^>]*> 40 18 3f e3 	invx.w	r15		;
+0+01cc <[^>]*> 40 18 34 40 00 00 	movx.w	#0,	r4	;
+0+01d2 <[^>]*> 00 18 75 40 00 00 	movx.a	#0,	r5	;
+0+01d8 <[^>]*> 40 18 76 40 00 00 	movx.b	#0,	r6	;
+0+01de <[^>]*> 40 18 37 40 00 00 	movx.w	#0,	r7	;
+0+01e4 <[^>]*> 40 18 15 42 00 00 	movx.w	&0x0000,r5	;0x0000
+0+01ea <[^>]*> 40 18 35 40 00 00 	movx.w	#0,	r5	;
+0+01f0 <[^>]*> 40 18 82 45 00 00 	movx.w	r5,	&0x0000	;
+0+01f6 <[^>]*> 40 1d b2 40 de bc 00 00 	movx.w	#-344866,&0x0000	;0xabcde
+0+01fe <[^>]*> 40 18 92 42 00 00 00 00 	movx.w	&0x0000,&0x0000	;0x0000
+0+0206 <[^>]*> 40 18 b2 40 00 00 00 00 	movx.w	#0,	&0x0000	;
+0+020e <[^>]*> 40 18 15 40 00 00 	movx.w	0x0000,	r5	;PC rel. 0x0212
+0+0214 <[^>]*> 40 18 80 45 00 00 	movx.w	r5,	0x0000	; PC rel. 0x0218
+0+021a <[^>]*> 40 1d b0 40 de bc 00 00 	movx.w	#-344866,0x0000	;0xabcde, PC rel. 0x0220
+0+0222 <[^>]*> 40 18 90 40 00 00 00 00 	movx.w	0x0000,	0x0000	;PC rel. 0x0226, PC rel. 0x0228
+0+022a <[^>]*> 40 18 0f 73 	sbcx.w	r15		;
+0+022e <[^>]*> 00 18 40 73 	sbcx.a	r0		;
+0+0232 <[^>]*> 40 18 4f 73 	sbcx.b	r15		;
+0+0236 <[^>]*> 40 18 87 73 00 00 	sbcx.w	0\(r7\)		;
+0+023c <[^>]*> 40 18 0f 7f 	subcx.w	r15,	r15	;
+0+0240 <[^>]*> 80 18 7f 70 45 23 	subcx.a	#74565,	r15	;0x12345
+0+0246 <[^>]*> 40 18 4f 7f 	subcx.b	r15,	r15	;
+0+024a <[^>]*> 40 18 b7 75 00 00 	subcx.w	@r5\+,	0\(r7\)	;
+0+0250 <[^>]*> 40 18 10 86 02 00 	subx.w	2\(r6\),	r0	;
+0+0256 <[^>]*> 00 18 f0 80 67 11 00 00 	subx.a	#4455,	0x0000	;#0x1167, PC rel. 0x025c
+0+025e <[^>]*> 40 18 50 86 02 00 	subx.b	2\(r6\),	r0	;
+0+0264 <[^>]*> 40 18 10 86 02 00 	subx.w	2\(r6\),	r0	;
+0+026a <[^>]*> 40 18 80 93 00 00 	cmpx.w	#0,	0x0000	;r3 As==00, PC rel. 0x026e
+0+0270 <[^>]*> 00 18 c0 93 00 00 	cmpx.a	#0,	0x0000	;r3 As==00, PC rel. 0x0274
+0+0276 <[^>]*> 40 18 c0 93 00 00 	cmpx.b	#0,	0x0000	;r3 As==00, PC rel. 0x027a
+0+027c <[^>]*> 40 18 80 93 00 00 	cmpx.w	#0,	0x0000	;r3 As==00, PC rel. 0x0280
+0+0282 <[^>]*> 40 18 b0 e0 5a 5a 00 00 	xorx.w	#23130,	0x0000	;#0x5a5a, PC rel. 0x0288
+0+028a <[^>]*> 40 18 90 e2 00 00 00 00 	xorx.w	&0x0000,0x0000	;0x0000, PC rel. 0x0290
+0+0292 <[^>]*> 40 18 a0 e8 00 00 	xorx.w	@r8,	0x0000	; PC rel. 0x0296
+0+0298 <[^>]*> 40 18 80 e8 00 00 	xorx.w	r8,	0x0000	; PC rel. 0x029c
+0+029e <[^>]*> 40 18 d0 e6 02 00 00 00 	xorx.b	2\(r6\),	0x0000	; PC rel. 0x02a4
+0+02a6 <[^>]*> 40 18 f0 e8 00 00 	xorx.b	@r8\+,	0x0000	; PC rel. 0x02aa
+0+02ac <[^>]*> 00 18 d2 e0 00 00 00 00 	xorx.a	0x0000,	&0x0000	;PC rel. 0x02b0
+0+02b4 <[^>]*> 40 18 26 e5 	xorx.w	@r5,	r6	;
+0+02b8 <[^>]*> 04 18 ff e0 39 30 78 56 	xorx.a	#12345,	284280\(r15\);#0x3039, 0x45678
+0+02c0 <[^>]*> a7 01 45 23 	adda	#74565,	r7	;0x12345
+0+02c4 <[^>]*> ee 06       	adda	r6,	r14	;
+0+02c6 <[^>]*> 80 00 00 00 	mova	#0,	r0	;
+0+02ca <[^>]*> 80 01 44 10 	mova	#69700,	r0	;0x11044
+0+02ce <[^>]*> c0 05       	mova	r5,	r0	;
+0+02d0 <[^>]*> 20 00 00 00 	bra	&0		;
+0+02d4 <[^>]*> 00 05       	bra	@r5		;
+0+02d6 <[^>]*> 10 05       	bra	@r5\+		;
+0+02d8 <[^>]*> 30 05 76 98 	bra	-26506\(r5\)	;0xffff9876
+0+02dc <[^>]*> 45 13       	calla	r5		;
+0+02de <[^>]*> 56 13 00 00 	calla	0\(r6\)		;0x00000
+0+02e2 <[^>]*> 67 13       	calla	@r7		;
+0+02e4 <[^>]*> 78 13       	calla	@r8\+		;
+0+02e6 <[^>]*> 80 13 00 00 	calla	&0		;0x00000
+0+02ea <[^>]*> 90 13 00 00 	calla	0\(PC\)		;PC rel. 0x002ec
+0+02ee <[^>]*> b0 13 00 00 	calla	#0		;0x00000
+0+02f2 <[^>]*> 40 18 06 43 	clrx.w	r6		;
+0+02f6 <[^>]*> d2 01       	cmpa	r1,	r2	;
+0+02f8 <[^>]*> 93 0f cb ed 	cmpa	#1043915,r3	;0xfedcb
+0+02fc <[^>]*> 40 18 25 83 	decdx.w	r5		;
+0+0300 <[^>]*> 40 18 25 53 	incdx.w	r5		;
+0+0304 <[^>]*> c8 09       	mova	r9,	r8	;
+0+0306 <[^>]*> 8c 01 45 23 	mova	#74565,	r12	;0x12345
+0+030a <[^>]*> 38 09 00 01 	mova	256\(r9\),r8	;0x00100
+0+030e <[^>]*> 2c 00 00 00 	mova	&0,	r12	;
+0+0312 <[^>]*> 08 09       	mova	@r9,	r8	;
+0+0314 <[^>]*> 18 09       	mova	@r9\+,	r8	;
+0+0316 <[^>]*> 79 08 00 01 	mova	r8,	256\(r9\)	; 0x00100
+0+031a <[^>]*> 60 0d 00 00 	mova	r13,	&0	;
+0+031e <[^>]*> 10 01       	reta			;
+0+0320 <[^>]*> 00 13       	reti			
+0+0322 <[^>]*> f6 05       	suba	r5,	r6	;
+0+0324 <[^>]*> b6 0f ff ff 	suba	#1048575,r6	;0xfffff
+0+0328 <[^>]*> 40 18 80 93 00 00 	cmpx.w	#0,	0x0000	;r3 As==00, PC rel. 0x032c
+0+032e <[^>]*> 05 17       	popm	#1,	r5	;16-bit words
+0+0330 <[^>]*> 2d 16       	popm.a	#3,	r15	;20-bit words
+0+0332 <[^>]*> 75 17       	popm	#8,	r12	;16-bit words
+0+0334 <[^>]*> 40 18 3a 41 	popx.w	r10		;
+0+0338 <[^>]*> 00 18 7a 41 	popx.a	r10		;
+0+033c <[^>]*> 40 18 7a 41 	popx.b	r10		;
+0+0340 <[^>]*> 40 18 3a 41 	popx.w	r10		;
+0+0344 <[^>]*> 09 15       	pushm	#1,	r9	;16-bit words
+0+0346 <[^>]*> 19 14       	pushm.a	#2,	r9	;20-bit words
+0+0348 <[^>]*> 29 15       	pushm	#3,	r9	;16-bit words
+0+034a <[^>]*> 40 18 08 12 	pushx.w	r8		;
+0+034e <[^>]*> 00 18 48 12 	pushx.a	r8		;
+0+0352 <[^>]*> 40 18 52 12 00 00 	pushx.b	&0x0000		;
+0+0358 <[^>]*> 40 18 08 12 	pushx.w	r8		;
+0+035c <[^>]*> 5f 02       	rlam	#1,	r15	;
+0+035e <[^>]*> 4f 06       	rlam.a	#2,	r15	;
+0+0360 <[^>]*> 5f 0a       	rlam	#3,	r15	;
+0+0362 <[^>]*> 40 18 06 56 	rlax.w	r6		;
+0+0366 <[^>]*> 00 18 46 56 	rlax.a	r6		;
+0+036a <[^>]*> 40 18 06 56 	rlax.w	r6		;
+0+036e <[^>]*> 40 18 06 66 	rlcx.w	r6		;
+0+0372 <[^>]*> 00 18 46 66 	rlcx.a	r6		;
+0+0376 <[^>]*> 40 18 06 66 	rlcx.w	r6		;
+0+037a <[^>]*> 56 01       	rram	#1,	r6	;
+0+037c <[^>]*> 46 0d       	rram.a	#4,	r6	;
+0+037e <[^>]*> 56 05       	rram	#2,	r6	;
+0+0380 <[^>]*> 40 18 0b 11 	rrax.w	r11		;
+0+0384 <[^>]*> 00 18 4b 11 	rrax.a	r11		;
+0+0388 <[^>]*> 40 18 0b 11 	rrax.w	r11		;
+0+038c <[^>]*> 55 0c       	rrcm	#4,	r5	;
+0+038e <[^>]*> 45 00       	rrcm.a	#1,	r5	;
+0+0390 <[^>]*> 55 08       	rrcm	#3,	r5	;
+0+0392 <[^>]*> 40 18 0d 10 	rrcx.w	r13		;
+0+0396 <[^>]*> 00 18 4d 10 	rrcx.a	r13		;
+0+039a <[^>]*> 40 18 0d 10 	rrcx.w	r13		;
+0+039e <[^>]*> 54 0b       	rrum	#3,	r4	;
+0+03a0 <[^>]*> 44 07       	rrum.a	#2,	r4	;
+0+03a2 <[^>]*> 54 03       	rrum	#1,	r4	;
+0+03a4 <[^>]*> 54 03       	rrum	#1,	r4	;
+0+03a6 <[^>]*> 47 03       	rrum.a	#1,	r7	;
+0+03a8 <[^>]*> 45 11       	rra.b	r5		;
+0+03aa <[^>]*> 75 c0 80 00 	bic.b	#128,	r5	;#0x0080
+0+03ae <[^>]*> 56 03       	rrum	#1,	r6	;
+0+03b0 <[^>]*> 40 18 81 10 	swpbx.w	r1		;
+0+03b4 <[^>]*> 00 18 90 10 00 00 	swpbx.a	0x0000		;PC rel. 0x03b8
+0+03ba <[^>]*> 40 18 8c 10 	swpbx.w	r12		;
+0+03be <[^>]*> 40 18 82 11 	sxtx.w	r2		;
+0+03c2 <[^>]*> 00 18 92 11 00 00 	sxtx.a	&0x0000		;
+0+03c8 <[^>]*> 40 18 82 11 	sxtx.w	r2		;
+0+03cc <[^>]*> 04 18 45 11 	rpt #5 \{ rrax.a	r5		;
+0+03d0 <[^>]*> 85 18 45 11 	rpt r5 \{ rrax.a	r5		;
diff --git a/gas/testsuite/gas/msp430/msp430x.s b/gas/testsuite/gas/msp430/msp430x.s
new file mode 100644
index 0000000..db27597
--- /dev/null
+++ b/gas/testsuite/gas/msp430/msp430x.s
@@ -0,0 +1,261 @@
+	.text
+	.global foo
+foo:
+	adc	r4		; MSP430 instruction for comparison purposes.
+
+	adcx	r4
+	adcx.a	bar
+	adcx.b	r6
+	adcx.w	r7
+
+	addcx	r8, r9
+	addcx.a	#0x12345, r10
+	addcx.b	r11, r12
+	addcx.w	r13, r14
+	
+	ADDX    @R9, PC
+	ADDX    R9, PC
+	ADDX.A  #FE000h, PC
+	ADDX.A  &EDE, PC
+	ADDX.A  @R9+, PC
+	ADDX.A  EDE, PC
+	addx.b	r1, r2
+	addx.w	r3, r4
+	ADDX    K(R4), R5
+	
+	ANDX    #1234, 4(R6)
+	ANDX    4(R7), 4(R6)
+	ANDX    @R5+, 4(R6)
+	ANDX    EDE, 4(R6)
+	ANDX    EDE, TONI
+	ANDX.A  @R5, 4(R6)
+	ANDX.A  R5, 4(R6)
+	ANDX.B  &EDE, 4(R6)
+	andx.w	r1, r2
+	
+	bicx	#0xa0, r14
+	bicx.a	#0xa0, r14
+	bicx.b	#0xa0, r14
+	bicx.w	#0xa0, r14
+	
+	bisx	#8, r11
+	bisx.a	#8, r11
+	bisx.b	#8, r11
+	bisx.w	#8, r11
+	
+	BITX    #20, R8
+	BITX    &EDE, &TONI
+	BITX    &EDE, R8
+	BITX    2(R5), R8
+	BITX    8(SP), &EDE
+	BITX    @R5+, &EDE
+	BITX    @R5+, R8
+	BITX    @R5, R8
+	BITX    EDE, &TONI
+	BITX.B  #12, &EDE
+	BITX.B  @R5, &EDE
+	BITX.B  EDE, R8
+	BITX.B  R5, R8
+	BITX.W  R5, &EDE
+	
+	clrx	TONI
+	clrx.a	fooz
+	clrx.b	bar
+	clrx.w	baz
+
+	cmpx	#0, r15
+	cmpx.a	#01800h, ede
+	cmpx.b	@r1, r15
+	cmpx.w	@r2+, &pin
+	
+	dadcx	fooz
+	dadcx.a 0(r12)
+	dadcx.b	bar
+	dadcx.w r12
+
+	daddx	@r5, r7
+	daddx.a	#10h, &decdr
+	daddx.b 2(r6), r4
+	daddx.w bcd, r4
+
+	decx	toni
+	decx.a	fooz
+	decx.b	bar
+	decx.w	fred
+	
+	decdx	toni
+	decdx.a	fooz
+	decdx.b	bar
+	decdx.w	fred
+
+	incx	r4
+	incx.a	r5
+	incx.b	r6
+	incx.w	r7
+	
+	incdx	r8
+	incdx.a	r9
+	incdx.b	r10
+	incdx.w	r11
+
+	invx	r12
+	invx.a	LEO
+	invx.b	r14
+	invx.w	r15
+
+	movx	#foo, r4
+	movx.a	#foo, r5
+	movx.b	#foo, r6
+	movx.w	#foo, r7
+	MOVX    &X, R5
+	MOVX    #X, R5
+	MOVX    R5, &Y
+	MOVX    #0xabcde, &Y
+	MOVX    &X, &Y
+	MOVX    #X, &Y
+	MOVX    X, R5
+	MOVX    R5, Y
+	MOVX    #0xabcde, Y
+	MOVX    X, Y
+
+	sbcx	r15
+	sbcx.a	012345h
+	sbcx.b	r15
+	sbcx.w	0(r7)
+	
+	subcx	r15, r15
+	subcx.a	#012345h, r15
+	subcx.b	r15, r15
+	subcx.w	@r5+, 0(r7)
+
+	SUBX    2(R6), PC
+	SUBX.A  #4455, ede
+	SUBX.B  2(R6), PC
+	SUBX.W  2(R6), PC
+
+	tstx	LEO
+	tstx.a	foo
+	tstx.b	bar
+	tstx.w	baz
+
+	XORX    #5A5Ah, EDE
+	XORX    &EDE, TONI
+	XORX    @R8, EDE
+	XORX    R8, EDE
+	XORX.B  2(R6), EDE
+	XORX.B  @R8+, EDE
+	xorx.a	toni, &cntr
+	xorx.w	@r5, r6
+	xorx.a	#12345, 0x45678h(r15)
+
+	adda	#0x12345, r7
+	adda	r6, r14
+
+	bra	#bar
+	bra	#011044H
+	bra	r5
+	bra	&ede
+	bra	@r5
+	bra	@r5+
+	bra	0x9876(r5)
+
+	calla	r5
+	calla	0x1234(r6)
+	calla	@r7
+	calla	@r8+
+	calla	&foo
+	calla	bar
+	calla	#011004h
+
+	clra	r6
+
+	cmpa	r1, r2
+	cmpa	#0xfedcb, r3
+
+	decda	r5
+	incda	r5
+
+	mova 	R9,R8
+	MOVA 	#12345h,R12
+	MOVA	100h(R9),R8
+	MOVA	&EDE,R12
+	MOVA	@R9,R8
+	MOVA	@R9+,R8
+	MOVA	R8,100h(R9)
+	MOVA	R13,&EDE
+
+	reta
+	reti
+
+	suba	r5, r6
+	suba	#0xfffff, r6
+
+	tsta	fooz
+
+	popm	#1, r5
+	popm.a	#3, r15
+	popm.w	#8, r12
+
+	popx	r10
+	popx.a	r10
+	popx.b	r10
+	popx.w	r10
+
+	pushm	#1, r9
+	pushm.a	#2, r9
+	pushm.w	#3, r9
+
+	pushx	r8
+	pushx.a	r8
+	pushx.b	&ede
+	pushx.w	r8
+
+	rlam	#1, r15
+	rlam.a	#2, r15
+	rlam.w	#3, r15
+
+	rlax	r6
+	rlax.a	r6
+	rlax.w	r6
+
+	rlcx	r6
+	rlcx.a	r6
+	rlcx.w	r6
+	
+	rram	#1, r6
+	rram.a	#4, r6
+	rram.w	#2, r6
+
+	rrax	r11
+	rrax.a	r11
+	rrax.w	r11
+	
+	rrcm	#4, r5
+	rrcm.a	#1, r5
+	rrcm.w	#3, r5
+
+	rrcx	r13
+	rrcx.a	r13
+	rrcx.w	r13
+
+	rrum	#3, r4
+	rrum.a	#2, r4
+	rrum.w	#1, r4
+
+	rrux	r4
+	rrux.a	r7
+	rrux.b	r5
+	rrux.w	r6
+
+	swpbx	r1
+	swpbx.a	ede
+	swpbx.w	r12
+
+	sxtx	r2
+	sxtx.a	&ede
+	sxtx.w	r2
+
+	rpt	#5
+	rrax.a	r5
+	rpt	r5
+	rrax.a	r5
diff --git a/gas/testsuite/gas/msp430/opcode.d b/gas/testsuite/gas/msp430/opcode.d
index 22df51c..9212d89 100644
--- a/gas/testsuite/gas/msp430/opcode.d
+++ b/gas/testsuite/gas/msp430/opcode.d
@@ -22,14 +22,14 @@
 0+024 <[^>]*> 8c 10       	swpb	r12		;
 0+026 <[^>]*> 0d 10       	rrc	r13		;
 0+028 <[^>]*> 30 41       	ret			
-0+02a <[^>]*> 31 40 00 00 	mov	#0,	r1	;#0x0000
-0+02e <[^>]*> b0 12 00 00 	call	#0		;#0x0000
+0+02a <[^>]*> 31 40 00 00 	mov	#0,	r1	;
+0+02e <[^>]*> b0 12 00 00 	call	#0		;
 0+032 <[^>]*> 1e 42 00 00 	mov	&0x0000,r14	;0x0000
 0+036 <[^>]*> 0f 4e       	mov	r14,	r15	;
 0+038 <[^>]*> 0f 5f       	rla	r15		;
 0+03a <[^>]*> 0f 7f       	subc	r15,	r15	;
 0+03c <[^>]*> 3f e3       	inv	r15		;
-0+03e <[^>]*> b0 12 00 00 	call	#0		;#0x0000
+0+03e <[^>]*> b0 12 00 00 	call	#0		;
 0+042 <[^>]*> 82 4e 00 00 	mov	r14,	&0x0000	;
 0+046 <[^>]*> 82 4f 00 00 	mov	r15,	&0x0000	;
 0+04a <[^>]*> 1e 42 00 00 	mov	&0x0000,r14	;0x0000
@@ -37,7 +37,7 @@
 0+050 <[^>]*> 0f 5f       	rla	r15		;
 0+052 <[^>]*> 0f 7f       	subc	r15,	r15	;
 0+054 <[^>]*> 3f e3       	inv	r15		;
-0+056 <[^>]*> b0 12 00 00 	call	#0		;#0x0000
+0+056 <[^>]*> b0 12 00 00 	call	#0		;
 0+05a <[^>]*> 82 4e 00 00 	mov	r14,	&0x0000	;
 0+05e <[^>]*> 82 4f 00 00 	mov	r15,	&0x0000	;
 0+062 <[^>]*> 3f 40 f0 00 	mov	#240,	r15	;#0x00f0
diff --git a/gas/testsuite/gas/msp430/opcode.s b/gas/testsuite/gas/msp430/opcode.s
index b85a463..4924a60 100644
--- a/gas/testsuite/gas/msp430/opcode.s
+++ b/gas/testsuite/gas/msp430/opcode.s
@@ -1,4 +1,4 @@
-	.arch msp430x123
+	.arch msp430f123
 	.text
 	.p2align 1,0
 	
diff --git a/gas/testsuite/gas/ppc/altivec2.d b/gas/testsuite/gas/ppc/altivec2.d
index 90a4b10..fc10fb5 100644
--- a/gas/testsuite/gas/ppc/altivec2.d
+++ b/gas/testsuite/gas/ppc/altivec2.d
@@ -58,4 +58,68 @@
   c0:	(10 d1 84 03|03 84 d1 10) 	vabsdub v6,v17,v16
   c4:	(12 b2 24 43|43 24 b2 12) 	vabsduh v21,v18,v4
   c8:	(13 34 4c 83|83 4c 34 13) 	vabsduw v25,v20,v9
+  cc:	(10 d1 a6 ad|ad a6 d1 10) 	vpermxor v6,v17,v20,v26
+  d0:	(13 ba 7f 3c|3c 7f ba 13) 	vaddeuqm v29,v26,v15,v28
+  d4:	(11 e8 3e 3d|3d 3e e8 11) 	vaddecuq v15,v8,v7,v24
+  d8:	(10 46 a8 7e|7e a8 46 10) 	vsubeuqm v2,v6,v21,v1
+  dc:	(13 a6 01 3f|3f 01 a6 13) 	vsubecuq v29,v6,v0,v4
+  e0:	(11 c9 18 88|88 18 c9 11) 	vmulouw v14,v9,v3
+  e4:	(13 10 90 89|89 90 10 13) 	vmuluwm v24,v16,v18
+  e8:	(11 51 88 c0|c0 88 51 11) 	vaddudm v10,v17,v17
+  ec:	(13 d9 20 c2|c2 20 d9 13) 	vmaxud  v30,v25,v4
+  f0:	(11 46 e0 c4|c4 e0 46 11) 	vrld    v10,v6,v28
+  f4:	(13 67 38 c7|c7 38 67 13) 	vcmpequd v27,v7,v7
+  f8:	(12 d0 c9 00|00 c9 d0 12) 	vadduqm v22,v16,v25
+  fc:	(10 35 e9 40|40 e9 35 10) 	vaddcuq v1,v21,v29
+ 100:	(12 8b 99 88|88 99 8b 12) 	vmulosw v20,v11,v19
+ 104:	(13 13 09 c2|c2 09 13 13) 	vmaxsd  v24,v19,v1
+ 108:	(11 bb f2 88|88 f2 bb 11) 	vmuleuw v13,v27,v30
+ 10c:	(11 38 8a c2|c2 8a 38 11) 	vminud  v9,v24,v17
+ 110:	(11 52 e2 c7|c7 e2 52 11) 	vcmpgtud v10,v18,v28
+ 114:	(10 1d b3 88|88 b3 1d 10) 	vmulesw v0,v29,v22
+ 118:	(11 bc 0b c2|c2 0b bc 11) 	vminsd  v13,v28,v1
+ 11c:	(11 54 2b c4|c4 2b 54 11) 	vsrad   v10,v20,v5
+ 120:	(13 75 2b c7|c7 2b 75 13) 	vcmpgtsd v27,v21,v5
+ 124:	(10 17 f6 01|01 f6 17 10) 	bcdadd\. v0,v23,v30,1
+ 128:	(13 38 d4 08|08 d4 38 13) 	vpmsumb v25,v24,v26
+ 12c:	(11 04 26 41|41 26 04 11) 	bcdsub\. v8,v4,v4,1
+ 130:	(12 0e d4 48|48 d4 0e 12) 	vpmsumh v16,v14,v26
+ 134:	(13 62 d4 4e|4e d4 62 13) 	vpkudum v27,v2,v26
+ 138:	(10 d7 8c 88|88 8c d7 10) 	vpmsumw v6,v23,v17
+ 13c:	(12 86 cc c8|c8 cc 86 12) 	vpmsumd v20,v6,v25
+ 140:	(13 76 84 ce|ce 84 76 13) 	vpkudus v27,v22,v16
+ 144:	(12 b4 94 c0|c0 94 b4 12) 	vsubudm v21,v20,v18
+ 148:	(12 b4 95 00|00 95 b4 12) 	vsubuqm v21,v20,v18
+ 14c:	(13 bd 35 08|08 35 bd 13) 	vcipher v29,v29,v6
+ 150:	(10 4d a5 09|09 a5 4d 10) 	vcipherlast v2,v13,v20
+ 154:	(12 80 95 0c|0c 95 80 12) 	vgbbd   v20,v18
+ 158:	(12 68 cd 40|40 cd 68 12) 	vsubcuq v19,v8,v25
+ 15c:	(11 3a ed 44|44 ed 3a 11) 	vorc    v9,v26,v29
+ 160:	(12 94 6d 48|48 6d 94 12) 	vncipher v20,v20,v13
+ 164:	(11 e5 dd 49|49 dd e5 11) 	vncipherlast v15,v5,v27
+ 168:	(10 73 35 4c|4c 35 73 10) 	vbpermq v3,v19,v6
+ 16c:	(13 c4 e5 4e|4e e5 c4 13) 	vpksdus v30,v4,v28
+ 170:	(10 04 75 84|84 75 04 10) 	vnand   v0,v4,v14
+ 174:	(12 28 ed c4|c4 ed 28 12) 	vsld    v17,v8,v29
+ 178:	(13 b4 05 c8|c8 05 b4 13) 	vsbox   v29,v20
+ 17c:	(11 67 5d ce|ce 5d 67 11) 	vpksdss v11,v7,v11
+ 180:	(10 73 84 c7|c7 84 73 10) 	vcmpequd\. v3,v19,v16
+ 184:	(12 40 8e 4e|4e 8e 40 12) 	vupkhsw v18,v17
+ 188:	(13 a8 6e 82|82 6e a8 13) 	vshasigmaw v29,v8,0,13
+ 18c:	(12 fc d6 84|84 d6 fc 12) 	veqv    v23,v28,v26
+ 190:	(13 a0 17 8c|8c 17 a0 13) 	vmrgew  v29,v0,v2
+ 194:	(13 a0 16 8c|8c 16 a0 13) 	vmrgow  v29,v0,v2
+ 198:	(13 73 06 c2|c2 06 73 13) 	vshasigmad v27,v19,0,0
+ 19c:	(12 9c e6 c4|c4 e6 9c 12) 	vsrd    v20,v28,v28
+ 1a0:	(12 40 ae ce|ce ae 40 12) 	vupklsw v18,v21
+ 1a4:	(13 c0 3f 02|02 3f c0 13) 	vclzb   v30,v7
+ 1a8:	(13 a0 af 03|03 af a0 13) 	vpopcntb v29,v21
+ 1ac:	(13 20 af 42|42 af 20 13) 	vclzh   v25,v21
+ 1b0:	(12 00 f7 43|43 f7 00 12) 	vpopcnth v16,v30
+ 1b4:	(13 80 1f 82|82 1f 80 13) 	vclzw   v28,v3
+ 1b8:	(11 40 4f 83|83 4f 40 11) 	vpopcntw v10,v9
+ 1bc:	(12 c0 4f c2|c2 4f c0 12) 	vclzd   v22,v9
+ 1c0:	(11 e0 f7 c3|c3 f7 e0 11) 	vpopcntd v15,v30
+ 1c4:	(10 5f 36 c7|c7 36 5f 10) 	vcmpgtud\. v2,v31,v6
+ 1c8:	(12 8f 17 c7|c7 17 8f 12) 	vcmpgtsd\. v20,v15,v2
 #pass
diff --git a/gas/testsuite/gas/ppc/altivec2.s b/gas/testsuite/gas/ppc/altivec2.s
index 9f11a8b..6233c0e 100644
--- a/gas/testsuite/gas/ppc/altivec2.s
+++ b/gas/testsuite/gas/ppc/altivec2.s
@@ -1,3 +1,4 @@
+	.text
 start:
 	lvepxl   3,0,28
 	lvepxl   19,4,18
@@ -50,3 +51,67 @@
 	vabsdub  6,17,16
 	vabsduh  21,18,4
 	vabsduw  25,20,9
+	vpermxor 6,17,20,26
+	vaddeuqm 29,26,15,28
+	vaddecuq 15,8,7,24
+	vsubeuqm 2,6,21,1
+	vsubecuq 29,6,0,4
+	vmulouw  14,9,3
+	vmuluwm  24,16,18
+	vaddudm  10,17,17
+	vmaxud   30,25,4
+	vrld     10,6,28
+	vcmpequd 27,7,7
+	vadduqm  22,16,25
+	vaddcuq  1,21,29
+	vmulosw  20,11,19
+	vmaxsd   24,19,1
+	vmuleuw  13,27,30
+	vminud   9,24,17
+	vcmpgtud 10,18,28
+	vmulesw  0,29,22
+	vminsd   13,28,1
+	vsrad    10,20,5
+	vcmpgtsd 27,21,5
+	bcdadd.  0,23,30,1
+	vpmsumb  25,24,26
+	bcdsub.  8,4,4,1
+	vpmsumh  16,14,26
+	vpkudum  27,2,26
+	vpmsumw  6,23,17
+	vpmsumd  20,6,25
+	vpkudus  27,22,16
+	vsubudm  21,20,18
+	vsubuqm  21,20,18
+	vcipher  29,29,6
+	vcipherlast 2,13,20
+	vgbbd    20,18
+	vsubcuq  19,8,25
+	vorc     9,26,29
+	vncipher 20,20,13
+	vncipherlast 15,5,27
+	vbpermq  3,19,6
+	vpksdus  30,4,28
+	vnand    0,4,14
+	vsld     17,8,29
+	vsbox    29,20
+	vpksdss  11,7,11
+	vcmpequd. 3,19,16
+	vupkhsw  18,17
+	vshasigmaw 29,8,0,13
+	veqv     23,28,26
+	vmrgew   29,0,2
+	vmrgow   29,0,2
+	vshasigmad 27,19,0,0
+	vsrd     20,28,28
+	vupklsw  18,21
+	vclzb    30,7
+	vpopcntb 29,21
+	vclzh    25,21
+	vpopcnth 16,30
+	vclzw    28,3
+	vpopcntw 10,9
+	vclzd    22,9
+	vpopcntd 15,30
+	vcmpgtud. 2,31,6
+	vcmpgtsd. 20,15,2
diff --git a/gas/testsuite/gas/ppc/power8.d b/gas/testsuite/gas/ppc/power8.d
index 1eb7fa9..2d576e6 100644
--- a/gas/testsuite/gas/ppc/power8.d
+++ b/gas/testsuite/gas/ppc/power8.d
@@ -27,3 +27,127 @@
   44:	(60 42 00 00|00 00 42 60) 	ori     r2,r2,0
   48:	(60 00 00 00|00 00 00 60) 	nop
   4c:	(60 42 00 00|00 00 42 60) 	ori     r2,r2,0
+  50:	(4c 00 01 24|24 01 00 4c) 	rfebb   
+  54:	(4c 00 01 24|24 01 00 4c) 	rfebb   
+  58:	(4c 00 09 24|24 09 00 4c) 	rfebb   1
+  5c:	(4d 95 04 60|60 04 95 4d) 	bctar-  12,4\*cr5\+gt
+  60:	(4c 87 04 61|61 04 87 4c) 	bctarl- 4,4\*cr1\+so
+  64:	(4d ac 04 60|60 04 ac 4d) 	bctar\+  12,4\*cr3\+lt
+  68:	(4c a2 04 61|61 04 a2 4c) 	bctarl\+ 4,eq
+  6c:	(4c 88 0c 60|60 0c 88 4c) 	bctar   4,4\*cr2\+lt,1
+  70:	(4c 87 14 61|61 14 87 4c) 	bctarl  4,4\*cr1\+so,2
+  74:	(7c 00 00 3c|3c 00 00 7c) 	waitasec
+  78:	(7c 00 41 1c|1c 41 00 7c) 	msgsndp r8
+  7c:	(7c 20 01 26|26 01 20 7c) 	mtsle   1
+  80:	(7c 00 d9 5c|5c d9 00 7c) 	msgclrp r27
+  84:	(7d 4a 61 6d|6d 61 4a 7d) 	stqcx\.  r10,r10,r12
+  88:	(7f 80 39 6d|6d 39 80 7f) 	stqcx\.  r28,0,r7
+  8c:	(7f 13 5a 28|28 5a 13 7f) 	lqarx   r24,r19,r11
+  90:	(7e c0 5a 28|28 5a c0 7e) 	lqarx   r22,0,r11
+  94:	(7e 80 32 5c|5c 32 80 7e) 	mfbhrbe r20,6
+  98:	(7f b1 83 29|29 83 b1 7f) 	pbt\.    r29,r17,r16
+  9c:	(7d c0 3b 29|29 3b c0 7d) 	pbt\.    r14,0,r7
+  a0:	(7c 00 03 5c|5c 03 00 7c) 	clrbhrb
+  a4:	(11 6a 05 ed|ed 05 6a 11) 	vpermxor v11,v10,v0,v23
+  a8:	(13 02 39 3c|3c 39 02 13) 	vaddeuqm v24,v2,v7,v4
+  ac:	(11 4a 40 bd|bd 40 4a 11) 	vaddecuq v10,v10,v8,v2
+  b0:	(10 af 44 fe|fe 44 af 10) 	vsubeuqm v5,v15,v8,v19
+  b4:	(11 9f 87 7f|7f 87 9f 11) 	vsubecuq v12,v31,v16,v29
+  b8:	(12 9d 68 88|88 68 9d 12) 	vmulouw v20,v29,v13
+  bc:	(13 a0 d0 89|89 d0 a0 13) 	vmuluwm v29,v0,v26
+  c0:	(11 15 e0 c0|c0 e0 15 11) 	vaddudm v8,v21,v28
+  c4:	(10 3a 08 c2|c2 08 3a 10) 	vmaxud  v1,v26,v1
+  c8:	(12 83 08 c4|c4 08 83 12) 	vrld    v20,v3,v1
+  cc:	(10 93 58 c7|c7 58 93 10) 	vcmpequd v4,v19,v11
+  d0:	(12 ee f1 00|00 f1 ee 12) 	vadduqm v23,v14,v30
+  d4:	(11 08 69 40|40 69 08 11) 	vaddcuq v8,v8,v13
+  d8:	(13 9b 21 88|88 21 9b 13) 	vmulosw v28,v27,v4
+  dc:	(10 64 21 c2|c2 21 64 10) 	vmaxsd  v3,v4,v4
+  e0:	(10 13 aa 88|88 aa 13 10) 	vmuleuw v0,v19,v21
+  e4:	(13 14 9a c2|c2 9a 14 13) 	vminud  v24,v20,v19
+  e8:	(10 1c 7a c7|c7 7a 1c 10) 	vcmpgtud v0,v28,v15
+  ec:	(12 a0 13 88|88 13 a0 12) 	vmulesw v21,v0,v2
+  f0:	(11 3a 4b c2|c2 4b 3a 11) 	vminsd  v9,v26,v9
+  f4:	(13 3d 5b c4|c4 5b 3d 13) 	vsrad   v25,v29,v11
+  f8:	(11 7c 5b c7|c7 5b 7c 11) 	vcmpgtsd v11,v28,v11
+  fc:	(10 a8 d6 01|01 d6 a8 10) 	bcdadd\. v5,v8,v26,1
+ 100:	(10 83 64 08|08 64 83 10) 	vpmsumb v4,v3,v12
+ 104:	(13 5f ae 41|41 ae 5f 13) 	bcdsub\. v26,v31,v21,1
+ 108:	(10 b1 84 48|48 84 b1 10) 	vpmsumh v5,v17,v16
+ 10c:	(12 f1 a4 4e|4e a4 f1 12) 	vpkudum v23,v17,v20
+ 110:	(13 15 ec 88|88 ec 15 13) 	vpmsumw v24,v21,v29
+ 114:	(11 36 6c c8|c8 6c 36 11) 	vpmsumd v9,v22,v13
+ 118:	(12 53 94 ce|ce 94 53 12) 	vpkudus v18,v19,v18
+ 11c:	(13 d0 b5 00|00 b5 d0 13) 	vsubuqm v30,v16,v22
+ 120:	(11 cb 3d 08|08 3d cb 11) 	vcipher v14,v11,v7
+ 124:	(11 42 b5 09|09 b5 42 11) 	vcipherlast v10,v2,v22
+ 128:	(12 e0 6d 0c|0c 6d e0 12) 	vgbbd   v23,v13
+ 12c:	(12 19 85 40|40 85 19 12) 	vsubcuq v16,v25,v16
+ 130:	(13 e1 2d 44|44 2d e1 13) 	vorc    v31,v1,v5
+ 134:	(10 91 fd 48|48 fd 91 10) 	vncipher v4,v17,v31
+ 138:	(13 02 dd 49|49 dd 02 13) 	vncipherlast v24,v2,v27
+ 13c:	(12 f5 bd 4c|4c bd f5 12) 	vbpermq v23,v21,v23
+ 140:	(13 72 4d 4e|4e 4d 72 13) 	vpksdus v27,v18,v9
+ 144:	(13 7d dd 84|84 dd 7d 13) 	vnand   v27,v29,v27
+ 148:	(12 73 c5 c4|c4 c5 73 12) 	vsld    v19,v19,v24
+ 14c:	(10 ad 05 c8|c8 05 ad 10) 	vsbox   v5,v13
+ 150:	(13 23 3d ce|ce 3d 23 13) 	vpksdss v25,v3,v7
+ 154:	(13 88 04 c7|c7 04 88 13) 	vcmpequd\. v28,v8,v0
+ 158:	(13 40 d6 4e|4e d6 40 13) 	vupkhsw v26,v26
+ 15c:	(10 a7 36 82|82 36 a7 10) 	vshasigmaw v5,v7,0,6
+ 160:	(13 95 76 84|84 76 95 13) 	veqv    v28,v21,v14
+ 164:	(10 28 9e 8c|8c 9e 28 10) 	vmrgow  v1,v8,v19
+ 168:	(10 0a 56 c2|c2 56 0a 10) 	vshasigmad v0,v10,0,10
+ 16c:	(10 bb 76 c4|c4 76 bb 10) 	vsrd    v5,v27,v14
+ 170:	(11 60 6e ce|ce 6e 60 11) 	vupklsw v11,v13
+ 174:	(11 c0 87 02|02 87 c0 11) 	vclzb   v14,v16
+ 178:	(12 80 df 03|03 df 80 12) 	vpopcntb v20,v27
+ 17c:	(13 80 5f 42|42 5f 80 13) 	vclzh   v28,v11
+ 180:	(13 00 4f 43|43 4f 00 13) 	vpopcnth v24,v9
+ 184:	(13 60 ff 82|82 ff 60 13) 	vclzw   v27,v31
+ 188:	(12 20 9f 83|83 9f 20 12) 	vpopcntw v17,v19
+ 18c:	(11 80 ef c2|c2 ef 80 11) 	vclzd   v12,v29
+ 190:	(12 e0 b7 c3|c3 b7 e0 12) 	vpopcntd v23,v22
+ 194:	(13 14 ee c7|c7 ee 14 13) 	vcmpgtud\. v24,v20,v29
+ 198:	(11 26 df c7|c7 df 26 11) 	vcmpgtsd\. v9,v6,v27
+ 19c:	(7f ce d0 19|19 d0 ce 7f) 	lxsiwzx vs62,r14,r26
+ 1a0:	(7d 00 c8 19|19 c8 00 7d) 	lxsiwzx vs40,0,r25
+ 1a4:	(7f 20 d0 98|98 d0 20 7f) 	lxsiwax vs25,0,r26
+ 1a8:	(7c 60 18 98|98 18 60 7c) 	lxsiwax vs3,0,r3
+ 1ac:	(7f cc 00 67|67 00 cc 7f) 	mfvsrd  r12,vs62
+ 1b0:	(7d 94 00 e6|e6 00 94 7d) 	mffprwz r20,f12
+ 1b4:	(7d c9 71 18|18 71 c9 7d) 	stxsiwx vs14,r9,r14
+ 1b8:	(7e a0 41 18|18 41 a0 7e) 	stxsiwx vs21,0,r8
+ 1bc:	(7e 0b 01 67|67 01 0b 7e) 	mtvsrd  vs48,r11
+ 1c0:	(7f f7 01 a7|a7 01 f7 7f) 	mtvrwa  v31,r23
+ 1c4:	(7e 1a 01 e6|e6 01 1a 7e) 	mtfprwz f16,r26
+ 1c8:	(7d b3 6c 18|18 6c b3 7d) 	lxsspx  vs13,r19,r13
+ 1cc:	(7e 40 6c 18|18 6c 40 7e) 	lxsspx  vs18,0,r13
+ 1d0:	(7d 62 25 19|19 25 62 7d) 	stxsspx vs43,r2,r4
+ 1d4:	(7e e0 5d 19|19 5d e0 7e) 	stxsspx vs55,0,r11
+ 1d8:	(f2 d0 c8 05|05 c8 d0 f2) 	xsaddsp vs54,vs48,vs25
+ 1dc:	(f1 d2 08 0c|0c 08 d2 f1) 	xsmaddasp vs14,vs50,vs1
+ 1e0:	(f3 56 50 42|42 50 56 f3) 	xssubsp vs26,vs22,vs42
+ 1e4:	(f3 75 a0 4e|4e a0 75 f3) 	xsmaddmsp vs27,vs53,vs52
+ 1e8:	(f1 00 d8 2a|2a d8 00 f1) 	xsrsqrtesp vs8,vs59
+ 1ec:	(f1 80 48 2e|2e 48 80 f1) 	xssqrtsp vs12,vs41
+ 1f0:	(f3 2b 00 83|83 00 2b f3) 	xsmulsp vs57,vs11,vs32
+ 1f4:	(f0 d4 d0 89|89 d0 d4 f0) 	xsmsubasp vs38,vs20,vs26
+ 1f8:	(f3 53 30 c0|c0 30 53 f3) 	xsdivsp vs26,vs19,vs6
+ 1fc:	(f0 65 b8 cf|cf b8 65 f0) 	xsmsubmsp vs35,vs37,vs55
+ 200:	(f3 60 40 69|69 40 60 f3) 	xsresp  vs59,vs8
+ 204:	(f1 81 0c 0f|0f 0c 81 f1) 	xsnmaddasp vs44,vs33,vs33
+ 208:	(f2 3e f4 4c|4c f4 3e f2) 	xsnmaddmsp vs17,vs62,vs30
+ 20c:	(f2 d4 fc 8d|8d fc d4 f2) 	xsnmsubasp vs54,vs52,vs31
+ 210:	(f0 a5 d4 cb|cb d4 a5 f0) 	xsnmsubmsp vs37,vs5,vs58
+ 214:	(f3 d6 65 56|56 65 d6 f3) 	xxlorc  vs30,vs54,vs44
+ 218:	(f2 2e ed 91|91 ed 2e f2) 	xxlnand vs49,vs14,vs29
+ 21c:	(f3 d6 f5 d1|d1 f5 d6 f3) 	xxleqv  vs62,vs22,vs30
+ 220:	(f3 80 b4 2f|2f b4 80 f3) 	xscvdpspn vs60,vs54
+ 224:	(f2 c0 6c 66|66 6c c0 f2) 	xsrsp   vs22,vs45
+ 228:	(f3 40 dc a2|a2 dc 40 f3) 	xscvuxdsp vs26,vs59
+ 22c:	(f0 c0 8c e3|e3 8c c0 f0) 	xscvsxdsp vs38,vs49
+ 230:	(f3 60 d5 2d|2d d5 60 f3) 	xscvspdpn vs59,vs26
+ 234:	(ff 0e 16 8c|8c 16 0e ff) 	fmrgow  f24,f14,f2
+ 238:	(fe c7 2f 8c|8c 2f c7 fe) 	fmrgew  f22,f7,f5
+#pass
diff --git a/gas/testsuite/gas/ppc/power8.s b/gas/testsuite/gas/ppc/power8.s
index 7b4a28e..8df4f6b 100644
--- a/gas/testsuite/gas/ppc/power8.s
+++ b/gas/testsuite/gas/ppc/power8.s
@@ -19,3 +19,126 @@
 	tresume.     
 	ori	     2,2,0
 	.p2align     4,,15
+	rfebb        0
+	rfebb
+	rfebb        1
+	bctar-       12,21
+	bctarl-      4,7
+	bctar+       12,12
+	bctarl+      4,2
+	bctar        4,8,1
+	bctarl       4,7,2
+	waitasec     
+	msgsndp      8
+	mtsle        1
+	msgclrp      27
+	stqcx.       10,10,12
+	stqcx.       28,0,7
+	lqarx        24,19,11,0
+	lqarx        22,0,11,0
+	mfbhrbe      20,6
+	pbt.         29,17,16
+	pbt.         14,0,7
+	clrbhrb      
+	vpermxor     11,10,0,23
+	vaddeuqm     24,2,7,4
+	vaddecuq     10,10,8,2
+	vsubeuqm     5,15,8,19
+	vsubecuq     12,31,16,29
+	vmulouw      20,29,13
+	vmuluwm      29,0,26
+	vaddudm      8,21,28
+	vmaxud       1,26,1
+	vrld         20,3,1
+	vcmpequd     4,19,11
+	vadduqm      23,14,30
+	vaddcuq      8,8,13
+	vmulosw      28,27,4
+	vmaxsd       3,4,4
+	vmuleuw      0,19,21
+	vminud       24,20,19
+	vcmpgtud     0,28,15
+	vmulesw      21,0,2
+	vminsd       9,26,9
+	vsrad        25,29,11
+	vcmpgtsd     11,28,11
+	bcdadd.      5,8,26,1
+	vpmsumb      4,3,12
+	bcdsub.      26,31,21,1
+	vpmsumh      5,17,16
+	vpkudum      23,17,20
+	vpmsumw      24,21,29
+	vpmsumd      9,22,13
+	vpkudus      18,19,18
+	vsubuqm      30,16,22
+	vcipher      14,11,7
+	vcipherlast  10,2,22
+	vgbbd        23,13
+	vsubcuq      16,25,16
+	vorc         31,1,5
+	vncipher     4,17,31
+	vncipherlast 24,2,27
+	vbpermq      23,21,23
+	vpksdus      27,18,9
+	vnand        27,29,27
+	vsld         19,19,24
+	vsbox        5,13
+	vpksdss      25,3,7
+	vcmpequd.    28,8,0
+	vupkhsw      26,26
+	vshasigmaw   5,7,0,6
+	veqv         28,21,14
+	vmrgow       1,8,19
+	vshasigmad   0,10,0,10
+	vsrd         5,27,14
+	vupklsw      11,13
+	vclzb        14,16
+	vpopcntb     20,27
+	vclzh        28,11
+	vpopcnth     24,9
+	vclzw        27,31
+	vpopcntw     17,19
+	vclzd        12,29
+	vpopcntd     23,22
+	vcmpgtud.    24,20,29
+	vcmpgtsd.    9,6,27
+	lxsiwzx      62,14,26
+	lxsiwzx      40,0,25
+	lxsiwax      25,0,26
+	lxsiwax      3,0,3
+	mfvsrd       12,62
+	mfvsrwz      20,12
+	stxsiwx      14,9,14
+	stxsiwx      21,0,8
+	mtvsrd       48,11
+	mtvsrwa      63,23
+	mtvsrwz      16,26
+	lxsspx       13,19,13
+	lxsspx       18,0,13
+	stxsspx      43,2,4
+	stxsspx      55,0,11
+	xsaddsp      54,48,25
+	xsmaddasp    14,50,1
+	xssubsp      26,22,42
+	xsmaddmsp    27,53,52
+	xsrsqrtesp   8,59
+	xssqrtsp     12,41
+	xsmulsp      57,11,32
+	xsmsubasp    38,20,26
+	xsdivsp      26,19,6
+	xsmsubmsp    35,37,55
+	xsresp       59,8
+	xsnmaddasp   44,33,33
+	xsnmaddmsp   17,62,30
+	xsnmsubasp   54,52,31
+	xsnmsubmsp   37,5,58
+	xxlorc       30,54,44
+	xxlnand      49,14,29
+	xxleqv       62,22,30
+	xscvdpspn    60,54
+	xsrsp        22,45
+	xscvuxdsp    26,59
+	xscvsxdsp    38,49
+	xscvspdpn    59,26
+	fmrgow       24,14,2
+	fmrgew       22,7,5
diff --git a/gas/testsuite/gas/ppc/ppc.exp b/gas/testsuite/gas/ppc/ppc.exp
index b7f56b0..fec714c 100644
--- a/gas/testsuite/gas/ppc/ppc.exp
+++ b/gas/testsuite/gas/ppc/ppc.exp
@@ -44,7 +44,6 @@
 }
 
 if { [istarget powerpc*-*-*] } then {
-    run_dump_test "simpshft"
     run_dump_test "regnames"
     if { [is_elf_format] } then {
 	run_dump_test "machine"
@@ -67,6 +66,7 @@
 	run_dump_test "altivec_xcoff"
 	run_dump_test "altivec_xcoff64"
     } else {
+	run_dump_test "simpshft"
 	run_dump_test "altivec"
 	run_dump_test "altivec2"
 	run_dump_test "altivec_and_spe"
@@ -85,6 +85,7 @@
 	run_dump_test "power7"
 	run_dump_test "power8"
 	run_dump_test "vsx"
+	run_dump_test "vsx2"
 	run_dump_test "htm"
 	run_dump_test "titan"
     }
diff --git a/gas/testsuite/gas/ppc/vsx.d b/gas/testsuite/gas/ppc/vsx.d
index 7ce57da..f5a6a14 100644
--- a/gas/testsuite/gas/ppc/vsx.d
+++ b/gas/testsuite/gas/ppc/vsx.d
@@ -166,3 +166,8 @@
  26c:	(f1 12 e7 bf|bf e7 12 f1) 	xxsel   vs40,vs50,vs60,vs62
  270:	(f1 12 e2 17|17 e2 12 f1) 	xxsldwi vs40,vs50,vs60,2
  274:	(f1 02 e2 93|93 e2 02 f1) 	xxspltw vs40,vs60,2
+ 278:	(7d 00 a6 99|99 a6 00 7d) 	lxvd2x  vs40,0,r20
+ 27c:	(7d 0a a6 99|99 a6 0a 7d) 	lxvd2x  vs40,r10,r20
+ 280:	(7d 00 a7 99|99 a7 00 7d) 	stxvd2x vs40,0,r20
+ 284:	(7d 0a a7 99|99 a7 0a 7d) 	stxvd2x vs40,r10,r20
+#pass
diff --git a/gas/testsuite/gas/ppc/vsx.s b/gas/testsuite/gas/ppc/vsx.s
index 6927ee1..bcc9c2d 100644
--- a/gas/testsuite/gas/ppc/vsx.s
+++ b/gas/testsuite/gas/ppc/vsx.s
@@ -158,3 +158,7 @@
 	xxsel      40,50,60,62
 	xxsldwi    40,50,60,2
 	xxspltw    40,60,2
+	lxvx       40,0,20
+	lxvx       40,10,20
+	stxvx      40,0,20
+	stxvx      40,10,20
diff --git a/gas/testsuite/gas/ppc/vsx2.d b/gas/testsuite/gas/ppc/vsx2.d
new file mode 100644
index 0000000..04e4294
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vsx2.d
@@ -0,0 +1,65 @@
+#as: -mvsx
+#objdump: -dr -Mvsx
+#name: VSX ISA 2.07 instructions
+
+.*
+
+Disassembly of section \.text:
+
+0+00 <vsx2>:
+   0:	(7f ce d0 19|19 d0 ce 7f) 	lxsiwzx vs62,r14,r26
+   4:	(7d 00 c8 19|19 c8 00 7d) 	lxsiwzx vs40,0,r25
+   8:	(7f 20 d0 98|98 d0 20 7f) 	lxsiwax vs25,0,r26
+   c:	(7c 60 18 98|98 18 60 7c) 	lxsiwax vs3,0,r3
+  10:	(7f cc 00 66|66 00 cc 7f) 	mfvsrd  r12,vs30
+  14:	(7f cc 00 66|66 00 cc 7f) 	mfvsrd  r12,vs30
+  18:	(7f cc 00 67|67 00 cc 7f) 	mfvsrd  r12,vs62
+  1c:	(7f cc 00 67|67 00 cc 7f) 	mfvsrd  r12,vs62
+  20:	(7d 94 00 e6|e6 00 94 7d) 	mffprwz r20,f12
+  24:	(7d 94 00 e6|e6 00 94 7d) 	mffprwz r20,f12
+  28:	(7d 95 00 e7|e7 00 95 7d) 	mfvrwz  r21,v12
+  2c:	(7d 95 00 e7|e7 00 95 7d) 	mfvrwz  r21,v12
+  30:	(7d c9 71 18|18 71 c9 7d) 	stxsiwx vs14,r9,r14
+  34:	(7e a0 41 18|18 41 a0 7e) 	stxsiwx vs21,0,r8
+  38:	(7d 7c 01 66|66 01 7c 7d) 	mtvsrd  vs11,r28
+  3c:	(7d 7c 01 66|66 01 7c 7d) 	mtvsrd  vs11,r28
+  40:	(7d 7d 01 67|67 01 7d 7d) 	mtvsrd  vs43,r29
+  44:	(7d 7d 01 67|67 01 7d 7d) 	mtvsrd  vs43,r29
+  48:	(7f 16 01 a6|a6 01 16 7f) 	mtfprwa f24,r22
+  4c:	(7f 16 01 a6|a6 01 16 7f) 	mtfprwa f24,r22
+  50:	(7f 37 01 a7|a7 01 37 7f) 	mtvrwa  v25,r23
+  54:	(7f 37 01 a7|a7 01 37 7f) 	mtvrwa  v25,r23
+  58:	(7f 5b 01 e6|e6 01 5b 7f) 	mtfprwz f26,r27
+  5c:	(7f 5b 01 e6|e6 01 5b 7f) 	mtfprwz f26,r27
+  60:	(7f 7c 01 e7|e7 01 7c 7f) 	mtvrwz  v27,r28
+  64:	(7f 7c 01 e7|e7 01 7c 7f) 	mtvrwz  v27,r28
+  68:	(7d b3 6c 18|18 6c b3 7d) 	lxsspx  vs13,r19,r13
+  6c:	(7e 40 6c 18|18 6c 40 7e) 	lxsspx  vs18,0,r13
+  70:	(7d 62 25 19|19 25 62 7d) 	stxsspx vs43,r2,r4
+  74:	(7e e0 5d 19|19 5d e0 7e) 	stxsspx vs55,0,r11
+  78:	(f2 d0 c8 05|05 c8 d0 f2) 	xsaddsp vs54,vs48,vs25
+  7c:	(f1 d2 08 0c|0c 08 d2 f1) 	xsmaddasp vs14,vs50,vs1
+  80:	(f3 56 50 42|42 50 56 f3) 	xssubsp vs26,vs22,vs42
+  84:	(f3 75 a0 4e|4e a0 75 f3) 	xsmaddmsp vs27,vs53,vs52
+  88:	(f1 00 d8 2a|2a d8 00 f1) 	xsrsqrtesp vs8,vs59
+  8c:	(f1 80 48 2e|2e 48 80 f1) 	xssqrtsp vs12,vs41
+  90:	(f3 2b 00 83|83 00 2b f3) 	xsmulsp vs57,vs11,vs32
+  94:	(f0 d4 d0 89|89 d0 d4 f0) 	xsmsubasp vs38,vs20,vs26
+  98:	(f3 53 30 c0|c0 30 53 f3) 	xsdivsp vs26,vs19,vs6
+  9c:	(f0 65 b8 cf|cf b8 65 f0) 	xsmsubmsp vs35,vs37,vs55
+  a0:	(f3 60 40 69|69 40 60 f3) 	xsresp  vs59,vs8
+  a4:	(f1 81 0c 0f|0f 0c 81 f1) 	xsnmaddasp vs44,vs33,vs33
+  a8:	(f2 3e f4 4c|4c f4 3e f2) 	xsnmaddmsp vs17,vs62,vs30
+  ac:	(f2 d4 fc 8d|8d fc d4 f2) 	xsnmsubasp vs54,vs52,vs31
+  b0:	(f0 a5 d4 cb|cb d4 a5 f0) 	xsnmsubmsp vs37,vs5,vs58
+  b4:	(f3 d6 65 56|56 65 d6 f3) 	xxlorc  vs30,vs54,vs44
+  b8:	(f2 2e ed 91|91 ed 2e f2) 	xxlnand vs49,vs14,vs29
+  bc:	(f3 d6 f5 d1|d1 f5 d6 f3) 	xxleqv  vs62,vs22,vs30
+  c0:	(f3 80 b4 2f|2f b4 80 f3) 	xscvdpspn vs60,vs54
+  c4:	(f2 c0 6c 66|66 6c c0 f2) 	xsrsp   vs22,vs45
+  c8:	(f3 40 dc a2|a2 dc 40 f3) 	xscvuxdsp vs26,vs59
+  cc:	(f0 c0 8c e3|e3 8c c0 f0) 	xscvsxdsp vs38,vs49
+  d0:	(f3 60 d5 2d|2d d5 60 f3) 	xscvspdpn vs59,vs26
+  d4:	(ff 0e 16 8c|8c 16 0e ff) 	fmrgow  f24,f14,f2
+  d8:	(fe c7 2f 8c|8c 2f c7 fe) 	fmrgew  f22,f7,f5
+#pass
diff --git a/gas/testsuite/gas/ppc/vsx2.s b/gas/testsuite/gas/ppc/vsx2.s
new file mode 100644
index 0000000..624614d
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vsx2.s
@@ -0,0 +1,57 @@
+	.text
+vsx2:
+	lxsiwzx      62,14,26
+	lxsiwzx      40,0,25
+	lxsiwax      25,0,26
+	lxsiwax      3,0,3
+	mfvsrd       12,30
+	mffprd       12,30
+	mfvsrd       12,62
+	mfvrd        12,30
+	mfvsrwz      20,12
+	mffprwz      20,12
+	mfvsrwz      21,44
+	mfvrwz       21,12
+	stxsiwx      14,9,14
+	stxsiwx      21,0,8
+	mtvsrd       11,28
+	mtfprd       11,28
+	mtvsrd       43,29
+	mtvrd        11,29
+	mtvsrwa      24,22
+	mtfprwa      24,22
+	mtvsrwa      57,23
+	mtvrwa       25,23
+	mtvsrwz      26,27
+	mtfprwz      26,27
+	mtvsrwz      59,28
+	mtvrwz       27,28
+	lxsspx       13,19,13
+	lxsspx       18,0,13
+	stxsspx      43,2,4
+	stxsspx      55,0,11
+	xsaddsp      54,48,25
+	xsmaddasp    14,50,1
+	xssubsp      26,22,42
+	xsmaddmsp    27,53,52
+	xsrsqrtesp   8,59
+	xssqrtsp     12,41
+	xsmulsp      57,11,32
+	xsmsubasp    38,20,26
+	xsdivsp      26,19,6
+	xsmsubmsp    35,37,55
+	xsresp       59,8
+	xsnmaddasp   44,33,33
+	xsnmaddmsp   17,62,30
+	xsnmsubasp   54,52,31
+	xsnmsubmsp   37,5,58
+	xxlorc       30,54,44
+	xxlnand      49,14,29
+	xxleqv       62,22,30
+	xscvdpspn    60,54
+	xsrsp        22,45
+	xscvuxdsp    26,59
+	xscvsxdsp    38,49
+	xscvspdpn    59,26
+	fmrgow       24,14,2
+	fmrgew       22,7,5
diff --git a/gas/testsuite/gas/s390/zarch-zEC12.d b/gas/testsuite/gas/s390/zarch-zEC12.d
index 829e4d3..25424c9 100644
--- a/gas/testsuite/gas/s390/zarch-zEC12.d
+++ b/gas/testsuite/gas/s390/zarch-zEC12.d
@@ -47,10 +47,10 @@
 .*:	eb 6c 7a 4d fe 2b [	 ]*clgtnh	%r6,-5555\(%r7\)
 .*:	eb 6c 7a 4d fe 2b [	 ]*clgtnh	%r6,-5555\(%r7\)
 .*:	ec 67 0c 0d 0e 59 [	 ]*risbgn	%r6,%r7,12,13,14
-.*:	ed 90 8f a0 6d aa [	 ]*cdzt	%f6,4000\(10,%r8\),13
-.*:	ed 90 8f a0 4d ab [	 ]*cxzt	%f4,4000\(10,%r8\),13
-.*:	ed 90 8f a0 6d a8 [	 ]*czdt	%f6,4000\(10,%r8\),13
-.*:	ed 90 8f a0 4d a9 [	 ]*czxt	%f4,4000\(10,%r8\),13
+.*:	ed 0f 8f a0 6d aa [	 ]*cdzt	%f6,4000\(16,%r8\),13
+.*:	ed 21 8f a0 4d ab [	 ]*cxzt	%f4,4000\(34,%r8\),13
+.*:	ed 0f 8f a0 6d a8 [	 ]*czdt	%f6,4000\(16,%r8\),13
+.*:	ed 21 8f a0 4d a9 [	 ]*czxt	%f4,4000\(34,%r8\),13
 .*:	b2 e8 c0 56 [	 ]*ppa	%r5,%r6,12
 .*:	b9 8f 60 59 [	 ]*crdte	%r5,%r6,%r9,0
 .*:	b9 8f 61 59 [	 ]*crdte	%r5,%r6,%r9,1
diff --git a/gas/testsuite/gas/s390/zarch-zEC12.s b/gas/testsuite/gas/s390/zarch-zEC12.s
index d1c58cd..a5ece0f 100644
--- a/gas/testsuite/gas/s390/zarch-zEC12.s
+++ b/gas/testsuite/gas/s390/zarch-zEC12.s
@@ -44,10 +44,10 @@
 	clgtnh	%r6,-5555(%r7)
 
 	risbgn	%r6,%r7,12,13,14
-	cdzt	%f6,4000(10,%r8),13
-	cxzt	%f4,4000(10,%r8),13
-	czdt	%f6,4000(10,%r8),13
-	czxt	%f4,4000(10,%r8),13
+	cdzt	%f6,4000(16,%r8),13
+	cxzt	%f4,4000(34,%r8),13
+	czdt	%f6,4000(16,%r8),13
+	czxt	%f4,4000(34,%r8),13
 
 	ppa	%r5,%r6,12
 	crdte	%r5,%r6,%r9
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 97d2e35..d53df06 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,88 @@
+2013-05-21  Cary Coutant  <ccoutant@google.com>
+
+	* symtab.h (Symbol::is_cxx_vtable): New function.
+	* target-reloc.h (relocate_section): Check for vtable symbol.
+	* testsuite/Makefile.am (missing_key_func.sh): New test case.
+	* testsuite/Makefile.in: Regenerate.
+	* testsuite/missing_key_func.cc: New test source.
+	* testsuite/missing_key_func.sh: New test script.
+
+2013-05-21  Cary Coutant  <ccoutant@google.com>
+
+    	* object.cc (Sized_relobj_file::get_symbol_location_info): Set
+    	type of enclosing symbol.
+    	(Relocate_info::location): Check symbol type when describing symbol.
+    	* object.h (Symbol_location_info): Remove unused line_number;
+    	add enclosing_symbol_type.
+    	* testsuite/debug_msg.sh: Adjust expected output.
+
+2013-05-13  Cary Coutant  <ccoutant@google.com>
+
+    	* configure.ac: Export DEFAULT_TARGET.
+    	* configure: Regenerate.
+    	* Makefile.in: Regenerate.
+    	* testsuite/Makefile.am: Add .EXPORT_ALL_VARIABLES.
+    	* testsuite/Makefile.in: Regenerate.
+    	* testsuite/debug_msg.sh: Delete duplicate tests.
+    	Don't check undef_int error message match for powerpc where the
+    	source file and line number aren't available.
+
+2013-05-10  Roland McGrath  <mcgrathr@google.com>
+
+	* options.h (General_options): Add --rosegment-gap option.
+	* options.cc (finalize): --rosegment-gap implies --rosegment.
+	* layout.cc (set_segment_offsets): Let user option override
+	target->rosegment_gap().
+
+2013-05-10  Roland McGrath  <mcgrathr@google.com>
+
+	* options.h (General_options): Remove leading space from help
+	messages for -nostdlib and --rosegment.
+
+2013-05-03  Maciej W. Rozycki  <macro@codesourcery.com>
+
+	PR ld/15365
+	* layout.cc (Layout::finalize): Make __ehdr_start STV_HIDDEN.
+
+2013-05-03  Alan Modra  <amodra@gmail.com>
+
+	* merge.cc (Output_merge_string::do_add_input_section): Correct
+	scan for number of strings.  Rename vars to avoid shadowing.
+	Include missing terminator in input_size_.
+
+2013-05-01  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* merge.cc (Output_merge_string<Char_type>::do_add_input_section):
+	Restore empty string handling.
+
+2013-05-01  Cary Coutant  <ccoutant@google.com>
+
+	* stringpool.cc (Stringpool_template::new_key_offset): Fix
+	uninitialized warning.
+
+2013-04-29  Alexander Ivchenko  <alexander.ivchenko@intel.com>
+
+	* output.cc (Output_section::add_merge_input_section): Allow
+	to merge sections if the alignment is more than character size.
+	* merge.h (Output_merge_string::Output_merge_string): Remove
+	assert.
+	* merge.cc (Output_merge_string<Char_type>::do_add_input_section): Count
+	only not-null strings. Check the alignment of strings.
+	* stringpool.h
+	(Stringpool_template<Stringpool_char>::Stringpool_template): Add
+	alignment as the argument.
+	(Stringpool_template<Stringpool_char>::addralign_): New class member.
+	* stringpool.cc (Stringpool_template<Stringpool_char>::new_key_offset):
+	Align non-zero length strings according to the addralign_.
+	(Stringpool_template<Stringpool_char>::set_string_offsets):
+	Updating offsets according to the given alignment.
+	* testsuite/Makefile.am (text_section_grouping): Test if string
+	literals are getting merged.
+	* testsuite/Makefile.in: Regenerate.
+	* testsuite/merge_string_literals_1.c: New file.
+	* testsuite/merge_string_literals_2.c: Ditto.
+	* testsuite/merge_string_literals.sh: Ditto.
+
 2013-04-26  Ian Lance Taylor  <iant@google.com>
 
 	* target-reloc.h (relocate_section): If the reloc offset is out of
@@ -14758,7 +14843,7 @@
 
 	* Added source code to GNU binutils.
 
-Copyright (C) 2008-2012 Free Software Foundation, Inc.
+Copyright (C) 2008-2013 Free Software Foundation, Inc.
 
 Copying and distribution of this file, with or without modification,
 are permitted in any medium without royalty provided the copyright
diff --git a/gold/Makefile.in b/gold/Makefile.in
index 5c4c4d6..09de14c 100644
--- a/gold/Makefile.in
+++ b/gold/Makefile.in
@@ -288,6 +288,7 @@
 CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DEFAULT_TARGET = @DEFAULT_TARGET@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 DLOPEN_LIBS = @DLOPEN_LIBS@
diff --git a/gold/configure b/gold/configure
index 7e58cdf..cb56b65 100755
--- a/gold/configure
+++ b/gold/configure
@@ -680,6 +680,7 @@
 CC
 NM
 TARGETOBJS
+DEFAULT_TARGET
 DEFAULT_TARGET_TILEGX_FALSE
 DEFAULT_TARGET_TILEGX_TRUE
 DEFAULT_TARGET_X86_64_FALSE
@@ -3475,6 +3476,8 @@
   DEFAULT_TARGET_TILEGX_FALSE=
 fi
 
+	DEFAULT_TARGET=${targ_obj}
+
       fi
     fi
   fi
diff --git a/gold/configure.ac b/gold/configure.ac
index b03c09d..e3e10b3 100644
--- a/gold/configure.ac
+++ b/gold/configure.ac
@@ -206,6 +206,8 @@
 	AM_CONDITIONAL(DEFAULT_TARGET_SPARC, test "$targ_obj" = "sparc")
 	AM_CONDITIONAL(DEFAULT_TARGET_X86_64, test "$targ_obj" = "x86_64")
 	AM_CONDITIONAL(DEFAULT_TARGET_TILEGX, test "$targ_obj" = "tilegx")
+	DEFAULT_TARGET=${targ_obj}
+	AC_SUBST(DEFAULT_TARGET)
       fi
     fi
   fi
diff --git a/gold/layout.cc b/gold/layout.cc
index b593acd..33fa473 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -1,6 +1,6 @@
 // layout.cc -- lay out output file sections for gold
 
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
 // Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
@@ -244,10 +244,10 @@
 {
  public:
   Hash_task(const unsigned char* src,
-            size_t size,
-            unsigned char* dst,
-            Task_token* build_id_blocker,
-            Task_token* final_blocker)
+	    size_t size,
+	    unsigned char* dst,
+	    Task_token* build_id_blocker,
+	    Task_token* final_blocker)
     : src_(src), size_(size), dst_(dst), build_id_blocker_(build_id_blocker),
       final_blocker_(final_blocker)
   { }
@@ -1098,7 +1098,7 @@
   // wind up in the .text section.  Sections that start with these
   // prefixes must appear first, and must appear in the order listed
   // here.
-  static const char* const text_section_sort[] = 
+  static const char* const text_section_sort[] =
   {
     ".text.unlikely",
     ".text.exit",
@@ -1158,7 +1158,7 @@
 	  = this->section_segment_map_.find(Const_section_id(object, shndx));
       if (it == this->section_segment_map_.end())
 	{
-          os = this->choose_output_section(object, name, sh_type,
+	  os = this->choose_output_section(object, name, sh_type,
 					   shdr.get_sh_flags(), true,
 					   ORDER_INVALID, false);
 	}
@@ -1254,7 +1254,7 @@
 Layout::insert_section_segment_map(Const_section_id secn,
 				   Unique_segment_info *s)
 {
-  gold_assert(this->unique_segment_for_sections_specified_); 
+  gold_assert(this->unique_segment_for_sections_specified_);
   this->section_segment_map_[secn] = s;
 }
 
@@ -1890,44 +1890,44 @@
   if (!os->is_unique_segment())
     {
       for (p = this->segment_list_.begin();
- 	   p != this->segment_list_.end();
+	   p != this->segment_list_.end();
 	   ++p)
 	{
-	  if ((*p)->type() != elfcpp::PT_LOAD)                        
-	    continue;                        
-	  if ((*p)->is_unique_segment())                        
-	    continue;                        
-	  if (!parameters->options().omagic()                        
-	      && ((*p)->flags() & elfcpp::PF_W) != (seg_flags & elfcpp::PF_W))                        
-	    continue;                        
-	  if ((target->isolate_execinstr() || parameters->options().rosegment())                        
-	      && ((*p)->flags() & elfcpp::PF_X) != (seg_flags & elfcpp::PF_X))                        
-	    continue;                        
-	  // If -Tbss was specified, we need to separate the data and BSS                        
-	  // segments.                        
-	  if (parameters->options().user_set_Tbss())                        
-	    {                        
-	      if ((os->type() == elfcpp::SHT_NOBITS)                        
-	          == (*p)->has_any_data_sections())                        
-	        continue;                        
-	    }                        
-	  if (os->is_large_data_section() && !(*p)->is_large_data_segment())                        
-	    continue;                        
-	                    
-	  if (is_address_set)                        
-	    {                        
-	      if ((*p)->are_addresses_set())                        
-	        continue;                        
-	                    
-	      (*p)->add_initial_output_data(os);                        
-	      (*p)->update_flags_for_output_section(seg_flags);                        
-	      (*p)->set_addresses(addr, addr);                        
-	      break;                        
-	    }                        
-	                    
-	  (*p)->add_output_section_to_load(this, os, seg_flags);                        
-	  break;                        
-	}                        
+	  if ((*p)->type() != elfcpp::PT_LOAD)
+	    continue;
+	  if ((*p)->is_unique_segment())
+	    continue;
+	  if (!parameters->options().omagic()
+	      && ((*p)->flags() & elfcpp::PF_W) != (seg_flags & elfcpp::PF_W))
+	    continue;
+	  if ((target->isolate_execinstr() || parameters->options().rosegment())
+	      && ((*p)->flags() & elfcpp::PF_X) != (seg_flags & elfcpp::PF_X))
+	    continue;
+	  // If -Tbss was specified, we need to separate the data and BSS
+	  // segments.
+	  if (parameters->options().user_set_Tbss())
+	    {
+	      if ((os->type() == elfcpp::SHT_NOBITS)
+		  == (*p)->has_any_data_sections())
+		continue;
+	    }
+	  if (os->is_large_data_section() && !(*p)->is_large_data_segment())
+	    continue;
+
+	  if (is_address_set)
+	    {
+	      if ((*p)->are_addresses_set())
+		continue;
+
+	      (*p)->add_initial_output_data(os);
+	      (*p)->update_flags_for_output_section(seg_flags);
+	      (*p)->set_addresses(addr, addr);
+	      break;
+	    }
+
+	  (*p)->add_output_section_to_load(this, os, seg_flags);
+	  break;
+	}
     }
 
   if (p == this->segment_list_.end()
@@ -2713,7 +2713,7 @@
     symtab->define_in_output_segment("__ehdr_start", NULL,
 				     Symbol_table::PREDEFINED, load_seg, 0, 0,
 				     elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
-				     elfcpp::STV_DEFAULT, 0,
+				     elfcpp::STV_HIDDEN, 0,
 				     Symbol::SEGMENT_START, true);
 
   // Set the file offsets of all the non-data sections we've seen so
@@ -3457,7 +3457,10 @@
 
 		  // If the target wants a fixed minimum distance from the
 		  // text segment to the read-only segment, move up now.
-		  uint64_t min_addr = start_addr + target->rosegment_gap();
+		  uint64_t min_addr =
+		    start_addr + (parameters->options().user_set_rosegment_gap()
+				  ? parameters->options().rosegment_gap()
+				  : target->rosegment_gap());
 		  if (addr < min_addr)
 		    addr = min_addr;
 
@@ -5270,20 +5273,20 @@
 
 Task_token*
 Layout::queue_build_id_tasks(Workqueue* workqueue, Task_token* build_id_blocker,
-                             Output_file* of)
+			     Output_file* of)
 {
   const size_t filesize = (this->output_file_size() <= 0 ? 0
-                           : static_cast<size_t>(this->output_file_size()));
+			   : static_cast<size_t>(this->output_file_size()));
   if (this->build_id_note_ != NULL
       && strcmp(parameters->options().build_id(), "tree") == 0
       && parameters->options().build_id_chunk_size_for_treehash() > 0
       && filesize > 0
       && (filesize >=
-          parameters->options().build_id_min_file_size_for_treehash()))
+	  parameters->options().build_id_min_file_size_for_treehash()))
     {
       static const size_t MD5_OUTPUT_SIZE_IN_BYTES = 16;
       const size_t chunk_size =
-          parameters->options().build_id_chunk_size_for_treehash();
+	  parameters->options().build_id_chunk_size_for_treehash();
       const size_t num_hashes = ((filesize - 1) / chunk_size) + 1;
       Task_token* post_hash_tasks_blocker = new Task_token(true);
       post_hash_tasks_blocker->add_blockers(num_hashes);
@@ -5293,15 +5296,15 @@
       unsigned char *dst = new unsigned char[this->size_of_array_of_hashes_];
       this->array_of_hashes_ = dst;
       for (size_t i = 0, src_offset = 0; i < num_hashes;
-           i++, dst += MD5_OUTPUT_SIZE_IN_BYTES, src_offset += chunk_size)
-        {
-          size_t size = std::min(chunk_size, filesize - src_offset);
-          workqueue->queue(new Hash_task(src + src_offset,
-                                         size,
-                                         dst,
-                                         build_id_blocker,
-                                         post_hash_tasks_blocker));
-        }
+	   i++, dst += MD5_OUTPUT_SIZE_IN_BYTES, src_offset += chunk_size)
+	{
+	  size_t size = std::min(chunk_size, filesize - src_offset);
+	  workqueue->queue(new Hash_task(src + src_offset,
+					 size,
+					 dst,
+					 build_id_blocker,
+					 post_hash_tasks_blocker));
+	}
       return post_hash_tasks_blocker;
     }
   return build_id_blocker;
@@ -5318,7 +5321,7 @@
     return;
 
   unsigned char* ov = of->get_output_view(this->build_id_note_->offset(),
-                                          this->build_id_note_->data_size());
+					  this->build_id_note_->data_size());
 
   if (this->array_of_hashes_ == NULL)
     {
@@ -5329,11 +5332,11 @@
       // If we get here with style == "tree" then the output must be
       // too small for chunking, and we use SHA-1 in that case.
       if ((strcmp(style, "sha1") == 0) || (strcmp(style, "tree") == 0))
-        sha1_buffer(reinterpret_cast<const char*>(iv), output_file_size, ov);
+	sha1_buffer(reinterpret_cast<const char*>(iv), output_file_size, ov);
       else if (strcmp(style, "md5") == 0)
-        md5_buffer(reinterpret_cast<const char*>(iv), output_file_size, ov);
+	md5_buffer(reinterpret_cast<const char*>(iv), output_file_size, ov);
       else
-        gold_unreachable();
+	gold_unreachable();
 
       of->free_input_view(0, output_file_size, iv);
     }
@@ -5342,7 +5345,7 @@
       // Non-overlapping substrings of the output file have been hashed.
       // Compute SHA-1 hash of the hashes.
       sha1_buffer(reinterpret_cast<const char*>(this->array_of_hashes_),
-                  this->size_of_array_of_hashes_, ov);
+		  this->size_of_array_of_hashes_, ov);
       delete[] this->array_of_hashes_;
       of->free_input_view(0, this->output_file_size(), this->input_view_);
     }
diff --git a/gold/merge.cc b/gold/merge.cc
index dde43e9..f370c9c 100644
--- a/gold/merge.cc
+++ b/gold/merge.cc
@@ -505,17 +505,17 @@
 Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
 						     unsigned int shndx)
 {
-  section_size_type len;
+  section_size_type sec_len;
   bool is_new;
   const unsigned char* pdata = object->decompressed_section_contents(shndx,
-								     &len,
+								     &sec_len,
 								     &is_new);
 
   const Char_type* p = reinterpret_cast<const Char_type*>(pdata);
-  const Char_type* pend = p + len / sizeof(Char_type);
+  const Char_type* pend = p + sec_len / sizeof(Char_type);
   const Char_type* pend0 = pend;
 
-  if (len % sizeof(Char_type) != 0)
+  if (sec_len % sizeof(Char_type) != 0)
     {
       object->error(_("mergeable string section length not multiple of "
 		      "character size"));
@@ -540,25 +540,44 @@
   this->merged_strings_lists_.push_back(merged_strings_list);
   Merged_strings& merged_strings = merged_strings_list->merged_strings;
 
-  // Count the number of strings in the section and size the list.
+  // Count the number of non-null strings in the section and size the list.
   size_t count = 0;
-  for (const Char_type* pt = p; pt < pend0; pt += string_length(pt) + 1)
-    ++count;
+  const Char_type* pt = p;
+  while (pt < pend0)
+    {
+      size_t len = string_length(pt);
+      if (len != 0)
+	++count;
+      pt += len + 1;
+    }
   if (pend0 < pend)
     ++count;
   merged_strings.reserve(count + 1);
 
   // The index I is in bytes, not characters.
   section_size_type i = 0;
+
+  // We assume here that the beginning of the section is correctly
+  // aligned, so each string within the section must retain the same
+  // modulo.
+  uintptr_t init_align_modulo = (reinterpret_cast<uintptr_t>(pdata)
+				 & (this->addralign() - 1));
+  bool has_misaligned_strings = false;
+
   while (p < pend0)
     {
       size_t len = string_length(p);
 
+      // Within merge input section each string must be aligned.
+      if (len != 0
+	  && ((reinterpret_cast<uintptr_t>(p) & (this->addralign() - 1))
+	      != init_align_modulo))
+	  has_misaligned_strings = true;
+
       Stringpool::Key key;
       this->stringpool_.add_with_length(p, len, true, &key);
 
       merged_strings.push_back(Merged_string(i, key));
-
       p += len + 1;
       i += (len + 1) * sizeof(Char_type);
     }
@@ -579,7 +598,13 @@
   merged_strings.push_back(Merged_string(i, 0));
 
   this->input_count_ += count;
-  this->input_size_ += len;
+  this->input_size_ += i;
+
+  if (has_misaligned_strings)
+    gold_warning(_("%s: section %s contains incorrectly aligned strings;"
+		   " the alignment of those strings won't be preserved"),
+		 object->name().c_str(),
+		 object->section_name(shndx).c_str());
 
   // For script processing, we keep the input sections.
   if (this->keeps_input_sections())
diff --git a/gold/merge.h b/gold/merge.h
index 625d731..92c634a 100644
--- a/gold/merge.h
+++ b/gold/merge.h
@@ -461,10 +461,9 @@
 {
  public:
   Output_merge_string(uint64_t addralign)
-    : Output_merge_base(sizeof(Char_type), addralign), stringpool_(),
+    : Output_merge_base(sizeof(Char_type), addralign), stringpool_(addralign),
       merged_strings_lists_(), input_count_(0), input_size_(0)
   {
-    gold_assert(addralign <= sizeof(Char_type));
     this->stringpool_.set_no_zero_null();
   }
 
diff --git a/gold/object.cc b/gold/object.cc
index 715f7ac..1f113d1 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -1,6 +1,6 @@
 // object.cc -- support for an object file for linking in gold
 
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
 // Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
@@ -2687,6 +2687,7 @@
 	  && (static_cast<off_t>(sym.get_st_value() + sym.get_st_size())
 	      > offset))
 	{
+	  info->enclosing_symbol_type = sym.get_st_type();
 	  if (sym.get_st_name() > names_size)
 	    info->enclosing_symbol_name = "(invalid)";
 	  else
@@ -2996,12 +2997,10 @@
 	  ret += ":";
 	  ret += info.source_file;
 	}
-      size_t len = info.enclosing_symbol_name.length() + 100;
-      char* buf = new char[len];
-      snprintf(buf, len, _(":function %s"),
-	       info.enclosing_symbol_name.c_str());
-      ret += buf;
-      delete[] buf;
+      ret += ":";
+      if (info.enclosing_symbol_type == elfcpp::STT_FUNC)
+	ret += _("function ");
+      ret += info.enclosing_symbol_name;
       return ret;
     }
 
diff --git a/gold/object.h b/gold/object.h
index a2baecc..c17c13d 100644
--- a/gold/object.h
+++ b/gold/object.h
@@ -1,6 +1,6 @@
 // object.h -- support for an object file for linking in gold  -*- C++ -*-
 
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
 // Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
@@ -103,7 +103,7 @@
 {
   std::string source_file;
   std::string enclosing_symbol_name;
-  int line_number;
+  elfcpp::STT enclosing_symbol_type;
 };
 
 // Data about a single relocation section.  This is read in
diff --git a/gold/options.cc b/gold/options.cc
index 5b94fae..000e6d0 100644
--- a/gold/options.cc
+++ b/gold/options.cc
@@ -1,6 +1,7 @@
 // options.c -- handle command line options for gold
 
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2013
+// Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -101,11 +102,11 @@
     {
       len += printf("-%c", this->shortname);
       if (this->helparg)
-        {
-          // -z takes long-names only.
-          gold_assert(this->dashes != DASH_Z);
-          len += printf(" %s", gettext(this->helparg));
-        }
+	{
+	  // -z takes long-names only.
+	  gold_assert(this->dashes != DASH_Z);
+	  len += printf(" %s", gettext(this->helparg));
+	}
       comma = true;
     }
   if (!this->longname.empty()
@@ -113,29 +114,29 @@
 	   && this->longname[1] == '\0'))
     {
       if (comma)
-        len += printf(", ");
+	len += printf(", ");
       switch (this->dashes)
-        {
-        case options::ONE_DASH: case options::EXACTLY_ONE_DASH:
-          len += printf("-");
-          break;
-        case options::TWO_DASHES: case options::EXACTLY_TWO_DASHES:
-          len += printf("--");
-          break;
-        case options::DASH_Z:
-          len += printf("-z ");
-          break;
-        default:
-          gold_unreachable();
-        }
+	{
+	case options::ONE_DASH: case options::EXACTLY_ONE_DASH:
+	  len += printf("-");
+	  break;
+	case options::TWO_DASHES: case options::EXACTLY_TWO_DASHES:
+	  len += printf("--");
+	  break;
+	case options::DASH_Z:
+	  len += printf("-z ");
+	  break;
+	default:
+	  gold_unreachable();
+	}
       len += printf("%s", this->longname.c_str());
       if (this->helparg)
-        {
-          // For most options, we print "--frob FOO".  But for -z
-          // we print "-z frob=FOO".
-          len += printf("%c%s", this->dashes == options::DASH_Z ? '=' : ' ',
-                        gettext(this->helparg));
-        }
+	{
+	  // For most options, we print "--frob FOO".  But for -z
+	  // we print "-z frob=FOO".
+	  len += printf("%c%s", this->dashes == options::DASH_Z ? '=' : ' ',
+			gettext(this->helparg));
+	}
     }
 
   if (len >= 30)
@@ -200,7 +201,7 @@
   *retval = strtol(arg, &endptr, 0);
   if (*endptr != '\0' || *retval < 0)
     gold_fatal(_("%s: invalid option value (expected an integer): %s"),
-               option_name, arg);
+	       option_name, arg);
 }
 
 void
@@ -210,7 +211,7 @@
   *retval = strtol(arg, &endptr, 0);
   if (*endptr != '\0')
     gold_fatal(_("%s: invalid option value (expected an integer): %s"),
-               option_name, arg);
+	       option_name, arg);
 }
 
 void
@@ -220,7 +221,7 @@
   *retval = strtoull(arg, &endptr, 0);
   if (*endptr != '\0')
     gold_fatal(_("%s: invalid option value (expected an integer): %s"),
-               option_name, arg);
+	       option_name, arg);
 }
 
 void
@@ -273,13 +274,13 @@
 
 void
 parse_choices(const char* option_name, const char* arg, const char** retval,
-              const char* choices[], int num_choices)
+	      const char* choices[], int num_choices)
 {
   for (int i = 0; i < num_choices; i++)
     if (strcmp(choices[i], arg) == 0)
       {
-        *retval = arg;
-        return;
+	*retval = arg;
+	return;
       }
 
   // If we get here, the user did not enter a valid choice, so we die.
@@ -288,10 +289,10 @@
     {
       choices_list += choices[i];
       if (i != num_choices - 1)
-        choices_list += ", ";
+	choices_list += ", ";
     }
   gold_fatal(_("%s: must take one of the following arguments: %s"),
-             option_name, choices_list.c_str());
+	     option_name, choices_list.c_str());
 }
 
 } // End namespace options.
@@ -340,21 +341,21 @@
 
 void
 General_options::parse_defsym(const char*, const char* arg,
-                              Command_line* cmdline)
+			      Command_line* cmdline)
 {
   cmdline->script_options().define_symbol(arg);
 }
 
 void
 General_options::parse_incremental(const char*, const char*,
-                                   Command_line*)
+				   Command_line*)
 {
   this->incremental_mode_ = INCREMENTAL_AUTO;
 }
 
 void
 General_options::parse_no_incremental(const char*, const char*,
-                                      Command_line*)
+				      Command_line*)
 {
   this->incremental_mode_ = INCREMENTAL_OFF;
 }
@@ -375,7 +376,7 @@
 
 void
 General_options::parse_incremental_changed(const char*, const char*,
-                                           Command_line*)
+					   Command_line*)
 {
   this->implicit_incremental_ = true;
   this->incremental_disposition_ = INCREMENTAL_CHANGED;
@@ -383,7 +384,7 @@
 
 void
 General_options::parse_incremental_unchanged(const char*, const char*,
-                                             Command_line*)
+					     Command_line*)
 {
   this->implicit_incremental_ = true;
   this->incremental_disposition_ = INCREMENTAL_UNCHANGED;
@@ -391,7 +392,7 @@
 
 void
 General_options::parse_incremental_unknown(const char*, const char*,
-                                           Command_line*)
+					   Command_line*)
 {
   this->implicit_incremental_ = true;
   this->incremental_disposition_ = INCREMENTAL_CHECK;
@@ -407,7 +408,7 @@
 
 void
 General_options::parse_library(const char*, const char* arg,
-                               Command_line* cmdline)
+			       Command_line* cmdline)
 {
   Input_file_argument::Input_file_type type;
   const char* name;
@@ -428,7 +429,7 @@
 #ifdef ENABLE_PLUGINS
 void
 General_options::parse_plugin(const char*, const char* arg,
-                              Command_line*)
+			      Command_line*)
 {
   this->add_plugin(arg);
 }
@@ -437,7 +438,7 @@
 
 void
 General_options::parse_plugin_opt(const char*, const char* arg,
-                                  Command_line*)
+				  Command_line*)
 {
   this->add_plugin_option(arg);
 }
@@ -445,7 +446,7 @@
 
 void
 General_options::parse_R(const char* option, const char* arg,
-                         Command_line* cmdline)
+			 Command_line* cmdline)
 {
   struct stat s;
   if (::stat(arg, &s) != 0 || S_ISDIR(s.st_mode))
@@ -456,7 +457,7 @@
 
 void
 General_options::parse_just_symbols(const char*, const char* arg,
-                                    Command_line* cmdline)
+				    Command_line* cmdline)
 {
   Input_file_argument file(arg, Input_file_argument::INPUT_FILE_TYPE_FILE,
 			   "", true, *this);
@@ -528,7 +529,7 @@
 
 void
 General_options::parse_script(const char*, const char* arg,
-                              Command_line* cmdline)
+			      Command_line* cmdline)
 {
   if (!read_commandline_script(arg, cmdline))
     gold::gold_fatal(_("unable to parse script file %s"), arg);
@@ -536,7 +537,7 @@
 
 void
 General_options::parse_version_script(const char*, const char* arg,
-                                      Command_line* cmdline)
+				      Command_line* cmdline)
 {
   if (!read_version_script(arg, cmdline))
     gold::gold_fatal(_("unable to parse version script file %s"), arg);
@@ -544,7 +545,7 @@
 
 void
 General_options::parse_dynamic_list(const char*, const char* arg,
-                                    Command_line* cmdline)
+				    Command_line* cmdline)
 {
   if (!read_dynamic_list(arg, cmdline, &this->dynamic_list_))
     gold::gold_fatal(_("unable to parse dynamic-list script file %s"), arg);
@@ -552,28 +553,28 @@
 
 void
 General_options::parse_start_group(const char*, const char*,
-                                   Command_line* cmdline)
+				   Command_line* cmdline)
 {
   cmdline->inputs().start_group();
 }
 
 void
 General_options::parse_end_group(const char*, const char*,
-                                 Command_line* cmdline)
+				 Command_line* cmdline)
 {
   cmdline->inputs().end_group();
 }
 
 void
 General_options::parse_start_lib(const char*, const char*,
-                                 Command_line* cmdline)
+				 Command_line* cmdline)
 {
   cmdline->inputs().start_lib(cmdline->position_dependent_options());
 }
 
 void
 General_options::parse_end_lib(const char*, const char*,
-                               Command_line* cmdline)
+			       Command_line* cmdline)
 {
   cmdline->inputs().end_lib();
 }
@@ -585,7 +586,7 @@
 
 void
 General_options::parse_exclude_libs(const char*, const char* arg,
-                                    Command_line*)
+				    Command_line*)
 {
   const char* p = arg;
 
@@ -659,15 +660,15 @@
   else
     {
       gold::gold_error(_("format '%s' not supported; treating as elf "
-                         "(supported formats: elf, binary)"),
-                       arg);
+			 "(supported formats: elf, binary)"),
+		       arg);
       return gold::General_options::OBJECT_FORMAT_ELF;
     }
 }
 
 void
 General_options::parse_fix_v4bx(const char*, const char*,
-                                Command_line*)
+				Command_line*)
 {
   this->fix_v4bx_ = FIX_V4BX_REPLACE;
 }
@@ -700,8 +701,8 @@
 usage()
 {
   fprintf(stderr,
-          _("%s: use the --help option for usage information\n"),
-          gold::program_name);
+	  _("%s: use the --help option for usage information\n"),
+	  gold::program_name);
   ::exit(EXIT_FAILURE);
 }
 
@@ -709,8 +710,8 @@
 usage(const char* msg, const char* opt)
 {
   fprintf(stderr,
-          _("%s: %s: %s\n"),
-          gold::program_name, opt, msg);
+	  _("%s: %s: %s\n"),
+	  gold::program_name, opt, msg);
   usage();
 }
 
@@ -721,12 +722,12 @@
 get_relative_sysroot(const char* from)
 {
   char* path = make_relative_prefix(gold::program_name, from,
-                                    TARGET_SYSTEM_ROOT);
+				    TARGET_SYSTEM_ROOT);
   if (path != NULL)
     {
       struct stat s;
       if (::stat(path, &s) == 0 && S_ISDIR(s.st_mode))
-        return path;
+	return path;
       free(path);
     }
 
@@ -749,9 +750,9 @@
     {
       char* path = get_relative_sysroot(BINDIR);
       if (path == NULL)
-        path = get_relative_sysroot(TOOLBINDIR);
+	path = get_relative_sysroot(TOOLBINDIR);
       if (path != NULL)
-        return path;
+	return path;
     }
 
   return sysroot;
@@ -768,14 +769,14 @@
 // NOTE: it is safe for argv and arg to point to the same place.
 gold::options::One_option*
 parse_long_option(int argc, const char** argv, bool equals_only,
-                  const char** arg, int* i)
+		  const char** arg, int* i)
 {
   const char* const this_argv = argv[*i];
 
   const char* equals = strchr(this_argv, '=');
   const char* option_start = this_argv + strspn(this_argv, "-");
   std::string option(option_start,
-                     equals ? equals - option_start : strlen(option_start));
+		     equals ? equals - option_start : strlen(option_start));
 
   gold::options::Option_map::iterator it
       = gold::options::long_options->find(option);
@@ -788,21 +789,21 @@
   if (this_argv[0] != '-')  // no dashes at all: had better be "-z <longopt>"
     {
       if (retval->dashes != gold::options::DASH_Z)
-        return NULL;
+	return NULL;
     }
   else if (this_argv[1] != '-')   // one dash
     {
       if (retval->dashes != gold::options::ONE_DASH
-          && retval->dashes != gold::options::EXACTLY_ONE_DASH
-          && retval->dashes != gold::options::TWO_DASHES)
-        return NULL;
+	  && retval->dashes != gold::options::EXACTLY_ONE_DASH
+	  && retval->dashes != gold::options::TWO_DASHES)
+	return NULL;
     }
   else                            // two dashes (or more!)
     {
       if (retval->dashes != gold::options::TWO_DASHES
-          && retval->dashes != gold::options::EXACTLY_TWO_DASHES
-          && retval->dashes != gold::options::ONE_DASH)
-        return NULL;
+	  && retval->dashes != gold::options::EXACTLY_TWO_DASHES
+	  && retval->dashes != gold::options::ONE_DASH)
+	return NULL;
     }
 
   // Now that we know the option is good (or else bad in a way that
@@ -813,20 +814,20 @@
   if (!retval->takes_argument())
     {
       if (equals)
-        usage(_("unexpected argument"), this_argv);
+	usage(_("unexpected argument"), this_argv);
       else
-        *arg = NULL;
+	*arg = NULL;
     }
   else
     {
       if (equals)
-        *arg = equals + 1;
+	*arg = equals + 1;
       else if (retval->takes_optional_argument())
 	*arg = retval->default_value;
       else if (*i < argc && !equals_only)
-        *arg = argv[(*i)++];
+	*arg = argv[(*i)++];
       else
-        usage(_("missing argument"), this_argv);
+	usage(_("missing argument"), this_argv);
     }
 
   return retval;
@@ -844,7 +845,7 @@
 // another short option in the same word.
 gold::options::One_option*
 parse_short_option(int argc, const char** argv, int pos_in_argv_i,
-                   const char** arg, int* i)
+		   const char** arg, int* i)
 {
   const char* const this_argv = argv[*i];
 
@@ -853,7 +854,7 @@
 
   // We handle -z as a special case.
   static gold::options::One_option dash_z("", gold::options::DASH_Z,
-                                          'z', "", NULL, "Z-OPTION", false,
+					  'z', "", NULL, "Z-OPTION", false,
 					  NULL);
   gold::options::One_option* retval = NULL;
   if (this_argv[pos_in_argv_i] == 'z')
@@ -862,7 +863,7 @@
     {
       const int char_as_int = static_cast<int>(this_argv[pos_in_argv_i]);
       if (char_as_int > 0 && char_as_int < 128)
-        retval = gold::options::short_options[char_as_int];
+	retval = gold::options::short_options[char_as_int];
     }
 
   if (retval == NULL)
@@ -874,20 +875,20 @@
       *arg = NULL;
       // We only advance past this argument if it's the only one in argv.
       if (this_argv[pos_in_argv_i + 1] == '\0')
-        ++(*i);
+	++(*i);
     }
   else
     {
       // If we take an argument, we'll eat up this entire argv entry.
       ++(*i);
       if (this_argv[pos_in_argv_i + 1] != '\0')
-        *arg = this_argv + pos_in_argv_i + 1;
+	*arg = this_argv + pos_in_argv_i + 1;
       else if (retval->takes_optional_argument())
 	*arg = retval->default_value;
       else if (*i < argc)
-        *arg = argv[(*i)++];
+	*arg = argv[(*i)++];
       else
-        usage(_("missing argument"), this_argv);
+	usage(_("missing argument"), this_argv);
     }
 
   // If we're a -z option, we need to parse our argument as a
@@ -898,7 +899,7 @@
       const char* dash_z_arg = *arg;
       retval = parse_long_option(1, arg, true, arg, &dummy_i);
       if (retval == NULL)
-        usage(_("unknown -z option"), dash_z_arg);
+	usage(_("unknown -z option"), dash_z_arg);
     }
 
   return retval;
@@ -952,7 +953,7 @@
     {
       this->set_sysroot(get_default_sysroot());
       if (this->sysroot() == NULL || this->sysroot()[0] == '\0')
-        return;
+	return;
     }
 
   char* canonical_sysroot = lrealpath(this->sysroot());
@@ -1117,8 +1118,8 @@
   if (this->thread_count() > 0 || this->thread_count_initial() > 0
       || this->thread_count_middle() > 0 || this->thread_count_final() > 0)
     gold_warning(_("ignoring --thread-count: "
-                   "%s was compiled without thread support"),
-                 program_name);
+		   "%s was compiled without thread support"),
+		 program_name);
 #endif
 
   std::string libpath;
@@ -1170,17 +1171,17 @@
       std::ifstream in;
       in.open(this->retain_symbols_file());
       if (!in)
-        gold_fatal(_("unable to open -retain-symbols-file file %s: %s"),
-                   this->retain_symbols_file(), strerror(errno));
+	gold_fatal(_("unable to open -retain-symbols-file file %s: %s"),
+		   this->retain_symbols_file(), strerror(errno));
       std::string line;
       std::getline(in, line);   // this chops off the trailing \n, if any
       while (in)
-        {
-          if (!line.empty() && line[line.length() - 1] == '\r')   // Windows
-            line.resize(line.length() - 1);
-          this->symbols_to_retain_.insert(line);
-          std::getline(in, line);
-        }
+	{
+	  if (!line.empty() && line[line.length() - 1] == '\r')   // Windows
+	    line.resize(line.length() - 1);
+	  this->symbols_to_retain_.insert(line);
+	  std::getline(in, line);
+	}
     }
 
   // -Bgroup implies --unresolved-symbols=report-all.
@@ -1239,7 +1240,7 @@
 
   if (this->implicit_incremental_ && this->incremental_mode_ == INCREMENTAL_OFF)
     gold_fatal(_("Options --incremental-changed, --incremental-unchanged, "
-                 "--incremental-unknown require the use of --incremental"));
+		 "--incremental-unknown require the use of --incremental"));
 
   // Check for options that are not compatible with incremental linking.
   // Where an option can be disabled without seriously changing the semantics
@@ -1272,6 +1273,10 @@
 	}
     }
 
+  // --rosegment-gap implies --rosegment.
+  if (this->user_set_rosegment_gap())
+    this->set_rosegment(true);
+
   // FIXME: we can/should be doing a lot more sanity checking here.
 }
 
@@ -1282,14 +1287,14 @@
 
 void
 Search_directory::add_sysroot(const char* sysroot,
-                              const char* canonical_sysroot)
+			      const char* canonical_sysroot)
 {
   gold_assert(*sysroot != '\0');
   if (this->put_in_sysroot_)
     {
       if (!IS_DIR_SEPARATOR(this->name_[0])
-          && !IS_DIR_SEPARATOR(sysroot[strlen(sysroot) - 1]))
-        this->name_ = '/' + this->name_;
+	  && !IS_DIR_SEPARATOR(sysroot[strlen(sysroot) - 1]))
+	this->name_ = '/' + this->name_;
       this->name_ = sysroot + this->name_;
       this->is_in_sysroot_ = true;
     }
@@ -1302,12 +1307,12 @@
       int canonical_name_len = strlen(canonical_name);
       int canonical_sysroot_len = strlen(canonical_sysroot);
       if (canonical_name_len > canonical_sysroot_len
-          && IS_DIR_SEPARATOR(canonical_name[canonical_sysroot_len]))
-        {
-          canonical_name[canonical_sysroot_len] = '\0';
-          if (FILENAME_CMP(canonical_name, canonical_sysroot) == 0)
-            this->is_in_sysroot_ = true;
-        }
+	  && IS_DIR_SEPARATOR(canonical_name[canonical_sysroot_len]))
+	{
+	  canonical_name[canonical_sysroot_len] = '\0';
+	  if (FILENAME_CMP(canonical_name, canonical_sysroot) == 0)
+	    this->is_in_sysroot_ = true;
+	}
       free(canonical_name);
     }
 }
@@ -1406,7 +1411,7 @@
 
 int
 Command_line::process_one_option(int argc, const char** argv, int i,
-                                 bool* no_more_options)
+				 bool* no_more_options)
 {
   gold_assert(argv[i][0] == '-' && !(*no_more_options));
 
@@ -1437,7 +1442,7 @@
     {
       option = parse_short_option(argc, argv, pos_in_argv_i, &arg, &new_i);
       if (!option)
-        break;
+	break;
       option->reader->parse_to_value(argv[i], arg, this, &this->options_);
       ++pos_in_argv_i;
     }
@@ -1459,15 +1464,15 @@
     {
       this->position_options_.copy_from_options(this->options());
       if (no_more_options || argv[i][0] != '-')
-        {
+	{
 	  Input_file_argument file(argv[i],
 				   Input_file_argument::INPUT_FILE_TYPE_FILE,
 				   "", false, this->position_options_);
-          this->inputs_.add_file(file);
-          ++i;
-        }
+	  this->inputs_.add_file(file);
+	  ++i;
+	}
       else
-        i = process_one_option(argc, argv, i, &no_more_options);
+	i = process_one_option(argc, argv, i, &no_more_options);
     }
 
   if (this->inputs_.in_group())
diff --git a/gold/options.h b/gold/options.h
index 75dbee5..0055826 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -1,6 +1,7 @@
 // options.h -- handle command line options for gold  -*- C++ -*-
 
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2013
+// Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -120,7 +121,7 @@
 
 extern void
 parse_choices(const char* option_name, const char* arg, const char** retval,
-              const char* choices[], int num_choices);
+	      const char* choices[], int num_choices);
 
 struct Struct_var;
 
@@ -168,7 +169,7 @@
   Struct_var* reader;
 
   One_option(const char* ln, Dashes d, char sn, const char* dv,
-             const char* hs, const char* ha, bool oa, Struct_var* r)
+	     const char* hs, const char* ha, bool oa, Struct_var* r)
     : longname(ln), dashes(d), shortname(sn), default_value(dv ? dv : ""),
       helpstring(hs), helparg(ha), optional_arg(oa), reader(r)
   {
@@ -219,7 +220,7 @@
   // OPTIONS: the global General_options object.  Used by DEFINE_special.
   virtual void
   parse_to_value(const char* option, const char* arg,
-                 Command_line* cmdline, General_options* options) = 0;
+		 Command_line* cmdline, General_options* options) = 0;
   virtual
   ~Struct_var()  // To make gcc happy.
   { }
@@ -230,16 +231,16 @@
 {
   // If you change this, change the parse-fn in DEFINE_special as well.
   typedef void (General_options::*Parse_function)(const char*, const char*,
-                                                  Command_line*);
+						  Command_line*);
   Struct_special(const char* varname, Dashes dashes, char shortname,
-                 Parse_function parse_function,
-                 const char* helpstring, const char* helparg)
+		 Parse_function parse_function,
+		 const char* helpstring, const char* helparg)
     : option(varname, dashes, shortname, "", helpstring, helparg, false, this),
       parse(parse_function)
   { }
 
   void parse_to_value(const char* option, const char* arg,
-                      Command_line* cmdline, General_options* options)
+		      Command_line* cmdline, General_options* options)
   { (options->*(this->parse))(option, arg, cmdline); }
 
   One_option option;
@@ -261,17 +262,17 @@
 // avoid unintended macro substitution of "assert()", we need to enclose
 // varname__ with parenthese.
 #define DEFINE_var(varname__, dashes__, shortname__, default_value__,        \
-                   default_value_as_string__, helpstring__, helparg__,       \
-                   optional_arg__, type__, param_type__, parse_fn__)	     \
+		   default_value_as_string__, helpstring__, helparg__,       \
+		   optional_arg__, type__, param_type__, parse_fn__)	     \
  public:                                                                     \
   param_type__                                                               \
   (varname__)() const                                                        \
   { return this->varname__##_.value; }                                       \
-                                                                             \
+									     \
   bool                                                                       \
   user_set_##varname__() const                                               \
   { return this->varname__##_.user_set_via_option; }                         \
-                                                                             \
+									     \
   void									     \
   set_user_set_##varname__()						     \
   { this->varname__##_.user_set_via_option = true; }			     \
@@ -281,18 +282,18 @@
   {                                                                          \
     Struct_##varname__()                                                     \
       : option(#varname__, dashes__, shortname__, default_value_as_string__, \
-               helpstring__, helparg__, optional_arg__, this),		     \
-        user_set_via_option(false), value(default_value__)                   \
+	       helpstring__, helparg__, optional_arg__, this),		     \
+	user_set_via_option(false), value(default_value__)                   \
     { }                                                                      \
-                                                                             \
+									     \
     void                                                                     \
     parse_to_value(const char* option_name, const char* arg,                 \
-                   Command_line*, General_options*)                          \
+		   Command_line*, General_options*)                          \
     {                                                                        \
       parse_fn__(option_name, arg, &this->value);                            \
       this->user_set_via_option = true;                                      \
     }                                                                        \
-                                                                             \
+									     \
     options::One_option option;                                              \
     bool user_set_via_option;                                                \
     type__ value;                                                            \
@@ -308,71 +309,71 @@
 // VARNAME, we also create an option called no-VARNAME (or, for a -z
 // option, noVARNAME).
 #define DEFINE_bool(varname__, dashes__, shortname__, default_value__,   \
-                    helpstring__, no_helpstring__)                       \
+		    helpstring__, no_helpstring__)                       \
   DEFINE_var(varname__, dashes__, shortname__, default_value__,          \
-             default_value__ ? "true" : "false", helpstring__, NULL,     \
-             false, bool, bool, options::parse_bool)			 \
+	     default_value__ ? "true" : "false", helpstring__, NULL,     \
+	     false, bool, bool, options::parse_bool)			 \
   struct Struct_no_##varname__ : public options::Struct_var              \
   {                                                                      \
     Struct_no_##varname__() : option((dashes__ == options::DASH_Z	 \
 				      ? "no" #varname__			 \
 				      : "no-" #varname__),		 \
 				     dashes__, '\0',			 \
-                                     default_value__ ? "false" : "true", \
-                                     no_helpstring__, NULL, false, this) \
+				     default_value__ ? "false" : "true", \
+				     no_helpstring__, NULL, false, this) \
     { }                                                                  \
-                                                                         \
+									 \
     void                                                                 \
     parse_to_value(const char*, const char*,                             \
-                   Command_line*, General_options* options)              \
+		   Command_line*, General_options* options)              \
     {                                                                    \
       options->set_##varname__(false);                                   \
       options->set_user_set_##varname__();                               \
     }                                                                    \
-                                                                         \
+									 \
     options::One_option option;                                          \
   };                                                                     \
   Struct_no_##varname__ no_##varname__##_initializer_
 
 #define DEFINE_enable(varname__, dashes__, shortname__, default_value__, \
-                      helpstring__, no_helpstring__)                     \
+		      helpstring__, no_helpstring__)                     \
   DEFINE_var(enable_##varname__, dashes__, shortname__, default_value__, \
-             default_value__ ? "true" : "false", helpstring__, NULL,     \
-             false, bool, bool, options::parse_bool)			 \
+	     default_value__ ? "true" : "false", helpstring__, NULL,     \
+	     false, bool, bool, options::parse_bool)			 \
   struct Struct_disable_##varname__ : public options::Struct_var         \
   {                                                                      \
     Struct_disable_##varname__() : option("disable-" #varname__,         \
-                                     dashes__, '\0',                     \
-                                     default_value__ ? "false" : "true", \
-                                     no_helpstring__, NULL, false, this) \
+				     dashes__, '\0',                     \
+				     default_value__ ? "false" : "true", \
+				     no_helpstring__, NULL, false, this) \
     { }                                                                  \
-                                                                         \
+									 \
     void                                                                 \
     parse_to_value(const char*, const char*,                             \
-                   Command_line*, General_options* options)              \
+		   Command_line*, General_options* options)              \
     { options->set_enable_##varname__(false); }                          \
-                                                                         \
+									 \
     options::One_option option;                                          \
   };                                                                     \
   Struct_disable_##varname__ disable_##varname__##_initializer_
 
 #define DEFINE_int(varname__, dashes__, shortname__, default_value__,   \
-                   helpstring__, helparg__)                             \
+		   helpstring__, helparg__)                             \
   DEFINE_var(varname__, dashes__, shortname__, default_value__,         \
-             #default_value__, helpstring__, helparg__, false,		\
-             int, int, options::parse_int)
+	     #default_value__, helpstring__, helparg__, false,		\
+	     int, int, options::parse_int)
 
 #define DEFINE_uint(varname__, dashes__, shortname__, default_value__,  \
-                   helpstring__, helparg__)                             \
+		   helpstring__, helparg__)                             \
   DEFINE_var(varname__, dashes__, shortname__, default_value__,         \
-             #default_value__, helpstring__, helparg__, false,		\
-             int, int, options::parse_uint)
+	     #default_value__, helpstring__, helparg__, false,		\
+	     int, int, options::parse_uint)
 
 #define DEFINE_uint64(varname__, dashes__, shortname__, default_value__, \
-                      helpstring__, helparg__)                           \
+		      helpstring__, helparg__)                           \
   DEFINE_var(varname__, dashes__, shortname__, default_value__,          \
-             #default_value__, helpstring__, helparg__, false,		 \
-             uint64_t, uint64_t, options::parse_uint64)
+	     #default_value__, helpstring__, helparg__, false,		 \
+	     uint64_t, uint64_t, options::parse_uint64)
 
 #define DEFINE_double(varname__, dashes__, shortname__, default_value__, \
 		      helpstring__, helparg__)				 \
@@ -387,19 +388,19 @@
 	     double, double, options::parse_percent)
 
 #define DEFINE_string(varname__, dashes__, shortname__, default_value__, \
-                      helpstring__, helparg__)                           \
+		      helpstring__, helparg__)                           \
   DEFINE_var(varname__, dashes__, shortname__, default_value__,          \
-             default_value__, helpstring__, helparg__, false,		 \
-             const char*, const char*, options::parse_string)
+	     default_value__, helpstring__, helparg__, false,		 \
+	     const char*, const char*, options::parse_string)
 
 // This is like DEFINE_string, but we convert each occurrence to a
 // Search_directory and store it in a vector.  Thus we also have the
 // add_to_VARNAME() method, to append to the vector.
 #define DEFINE_dirlist(varname__, dashes__, shortname__,                  \
-                           helpstring__, helparg__)                       \
+			   helpstring__, helparg__)                       \
   DEFINE_var(varname__, dashes__, shortname__, ,                          \
-             "", helpstring__, helparg__, false, options::Dir_list,	  \
-             const options::Dir_list&, options::parse_dirlist)            \
+	     "", helpstring__, helparg__, false, options::Dir_list,	  \
+	     const options::Dir_list&, options::parse_dirlist)            \
   void                                                                    \
   add_to_##varname__(const char* new_value)                               \
   { options::parse_dirlist(NULL, new_value, &this->varname__##_.value); } \
@@ -409,10 +410,10 @@
 
 // This is like DEFINE_string, but we store a set of strings.
 #define DEFINE_set(varname__, dashes__, shortname__,                      \
-                   helpstring__, helparg__)                               \
+		   helpstring__, helparg__)                               \
   DEFINE_var(varname__, dashes__, shortname__, ,                          \
-             "", helpstring__, helparg__, false, options::String_set,     \
-             const options::String_set&, options::parse_set)              \
+	     "", helpstring__, helparg__, false, options::String_set,     \
+	     const options::String_set&, options::parse_set)              \
  public:                                                                  \
   bool                                                                    \
   any_##varname__() const                                                 \
@@ -422,8 +423,8 @@
   is_##varname__(const char* symbol) const                                \
   {                                                                       \
     return (!this->varname__##_.value.empty()                             \
-            && (this->varname__##_.value.find(std::string(symbol))        \
-                != this->varname__##_.value.end()));                      \
+	    && (this->varname__##_.value.find(std::string(symbol))        \
+		!= this->varname__##_.value.end()));                      \
   }									  \
 									  \
   options::String_set::const_iterator					  \
@@ -438,17 +439,17 @@
 // After helparg__ should come an initializer list, like
 //   {"foo", "bar", "baz"}
 #define DEFINE_enum(varname__, dashes__, shortname__, default_value__,   \
-                    helpstring__, helparg__, ...)                        \
+		    helpstring__, helparg__, ...)                        \
   DEFINE_var(varname__, dashes__, shortname__, default_value__,          \
-             default_value__, helpstring__, helparg__, false,		 \
-             const char*, const char*, parse_choices_##varname__)        \
+	     default_value__, helpstring__, helparg__, false,		 \
+	     const char*, const char*, parse_choices_##varname__)        \
  private:                                                                \
   static void parse_choices_##varname__(const char* option_name,         \
-                                        const char* arg,                 \
-                                        const char** retval) {           \
+					const char* arg,                 \
+					const char** retval) {           \
     const char* choices[] = __VA_ARGS__;                                 \
     options::parse_choices(option_name, arg, retval,                     \
-                           choices, sizeof(choices) / sizeof(*choices)); \
+			   choices, sizeof(choices) / sizeof(*choices)); \
   }
 
 // This is like DEFINE_bool, but VARNAME is the name of a different
@@ -530,16 +531,16 @@
 // General_options; you are responsible for defining it there.
 // helparg__ should be NULL iff this special-option is a boolean.
 #define DEFINE_special(varname__, dashes__, shortname__,                \
-                       helpstring__, helparg__)                         \
+		       helpstring__, helparg__)                         \
  private:                                                               \
   void parse_##varname__(const char* option, const char* arg,           \
-                         Command_line* inputs);                         \
+			 Command_line* inputs);                         \
   struct Struct_##varname__ : public options::Struct_special            \
   {                                                                     \
     Struct_##varname__()                                                \
       : options::Struct_special(#varname__, dashes__, shortname__,      \
-                                &General_options::parse_##varname__,    \
-                                helpstring__, helparg__)                \
+				&General_options::parse_##varname__,    \
+				helpstring__, helparg__)                \
     { }                                                                 \
   };                                                                    \
   Struct_##varname__ varname__##_initializer_
@@ -551,8 +552,8 @@
 			       default_value__,				\
 			       helpstring__, helparg__)			\
   DEFINE_var(varname__, dashes__, shortname__, default_value__,		\
-             default_value__, helpstring__, helparg__, true,		\
-             const char*, const char*, options::parse_optional_string)
+	     default_value__, helpstring__, helparg__, true,		\
+	     const char*, const char*, options::parse_optional_string)
 
 // A directory to search.  For each directory we record whether it is
 // in the sysroot.  We need to know this so that, if a linker script
@@ -620,11 +621,11 @@
   // NOTE: For every option that you add here, also consider if you
   // should add it to Position_dependent_options.
   DEFINE_special(help, options::TWO_DASHES, '\0',
-                 N_("Report usage information"), NULL);
+		 N_("Report usage information"), NULL);
   DEFINE_special(version, options::TWO_DASHES, 'v',
-                 N_("Report version information"), NULL);
+		 N_("Report version information"), NULL);
   DEFINE_special(V, options::EXACTLY_ONE_DASH, '\0',
-                 N_("Report version and target information"), NULL);
+		 N_("Report version and target information"), NULL);
 
   // These options are sorted approximately so that for each letter in
   // the alphabet, we show the option whose shortname is that letter
@@ -641,12 +642,12 @@
 		    N_("Do not allow multiple definitions"), false);
 
   DEFINE_bool(allow_shlib_undefined, options::TWO_DASHES, '\0', false,
-              N_("Allow unresolved references in shared libraries"),
-              N_("Do not allow unresolved references in shared libraries"));
+	      N_("Allow unresolved references in shared libraries"),
+	      N_("Do not allow unresolved references in shared libraries"));
 
   DEFINE_bool(as_needed, options::TWO_DASHES, '\0', false,
-              N_("Only set DT_NEEDED for shared libraries if used"),
-              N_("Always DT_NEEDED for shared libraries"));
+	      N_("Only set DT_NEEDED for shared libraries if used"),
+	      N_("Always DT_NEEDED for shared libraries"));
 
   DEFINE_enum(assert, options::ONE_DASH, '\0', NULL,
 	      N_("Ignored"), N_("[ignored]"),
@@ -657,10 +658,10 @@
   // accept any string.  We'll fail later (when the string is parsed),
   // if the target isn't actually supported.
   DEFINE_string(format, options::TWO_DASHES, 'b', "elf",
-                N_("Set input format"), ("[elf,binary]"));
+		N_("Set input format"), ("[elf,binary]"));
 
   DEFINE_bool(Bdynamic, options::ONE_DASH, '\0', true,
-              N_("-l searches for shared libraries"), NULL);
+	      N_("-l searches for shared libraries"), NULL);
   DEFINE_bool_alias(Bstatic, Bdynamic, options::ONE_DASH, '\0',
 		    N_("-l does not search for shared libraries"), NULL,
 		    true);
@@ -673,7 +674,7 @@
 	      N_("Use group name lookup rules for shared library"), NULL);
 
   DEFINE_bool(Bsymbolic, options::ONE_DASH, '\0', false,
-              N_("Bind defined symbols locally"), NULL);
+	      N_("Bind defined symbols locally"), NULL);
 
   DEFINE_bool(Bsymbolic_functions, options::ONE_DASH, '\0', false,
 	      N_("Bind defined function symbols locally"), NULL);
@@ -683,13 +684,13 @@
 			 N_("[=STYLE]"));
 
   DEFINE_uint64(build_id_chunk_size_for_treehash,
-                options::TWO_DASHES, '\0', 2 << 20,
-                N_("Chunk size for '--build-id=tree'"), N_("SIZE"));
+		options::TWO_DASHES, '\0', 2 << 20,
+		N_("Chunk size for '--build-id=tree'"), N_("SIZE"));
 
   DEFINE_uint64(build_id_min_file_size_for_treehash, options::TWO_DASHES,
-                '\0', 40 << 20,
-                N_("Minimum output file size for '--build-id=tree' to work"
-                   " differently than '--build-id=sha1'"), N_("SIZE"));
+		'\0', 40 << 20,
+		N_("Minimum output file size for '--build-id=tree' to work"
+		   " differently than '--build-id=sha1'"), N_("SIZE"));
 
   DEFINE_bool(check_sections, options::TWO_DASHES, '\0', true,
 	      N_("Check segment addresses for overlaps (default)"),
@@ -697,14 +698,14 @@
 
 #ifdef HAVE_ZLIB_H
   DEFINE_enum(compress_debug_sections, options::TWO_DASHES, '\0', "none",
-              N_("Compress .debug_* sections in the output file"),
-              ("[none,zlib]"),
-              {"none", "zlib"});
+	      N_("Compress .debug_* sections in the output file"),
+	      ("[none,zlib]"),
+	      {"none", "zlib"});
 #else
   DEFINE_enum(compress_debug_sections, options::TWO_DASHES, '\0', "none",
-              N_("Compress .debug_* sections in the output file"),
-              N_("[none]"),
-              {"none"});
+	      N_("Compress .debug_* sections in the output file"),
+	      N_("[none]"),
+	      {"none"});
 #endif
 
   DEFINE_bool(copy_dt_needed_entries, options::TWO_DASHES, '\0', false,
@@ -720,19 +721,19 @@
 	      N_("Handle constructors as directed by compiler"));
 
   DEFINE_bool(define_common, options::TWO_DASHES, 'd', false,
-              N_("Define common symbols"),
-              N_("Do not define common symbols"));
+	      N_("Define common symbols"),
+	      N_("Do not define common symbols"));
   DEFINE_bool(dc, options::ONE_DASH, '\0', false,
-              N_("Alias for -d"), NULL);
+	      N_("Alias for -d"), NULL);
   DEFINE_bool(dp, options::ONE_DASH, '\0', false,
-              N_("Alias for -d"), NULL);
+	      N_("Alias for -d"), NULL);
 
   DEFINE_string(debug, options::TWO_DASHES, '\0', "",
-                N_("Turn on debugging"),
-                N_("[all,files,script,task][,...]"));
+		N_("Turn on debugging"),
+		N_("[all,files,script,task][,...]"));
 
   DEFINE_special(defsym, options::TWO_DASHES, '\0',
-                 N_("Define a symbol"), N_("SYMBOL=EXPRESSION"));
+		 N_("Define a symbol"), N_("SYMBOL=EXPRESSION"));
 
   DEFINE_optional_string(demangle, options::TWO_DASHES, '\0', NULL,
 			 N_("Demangle C++ symbols in log messages"),
@@ -743,35 +744,35 @@
 	      NULL);
 
   DEFINE_bool(detect_odr_violations, options::TWO_DASHES, '\0', false,
-              N_("Look for violations of the C++ One Definition Rule"),
+	      N_("Look for violations of the C++ One Definition Rule"),
 	      N_("Do not look for violations of the C++ One Definition Rule"));
 
   DEFINE_bool(discard_all, options::TWO_DASHES, 'x', false,
 	      N_("Delete all local symbols"), NULL);
   DEFINE_bool(discard_locals, options::TWO_DASHES, 'X', false,
-              N_("Delete all temporary local symbols"), NULL);
+	      N_("Delete all temporary local symbols"), NULL);
 
   DEFINE_bool(dynamic_list_data, options::TWO_DASHES, '\0', false,
-              N_("Add data symbols to dynamic symbols"), NULL);
+	      N_("Add data symbols to dynamic symbols"), NULL);
 
   DEFINE_bool(dynamic_list_cpp_new, options::TWO_DASHES, '\0', false,
-              N_("Add C++ operator new/delete to dynamic symbols"), NULL);
+	      N_("Add C++ operator new/delete to dynamic symbols"), NULL);
 
   DEFINE_bool(dynamic_list_cpp_typeinfo, options::TWO_DASHES, '\0', false,
-              N_("Add C++ typeinfo to dynamic symbols"), NULL);
+	      N_("Add C++ typeinfo to dynamic symbols"), NULL);
 
   DEFINE_special(dynamic_list, options::TWO_DASHES, '\0',
-                 N_("Read a list of dynamic symbols"), N_("FILE"));
+		 N_("Read a list of dynamic symbols"), N_("FILE"));
 
   DEFINE_string(entry, options::TWO_DASHES, 'e', NULL,
-                N_("Set program start address"), N_("ADDRESS"));
+		N_("Set program start address"), N_("ADDRESS"));
 
   DEFINE_special(exclude_libs, options::TWO_DASHES, '\0',
 		 N_("Exclude libraries from automatic export"),
 		 N_(("lib,lib ...")));
 
   DEFINE_bool(export_dynamic, options::TWO_DASHES, 'E', false,
-              N_("Export all dynamic symbols"),
+	      N_("Export all dynamic symbols"),
 	      N_("Do not export all dynamic symbols (default)"));
 
   DEFINE_set(export_dynamic_symbol, options::TWO_DASHES, '\0',
@@ -784,7 +785,7 @@
 		 N_("Link little-endian objects."), NULL);
 
   DEFINE_bool(eh_frame_hdr, options::TWO_DASHES, '\0', false,
-              N_("Create exception frame header"), NULL);
+	      N_("Create exception frame header"), NULL);
 
   DEFINE_bool(enum_size_warning, options::TWO_DASHES, '\0', true, NULL,
 	      N_("(ARM only) Do not warn about objects with incompatible "
@@ -803,7 +804,7 @@
 	      N_("Do not treat warnings as errors"));
 
   DEFINE_string(fini, options::ONE_DASH, '\0', "_fini",
-                N_("Call SYMBOL at unload-time"), N_("SYMBOL"));
+		N_("Call SYMBOL at unload-time"), N_("SYMBOL"));
 
   DEFINE_bool(fix_cortex_a8, options::TWO_DASHES, '\0', false,
 	      N_("(ARM only) Fix binaries for Cortex-A8 erratum."),
@@ -818,13 +819,13 @@
 	      N_("(ARM only) Do not merge exidx entries in debuginfo."));
 
   DEFINE_special(fix_v4bx, options::TWO_DASHES, '\0',
-                 N_("(ARM only) Rewrite BX rn as MOV pc, rn for ARMv4"),
-                 NULL);
+		 N_("(ARM only) Rewrite BX rn as MOV pc, rn for ARMv4"),
+		 NULL);
 
   DEFINE_special(fix_v4bx_interworking, options::TWO_DASHES, '\0',
-                 N_("(ARM only) Rewrite BX rn branch to ARMv4 interworking "
-                    "veneer"),
-                 NULL);
+		 N_("(ARM only) Rewrite BX rn branch to ARMv4 interworking "
+		    "veneer"),
+		 NULL);
 
   DEFINE_bool(g, options::EXACTLY_ONE_DASH, '\0', false,
 	      N_("Ignored"), NULL);
@@ -838,7 +839,7 @@
 	      N_("Disable STB_GNU_UNIQUE symbol binding"));
 
   DEFINE_string(soname, options::ONE_DASH, 'h', NULL,
-                N_("Set shared library name"), N_("FILENAME"));
+		N_("Set shared library name"), N_("FILENAME"));
 
   DEFINE_double(hash_bucket_empty_fraction, options::TWO_DASHES, '\0', 0.0,
 		N_("Min fraction of empty buckets in dynamic hash"),
@@ -849,7 +850,7 @@
 	      {"sysv", "gnu", "both"});
 
   DEFINE_string(dynamic_linker, options::TWO_DASHES, 'I', NULL,
-                N_("Set dynamic linker path"), N_("PROGRAM"));
+		N_("Set dynamic linker path"), N_("PROGRAM"));
 
   DEFINE_special(incremental, options::TWO_DASHES, '\0',
 		 N_("Do an incremental link if possible; "
@@ -867,21 +868,21 @@
 		 N_("Do an incremental link; exit if not possible"), NULL);
 
   DEFINE_string(incremental_base, options::TWO_DASHES, '\0', NULL,
-                N_("Set base file for incremental linking"
-                   " (default is output file)"),
-                N_("FILE"));
+		N_("Set base file for incremental linking"
+		   " (default is output file)"),
+		N_("FILE"));
 
   DEFINE_special(incremental_changed, options::TWO_DASHES, '\0',
-                 N_("Assume files changed"), NULL);
+		 N_("Assume files changed"), NULL);
 
   DEFINE_special(incremental_unchanged, options::TWO_DASHES, '\0',
-                 N_("Assume files didn't change"), NULL);
+		 N_("Assume files didn't change"), NULL);
 
   DEFINE_special(incremental_unknown, options::TWO_DASHES, '\0',
-                 N_("Use timestamps to check files (default)"), NULL);
+		 N_("Use timestamps to check files (default)"), NULL);
 
   DEFINE_special(incremental_startup_unchanged, options::TWO_DASHES, '\0',
-                 N_("Assume startup files unchanged "
+		 N_("Assume startup files unchanged "
 		    "(files preceding this option)"), NULL);
 
   DEFINE_percent(incremental_patch, options::TWO_DASHES, '\0', 10,
@@ -889,29 +890,29 @@
 		 N_("PERCENT"));
 
   DEFINE_string(init, options::ONE_DASH, '\0', "_init",
-                N_("Call SYMBOL at load-time"), N_("SYMBOL"));
+		N_("Call SYMBOL at load-time"), N_("SYMBOL"));
 
   DEFINE_special(just_symbols, options::TWO_DASHES, '\0',
-                 N_("Read only symbol values from FILE"), N_("FILE"));
+		 N_("Read only symbol values from FILE"), N_("FILE"));
 
   DEFINE_bool(map_whole_files, options::TWO_DASHES, '\0',
 	      sizeof(void*) >= 8,
-              N_("Map whole files to memory (default on 64-bit hosts)"),
-              N_("Map relevant file parts to memory (default on 32-bit "
-                 "hosts)"));
+	      N_("Map whole files to memory (default on 64-bit hosts)"),
+	      N_("Map relevant file parts to memory (default on 32-bit "
+		 "hosts)"));
   DEFINE_bool(keep_files_mapped, options::TWO_DASHES, '\0', true,
-              N_("Keep files mapped across passes (default)"),
-              N_("Release mapped files after each pass"));
+	      N_("Keep files mapped across passes (default)"),
+	      N_("Release mapped files after each pass"));
 
   DEFINE_bool(ld_generated_unwind_info, options::TWO_DASHES, '\0', true,
 	      N_("Generate unwind information for PLT (default)"),
 	      N_("Do not generate unwind information for PLT"));
 
   DEFINE_special(library, options::TWO_DASHES, 'l',
-                 N_("Search for library LIBNAME"), N_("LIBNAME"));
+		 N_("Search for library LIBNAME"), N_("LIBNAME"));
 
   DEFINE_dirlist(library_path, options::TWO_DASHES, 'L',
-                 N_("Add directory to search path"), N_("DIR"));
+		 N_("Add directory to search path"), N_("DIR"));
 
   DEFINE_bool(text_reorder, options::TWO_DASHES, '\0', true,
 	      N_("Enable text section reordering for GCC section names "
@@ -919,19 +920,23 @@
 	      N_("Disable text section reordering for GCC section names"));
 
   DEFINE_bool(nostdlib, options::ONE_DASH, '\0', false,
-              N_(" Only search directories specified on the command line."),
-              NULL);
+	      N_("Only search directories specified on the command line."),
+	      NULL);
 
   DEFINE_bool(rosegment, options::TWO_DASHES, '\0', false,
-              N_(" Put read-only non-executable sections in their own segment"),
-              NULL);
+	      N_("Put read-only non-executable sections in their own segment"),
+	      NULL);
+
+  DEFINE_uint64(rosegment_gap, options::TWO_DASHES, '\0', -1U,
+		N_("Set offset between executable and read-only segments"),
+		N_("OFFSET"));
 
   DEFINE_string(m, options::EXACTLY_ONE_DASH, 'm', "",
-                N_("Set GNU linker emulation; obsolete"), N_("EMULATION"));
+		N_("Set GNU linker emulation; obsolete"), N_("EMULATION"));
 
   DEFINE_bool(mmap_output_file, options::TWO_DASHES, '\0', true,
-              N_("Map the output file for writing (default)."),
-              N_("Do not map the output file for writing."));
+	      N_("Map the output file for writing (default)."),
+	      N_("Do not map the output file for writing."));
 
   DEFINE_bool(print_map, options::TWO_DASHES, 'M', false,
 	      N_("Write map file on standard output"), NULL);
@@ -956,10 +961,10 @@
 		    NULL, false);
 
   DEFINE_string(output, options::TWO_DASHES, 'o', "a.out",
-                N_("Set output file name"), N_("FILE"));
+		N_("Set output file name"), N_("FILE"));
 
   DEFINE_uint(optimize, options::EXACTLY_ONE_DASH, 'O', 0,
-              N_("Optimize output file size"), N_("LEVEL"));
+	      N_("Optimize output file size"), N_("LEVEL"));
 
   DEFINE_string(oformat, options::EXACTLY_TWO_DASHES, '\0', "elf",
 		N_("Set output format"), N_("[binary]"));
@@ -990,18 +995,18 @@
 
 #ifdef ENABLE_PLUGINS
   DEFINE_special(plugin, options::TWO_DASHES, '\0',
-                 N_("Load a plugin library"), N_("PLUGIN"));
+		 N_("Load a plugin library"), N_("PLUGIN"));
   DEFINE_special(plugin_opt, options::TWO_DASHES, '\0',
-                 N_("Pass an option to the plugin"), N_("OPTION"));
+		 N_("Pass an option to the plugin"), N_("OPTION"));
 #endif
 
   DEFINE_bool(posix_fallocate, options::TWO_DASHES, '\0', true,
-              N_("Use posix_fallocate to reserve space in the output file"
+	      N_("Use posix_fallocate to reserve space in the output file"
 		 " (default)."),
-              N_("Use fallocate or ftruncate to reserve space."));
+	      N_("Use fallocate or ftruncate to reserve space."));
 
   DEFINE_bool(preread_archive_symbols, options::TWO_DASHES, '\0', false,
-              N_("Preread archive symbols when multi-threaded"), NULL);
+	      N_("Preread archive symbols when multi-threaded"), NULL);
 
   DEFINE_bool(print_output_format, options::TWO_DASHES, '\0', false,
 	      N_("Print default output format"), NULL);
@@ -1014,10 +1019,10 @@
 	      N_("Ignored for SVR4 compatibility"), NULL);
 
   DEFINE_bool(emit_relocs, options::TWO_DASHES, 'q', false,
-              N_("Generate relocations in output"), NULL);
+	      N_("Generate relocations in output"), NULL);
 
   DEFINE_bool(relocatable, options::EXACTLY_ONE_DASH, 'r', false,
-              N_("Generate relocatable output"), NULL);
+	      N_("Generate relocatable output"), NULL);
   DEFINE_bool_alias(i, relocatable, options::EXACTLY_ONE_DASH, '\0',
 		    N_("Synonym for -r"), NULL, false);
 
@@ -1025,20 +1030,20 @@
 	      N_("Relax branches on certain targets"), NULL);
 
   DEFINE_string(retain_symbols_file, options::TWO_DASHES, '\0', NULL,
-                N_("keep only symbols listed in this file"), N_("FILE"));
+		N_("keep only symbols listed in this file"), N_("FILE"));
 
   // -R really means -rpath, but can mean --just-symbols for
   // compatibility with GNU ld.  -rpath is always -rpath, so we list
   // it separately.
   DEFINE_special(R, options::EXACTLY_ONE_DASH, 'R',
-                 N_("Add DIR to runtime search path"), N_("DIR"));
+		 N_("Add DIR to runtime search path"), N_("DIR"));
 
   DEFINE_dirlist(rpath, options::ONE_DASH, '\0',
-                 N_("Add DIR to runtime search path"), N_("DIR"));
+		 N_("Add DIR to runtime search path"), N_("DIR"));
 
   DEFINE_dirlist(rpath_link, options::TWO_DASHES, '\0',
-                 N_("Add DIR to link time shared library search path"),
-                 N_("DIR"));
+		 N_("Add DIR to link time shared library search path"),
+		 N_("DIR"));
 
   DEFINE_string(section_ordering_file, options::TWO_DASHES, '\0', NULL,
 		N_("Layout sections in the order specified."),
@@ -1056,33 +1061,33 @@
 	      N_("COUNT"));
 
   DEFINE_bool(strip_all, options::TWO_DASHES, 's', false,
-              N_("Strip all symbols"), NULL);
+	      N_("Strip all symbols"), NULL);
   DEFINE_bool(strip_debug, options::TWO_DASHES, 'S', false,
-              N_("Strip debugging information"), NULL);
+	      N_("Strip debugging information"), NULL);
   DEFINE_bool(strip_debug_non_line, options::TWO_DASHES, '\0', false,
-              N_("Emit only debug line number information"), NULL);
+	      N_("Emit only debug line number information"), NULL);
   DEFINE_bool(strip_debug_gdb, options::TWO_DASHES, '\0', false,
-              N_("Strip debug symbols that are unused by gdb "
-                 "(at least versions <= 7.4)"), NULL);
+	      N_("Strip debug symbols that are unused by gdb "
+		 "(at least versions <= 7.4)"), NULL);
   DEFINE_bool(strip_lto_sections, options::TWO_DASHES, '\0', true,
-              N_("Strip LTO intermediate code sections"), NULL);
+	      N_("Strip LTO intermediate code sections"), NULL);
 
   DEFINE_int(stub_group_size, options::TWO_DASHES , '\0', 1,
-             N_("(ARM, PowerPC only) The maximum distance from instructions "
+	     N_("(ARM, PowerPC only) The maximum distance from instructions "
 		"in a group of sections to their stubs.  Negative values mean "
 		"stubs are always after (PowerPC before) the group.  1 means "
 		"use default size.\n"),
 	     N_("SIZE"));
 
   DEFINE_bool(no_keep_memory, options::TWO_DASHES, '\0', false,
-              N_("Use less memory and more disk I/O "
-                 "(included only for compatibility with GNU ld)"), NULL);
+	      N_("Use less memory and more disk I/O "
+		 "(included only for compatibility with GNU ld)"), NULL);
 
   DEFINE_bool(shared, options::ONE_DASH, 'G', false,
-              N_("Generate shared library"), NULL);
+	      N_("Generate shared library"), NULL);
 
   DEFINE_bool(Bshareable, options::ONE_DASH, '\0', false,
-              N_("Generate shared library"), NULL);
+	      N_("Generate shared library"), NULL);
 
   DEFINE_uint(split_stack_adjust_size, options::TWO_DASHES, '\0', 0x4000,
 	      N_("Stack size when -fsplit-stack function calls non-split"),
@@ -1091,63 +1096,63 @@
   // This is not actually special in any way, but I need to give it
   // a non-standard accessor-function name because 'static' is a keyword.
   DEFINE_special(static, options::ONE_DASH, '\0',
-                 N_("Do not link against shared libraries"), NULL);
+		 N_("Do not link against shared libraries"), NULL);
 
   DEFINE_enum(icf, options::TWO_DASHES, '\0', "none",
-              N_("Identical Code Folding. "
-                 "\'--icf=safe\' Folds ctors, dtors and functions whose"
-                 " pointers are definitely not taken."),
-	      ("[none,all,safe]"),	
-              {"none", "all", "safe"});
+	      N_("Identical Code Folding. "
+		 "\'--icf=safe\' Folds ctors, dtors and functions whose"
+		 " pointers are definitely not taken."),
+	      ("[none,all,safe]"),
+	      {"none", "all", "safe"});
 
   DEFINE_uint(icf_iterations, options::TWO_DASHES , '\0', 0,
-              N_("Number of iterations of ICF (default 2)"), N_("COUNT"));
+	      N_("Number of iterations of ICF (default 2)"), N_("COUNT"));
 
   DEFINE_bool(print_icf_sections, options::TWO_DASHES, '\0', false,
-              N_("List folded identical sections on stderr"),
-              N_("Do not list folded identical sections"));
+	      N_("List folded identical sections on stderr"),
+	      N_("Do not list folded identical sections"));
 
   DEFINE_set(keep_unique, options::TWO_DASHES, '\0',
 	     N_("Do not fold this symbol during ICF"), N_("SYMBOL"));
 
   DEFINE_bool(gc_sections, options::TWO_DASHES, '\0', false,
-              N_("Remove unused sections"),
-              N_("Don't remove unused sections (default)"));
+	      N_("Remove unused sections"),
+	      N_("Don't remove unused sections (default)"));
 
   DEFINE_bool(print_gc_sections, options::TWO_DASHES, '\0', false,
-              N_("List removed unused sections on stderr"),
-              N_("Do not list removed unused sections"));
+	      N_("List removed unused sections on stderr"),
+	      N_("Do not list removed unused sections"));
 
   DEFINE_bool(stats, options::TWO_DASHES, '\0', false,
-              N_("Print resource usage statistics"), NULL);
+	      N_("Print resource usage statistics"), NULL);
 
   DEFINE_string(sysroot, options::TWO_DASHES, '\0', "",
-                N_("Set target system root directory"), N_("DIR"));
+		N_("Set target system root directory"), N_("DIR"));
 
   DEFINE_bool(trace, options::TWO_DASHES, 't', false,
-              N_("Print the name of each input file"), NULL);
+	      N_("Print the name of each input file"), NULL);
 
   DEFINE_special(script, options::TWO_DASHES, 'T',
-                 N_("Read linker script"), N_("FILE"));
+		 N_("Read linker script"), N_("FILE"));
 
   DEFINE_bool(threads, options::TWO_DASHES, '\0', false,
-              N_("Run the linker multi-threaded"),
-              N_("Do not run the linker multi-threaded"));
+	      N_("Run the linker multi-threaded"),
+	      N_("Do not run the linker multi-threaded"));
   DEFINE_uint(thread_count, options::TWO_DASHES, '\0', 0,
-              N_("Number of threads to use"), N_("COUNT"));
+	      N_("Number of threads to use"), N_("COUNT"));
   DEFINE_uint(thread_count_initial, options::TWO_DASHES, '\0', 0,
-              N_("Number of threads to use in initial pass"), N_("COUNT"));
+	      N_("Number of threads to use in initial pass"), N_("COUNT"));
   DEFINE_uint(thread_count_middle, options::TWO_DASHES, '\0', 0,
-              N_("Number of threads to use in middle pass"), N_("COUNT"));
+	      N_("Number of threads to use in middle pass"), N_("COUNT"));
   DEFINE_uint(thread_count_final, options::TWO_DASHES, '\0', 0,
-              N_("Number of threads to use in final pass"), N_("COUNT"));
+	      N_("Number of threads to use in final pass"), N_("COUNT"));
 
   DEFINE_uint64(Tbss, options::ONE_DASH, '\0', -1U,
-                N_("Set the address of the bss segment"), N_("ADDRESS"));
+		N_("Set the address of the bss segment"), N_("ADDRESS"));
   DEFINE_uint64(Tdata, options::ONE_DASH, '\0', -1U,
-                N_("Set the address of the data segment"), N_("ADDRESS"));
+		N_("Set the address of the data segment"), N_("ADDRESS"));
   DEFINE_uint64(Ttext, options::ONE_DASH, '\0', -1U,
-                N_("Set the address of the text segment"), N_("ADDRESS"));
+		N_("Set the address of the text segment"), N_("ADDRESS"));
   DEFINE_uint64_alias(Ttext_segment, Ttext, options::ONE_DASH, '\0',
 		      N_("Set the address of the text segment"),
 		      N_("ADDRESS"));
@@ -1171,10 +1176,10 @@
 		  "ignore-in-shared-libs"});
 
   DEFINE_bool(verbose, options::TWO_DASHES, '\0', false,
-              N_("Synonym for --debug=files"), NULL);
+	      N_("Synonym for --debug=files"), NULL);
 
   DEFINE_special(version_script, options::TWO_DASHES, '\0',
-                 N_("Read version script"), N_("FILE"));
+		 N_("Read version script"), N_("FILE"));
 
   DEFINE_bool(warn_common, options::TWO_DASHES, '\0', false,
 	      N_("Warn about duplicate common symbols"),
@@ -1214,14 +1219,14 @@
 		 "wchar_t sizes"));
 
   DEFINE_bool(whole_archive, options::TWO_DASHES, '\0', false,
-              N_("Include all archive contents"),
-              N_("Include only needed archive contents"));
+	      N_("Include all archive contents"),
+	      N_("Include only needed archive contents"));
 
   DEFINE_set(wrap, options::TWO_DASHES, '\0',
 	     N_("Use wrapper functions for SYMBOL"), N_("SYMBOL"));
 
   DEFINE_set(trace_symbol, options::TWO_DASHES, 'y',
-             N_("Trace references to symbol"), N_("SYMBOL"));
+	     N_("Trace references to symbol"), N_("SYMBOL"));
 
   DEFINE_bool(undefined_version, options::TWO_DASHES, '\0', true,
 	      N_("Allow unused version in script (default)"),
@@ -1232,15 +1237,15 @@
 		N_("PATH"));
 
   DEFINE_special(start_group, options::TWO_DASHES, '(',
-                 N_("Start a library search group"), NULL);
+		 N_("Start a library search group"), NULL);
   DEFINE_special(end_group, options::TWO_DASHES, ')',
-                 N_("End a library search group"), NULL);
+		 N_("End a library search group"), NULL);
 
 
   DEFINE_special(start_lib, options::TWO_DASHES, '\0',
-                 N_("Start a library"), NULL);
+		 N_("Start a library"), NULL);
   DEFINE_special(end_lib, options::TWO_DASHES, '\0',
-                 N_("End a library "), NULL);
+		 N_("End a library "), NULL);
 
   DEFINE_string(fuse_ld, options::ONE_DASH, '\0', "",
 		N_("Ignored for GCC linker option compatibility"),
@@ -1252,12 +1257,12 @@
 	      N_("Sort dynamic relocs"),
 	      N_("Do not sort dynamic relocs"));
   DEFINE_uint64(common_page_size, options::DASH_Z, '\0', 0,
-                N_("Set common page size to SIZE"), N_("SIZE"));
+		N_("Set common page size to SIZE"), N_("SIZE"));
   DEFINE_bool(defs, options::DASH_Z, '\0', false,
-              N_("Report undefined symbols (even with --shared)"),
-              NULL);
+	      N_("Report undefined symbols (even with --shared)"),
+	      NULL);
   DEFINE_bool(execstack, options::DASH_Z, '\0', false,
-              N_("Mark output as requiring executable stack"), NULL);
+	      N_("Mark output as requiring executable stack"), NULL);
   DEFINE_bool(initfirst, options::DASH_Z, '\0', false,
 	      N_("Mark DSO to be initialized first at runtime"),
 	      NULL);
@@ -1271,7 +1276,7 @@
 	      N_("Mark object requiring immediate process"),
 	      NULL);
   DEFINE_uint64(max_page_size, options::DASH_Z, '\0', 0,
-                N_("Set maximum page size to SIZE"), N_("SIZE"));
+		N_("Set maximum page size to SIZE"), N_("SIZE"));
   DEFINE_bool(muldefs, options::DASH_Z, '\0', false,
 	      N_("Allow multiple definitions of symbols"),
 	      NULL);
@@ -1293,13 +1298,13 @@
 	      N_("Mark DSO not available to dldump"),
 	      NULL);
   DEFINE_bool(noexecstack, options::DASH_Z, '\0', false,
-              N_("Mark output as not requiring executable stack"), NULL);
+	      N_("Mark output as not requiring executable stack"), NULL);
   DEFINE_bool(now, options::DASH_Z, '\0', false,
 	      N_("Mark object for immediate function binding"),
 	      NULL);
   DEFINE_bool(origin, options::DASH_Z, '\0', false,
 	      N_("Mark DSO to indicate that needs immediate $ORIGIN "
-                 "processing at runtime"), NULL);
+		 "processing at runtime"), NULL);
   DEFINE_bool(relro, options::DASH_Z, '\0', false,
 	      N_("Where possible mark variables read-only after relocation"),
 	      N_("Don't mark variables read-only after relocation"));
@@ -1381,7 +1386,7 @@
   should_retain_symbol(const char* symbol_name) const
     {
       if (symbols_to_retain_.empty())    // means flag wasn't specified
-        return true;
+	return true;
       return symbols_to_retain_.find(symbol_name) != symbols_to_retain_.end();
     }
 
@@ -1524,7 +1529,7 @@
     // Do not fold any functions (Default or --icf=none).
     ICF_NONE,
     // All functions are candidates for folding. (--icf=all).
-    ICF_ALL,	
+    ICF_ALL,
     // Only ctors and dtors are candidates for folding. (--icf=safe).
     ICF_SAFE
   };
@@ -1617,7 +1622,7 @@
   type__                                        \
   varname__() const                             \
   { return this->varname__##_; }                \
-                                                \
+						\
   void                                          \
   set_##varname__(type__ value)                 \
   { this->varname__##_ = value; }               \
@@ -1628,7 +1633,7 @@
 {
  public:
   Position_dependent_options(const General_options& options
-                             = Position_dependent_options::default_options_)
+			     = Position_dependent_options::default_options_)
   { copy_from_options(options); }
 
   void copy_from_options(const General_options& options)
@@ -1685,9 +1690,9 @@
   { }
 
   Input_file_argument(const char* name, Input_file_type type,
-                      const char* extra_search_path,
-                      bool just_symbols,
-                      const Position_dependent_options& options)
+		      const char* extra_search_path,
+		      bool just_symbols,
+		      const Position_dependent_options& options)
     : name_(name), type_(type), extra_search_path_(extra_search_path),
       just_symbols_(just_symbols), options_(options), arg_serial_(0)
   { }
@@ -1697,9 +1702,9 @@
   // position-independent vars from the General_options and only store
   // those.
   Input_file_argument(const char* name, Input_file_type type,
-                      const char* extra_search_path,
-                      bool just_symbols,
-                      const General_options& options)
+		      const char* extra_search_path,
+		      bool just_symbols,
+		      const General_options& options)
     : name_(name), type_(type), extra_search_path_(extra_search_path),
       just_symbols_(just_symbols), options_(options), arg_serial_(0)
   { }
@@ -1724,8 +1729,8 @@
   extra_search_path() const
   {
     return (this->extra_search_path_.empty()
-            ? NULL
-            : this->extra_search_path_.c_str());
+	    ? NULL
+	    : this->extra_search_path_.c_str());
   }
 
   // Return whether we should only read symbols from this file.
@@ -2038,7 +2043,7 @@
   // is set to true if argv[i] is "--".
   int
   process_one_option(int argc, const char** argv, int i,
-                     bool* no_more_options);
+		     bool* no_more_options);
 
   // Get the general options.
   const General_options&
diff --git a/gold/output.cc b/gold/output.cc
index 22c0bf0..75ce840 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -2635,11 +2635,6 @@
 {
   bool is_string = (flags & elfcpp::SHF_STRINGS) != 0;
 
-  // We only merge strings if the alignment is not more than the
-  // character size.  This could be handled, but it's unusual.
-  if (is_string && addralign > entsize)
-    return false;
-
   // We cannot restore merged input section states.
   gold_assert(this->checkpoint_ == NULL);
 
diff --git a/gold/stringpool.cc b/gold/stringpool.cc
index 434b2d6..665fcc8 100644
--- a/gold/stringpool.cc
+++ b/gold/stringpool.cc
@@ -34,9 +34,10 @@
 {
 
 template<typename Stringpool_char>
-Stringpool_template<Stringpool_char>::Stringpool_template()
+Stringpool_template<Stringpool_char>::Stringpool_template(uint64_t addralign)
   : string_set_(), key_to_offset_(), strings_(), strtab_size_(0),
-    zero_null_(true), optimize_(false), offset_(sizeof(Stringpool_char))
+    zero_null_(true), optimize_(false), offset_(sizeof(Stringpool_char)),
+    addralign_(addralign)
 {
   if (parameters->options_valid() && parameters->options().optimize() >= 2)
     this->optimize_ = true;
@@ -222,7 +223,10 @@
   else
     {
       offset = this->offset_;
-      this->offset_ += (length + 1) * sizeof(Stringpool_char);
+      // Align non-zero length strings.
+      if (length != 0)
+	offset = align_address(offset, this->addralign_);
+      this->offset_ = offset + (length + 1) * sizeof(Stringpool_char);
     }
   this->key_to_offset_.push_back(offset);
 }
@@ -421,8 +425,8 @@
 			      * charsize));
           else
             {
-              this_offset = offset;
-              offset += ((*curr)->first.length + 1) * charsize;
+              this_offset = align_address(offset, this->addralign_);
+              offset = this_offset + ((*curr)->first.length + 1) * charsize;
             }
 	  this->key_to_offset_[(*curr)->second - 1] = this_offset;
 	  last_offset = this_offset;
diff --git a/gold/stringpool.h b/gold/stringpool.h
index c51b143..b638329 100644
--- a/gold/stringpool.h
+++ b/gold/stringpool.h
@@ -180,7 +180,7 @@
   typedef size_t Key;
 
   // Create a Stringpool.
-  Stringpool_template();
+  Stringpool_template(uint64_t addralign = 1);
 
   ~Stringpool_template();
 
@@ -409,6 +409,8 @@
   bool optimize_;
   // offset of the next string.
   section_offset_type offset_;
+  // The alignment of strings in the stringpool.
+  uint64_t addralign_;
 };
 
 // The most common type of Stringpool.
diff --git a/gold/symtab.h b/gold/symtab.h
index 689d99f..9299ea8 100644
--- a/gold/symtab.h
+++ b/gold/symtab.h
@@ -817,6 +817,11 @@
   is_predefined() const
   { return this->is_predefined_; }
 
+  // Return true if this is a C++ vtable symbol.
+  bool
+  is_cxx_vtable() const
+  { return is_prefix_of("_ZTV", this->name_); }
+
  protected:
   // Instances of this class should always be created at a specific
   // size.
diff --git a/gold/target-reloc.h b/gold/target-reloc.h
index cf5e389..b544c78 100644
--- a/gold/target-reloc.h
+++ b/gold/target-reloc.h
@@ -411,7 +411,13 @@
 	}
 
       if (issue_undefined_symbol_error(sym))
-	gold_undefined_symbol_at_location(sym, relinfo, i, offset);
+	{
+	  gold_undefined_symbol_at_location(sym, relinfo, i, offset);
+	  if (sym->is_cxx_vtable())
+	    gold_info(_("%s: the vtable symbol may be undefined because "
+			"the class is missing its key function"),
+		      program_name);
+	}
       else if (sym != NULL
 	       && sym->visibility() != elfcpp::STV_DEFAULT
 	       && (sym->is_undefined() || sym->is_from_dynobj()))
diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
index 4d02925..4936e14 100644
--- a/gold/testsuite/Makefile.am
+++ b/gold/testsuite/Makefile.am
@@ -53,26 +53,6 @@
 TEST_NM = $(top_builddir)/../binutils/nm-new
 TEST_AS = $(top_builddir)/../gas/as-new
 
-# Make the default target available to scripts as $DEFAULT_TARGET.
-if DEFAULT_TARGET_ARM
-export DEFAULT_TARGET = arm
-endif
-if DEFAULT_TARGET_I386
-export DEFAULT_TARGET = i386
-endif
-if DEFAULT_TARGET_POWERPC
-export DEFAULT_TARGET = powerpc
-endif
-if DEFAULT_TARGET_SPARC
-export DEFAULT_TARGET = sparc
-endif
-if DEFAULT_TARGET_X86_64
-export DEFAULT_TARGET = x86_64
-endif
-if DEFAULT_TARGET_TILEGX
-export DEFAULT_TARGET = tilegx
-endif
-
 if PLUGINS
 LIBDL = -ldl
 endif
@@ -91,7 +71,10 @@
 # the right choice for files 'make' builds that people rebuild.
 MOSTLYCLEANFILES = *.so *.syms *.stdout
 
-
+# Export make variables to the shell scripts so that they can see
+# (for example) DEFAULT_TARGET.
+.EXPORT_ALL_VARIABLES:
+ 
 # We will add to these later, for each individual test.  Note
 # that we add each test under check_SCRIPTS or check_PROGRAMS;
 # the TESTS variable is automatically populated from these.
@@ -329,6 +312,18 @@
 icf_sht_rel_addend_test.stdout: icf_sht_rel_addend_test
 	$(TEST_NM) icf_sht_rel_addend_test > icf_sht_rel_addend_test.stdout
 
+check_SCRIPTS += merge_string_literals.sh
+check_DATA += merge_string_literals.stdout
+MOSTLYCLEANFILES += merge_string_literals
+merge_string_literals_1.o: merge_string_literals_1.c
+	$(CXXCOMPILE) -O2 -c -fPIC -g -o $@ $<
+merge_string_literals_2.o: merge_string_literals_2.c
+	$(CXXCOMPILE) -O2 -c -fPIC -g -o $@ $<
+merge_string_literals: merge_string_literals_1.o merge_string_literals_2.o gcctestdir/ld
+	$(CXXLINK) -Bgcctestdir/ merge_string_literals_1.o merge_string_literals_2.o -O2 -shared -nostdlib
+merge_string_literals.stdout: merge_string_literals
+	$(TEST_OBJDUMP) -s -j.rodata merge_string_literals > merge_string_literals.stdout
+
 check_PROGRAMS += basic_test
 check_PROGRAMS += basic_pic_test
 basic_test.o: basic_test.cc
@@ -979,6 +974,20 @@
 	  exit 1; \
 	fi
 
+# Test error message when a vtable is undefined.
+check_SCRIPTS += missing_key_func.sh
+check_DATA += missing_key_func.err
+MOSTLYCLEANFILES += missing_key_func.err
+missing_key_func.o: missing_key_func.cc
+	$(CXXCOMPILE) -O0 -g -c -o $@ $(srcdir)/missing_key_func.cc
+missing_key_func.err: missing_key_func.o gcctestdir/ld
+	@echo $(CXXLINK) -Bgcctestdir/ -o missing_key_func missing_key_func.o "2>$@"
+	@if $(CXXLINK) -Bgcctestdir/ -o missing_key_func missing_key_func.o 2>$@; \
+	then \
+	  echo 1>&2 "Link of missing_key_func should have failed"; \
+	  rm -f $@; \
+	  exit 1; \
+	fi
 
 if HAVE_ZLIB
 
diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
index fa9e80f..495b7d0 100644
--- a/gold/testsuite/Makefile.in
+++ b/gold/testsuite/Makefile.in
@@ -69,6 +69,8 @@
 
 # Test --detect-odr-violations
 
+# Test error message when a vtable is undefined.
+
 # Similar to --detect-odr-violations: check for undefined symbols in .so's
 
 # Test --dynamic-list, --dynamic-list-data, --dynamic-list-cpp-new,
@@ -85,12 +87,13 @@
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	icf_preemptible_functions_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	icf_string_merge_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	icf_sht_rel_addend_test.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	merge_string_literals.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	two_file_shared.sh weak_plt.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@	debug_msg.sh undef_symbol.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@	ver_test_1.sh ver_test_2.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@	ver_test_4.sh ver_test_5.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@	ver_test_7.sh ver_test_10.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@	relro_test.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	debug_msg.sh missing_key_func.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	undef_symbol.sh ver_test_1.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	ver_test_2.sh ver_test_4.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	ver_test_5.sh ver_test_7.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	ver_test_10.sh relro_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	ver_matching_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	script_test_3.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	script_test_4.sh \
@@ -119,8 +122,10 @@
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	icf_preemptible_functions_test.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	icf_string_merge_test.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	icf_sht_rel_addend_test.stdout \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	merge_string_literals.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	two_file_shared.dbg \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@	weak_plt_shared.so debug_msg.err
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	weak_plt_shared.so debug_msg.err \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	missing_key_func.err
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_4 = incremental_test \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	incremental_test.cmdline \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	gc_comdat_test gc_tls_test \
@@ -140,6 +145,7 @@
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	icf_preemptible_functions_test \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	icf_string_merge_test \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	icf_sht_rel_addend_test \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	merge_string_literals \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	two_file_shared.dbg \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	alt/weak_undef_lib.so
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_5 = icf_virtual_function_folding_test \
@@ -222,7 +228,8 @@
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	many_sections_check.h
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_26 = many_sections_define.h \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	many_sections_check.h \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@	debug_msg.err
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	debug_msg.err \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	missing_key_func.err
 @GCC_FALSE@initpri1_DEPENDENCIES =
 @NATIVE_LINKER_FALSE@initpri1_DEPENDENCIES =
 @GCC_FALSE@initpri2_DEPENDENCIES =
@@ -1904,6 +1911,7 @@
 CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
+DEFAULT_TARGET = @DEFAULT_TARGET@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 DLOPEN_LIBS = @DLOPEN_LIBS@
@@ -3755,12 +3763,16 @@
 	@p='icf_string_merge_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 icf_sht_rel_addend_test.sh.log: icf_sht_rel_addend_test.sh
 	@p='icf_sht_rel_addend_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+merge_string_literals.sh.log: merge_string_literals.sh
+	@p='merge_string_literals.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 two_file_shared.sh.log: two_file_shared.sh
 	@p='two_file_shared.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 weak_plt.sh.log: weak_plt.sh
 	@p='weak_plt.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 debug_msg.sh.log: debug_msg.sh
 	@p='debug_msg.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+missing_key_func.sh.log: missing_key_func.sh
+	@p='missing_key_func.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 undef_symbol.sh.log: undef_symbol.sh
 	@p='undef_symbol.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 ver_test_1.sh.log: ver_test_1.sh
@@ -4296,13 +4308,9 @@
 	recheck recheck-html tags uninstall uninstall-am
 
 
-# Make the default target available to scripts as $DEFAULT_TARGET.
-@DEFAULT_TARGET_ARM_TRUE@export DEFAULT_TARGET = arm
-@DEFAULT_TARGET_I386_TRUE@export DEFAULT_TARGET = i386
-@DEFAULT_TARGET_POWERPC_TRUE@export DEFAULT_TARGET = powerpc
-@DEFAULT_TARGET_SPARC_TRUE@export DEFAULT_TARGET = sparc
-@DEFAULT_TARGET_X86_64_TRUE@export DEFAULT_TARGET = x86_64
-@DEFAULT_TARGET_TILEGX_TRUE@export DEFAULT_TARGET = tilegx
+# Export make variables to the shell scripts so that they can see
+# (for example) DEFAULT_TARGET.
+.EXPORT_ALL_VARIABLES:
 
 # The unittests themselves
 
@@ -4440,6 +4448,14 @@
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	$(CXXLINK) -Bgcctestdir/ -Wl,--icf=all icf_sht_rel_addend_test_1.o icf_sht_rel_addend_test_2.o
 @GCC_TRUE@@NATIVE_LINKER_TRUE@icf_sht_rel_addend_test.stdout: icf_sht_rel_addend_test
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	$(TEST_NM) icf_sht_rel_addend_test > icf_sht_rel_addend_test.stdout
+@GCC_TRUE@@NATIVE_LINKER_TRUE@merge_string_literals_1.o: merge_string_literals_1.c
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	$(CXXCOMPILE) -O2 -c -fPIC -g -o $@ $<
+@GCC_TRUE@@NATIVE_LINKER_TRUE@merge_string_literals_2.o: merge_string_literals_2.c
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	$(CXXCOMPILE) -O2 -c -fPIC -g -o $@ $<
+@GCC_TRUE@@NATIVE_LINKER_TRUE@merge_string_literals: merge_string_literals_1.o merge_string_literals_2.o gcctestdir/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	$(CXXLINK) -Bgcctestdir/ merge_string_literals_1.o merge_string_literals_2.o -O2 -shared -nostdlib
+@GCC_TRUE@@NATIVE_LINKER_TRUE@merge_string_literals.stdout: merge_string_literals
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	$(TEST_OBJDUMP) -s -j.rodata merge_string_literals > merge_string_literals.stdout
 @GCC_TRUE@@NATIVE_LINKER_TRUE@basic_test.o: basic_test.cc
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	$(CXXCOMPILE) -O0 -c -o $@ $<
 @GCC_TRUE@@NATIVE_LINKER_TRUE@basic_test: basic_test.o gcctestdir/ld
@@ -4653,6 +4669,16 @@
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	  rm -f $@; \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	  exit 1; \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	fi
+@GCC_TRUE@@NATIVE_LINKER_TRUE@missing_key_func.o: missing_key_func.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	$(CXXCOMPILE) -O0 -g -c -o $@ $(srcdir)/missing_key_func.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@missing_key_func.err: missing_key_func.o gcctestdir/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	@echo $(CXXLINK) -Bgcctestdir/ -o missing_key_func missing_key_func.o "2>$@"
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	@if $(CXXLINK) -Bgcctestdir/ -o missing_key_func missing_key_func.o 2>$@; \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	then \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	  echo 1>&2 "Link of missing_key_func should have failed"; \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	  rm -f $@; \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	  exit 1; \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	fi
 @GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@debug_msg_cdebug.o: debug_msg.cc gcctestdir/as
 @GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@	$(CXXCOMPILE) -Bgcctestdir/ -O0 -g -Wa,--compress-debug-sections -c -w -o $@ $(srcdir)/debug_msg.cc
 @GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@odr_violation1_cdebug.o: odr_violation1.cc gcctestdir/as
diff --git a/gold/testsuite/debug_msg.sh b/gold/testsuite/debug_msg.sh
index c0d03b3..1227f3f 100755
--- a/gold/testsuite/debug_msg.sh
+++ b/gold/testsuite/debug_msg.sh
@@ -2,7 +2,8 @@
 
 # debug_msg.sh -- a test case for printing debug info for missing symbols.
 
-# Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+# Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2013
+# Free Software Foundation, Inc.
 # Written by Ian Lance Taylor <iant@google.com>.
 
 # This file is part of gold.
@@ -55,9 +56,9 @@
 
 # We don't know how the compiler might order these variables, so we
 # can't test for the actual offset from .data, hence the regexp.
-check debug_msg.err "debug_msg.o:debug_msg.cc:function fn_array: error: undefined reference to 'undef_fn1()'"
-check debug_msg.err "debug_msg.o:debug_msg.cc:function fn_array: error: undefined reference to 'undef_fn2()'"
-check debug_msg.err "debug_msg.o:debug_msg.cc:function badref1: error: undefined reference to 'undef_int'"
+check debug_msg.err "debug_msg.o:debug_msg.cc:fn_array: error: undefined reference to 'undef_fn1()'"
+check debug_msg.err "debug_msg.o:debug_msg.cc:fn_array: error: undefined reference to 'undef_fn2()'"
+check debug_msg.err "debug_msg.o:debug_msg.cc:badref1: error: undefined reference to 'undef_int'"
 
 # These tests check only for the source file's file name (not the complete
 # path) because use of -fdebug-prefix-map may change the path to the source
@@ -66,10 +67,10 @@
 check debug_msg.err ".*/debug_msg.cc:55: error: undefined reference to 'undef_fn2()'"
 check debug_msg.err ".*/debug_msg.cc:43: error: undefined reference to 'undef_fn1()'"
 check debug_msg.err ".*/debug_msg.cc:44: error: undefined reference to 'undef_fn2()'"
-check debug_msg.err ".*/debug_msg.cc:.*: error: undefined reference to 'undef_int'"
-check debug_msg.err ".*/debug_msg.cc:43: error: undefined reference to 'undef_fn1()'"
-check debug_msg.err ".*/debug_msg.cc:44: error: undefined reference to 'undef_fn2()'"
-check debug_msg.err ".*/debug_msg.cc:.*: error: undefined reference to 'undef_int'"
+if test "$DEFAULT_TARGET" != "powerpc"
+then
+  check debug_msg.err ".*/debug_msg.cc:.*: error: undefined reference to 'undef_int'"
+fi
 
 # Check we detected the ODR (One Definition Rule) violation.
 check debug_msg.err ": symbol 'Ordering::operator()(int, int)' defined in multiple places (possible ODR violation):"
@@ -93,17 +94,17 @@
 # Check for the same error messages when using --compressed-debug-sections.
 if test -r debug_msg_cdebug.err
 then
-  check debug_msg_cdebug.err "debug_msg_cdebug.o:debug_msg.cc:function fn_array: error: undefined reference to 'undef_fn1()'"
-  check debug_msg_cdebug.err "debug_msg_cdebug.o:debug_msg.cc:function fn_array: error: undefined reference to 'undef_fn2()'"
-  check debug_msg_cdebug.err "debug_msg_cdebug.o:debug_msg.cc:function badref1: error: undefined reference to 'undef_int'"
+  check debug_msg_cdebug.err "debug_msg_cdebug.o:debug_msg.cc:fn_array: error: undefined reference to 'undef_fn1()'"
+  check debug_msg_cdebug.err "debug_msg_cdebug.o:debug_msg.cc:fn_array: error: undefined reference to 'undef_fn2()'"
+  check debug_msg_cdebug.err "debug_msg_cdebug.o:debug_msg.cc:badref1: error: undefined reference to 'undef_int'"
   check debug_msg_cdebug.err ".*/debug_msg.cc:50: error: undefined reference to 'undef_fn1()'"
   check debug_msg_cdebug.err ".*/debug_msg.cc:55: error: undefined reference to 'undef_fn2()'"
   check debug_msg_cdebug.err ".*/debug_msg.cc:43: error: undefined reference to 'undef_fn1()'"
   check debug_msg_cdebug.err ".*/debug_msg.cc:44: error: undefined reference to 'undef_fn2()'"
-  check debug_msg_cdebug.err ".*/debug_msg.cc:.*: error: undefined reference to 'undef_int'"
-  check debug_msg_cdebug.err ".*/debug_msg.cc:43: error: undefined reference to 'undef_fn1()'"
-  check debug_msg_cdebug.err ".*/debug_msg.cc:44: error: undefined reference to 'undef_fn2()'"
-  check debug_msg_cdebug.err ".*/debug_msg.cc:.*: error: undefined reference to 'undef_int'"
+  if test "$DEFAULT_TARGET" != "powerpc"
+  then
+    check debug_msg_cdebug.err ".*/debug_msg.cc:.*: error: undefined reference to 'undef_int'"
+  fi
   check debug_msg_cdebug.err ": symbol 'Ordering::operator()(int, int)' defined in multiple places (possible ODR violation):"
   check debug_msg_cdebug.err "odr_violation1.cc:6"
   check debug_msg_cdebug.err "odr_violation2.cc:12"
diff --git a/gold/testsuite/merge_string_literals.sh b/gold/testsuite/merge_string_literals.sh
new file mode 100755
index 0000000..486a895
--- /dev/null
+++ b/gold/testsuite/merge_string_literals.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+# merge_string_literals.sh -- test
+
+# Copyright 2013 Free Software Foundation, Inc.
+# Written by Alexander Ivchenko <alexander.ivchenko@intel.com>.
+
+# This file is part of gold.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# The goal of this program is to check whether string literals from different
+# object files are merged together
+
+set -e
+
+check()
+{
+    number_of_occurrence=`grep $2 ./$1 -o| wc -l`
+    if [ $number_of_occurrence != $3 ]
+    then
+	echo "String literals were not merged"
+	exit 1
+    fi
+}
+
+# If string literals were merged, then "abcd" appears two times
+check merge_string_literals.stdout "abcd" 2
diff --git a/gold/testsuite/merge_string_literals_1.c b/gold/testsuite/merge_string_literals_1.c
new file mode 100644
index 0000000..fc0487c
--- /dev/null
+++ b/gold/testsuite/merge_string_literals_1.c
@@ -0,0 +1,31 @@
+// merge_string_literals_1.c -- a test case for gold
+
+// Copyright 2013 Free Software Foundation, Inc.
+// Written by Alexander Ivchenko <alexander.ivchenko@intel.com>
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// The goal of this program is to check whether string literals from different
+// object files are merged together
+
+const char* bar1() {
+    return "abcdefghijklmnopqrstuvwxyz0123456789";
+}
+const char* bar1_short() {
+    return "abcdef";
+}
diff --git a/gold/testsuite/merge_string_literals_2.c b/gold/testsuite/merge_string_literals_2.c
new file mode 100644
index 0000000..d1185cd
--- /dev/null
+++ b/gold/testsuite/merge_string_literals_2.c
@@ -0,0 +1,31 @@
+// merge_string_literals_2.c -- a test case for gold
+
+// Copyright 2013 Free Software Foundation, Inc.
+// Written by Alexander Ivchenko <alexander.ivchenko@intel.com>
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// The goal of this program is to check whether string literals from different
+// object files are merged together
+
+const char* bar2() {
+    return "abcdefghijklmnopqrstuvwxyz0123456789";
+}
+const char* bar2_short() {
+    return "abcdef";
+}
diff --git a/gold/testsuite/missing_key_func.cc b/gold/testsuite/missing_key_func.cc
new file mode 100644
index 0000000..5a5b7d9
--- /dev/null
+++ b/gold/testsuite/missing_key_func.cc
@@ -0,0 +1,46 @@
+// basic_test.cc -- a test case for gold
+
+// Copyright 2013 Free Software Foundation, Inc.
+// Written by Cary Coutant <ccoutant@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// Define a class, but leave its key function undefined.
+
+class C
+{
+ public:
+  C() : c(1) { }
+  virtual void set();
+  virtual void clear();
+  int c;
+};
+
+void
+C::clear()
+{
+  c = 0;
+}
+
+int
+main()
+{
+  C c;
+  c.clear();
+  return c.c;
+}
diff --git a/gold/testsuite/missing_key_func.sh b/gold/testsuite/missing_key_func.sh
new file mode 100755
index 0000000..54c7b57
--- /dev/null
+++ b/gold/testsuite/missing_key_func.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+# missing_key_func.sh -- a test case for printing error messages when
+# a class is missing its key function.
+
+# Copyright 2013 Free Software Foundation, Inc.
+# Written by Cary Coutant <ccoutant@google.com>
+
+# This file is part of gold.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# This file goes with debug_msg.cc, a C++ source file constructed to
+# have undefined references.  We compile that file with debug
+# information and then try to link it, and make sure the proper errors
+# are displayed.  The errors will be found in debug_msg.err.
+
+check()
+{
+    if ! grep -q "$2" "$1"
+    then
+	echo "Did not find expected error in $1:"
+	echo "   $2"
+	echo ""
+	echo "Actual error output below:"
+	cat "$1"
+	exit 1
+    fi
+}
+
+check_missing()
+{
+    if grep -q "$2" "$1"
+    then
+	echo "Found unexpected error in $1:"
+	echo "   $2"
+	echo ""
+	echo "Actual error output below:"
+	cat "$1"
+	exit 1
+    fi
+}
+
+check missing_key_func.err "error: undefined reference to 'vtable for C'"
+check missing_key_func.err "class is missing its key function"
diff --git a/gprof/ChangeLog b/gprof/ChangeLog
index 847c75f..d855667 100644
--- a/gprof/ChangeLog
+++ b/gprof/ChangeLog
@@ -1,3 +1,15 @@
+2013-05-24  Alan Modra  <amodra@gmail.com>
+
+	* aarch64.c (aarch64_find_call): Promote to bfd_vma before sign
+	extending.
+
+2013-05-22  Venkataramanan Kumar  <Venkataramanan.kumar@linaro.org>
+
+	* aarch64.c: New file.
+	* corefile.c (find_call): Call aarch64_find_call for bfd_arch_aarch64.
+	* Makefile.am (sources): Add aarch64.c.
+	* Makefile.in: Regenerate.
+
 For older changes see ChangeLog-2012
 
 Copyright (C) 2013 Free Software Foundation, Inc.
diff --git a/gprof/Makefile.am b/gprof/Makefile.am
index 0540793..97d8c17 100644
--- a/gprof/Makefile.am
+++ b/gprof/Makefile.am
@@ -43,7 +43,7 @@
 sources = basic_blocks.c call_graph.c cg_arcs.c cg_dfn.c \
 	cg_print.c corefile.c gmon_io.c gprof.c hertz.c hist.c source.c \
 	search_list.c symtab.c sym_ids.c utils.c \
-	i386.c alpha.c vax.c tahoe.c sparc.c mips.c
+	i386.c alpha.c vax.c tahoe.c sparc.c mips.c aarch64.c
 gprof_SOURCES = $(sources) flat_bl.c bsd_callg_bl.c fsf_callg_bl.c
 gprof_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a $(LIBINTL_DEP)
 gprof_LDADD = ../bfd/libbfd.la ../libiberty/libiberty.a $(LIBINTL)
diff --git a/gprof/Makefile.in b/gprof/Makefile.in
index c9f828e..3a5bcdc 100644
--- a/gprof/Makefile.in
+++ b/gprof/Makefile.in
@@ -92,7 +92,8 @@
 	hertz.$(OBJEXT) hist.$(OBJEXT) source.$(OBJEXT) \
 	search_list.$(OBJEXT) symtab.$(OBJEXT) sym_ids.$(OBJEXT) \
 	utils.$(OBJEXT) i386.$(OBJEXT) alpha.$(OBJEXT) vax.$(OBJEXT) \
-	tahoe.$(OBJEXT) sparc.$(OBJEXT) mips.$(OBJEXT)
+	tahoe.$(OBJEXT) sparc.$(OBJEXT) mips.$(OBJEXT) \
+	aarch64.$(OBJEXT)
 am_gprof_OBJECTS = $(am__objects_1) flat_bl.$(OBJEXT) \
 	bsd_callg_bl.$(OBJEXT) fsf_callg_bl.$(OBJEXT)
 gprof_OBJECTS = $(am_gprof_OBJECTS)
@@ -309,7 +310,7 @@
 sources = basic_blocks.c call_graph.c cg_arcs.c cg_dfn.c \
 	cg_print.c corefile.c gmon_io.c gprof.c hertz.c hist.c source.c \
 	search_list.c symtab.c sym_ids.c utils.c \
-	i386.c alpha.c vax.c tahoe.c sparc.c mips.c
+	i386.c alpha.c vax.c tahoe.c sparc.c mips.c aarch64.c
 
 gprof_SOURCES = $(sources) flat_bl.c bsd_callg_bl.c fsf_callg_bl.c
 gprof_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a $(LIBINTL_DEP)
@@ -451,6 +452,7 @@
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aarch64.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basic_blocks.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd_callg_bl.Po@am__quote@
diff --git a/gprof/aarch64.c b/gprof/aarch64.c
new file mode 100644
index 0000000..68febf9
--- /dev/null
+++ b/gprof/aarch64.c
@@ -0,0 +1,99 @@
+/* Gprof -c option support for AArch64.
+   Copyright 2013 Linaro Ltd.
+
+   Based upon gprof/i386.c.
+
+   Copyright (c) 1983, 1993, 2001
+   The Regents of the University of California.  All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   1.  Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+   2.  Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+   3.  Neither the name of the University nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+   OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+   SUCH DAMAGE.  */
+
+#include "gprof.h"
+#include "search_list.h"
+#include "source.h"
+#include "symtab.h"
+#include "cg_arcs.h"
+#include "corefile.h"
+#include "hist.h"
+
+#define BRANCH_MASK    0x7c000000
+#define BRANCH_PATTERN 0x14000000
+
+void aarch64_find_call (Sym *, bfd_vma, bfd_vma);
+
+void
+aarch64_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
+{
+  bfd_vma pc, dest_pc, offset;
+  unsigned int insn;
+  Sym *child;
+
+  DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n",
+			  parent->name, (unsigned long) p_lowpc,
+			  (unsigned long) p_highpc));
+
+  for (pc = p_lowpc; pc < p_highpc; pc += 4)
+    {
+
+      insn = bfd_get_32 (core_bfd, ((unsigned char *) core_text_space
+				    + pc - core_text_sect->vma));
+
+      if ((insn & BRANCH_MASK) == BRANCH_PATTERN)
+	{
+	  DBG (CALLDEBUG,
+	       printf ("[find_call] 0x%lx: bl", (unsigned long) pc));
+
+	  /* Regular pc relative addressing check that this is the
+	     address of a function.  */
+	  offset = ((((bfd_vma) insn & 0x3ffffff) ^ 0x2000000) - 0x2000000) << 2;
+
+	  dest_pc = pc + offset;
+
+	  if (hist_check_address (dest_pc))
+	    {
+	      child = sym_lookup (&symtab, dest_pc);
+
+	      if (child)
+		{
+		  DBG (CALLDEBUG,
+		       printf ("\tdest_pc=0x%lx, (name=%s, addr=0x%lx)\n",
+			       (unsigned long) dest_pc, child->name,
+			       (unsigned long) child->addr));
+
+		  if (child->addr == dest_pc)
+		    {
+		      /* a hit.  */
+		      arc_add (parent, child, (unsigned long) 0);
+		      continue;
+		    }
+		}
+	    }
+
+	  /* Something funny going on.  */
+	  DBG (CALLDEBUG, printf ("\tbut it's a botch\n"));
+	}
+    }
+}
diff --git a/gprof/corefile.c b/gprof/corefile.c
index 985ea26..0aabbad 100644
--- a/gprof/corefile.c
+++ b/gprof/corefile.c
@@ -54,6 +54,7 @@
 extern void tahoe_find_call (Sym *, bfd_vma, bfd_vma);
 extern void sparc_find_call (Sym *, bfd_vma, bfd_vma);
 extern void mips_find_call  (Sym *, bfd_vma, bfd_vma);
+extern void aarch64_find_call (Sym *, bfd_vma, bfd_vma);
 
 static void
 parse_error (const char *filename)
@@ -320,6 +321,10 @@
       mips_find_call (parent, p_lowpc, p_highpc);
       break;
 
+    case bfd_arch_aarch64:
+      aarch64_find_call (parent, p_lowpc, p_highpc);
+      break;
+
     default:
       fprintf (stderr, _("%s: -c not supported on architecture %s\n"),
 	       whoami, bfd_printable_name(core_bfd));
diff --git a/include/ChangeLog b/include/ChangeLog
index f084976..4d02320 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2013-05-06  Paul Brook  <paul@codesourcery.com>
+
+        include/elf/
+        * mips.h (R_MIPS_PC32): Update comment.
+
 2013-04-03  Jason Merrill  <jason@redhat.com>
 
 	Demangle C++11 ref-qualifier.
diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog
index c7265920..2263307 100644
--- a/include/elf/ChangeLog
+++ b/include/elf/ChangeLog
@@ -1,3 +1,17 @@
+2013-05-22  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* common.h (EM_INTEL205): New.
+	(EM_INTEL206): Likewise.
+	(EM_INTEL207): Likewise.
+	(EM_INTEL208): Likewise.
+	(EM_INTEL209): Likewise.
+
+2013-05-02  Nick Clifton  <nickc@redhat.com>
+
+	* msp430.h: Add MSP430X relocs.
+	Add some more MSP430 machine numbers.
+	Add values used by .MSP430.attributes section.
+
 2013-03-21  Michael Schewe  <michael.schewe@gmx.net>
 
 	* h8.h: Add new reloc R_H8_DISP32A16 for relaxation of
diff --git a/include/elf/common.h b/include/elf/common.h
index 697a6e6..decd37f 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -296,6 +296,11 @@
 #define EM_TILEGX	191	/* Tilera TILE-Gx multicore architecture family */
 #define EM_RL78		197	/* Renesas RL78 family.  */
 #define EM_78K0R	199	/* Renesas 78K0R.  */
+#define EM_INTEL205	205	/* Reserved by Intel */
+#define EM_INTEL206	206	/* Reserved by Intel */
+#define EM_INTEL207	207	/* Reserved by Intel */
+#define EM_INTEL208	208	/* Reserved by Intel */
+#define EM_INTEL209	209	/* Reserved by Intel */
 
 /* If it is necessary to assign new unofficial EM_* values, please pick large
    random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
diff --git a/include/elf/mips.h b/include/elf/mips.h
index ca9fdcd..493bbfd 100644
--- a/include/elf/mips.h
+++ b/include/elf/mips.h
@@ -152,9 +152,8 @@
   FAKE_RELOC (R_MICROMIPS_max, 174)
 
   /* This was a GNU extension used by embedded-PIC.  It was co-opted by
-     mips-linux for exception-handling data.  It is no longer used, but
-     should continue to be supported by the linker for backward
-     compatibility.  (GCC stopped using it in May, 2004.)  */
+     mips-linux for exception-handling data.  GCC stopped using it in
+     May, 2004, then started using it again for compact unwind tables.  */
   RELOC_NUMBER (R_MIPS_PC32, 248)
   /* FIXME: this relocation is used internally by gas.  */
   RELOC_NUMBER (R_MIPS_GNU_REL16_S2, 250)
diff --git a/include/elf/msp430.h b/include/elf/msp430.h
index 44f5c51..ac8e28c 100644
--- a/include/elf/msp430.h
+++ b/include/elf/msp430.h
@@ -1,5 +1,5 @@
 /* MSP430 ELF support for BFD.
-   Copyright (C) 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2002-2013 Free Software Foundation, Inc.
    Contributed by Dmitry Diky <diwil@mail.ru>
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -33,6 +33,11 @@
 #define E_MSP430_MACH_MSP430x14  14
 #define E_MSP430_MACH_MSP430x15  15
 #define E_MSP430_MACH_MSP430x16  16
+#define E_MSP430_MACH_MSP430x20  20
+#define E_MSP430_MACH_MSP430x22  22
+#define E_MSP430_MACH_MSP430x23  23
+#define E_MSP430_MACH_MSP430x24  24
+#define E_MSP430_MACH_MSP430x26  26
 #define E_MSP430_MACH_MSP430x31  31
 #define E_MSP430_MACH_MSP430x32  32
 #define E_MSP430_MACH_MSP430x33  33
@@ -40,6 +45,19 @@
 #define E_MSP430_MACH_MSP430x42  42
 #define E_MSP430_MACH_MSP430x43  43
 #define E_MSP430_MACH_MSP430x44  44
+#define E_MSP430_MACH_MSP430X    45
+#define E_MSP430_MACH_MSP430x46  46
+#define E_MSP430_MACH_MSP430x47  47
+#define E_MSP430_MACH_MSP430x54  54
+
+#define SHT_MSP430_ATTRIBUTES	0x70000003	/* Section holds ABI attributes.  */
+#define SHT_MSP430_SEC_FLAGS	0x7f000005	/* Holds TI compiler's section flags.  */
+#define SHT_MSP430_SYM_ALIASES	0x7f000006	/* Holds TI compiler's symbol aliases.  */
+
+/* Tag values for an attribute section.  */
+#define OFBA_MSPABI_Tag_ISA		4
+#define OFBA_MSPABI_Tag_Code_Model	6
+#define OFBA_MSPABI_Tag_Data_Model	8
 
 /* Relocations.  */
 START_RELOC_NUMBERS (elf_msp430_reloc_type)
@@ -52,7 +70,32 @@
      RELOC_NUMBER (R_MSP430_16_PCREL_BYTE, 	6)
      RELOC_NUMBER (R_MSP430_2X_PCREL,		7)
      RELOC_NUMBER (R_MSP430_RL_PCREL,		8)
-
+     RELOC_NUMBER (R_MSP430_8,			9)
+     RELOC_NUMBER (R_MSP430_SYM_DIFF,		10)
 END_RELOC_NUMBERS (R_MSP430_max)
 
+START_RELOC_NUMBERS (elf_msp430x_reloc_type)
+     RELOC_NUMBER (R_MSP430_ABS32, 1)		/* aka R_MSP430_32 */
+     RELOC_NUMBER (R_MSP430_ABS16, 2)		/* aka R_MSP430_16 */
+     RELOC_NUMBER (R_MSP430_ABS8, 3)
+     RELOC_NUMBER (R_MSP430_PCR16, 4)		/* aka R_MSP430_16_PCREL */
+     RELOC_NUMBER (R_MSP430X_PCR20_EXT_SRC, 5)
+     RELOC_NUMBER (R_MSP430X_PCR20_EXT_DST, 6)
+     RELOC_NUMBER (R_MSP430X_PCR20_EXT_ODST, 7)
+     RELOC_NUMBER (R_MSP430X_ABS20_EXT_SRC, 8)
+     RELOC_NUMBER (R_MSP430X_ABS20_EXT_DST, 9)
+     RELOC_NUMBER (R_MSP430X_ABS20_EXT_ODST, 10)
+     RELOC_NUMBER (R_MSP430X_ABS20_ADR_SRC, 11)
+     RELOC_NUMBER (R_MSP430X_ABS20_ADR_DST, 12)
+     RELOC_NUMBER (R_MSP430X_PCR16, 13)		/* Like R_MSP430_PCR16 but with overflow checking.  */
+     RELOC_NUMBER (R_MSP430X_PCR20_CALL, 14)
+     RELOC_NUMBER (R_MSP430X_ABS16, 15)		/* Like R_MSP430_ABS16 but with overflow checking.  */
+     RELOC_NUMBER (R_MSP430_ABS_HI16, 16)
+     RELOC_NUMBER (R_MSP430_PREL31, 17)
+     RELOC_NUMBER (R_MSP430_EHTYPE, 18)		/* Mentioned in ABI.  */
+     RELOC_NUMBER (R_MSP430X_10_PCREL, 19)	/* Red Hat invention.  Used for Jump instructions.  */
+     RELOC_NUMBER (R_MSP430X_2X_PCREL, 20)	/* Red Hat invention.  Used for relaxing jumps.  */
+     RELOC_NUMBER (R_MSP430X_SYM_DIFF, 21)	/* Red Hat invention.  Used for relaxing debug info.  */
+END_RELOC_NUMBERS (R_MSP430x_max)
+
 #endif /* _ELF_MSP430_H */
diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog
index 9eed104..7ed2c68 100644
--- a/include/opcode/ChangeLog
+++ b/include/opcode/ChangeLog
@@ -1,3 +1,20 @@
+2013-05-22  Jürgen Urban  <JuergenUrban@gmx.de>
+
+	* mips.h (M_LQC2_AB, M_SQC2_AB): New macros.
+
+2013-05-09  Andrew Pinski  <apinski@cavium.com>
+
+	* mips.h (OP_MASK_CODE10): Correct definition.
+	(OP_SH_CODE10): Likewise.
+	Add a comment that "+J" is used now for OP_*CODE10.
+	(INSN_ASE_MASK): Update.
+	(INSN_VIRT): New macro.
+	(INSN_VIRT64): New macro
+
+2013-05-02  Nick Clifton  <nickc@redhat.com>
+
+	* msp430.h: Add patterns for MSP430X instructions.
+
 2013-04-06  David S. Miller  <davem@davemloft.net>
 
 	* sparc.h (F_PREFERRED): Define.
diff --git a/include/opcode/mips.h b/include/opcode/mips.h
index ef81bbe..07259ea 100644
--- a/include/opcode/mips.h
+++ b/include/opcode/mips.h
@@ -212,6 +212,10 @@
 #define	OP_OP_SDC2		0x3e
 #define	OP_OP_SDC3		0x3f	/* a.k.a. sd */
 
+/* MIPS VIRT ASE */
+#define OP_MASK_CODE10		0x3ff
+#define OP_SH_CODE10		11
+
 /* Values in the 'VSEL' field.  */
 #define MDMX_FMTSEL_IMM_QH	0x1d
 #define MDMX_FMTSEL_IMM_OB	0x1e
@@ -255,8 +259,6 @@
    of the operand handling in GAS.  The fields below only exist
    in the microMIPS encoding, so define each one to have an empty
    range.  */
-#define OP_MASK_CODE10		0
-#define OP_SH_CODE10		0
 #define OP_MASK_TRAP		0
 #define OP_SH_TRAP		0
 #define OP_MASK_OFFSET10	0
@@ -486,6 +488,9 @@
    "~" 12 bit offset (OP_*_OFFSET12)
    "\" 3 bit position for aset and aclr (OP_*_3BITPOS)
 
+   VIRT ASE usage:
+   "+J" 10-bit hypcall code (OP_*CODE10)
+
    UDI immediates:
    "+1" UDI immediate bits 6-10
    "+2" UDI immediate bits 6-15
@@ -528,7 +533,7 @@
    Extension character sequences used so far ("+" followed by the
    following), for quick reference when adding more:
    "1234"
-   "ABCDEFGHIPQSTXZ"
+   "ABCDEFGHIJPQSTXZ"
    "abcpstxz"
 */
 
@@ -726,7 +731,7 @@
 #define INSN_OCTEON2		  0x00000100
 
 /* Masks used for MIPS-defined ASEs.  */
-#define INSN_ASE_MASK		  0x3c00f010
+#define INSN_ASE_MASK		  0x3c00f0d0
 
 /* DSP ASE */ 
 #define INSN_DSP                  0x00001000
@@ -735,6 +740,10 @@
 /* MIPS R5900 instruction */
 #define INSN_5900                 0x00004000
 
+/* Virtualization ASE */
+#define INSN_VIRT		  0x00000080
+#define INSN_VIRT64		  0x00000040
+
 /* MIPS-3D ASE */
 #define INSN_MIPS3D               0x00008000
 
@@ -1061,6 +1070,7 @@
   M_LDC1_AB,
   M_LDC2_AB,
   M_LDC2_OB,
+  M_LQC2_AB,
   M_LDC3_AB,
   M_LDL_AB,
   M_LDL_OB,
@@ -1154,6 +1164,7 @@
   M_SDC1_AB,
   M_SDC2_AB,
   M_SDC2_OB,
+  M_SQC2_AB,
   M_SDC3_AB,
   M_SDL_AB,
   M_SDL_OB,
diff --git a/include/opcode/msp430.h b/include/opcode/msp430.h
index d3bf130..caddc42 100644
--- a/include/opcode/msp430.h
+++ b/include/opcode/msp430.h
@@ -1,6 +1,6 @@
 /* Opcode table for the TI MSP430 microcontrollers
 
-   Copyright 2002, 2004, 2010 Free Software Foundation, Inc.
+   Copyright 2002-2013 Free Software Foundation, Inc.
    Contributed by Dmitry Diky <diwil@mail.ru>
    
    This program is free software; you can redistribute it and/or modify
@@ -119,6 +119,74 @@
   MSP_INSN (bleu,  5, 2, 0, 0xffff),
   MSP_INSN (ble,   5, 3, 0, 0xffff),
 
+  /* MSP430X instructions - these ones use an extension word.
+     A negative format indicates an MSP430X instruction.  */
+  MSP_INSN (addcx, -2, 2, 0x6000, 0xf000),
+  MSP_INSN (addx,  -2, 2, 0x5000, 0xf000),
+  MSP_INSN (andx,  -2, 2, 0xf000, 0xf000),
+  MSP_INSN (bicx,  -2, 2, 0xc000, 0xf000),
+  MSP_INSN (bisx,  -2, 2, 0xd000, 0xf000),
+  MSP_INSN (bitx,  -2, 2, 0xb000, 0xf000),
+  MSP_INSN (cmpx,  -2, 2, 0x9000, 0xf000),
+  MSP_INSN (daddx, -2, 2, 0xa000, 0xf000),
+  MSP_INSN (movx,  -2, 2, 0x4000, 0xf000),
+  MSP_INSN (subcx, -2, 2, 0x7000, 0xf000),
+  MSP_INSN (subx,  -2, 2, 0x8000, 0xf000),
+  MSP_INSN (xorx,  -2, 2, 0xe000, 0xf000),
+
+  /* MSP430X Synthetic instructions.  */
+  MSP_INSN (adcx,  -1, 1, 0x6300, 0xff30),
+  MSP_INSN (clra,  -1, 1, 0x4300, 0xff30),
+  MSP_INSN (clrx,  -1, 1, 0x4300, 0xff30),
+  MSP_INSN (dadcx, -1, 1, 0xa300, 0xff30),
+  MSP_INSN (decx,  -1, 1, 0x8310, 0xff30),  
+  MSP_INSN (decda, -1, 1, 0x8320, 0xff30),
+  MSP_INSN (decdx, -1, 1, 0x8320, 0xff30),
+  MSP_INSN (incx,  -1, 1, 0x5310, 0xff30),  
+  MSP_INSN (incda, -1, 1, 0x5320, 0xff30),
+  MSP_INSN (incdx, -1, 1, 0x5320, 0xff30),
+  MSP_INSN (invx,  -1, 1, 0xe330, 0xfff0),
+  MSP_INSN (popx,  -1, 1, 0x4130, 0xff30),
+  MSP_INSN (rlax,  -1, 2, 0x5000, 0xf000),  
+  MSP_INSN (rlcx,  -1, 2, 0x6000, 0xf000),
+  MSP_INSN (sbcx,  -1, 1, 0x7300, 0xff30),
+  MSP_INSN (tsta,  -1, 1, 0x9300, 0xff30),
+  MSP_INSN (tstx,  -1, 1, 0x9300, 0xff30),
+
+  MSP_INSN (pushx, -3, 1, 0x1200, 0xff80),
+  MSP_INSN (rrax,  -3, 1, 0x1100, 0xff80),
+  MSP_INSN (rrcx,  -3, 1, 0x1000, 0xff80),
+  MSP_INSN (swpbx, -3, 1, 0x1080, 0xffc0),
+  MSP_INSN (sxtx,  -3, 1, 0x1180, 0xffc0),
+
+  /* MSP430X Address instructions - no extension word needed.
+     The insn_opnumb field is used to encode the nature of the
+     instruction for assembly and disassembly purposes.  */
+  MSP_INSN (calla, -1, 4, 0x1300, 0xff00),
+
+  MSP_INSN (popm,  -1, 5, 0x1600, 0xfe00),
+  MSP_INSN (pushm, -1, 5, 0x1400, 0xfe00),
+
+  MSP_INSN (rrcm,  -1, 6, 0x0040, 0xf3e0),
+  MSP_INSN (rram,  -1, 6, 0x0140, 0xf3e0),
+  MSP_INSN (rlam,  -1, 6, 0x0240, 0xf3e0),
+  MSP_INSN (rrum,  -1, 6, 0x0340, 0xf3e0),
+
+  MSP_INSN (rrux,  -1, 7, 0x0340, 0xffe0), /* Synthesized in terms of RRUM.  */
+
+  MSP_INSN (adda,  -1, 8, 0x00a0, 0xf0b0),
+  MSP_INSN (cmpa,  -1, 8, 0x0090, 0xf0b0),
+  MSP_INSN (suba,  -1, 8, 0x00b0, 0xf0b0),
+
+  MSP_INSN (reta,  -1, 9, 0x0110, 0xffff),
+  MSP_INSN (bra,   -1, 9, 0x0000, 0xf0cf),
+  MSP_INSN (mova,  -1, 9, 0x0000, 0xf080),
+  MSP_INSN (mova,  -1, 9, 0x0080, 0xf0b0),
+  MSP_INSN (mova,  -1, 9, 0x00c0, 0xf0f0),
+
+  /* Pseudo instruction to set the repeat field in the extension word.  */
+  MSP_INSN (rpt,   -1, 10, 0x0000, 0x0000),
+
   /* End of instruction set.  */
   { NULL, 0, 0, 0, 0 }
 };
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 7317e43..e41c4dd 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,46 @@
+2013-05-03  Alan Modra  <amodra@gmail.com>
+
+	PR ld/15365
+	* emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
+	Restrict __ehdr_start's export class to no less than STV_HIDDEN.
+
+2013-05-03  Alan Modra  <amodra@gmail.com>
+
+	* emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
+	Only call lang_for_each_statement if an ELF hash table is used.
+
+2013-05-02  Nick Clifton  <nickc@redhat.com>
+
+	* Makefile.am: Add emsp430X.c
+	* Makefine.in: Regenerate.
+	* configure.tgt (msp430): Add msp430X emulation.
+	* ldmain.c (multiple_definition): Only disable relaxation if it
+	was enabled by the user.
+	* ldmain.h (RELAXATION_ENABLED_BY_USER): New macro.
+	* emulparams/msp430all.sh: Add support for MSP430X.
+	* emultempl/generic.em: (before_parse): Enable relaxation for the
+	MSP430.
+	* scripttempl/msp430.sc: Reorganize sections.  Add .rodata
+	section.
+	* scripttempl/msp430_3.sc: Likewise.
+	* NEWS: Mention support for MSP430X.
+
+2013-05-01  Maciej W. Rozycki  <macro@codesourcery.com>
+
+	* configure.tgt: Replace alpha*-*-linuxecoff* pattern with
+	alpha*-*-linux*ecoff*.  Update the `sed' pattern used to convert
+	from alpha*-*-linux-* to alpha*-*-linux*ecoff*.
+
+2013-05-01  Maciej W. Rozycki  <macro@codesourcery.com>
+
+	* emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
+	Use is_elf_hash_table rather than a handcoded condition.
+
+2013-04-30  Nick Clifton  <nickc@redhat.com>
+
+	* ld.texinfo (SORT_BY_ALIGNMENT): Fix and clarify typo - sections
+	are sorted by descending order of alignment.
+
 2013-04-29  Nick Clifton  <nickc@redhat.com>
 
 	* scripttempl/DWARF.sc: Add support for .debug_line.* and
diff --git a/ld/Makefile.am b/ld/Makefile.am
index e0366f3..0eba8a9 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -424,6 +424,7 @@
 	emsp430xW423.c \
 	emsp430xW425.c \
 	emsp430xW427.c \
+	emsp430X.c \
 	enews.c \
 	ens32knbsd.c \
 	eor32.c \
@@ -1773,6 +1774,10 @@
   $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
   ${GEN_DEPENDS}
 	${GENSCRIPTS} msp430xW427 "$(tdir_msp430xW427)" msp430all
+emsp430X.c: $(srcdir)/emulparams/msp430all.sh \
+  $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
+  ${GEN_DEPENDS}
+	${GENSCRIPTS} msp430X "$(tdir_msp430X)" msp430all
 enews.c: $(srcdir)/emulparams/news.sh \
   $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} news "$(tdir_news)"
diff --git a/ld/Makefile.in b/ld/Makefile.in
index 042e9f2..9140c73 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -732,6 +732,7 @@
 	emsp430xW423.c \
 	emsp430xW425.c \
 	emsp430xW427.c \
+	emsp430X.c \
 	enews.c \
 	ens32knbsd.c \
 	eor32.c \
@@ -1343,6 +1344,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emmo.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10200.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10300.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430X.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x110.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1101.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1111.Po@am__quote@
@@ -3259,6 +3261,10 @@
   $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
   ${GEN_DEPENDS}
 	${GENSCRIPTS} msp430xW427 "$(tdir_msp430xW427)" msp430all
+emsp430X.c: $(srcdir)/emulparams/msp430all.sh \
+  $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
+  ${GEN_DEPENDS}
+	${GENSCRIPTS} msp430X "$(tdir_msp430X)" msp430all
 enews.c: $(srcdir)/emulparams/news.sh \
   $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} news "$(tdir_news)"
diff --git a/ld/NEWS b/ld/NEWS
index 5217e4c..fa11d2d 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,7 @@
 -*- text -*-
 
+* Add support for the Texas Instruments MSP430X processor.
+
 * Add support for Altera Nios II.
 
 * Add support for the V850E3V5 architecture.
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 65884fa..5694580 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -57,10 +57,10 @@
 		        targ_emul=elf64alpha_fbsd
 			targ_extra_emuls="elf64alpha alpha"
 			tdir_alpha=`echo ${targ_alias} | sed -e 's/freebsd/freebsdecoff/'` ;;
-alpha*-*-linuxecoff*)	targ_emul=alpha targ_extra_emuls=elf64alpha
+alpha*-*-linux*ecoff*)	targ_emul=alpha targ_extra_emuls=elf64alpha
 			tdir_elf64alpha=`echo ${targ_alias} | sed -e 's/ecoff//'` ;;
 alpha*-*-linux-*)	targ_emul=elf64alpha targ_extra_emuls=alpha
-			tdir_alpha=`echo ${targ_alias} | sed -e 's/linux/linuxecoff/'` ;;
+			tdir_alpha=`echo ${targ_alias} | sed -e 's/linux\(-gnu\)*/linux\1ecoff/'` ;;
 alpha*-*-osf*)		targ_emul=alpha ;;
 alpha*-*-gnu*)		targ_emul=elf64alpha ;;
 alpha*-*-netware*)	targ_emul=alpha ;;
@@ -519,7 +519,7 @@
 mt-*elf)                targ_emul=elf32mt
 			;;
 msp430-*-*)             targ_emul=msp430x110
-                        targ_extra_emuls="msp430x112 msp430x1101 msp430x1111 msp430x1121 msp430x1122 msp430x1132 msp430x122 msp430x123 msp430x1222 msp430x1232 msp430x133 msp430x135 msp430x1331 msp430x1351 msp430x147 msp430x148 msp430x149 msp430x155 msp430x156 msp430x157 msp430x167 msp430x168 msp430x169 msp430x1610 msp430x1611 msp430x1612 msp430x2101 msp430x2111 msp430x2121 msp430x2131 msp430x311 msp430x312 msp430x313 msp430x314 msp430x315 msp430x323 msp430x325 msp430x336 msp430x337 msp430x412 msp430x413 msp430x415 msp430x417 msp430xE423 msp430xE425 msp430xE427 msp430xW423 msp430xW425 msp430xW427 msp430xG437 msp430xG438 msp430xG439 msp430x435 msp430x436 msp430x437 msp430x447 msp430x448 msp430x449"
+                        targ_extra_emuls="msp430x112 msp430x1101 msp430x1111 msp430x1121 msp430x1122 msp430x1132 msp430x122 msp430x123 msp430x1222 msp430x1232 msp430x133 msp430x135 msp430x1331 msp430x1351 msp430x147 msp430x148 msp430x149 msp430x155 msp430x156 msp430x157 msp430x167 msp430x168 msp430x169 msp430x1610 msp430x1611 msp430x1612 msp430x2101 msp430x2111 msp430x2121 msp430x2131 msp430x311 msp430x312 msp430x313 msp430x314 msp430x315 msp430x323 msp430x325 msp430x336 msp430x337 msp430x412 msp430x413 msp430x415 msp430x417 msp430xE423 msp430xE425 msp430xE427 msp430xW423 msp430xW425 msp430xW427 msp430xG437 msp430xG438 msp430xG439 msp430x435 msp430x436 msp430x437 msp430x447 msp430x448 msp430x449 msp430X"
 			;;
 nios2*-*-*)		targ_emul=nios2elf ;;
 ns32k-pc532-mach* | ns32k-pc532-ux*)  targ_emul=pc532macha ;;
diff --git a/ld/emulparams/msp430all.sh b/ld/emulparams/msp430all.sh
index 57d21c2..3a2f79d 100644
--- a/ld/emulparams/msp430all.sh
+++ b/ld/emulparams/msp430all.sh
@@ -551,3 +551,12 @@
 RAM_SIZE=0x400
 STACK=0x600
 fi
+
+if [ "${MSP430_NAME}" = "msp430X" ] ; then
+ARCH=msp:43
+ROM_START=0x02000
+ROM_SIZE=0x0dfe0
+RAM_START=0x10000
+RAM_SIZE=0x30000
+STACK=0x600
+fi
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 3653955..aa4f355 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1484,13 +1484,22 @@
   asection *sinterp;
   bfd *abfd;
 
-  if (link_info.hash->type == bfd_link_elf_hash_table)
-    _bfd_elf_tls_setup (link_info.output_bfd, &link_info);
+  if (is_elf_hash_table (link_info.hash))
+    {
+      _bfd_elf_tls_setup (link_info.output_bfd, &link_info);
 
-  /* If we are going to make any variable assignments, we need to let
-     the ELF backend know about them in case the variables are
-     referred to by dynamic objects.  */
-  lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
+      /* Make __ehdr_start hidden if it has been referenced, to
+	 prevent the symbol from being dynamic.  */
+      if (!bfd_elf_record_link_assignment (link_info.output_bfd, &link_info,
+					   "__ehdr_start", TRUE, TRUE))
+	einfo ("%P%F: failed to record assignment to %s: %E\n",
+	       "__ehdr_start");
+
+      /* If we are going to make any variable assignments, we need to
+	 let the ELF backend know about them in case the variables are
+	 referred to by dynamic objects.  */
+      lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
+    }
 
   /* Let the ELF backend work out the sizes of any sections required
      by dynamic linking.  */
diff --git a/ld/emultempl/generic.em b/ld/emultempl/generic.em
index 20ec356..dce2bff 100644
--- a/ld/emultempl/generic.em
+++ b/ld/emultempl/generic.em
@@ -57,6 +57,18 @@
 #ifndef TARGET_			/* I.e., if not generic.  */
   ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown);
 #endif /* not TARGET_ */
+EOF
+  # The MSP430 port *needs* linker relaxtion in order to cope with large
+  # functions where conditional branches do not fit into a +/- 1024 byte range.
+  case ${target} in
+    msp430-*-* )
+fragment <<EOF
+  if (! link_info.relocatable)
+    TARGET_ENABLE_RELAXATION;
+EOF
+    ;;
+  esac
+fragment <<EOF
 }
 
 EOF
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 79591c7..0e31d31 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -4031,7 +4031,9 @@
 @cindex SORT_BY_ALIGNMENT
 @code{SORT_BY_ALIGNMENT} is very similar to @code{SORT_BY_NAME}. The
 difference is @code{SORT_BY_ALIGNMENT} will sort sections into
-ascending order by alignment before placing them in the output file.
+descending order by alignment before placing them in the output file.
+Larger alignments are placed before smaller alignments in order to
+reduce the amount of padding necessary.
 
 @cindex SORT_BY_INIT_PRIORITY
 @code{SORT_BY_INIT_PRIORITY} is very similar to @code{SORT_BY_NAME}. The
@@ -4048,11 +4050,11 @@
 @enumerate
 @item
 @code{SORT_BY_NAME} (@code{SORT_BY_ALIGNMENT} (wildcard section pattern)).
-It will sort the input sections by name first, then by alignment if 2
+It will sort the input sections by name first, then by alignment if two
 sections have the same name.
 @item
 @code{SORT_BY_ALIGNMENT} (@code{SORT_BY_NAME} (wildcard section pattern)).
-It will sort the input sections by alignment first, then by name if 2
+It will sort the input sections by alignment first, then by name if two
 sections have the same alignment.
 @item
 @code{SORT_BY_NAME} (@code{SORT_BY_NAME} (wildcard section pattern)) is
diff --git a/ld/ldmain.c b/ld/ldmain.c
index e7d726a..5181c61 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -1,7 +1,5 @@
 /* Main program of GNU linker.
-   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
-   Free Software Foundation, Inc.
+   Copyright 1991-2013 Free Software Foundation, Inc.
    Written by Steve Chamberlain steve@cygnus.com
 
    This file is part of the GNU Binutils.
@@ -936,10 +934,10 @@
   if (obfd != NULL)
     einfo (_("%D: first defined here\n"), obfd, osec, oval);
 
-  if (RELAXATION_ENABLED)
+  if (RELAXATION_ENABLED_BY_USER)
     {
       einfo (_("%P: Disabling relaxation: it will not work with multiple definitions\n"));
-      link_info.disable_target_specific_optimizations = -1;
+      DISABLE_RELAXATION;
     }
 
   return TRUE;
diff --git a/ld/ldmain.h b/ld/ldmain.h
index 66aa628..39ab014 100644
--- a/ld/ldmain.h
+++ b/ld/ldmain.h
@@ -1,6 +1,5 @@
 /* ldmain.h -
-   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2002, 2003, 2004,
-   2005, 2007, 2008, 2009, 2012 Free Software Foundation, Inc.
+   Copyright 1991-2013 Free Software Foundation, Inc.
 
    This file is part of the GNU Binutils.
 
@@ -42,11 +41,16 @@
 #define RELAXATION_DISABLED_BY_DEFAULT	\
   (link_info.disable_target_specific_optimizations < 0)
 #define RELAXATION_DISABLED_BY_USER	\
-  (link_info.disable_target_specific_optimizations > 0)
+  (link_info.disable_target_specific_optimizations > 1)
 #define RELAXATION_ENABLED		\
+  (link_info.disable_target_specific_optimizations == 0 \
+   || link_info.disable_target_specific_optimizations == 1)
+#define RELAXATION_ENABLED_BY_USER		\
   (link_info.disable_target_specific_optimizations == 0)
-#define DISABLE_RELAXATION		\
+#define TARGET_ENABLE_RELAXATION		\
   do { link_info.disable_target_specific_optimizations = 1; } while (0)
+#define DISABLE_RELAXATION		\
+  do { link_info.disable_target_specific_optimizations = 2; } while (0)
 #define ENABLE_RELAXATION		\
   do { link_info.disable_target_specific_optimizations = 0; } while (0)
 
diff --git a/ld/scripttempl/elf32msp430.sc b/ld/scripttempl/elf32msp430.sc
index 53a87b8..c699a91 100644
--- a/ld/scripttempl/elf32msp430.sc
+++ b/ld/scripttempl/elf32msp430.sc
@@ -35,6 +35,31 @@
 
 SECTIONS
 {
+  /* Bootloader.  */
+  .bootloader ${RELOCATING-0} :
+  {
+    ${RELOCATING+ PROVIDE (__boot_start = .) ; }
+    *(.bootloader)
+    ${RELOCATING+. = ALIGN(2);}
+    *(.bootloader.*)
+  } ${RELOCATING+ > bootloader}
+  
+  /* Information memory.  */
+  .infomem ${RELOCATING-0} :
+  {
+    *(.infomem)
+    ${RELOCATING+. = ALIGN(2);}
+    *(.infomem.*)
+  } ${RELOCATING+ > infomem}
+
+  /* Information memory (not loaded into MPU).  */
+  .infomemnobits ${RELOCATING-0} :
+  {
+    *(.infomemnobits)
+    ${RELOCATING+. = ALIGN(2);}
+    *(.infomemnobits.*)
+  } ${RELOCATING+ > infomemnobits}
+
   /* Read-only sections, merged into text segment.  */
   ${TEXT_DYNAMIC+${DYNAMIC}}
   .hash        ${RELOCATING-0} : { *(.hash)             }
@@ -122,6 +147,8 @@
     *(.text)
     ${RELOCATING+. = ALIGN(2);}
     *(.text.*)
+    ${RELOCATING+. = ALIGN(2);}
+    *(.text:*)
 
     ${RELOCATING+. = ALIGN(2);}
     *(SORT_NONE(.fini9))
@@ -139,42 +166,84 @@
     _etext = .;
   } ${RELOCATING+ > text}
 
-  .data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text))}
+  .rodata :
+  {
+    . = ALIGN(2);
+    *(.plt)
+    *(.rodata .rodata.* .gnu.linkonce.r.* .const .const:*)
+    *(.rodata1)
+
+    *(.eh_frame_hdr)
+    KEEP (*(.eh_frame))
+
+    KEEP (*(.gcc_except_table)) *(.gcc_except_table.*)
+
+    PROVIDE (__preinit_array_start = .);
+    KEEP (*(.preinit_array))
+    PROVIDE (__preinit_array_end = .);
+
+    PROVIDE (__init_array_start = .);
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array))
+    PROVIDE (__init_array_end = .);
+
+    PROVIDE (__fini_array_start = .);
+    KEEP (*(.fini_array))
+    KEEP (*(SORT(.fini_array.*)))
+    PROVIDE (__fini_array_end = .);
+    LONG(0); /* Sentinel.  */
+
+    /* gcc uses crtbegin.o to find the start of the constructors, so
+       we make sure it is first.  Because this is a wildcard, it
+       doesn't matter if the user does not actually link against
+       crtbegin.o; the linker won't look for a file to match a
+       wildcard.  The wildcard also means that it doesn't matter which
+       directory crtbegin.o is in.  */
+    KEEP (*crtbegin*.o(.ctors))
+
+    /* We don't want to include the .ctor section from from the
+       crtend.o file until after the sorted ctors.  The .ctor section
+       from the crtend file contains the end of ctors marker and it
+       must be last */
+    KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+
+    KEEP (*crtbegin*.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+  } ${RELOCATING+ > text}
+
+  .vectors ${RELOCATING-0}:
+  {
+    ${RELOCATING+ PROVIDE (__vectors_start = .) ; }
+    *(.vectors*)
+    ${RELOCATING+ _vectors_end = . ; }
+  } ${RELOCATING+ > vectors}
+
+  .data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text) + SIZEOF (.rodata))}
   {  
     ${RELOCATING+ PROVIDE (__data_start = .) ; }
+    ${RELOCATING+ PROVIDE (__datastart = .) ; }
     ${RELOCATING+. = ALIGN(2);}
+
+    KEEP (*(.jcr))
+    *(.data.rel.ro.local) *(.data.rel.ro*)
+    *(.dynamic)
+
     *(.data)
     *(.data.*)
     *(.gnu.linkonce.d*)
+    KEEP (*(.gnu.linkonce.d.*personality*))
+    *(.data1)
+    *(.got.plt) *(.got)
+    ${RELOCATING+. = ALIGN(2);}
+    *(.sdata .sdata.* .gnu.linkonce.s.*)
     ${RELOCATING+. = ALIGN(2);}
     ${RELOCATING+ _edata = . ; }
   } ${RELOCATING+ > data}
   
-  /* Bootloader.  */
-  .bootloader ${RELOCATING-0} :
-  {
-    ${RELOCATING+ PROVIDE (__boot_start = .) ; }
-    *(.bootloader)
-    ${RELOCATING+. = ALIGN(2);}
-    *(.bootloader.*)
-  } ${RELOCATING+ > bootloader}
-  
-  /* Information memory.  */
-  .infomem ${RELOCATING-0} :
-  {
-    *(.infomem)
-    ${RELOCATING+. = ALIGN(2);}
-    *(.infomem.*)
-  } ${RELOCATING+ > infomem}
-
-  /* Information memory (not loaded into MPU).  */
-  .infomemnobits ${RELOCATING-0} :
-  {
-    *(.infomemnobits)
-    ${RELOCATING+. = ALIGN(2);}
-    *(.infomemnobits.*)
-  } ${RELOCATING+ > infomemnobits}
-
   .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
   {
     ${RELOCATING+. = ALIGN(2);}
@@ -194,13 +263,6 @@
     ${RELOCATING+ _end = . ;  }
   } ${RELOCATING+ > data}
 
-  .vectors ${RELOCATING-0}:
-  {
-    ${RELOCATING+ PROVIDE (__vectors_start = .) ; }
-    *(.vectors*)
-    ${RELOCATING+ _vectors_end = . ; }
-  } ${RELOCATING+ > vectors}
-
   ${HEAP_SECTION_MSP430}
 
   /* Stabs for profiling information*/
@@ -214,12 +276,18 @@
   .stab.index 0 : { *(.stab.index) }
   .stab.indexstr 0 : { *(.stab.indexstr) }
   .comment 0 : { *(.comment) }
- 
 EOF
 
-. $srcdir/scripttempl/DWARF.sc
+source $srcdir/scripttempl/DWARF.sc
 
 cat <<EOF
+  .MP430.attributes 0 :
+  {
+    KEEP (*(.MSP430.attributes))
+    KEEP (*(.gnu.attributes))
+    KEEP (*(__TI_build_attributes))
+  }
+
   PROVIDE (__stack = ${STACK}) ;
   PROVIDE (__data_start_rom = _etext) ;
   PROVIDE (__data_end_rom   = _etext + SIZEOF (.data)) ;
diff --git a/ld/scripttempl/elf32msp430_3.sc b/ld/scripttempl/elf32msp430_3.sc
index 9a23d02..ade5fcb 100644
--- a/ld/scripttempl/elf32msp430_3.sc
+++ b/ld/scripttempl/elf32msp430_3.sc
@@ -98,6 +98,8 @@
     *(.text)
     ${RELOCATING+. = ALIGN(2);}
     *(.text.*)
+    ${RELOCATING+. = ALIGN(2);}
+    *(.text:*)
 
     ${RELOCATING+. = ALIGN(2);}
     *(SORT_NONE(.fini9))
@@ -115,6 +117,13 @@
     ${RELOCATING+ _etext = . ; }
   } ${RELOCATING+ > text}
 
+  .rodata :
+  {
+    *(.rodata .rodata.* .gnu.linkonce.r.*)
+    *(.const)
+    *(.const:*)
+  } ${RELOCATING+ > text}
+
   .data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text))}
   {  
     ${RELOCATING+ PROVIDE (__data_start = .) ; }
@@ -152,6 +161,13 @@
     ${RELOCATING+ _vectors_end = . ; }
   } ${RELOCATING+ > vectors}
 
+  .MP430.attributes 0 :
+  {
+    KEEP (*(.MSP430.attributes))
+    KEEP (*(.gnu.attributes))
+    KEEP (*(__TI_build_attributes))
+  }
+
   /* Stabs debugging sections.  */
   .stab 0 : { *(.stab) } 
   .stabstr 0 : { *(.stabstr) }
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 27dae44..cad469c 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,80 @@
+2013-05-21  Alan Modra  <amodra@gmail.com>
+
+	PR ld/12982
+	* ld-plugin/pr12982.d: Fail if RWE GNU_STACK present.
+
+2013-05-21  Alan Modra  <amodra@gmail.com>
+
+	* ld-powerpc/export-class.exp (supports_ppc64): Delete.
+	(powerpc_export_class_test): Add "endian" param.
+	(abis): Add little-endian targets and test.
+	* ld-powerpc/powerpc-64-export-class.xd: Update for little-endian.
+
+2013-05-10  Joel Brobecker  <brobecker@adacore.com>
+
+	* ld-powerpc/aix-core-sec-1.hd, ld-powerpc/aix-core-sec-2.hd,
+	ld-powerpc/aix-core-sec-3.hd: Adjust expected section flags
+	for section .loader.
+
+2013-05-03  Maciej W. Rozycki  <macro@codesourcery.com>
+
+	PR ld/15365
+	* ld-elf/ehdr_start.d: Expect __ehdr_start to be STB_LOCAL.
+	* ld-mips-elf/ehdr_start-1.nd: New test.
+	* ld-mips-elf/ehdr_start-2.nd: New test.
+	* ld-mips-elf/ehdr_start-1.ld: New test linker script.
+	* ld-mips-elf/ehdr_start-2.ld: New test linker script.
+	* ld-mips-elf/ehdr_start-new.s: New test source.
+	* ld-mips-elf/ehdr_start-o32.s: New test source.
+	* ld-mips-elf/mips-elf.exp: Run the new tests.
+
+2013-05-03  Maciej W. Rozycki  <macro@codesourcery.com>
+
+	* ld-elf/provide-hidden-s.nd: New test.
+	* ld-elf/provide-hidden-abs.nd: New test.
+	* ld-elf/provide-hidden-def.nd: New test.
+	* ld-elf/provide-hidden-dyn.nd: New test.
+	* ld-elf/provide-hidden-sec.nd: New test.
+	* ld-elf/provide-hidden-dynabs.nd: New test.
+	* ld-elf/provide-hidden-dynsec.nd: New test.
+	* ld-elf/provide-hidden-s.ld: New test linker script.
+	* ld-elf/provide-hidden-1.ld: New test linker script.
+	* ld-elf/provide-hidden-2.ld: New test linker script.
+	* ld-elf/provide-hidden-1.s: New test source.
+	* ld-elf/provide-hidden-2.s: New test source.
+	* ld-elf/provide-hidden-3.s: New test source.
+	* ld-elf/provide-hidden-4.s: New test source.
+	* ld-elf/provide-hidden.exp: New test script.
+
+2013-05-02  Nick Clifton  <nickc@redhat.com>
+
+	* ld-elf/flags1.d: Expect this test to pass on the MSP430.
+	* ld-elf/init-fini-arrays.d: Expect this test to fail on the
+	MSP430.
+	* ld-elf/merge.d: Expect this test to pass on the MSP430.
+	* ld-elf/sec64k.exp: Skip these tests for the MSP430.
+	* ld-gc/pr13683.d: Expect this test to fail on the MSP430.
+	* ld-srec/srec.exp: Expect these tests to fail on the MSP430.
+	* ld-undefined/undefined.exp: Expect the UNDEFINED LINE test to
+	fail on the MSP430.
+
+2013-05-01  Maciej W. Rozycki  <macro@codesourcery.com>
+
+	* lib/ld-lib.exp (check_shared_lib_support): Also exclude
+	mips*-*-elf.
+
+2013-04-30  Hans-Peter Nilsson  <hp@axis.com>
+
+	* lib/ld-lib.exp (check_shared_lib_support): Match cris*-*-elf as
+	a negative pattern instead of cris*-*-*.
+
+2013-04-30  Will Newton  <will.newton@linaro.org>
+
+	* ld-arm/arm-elf.exp: Use linker script for IFUNC test 17.
+	* ld-arm/ifunc-17.dd: Update offsets for linker script.
+	* ld-arm/ifunc-17.gd: Likewise.
+	* ld-arm/ifunc-17.rd: Likewise.
+
 2013-04-29  Will Newton  <will.newton@linaro.org>
 
 	* ld-arm/arm-elf.exp: Add IFUNC test 17.
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index c488e3c..a6abe82 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -451,7 +451,7 @@
       {objdump {-s -j.data -j.got} ifunc-16.gd}
       {readelf -r ifunc-16.rd}}
      "ifunc-16"}
-    {"IFUNC test 17" "" "" "" {ifunc-17.s}
+    {"IFUNC test 17" "-T ifunc-static.ld" "" "" {ifunc-17.s}
      {{objdump -d ifunc-17.dd}
       {objdump {-s -j.data -j.got} ifunc-17.gd}
       {readelf -r ifunc-17.rd}}
diff --git a/ld/testsuite/ld-arm/ifunc-17.dd b/ld/testsuite/ld-arm/ifunc-17.dd
index f23a249..ee5cd05 100644
--- a/ld/testsuite/ld-arm/ifunc-17.dd
+++ b/ld/testsuite/ld-arm/ifunc-17.dd
@@ -4,22 +4,22 @@
 
 Disassembly of section \.iplt:
 
-00008084 <.iplt>:
+00009000 <.iplt>:
 #------------------------------------------------------------------------------
 #------ appfunc1's .iplt entry
 #------------------------------------------------------------------------------
-    8084:	e28fc600 	add	ip, pc, #0, 12
-    8088:	e28cca08 	add	ip, ip, #8, 20	; 0x8000
-    808c:	e5bcf01c 	ldr	pc, \[ip, #28\]!
+    9000:	e28fc600 	add	ip, pc, #0, 12
+    9004:	e28cca08 	add	ip, ip, #8, 20	; 0x8000
+    9008:	e5bcf004 	ldr	pc, \[ip, #4\]!
 
 Disassembly of section \.text:
 
-00008090 <appfunc1>:
-    8090:	46f7      	mov	pc, lr
+0000a000 <appfunc1>:
+    a000:	46f7      	mov	pc, lr
 
-00008092 <appfunc2>:
-    8092:	46f7      	mov	pc, lr
+0000a002 <appfunc2>:
+    a002:	46f7      	mov	pc, lr
 
-00008094 <_start>:
-    8094:	f7ff eff6 	blx	8084 <appfunc1-0xc>
-    8098:	00000010 	\.word	0x00000010
+0000a004 <_start>:
+    a004:	f7fe effc 	blx	9000 <appfunc1-0x1000>
+    a008:	00000010 	\.word	0x00000010
diff --git a/ld/testsuite/ld-arm/ifunc-17.gd b/ld/testsuite/ld-arm/ifunc-17.gd
index 4a12eb8..dadfc9e 100644
--- a/ld/testsuite/ld-arm/ifunc-17.gd
+++ b/ld/testsuite/ld-arm/ifunc-17.gd
@@ -3,8 +3,8 @@
 
 Contents of section \.got:
 #------------------------------------------------------------------------------
-#------ 000100a8: 0x8091 (appfunc1)
-#------ 000100ac: 0x8093 (appfunc2)
+#------ 0001100c: 0xa001 (appfunc1)
+#------ 00011010: 0xa003 (appfunc2)
 #------------------------------------------------------------------------------
- 1009c 00000000 00000000 00000000 91800000  .*
- 100ac 93800000                             .*
+ 11000 00000000 00000000 00000000 01a00000  .*
+ 11010 03a00000                             .*
diff --git a/ld/testsuite/ld-arm/ifunc-17.rd b/ld/testsuite/ld-arm/ifunc-17.rd
index a93fd64..b167f45 100644
--- a/ld/testsuite/ld-arm/ifunc-17.rd
+++ b/ld/testsuite/ld-arm/ifunc-17.rd
@@ -1,5 +1,5 @@
 
-Relocation section '\.rel\.dyn' at offset 0x74 contains 2 entries:
+Relocation section '\.rel\.dyn' at offset 0x8000 contains 2 entries:
  Offset     Info    Type            Sym\.Value  Sym\. Name
-000100a8  ......a0 R_ARM_IRELATIVE  
-000100ac  ......a0 R_ARM_IRELATIVE  
+0001100c  ......a0 R_ARM_IRELATIVE  
+00011010  ......a0 R_ARM_IRELATIVE  
diff --git a/ld/testsuite/ld-elf/ehdr_start.d b/ld/testsuite/ld-elf/ehdr_start.d
index 9a82882..52e5b54 100644
--- a/ld/testsuite/ld-elf/ehdr_start.d
+++ b/ld/testsuite/ld-elf/ehdr_start.d
@@ -4,5 +4,5 @@
 #target: *-*-linux* *-*-gnu* *-*-nacl*
 
 #...
-[0-9a-f]*000 [ADRT] __ehdr_start
+[0-9a-f]*000 [Adrt] __ehdr_start
 #pass
diff --git a/ld/testsuite/ld-elf/flags1.d b/ld/testsuite/ld-elf/flags1.d
index ab8facc..63c2e3a 100644
--- a/ld/testsuite/ld-elf/flags1.d
+++ b/ld/testsuite/ld-elf/flags1.d
@@ -3,9 +3,9 @@
 #objcopy_linked_file: --set-section-flags .post_text_reserve=contents,alloc,load,readonly,code
 #readelf: -l --wide
 #xfail: "avr-*-*" "dlx-*-*" "h8300-*-*" "i960-*-*" "ip2k-*-*" "m32r-*-*"
-#xfail: "moxie-*-*" "mt-*-*" "msp430-*-*" "*-*-nacl*"
+#xfail: "moxie-*-*" "mt-*-*" "*-*-nacl*"
 #xfail: "*-*-hpux*" "hppa*64*-*-*"
-# Fails on the AVR, DLX, H8300, I960, IP2K, M32R, MOXIE, MT, and MSP430,
+# Fails on the AVR, DLX, H8300, I960, IP2K, M32R, MOXIE, MT,
 #  and all NaCl targets,
 #  because the two sections are not merged into one segment.
 #  (There is no good reason why they have to be).
diff --git a/ld/testsuite/ld-elf/init-fini-arrays.d b/ld/testsuite/ld-elf/init-fini-arrays.d
index 1b182b9..46b536c 100644
--- a/ld/testsuite/ld-elf/init-fini-arrays.d
+++ b/ld/testsuite/ld-elf/init-fini-arrays.d
@@ -1,9 +1,10 @@
 #source: init-fini-arrays.s
 #ld: -r
 #readelf: -S --wide
-#xfail: cr16-*-* crx-*-*
+#xfail: cr16-*-* crx-*-* msp430-*-*
+# msp430 puts the init_array and fini_array inside the .rodata section.
 # cr16 and crx use non-standard scripts with memory regions, which don't play
-# well with unique group sections under ld -r.
+#  well with unique group sections under ld -r.
 
 #...
   \[[ 0-9]+\] \.init_array\.01000[ \t]+PROGBITS[ \t0-9a-f]+WA?.*
diff --git a/ld/testsuite/ld-elf/merge.d b/ld/testsuite/ld-elf/merge.d
index 3593f96..c50de10 100644
--- a/ld/testsuite/ld-elf/merge.d
+++ b/ld/testsuite/ld-elf/merge.d
@@ -4,7 +4,7 @@
 #xfail: "arc-*-*" "avr-*-*" "bfin-*-*" "cr16-*-*" "cris*-*-*" "crx-*-*" "d10v-*-*" "d30v-*-*"
 #xfail: "dlx-*-*" "fr30-*-*" "frv-*-*" "hppa*64*-*-*" "h8300-*-*" "score-*-*"
 #xfail: "i370-*-*" "i860-*-*" "i960-*-*" "ip2k-*-*" "iq2000-*-*" "lm32-*-*"
-#xfail: "mcore-*-*" "mn102*-*-*" "mips*-*-*" "ms1-*-*" "msp430-*-*" "mep-*-*"
+#xfail: "mcore-*-*" "mn102*-*-*" "mips*-*-*" "ms1-*-*" "mep-*-*"
 #xfail: "or32-*-*" "pj-*-*" "sparc*-*-*" "tic6x-*-*" "vax-*-*" "xstormy16-*-*"
 #xfail: "xtensa*-*-*" "metag-*-*"
 
diff --git a/ld/testsuite/ld-elf/provide-hidden-1.ld b/ld/testsuite/ld-elf/provide-hidden-1.ld
new file mode 100644
index 0000000..47cdbb7
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-1.ld
@@ -0,0 +1,15 @@
+SECTIONS
+{
+  . = 0x12300000;
+  .data :
+    {
+      PROVIDE_HIDDEN (foo = . + 0x11100000);
+      *(.data)
+    }
+  .got : { *(.got) }
+  .interp : { *(.interp) }
+  .dynsym : { *(.dynsym) }
+  .dynstr : { *(.dynstr) }
+  .dynamic : { *(.dynamic) }
+  .hash : { *(.hash) }
+}
diff --git a/ld/testsuite/ld-elf/provide-hidden-1.s b/ld/testsuite/ld-elf/provide-hidden-1.s
new file mode 100644
index 0000000..c845ffb
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-1.s
@@ -0,0 +1,4 @@
+	.data
+	.globl	foo
+foo:
+	.dc.a	foo
diff --git a/ld/testsuite/ld-elf/provide-hidden-2.ld b/ld/testsuite/ld-elf/provide-hidden-2.ld
new file mode 100644
index 0000000..0b04c49
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-2.ld
@@ -0,0 +1,12 @@
+SECTIONS
+{
+  . = 0x12300000;
+  PROVIDE_HIDDEN (foo = . + 0x11100000);
+  .data : { *(.data) }
+  .got : { *(.got) }
+  .interp : { *(.interp) }
+  .dynsym : { *(.dynsym) }
+  .dynstr : { *(.dynstr) }
+  .dynamic : { *(.dynamic) }
+  .hash : { *(.hash) }
+}
diff --git a/ld/testsuite/ld-elf/provide-hidden-2.s b/ld/testsuite/ld-elf/provide-hidden-2.s
new file mode 100644
index 0000000..bbaa7de
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-2.s
@@ -0,0 +1,5 @@
+	.data
+	.globl	foo
+	.internal foo
+foo:
+	.dc.a	foo
diff --git a/ld/testsuite/ld-elf/provide-hidden-3.s b/ld/testsuite/ld-elf/provide-hidden-3.s
new file mode 100644
index 0000000..9413280
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-3.s
@@ -0,0 +1,4 @@
+	.data
+	.globl	bar
+bar:
+	.dc.a	foo
diff --git a/ld/testsuite/ld-elf/provide-hidden-4.s b/ld/testsuite/ld-elf/provide-hidden-4.s
new file mode 100644
index 0000000..2d8f37e
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-4.s
@@ -0,0 +1,5 @@
+	.data
+	.globl	bar
+	.internal foo
+bar:
+	.dc.a	foo
diff --git a/ld/testsuite/ld-elf/provide-hidden-abs.nd b/ld/testsuite/ld-elf/provide-hidden-abs.nd
new file mode 100644
index 0000000..642a7a0
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-abs.nd
@@ -0,0 +1,5 @@
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +ABS foo
+#pass
diff --git a/ld/testsuite/ld-elf/provide-hidden-def.nd b/ld/testsuite/ld-elf/provide-hidden-def.nd
new file mode 100644
index 0000000..d4355c8
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-def.nd
@@ -0,0 +1,5 @@
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*12300000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +[0-9]+ foo
+#pass
diff --git a/ld/testsuite/ld-elf/provide-hidden-dyn.nd b/ld/testsuite/ld-elf/provide-hidden-dyn.nd
new file mode 100644
index 0000000..230f7fd
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-dyn.nd
@@ -0,0 +1,7 @@
+#failif
+Symbol table '\.dynsym' contains [0-9]+ entries:
+#...
+.* foo
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+#pass
diff --git a/ld/testsuite/ld-elf/provide-hidden-dynabs.nd b/ld/testsuite/ld-elf/provide-hidden-dynabs.nd
new file mode 100644
index 0000000..86e3adc
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-dynabs.nd
@@ -0,0 +1,8 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +ABS foo
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +ABS foo
+#pass
diff --git a/ld/testsuite/ld-elf/provide-hidden-dynsec.nd b/ld/testsuite/ld-elf/provide-hidden-dynsec.nd
new file mode 100644
index 0000000..716dfa1
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-dynsec.nd
@@ -0,0 +1,8 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +[0-9]+ foo
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +[0-9]+ foo
+#pass
diff --git a/ld/testsuite/ld-elf/provide-hidden-s.ld b/ld/testsuite/ld-elf/provide-hidden-s.ld
new file mode 100644
index 0000000..cca804f
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-s.ld
@@ -0,0 +1,11 @@
+SECTIONS
+{
+  . = 0x12300000;
+  .data : { *(.data) }
+  .got : { *(.got) }
+  .interp : { *(.interp) }
+  .dynsym : { *(.dynsym) }
+  .dynstr : { *(.dynstr) }
+  .dynamic : { *(.dynamic) }
+  .hash : { *(.hash) }
+}
diff --git a/ld/testsuite/ld-elf/provide-hidden-s.nd b/ld/testsuite/ld-elf/provide-hidden-s.nd
new file mode 100644
index 0000000..4fd2cc5
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-s.nd
@@ -0,0 +1,8 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*12300000 +0 (?:NOTYPE|OBJECT) +GLOBAL +DEFAULT +[0-9]+ foo
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*12300000 +0 (?:NOTYPE|OBJECT) +GLOBAL +DEFAULT +[0-9]+ foo
+#pass
diff --git a/ld/testsuite/ld-elf/provide-hidden-sec.nd b/ld/testsuite/ld-elf/provide-hidden-sec.nd
new file mode 100644
index 0000000..f155d66
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-sec.nd
@@ -0,0 +1,5 @@
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +[0-9]+ foo
+#pass
diff --git a/ld/testsuite/ld-elf/provide-hidden.exp b/ld/testsuite/ld-elf/provide-hidden.exp
new file mode 100644
index 0000000..7246d11
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden.exp
@@ -0,0 +1,154 @@
+# Expect script for the PROVIDE_HIDDEN linker script command.
+#
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+#
+# Written by Maciej W. Rozycki <macro@codesourcery.com>
+#
+
+# Export classes only make sense for ELF shared-library targets.
+if { ![is_elf_format] || ![check_shared_lib_support] } {
+    return
+}
+
+# This target requires extra GAS options when building code for shared
+# libraries.
+set AFLAGS_PIC ""
+if [istarget "tic6x-*-*"] {
+    append AFLAGS_PIC " -mpic -mpid=near"
+}
+
+set testname "PROVIDE_HIDDEN test"
+
+run_ld_link_tests [list \
+    [list \
+	"$testname (auxiliary shared object)" \
+	"-shared -T provide-hidden-s.ld" "" \
+	"$AFLAGS_PIC" \
+	[list provide-hidden-1.s ] \
+	[list "readelf -s provide-hidden-s.nd"] \
+	"provide-hidden-s.so"]]
+
+run_ld_link_tests [list \
+    [list \
+	"$testname 1" \
+	"-T provide-hidden-1.ld" "" \
+	"" \
+	[list provide-hidden-1.s] \
+	[list \
+	    [list readelf -s provide-hidden-def.nd] \
+	    [list readelf -s provide-hidden-dyn.nd]] \
+	"provide-hidden-1"] \
+    [list \
+	"$testname 2" \
+	"-T provide-hidden-1.ld" "" \
+	"" \
+	[list provide-hidden-2.s] \
+	[list \
+	    [list readelf -s provide-hidden-def.nd] \
+	    [list readelf -s provide-hidden-dyn.nd]] \
+	"provide-hidden-2"] \
+    [list \
+	"$testname 3" \
+	"-T provide-hidden-1.ld" "" \
+	"" \
+	[list provide-hidden-3.s] \
+	[list \
+	    [list readelf -s provide-hidden-sec.nd] \
+	    [list readelf -s provide-hidden-dyn.nd]] \
+	"provide-hidden-3"] \
+    [list \
+	"$testname 4" \
+	"-T provide-hidden-1.ld" "tmpdir/provide-hidden-s.so" \
+	"" \
+	[list provide-hidden-3.s] \
+	[list "readelf -s provide-hidden-dynsec.nd"] \
+	"provide-hidden-4"] \
+    [list \
+	"$testname 5" \
+	"-T provide-hidden-1.ld" "" \
+	"" \
+	[list provide-hidden-4.s] \
+	[list \
+	    [list readelf -s provide-hidden-sec.nd] \
+	    [list readelf -s provide-hidden-dyn.nd]] \
+	"provide-hidden-5"] \
+    [list \
+	"$testname 6" \
+	"-T provide-hidden-1.ld" "tmpdir/provide-hidden-s.so" \
+	"" \
+	[list provide-hidden-4.s] \
+	[list \
+	    [list readelf -s provide-hidden-sec.nd] \
+	    [list readelf -s provide-hidden-dyn.nd]] \
+	"provide-hidden-6"] \
+    [list \
+	"$testname 7" \
+	"-T provide-hidden-2.ld" "" \
+	"" \
+	[list provide-hidden-1.s] \
+	[list \
+	    [list readelf -s provide-hidden-def.nd] \
+	    [list readelf -s provide-hidden-dyn.nd]] \
+	"provide-hidden-7"] \
+    [list \
+	"$testname 8" \
+	"-T provide-hidden-2.ld" "" \
+	"" \
+	[list provide-hidden-2.s] \
+	[list \
+	    [list readelf -s provide-hidden-def.nd] \
+	    [list readelf -s provide-hidden-dyn.nd]] \
+	"provide-hidden-8"] \
+    [list \
+	"$testname 9" \
+	"-T provide-hidden-2.ld" "" \
+	"" \
+	[list provide-hidden-3.s] \
+	[list \
+	    [list readelf -s provide-hidden-abs.nd] \
+	    [list readelf -s provide-hidden-dyn.nd]] \
+	"provide-hidden-9"] \
+    [list \
+	"$testname 10" \
+	"-T provide-hidden-2.ld" "tmpdir/provide-hidden-s.so" \
+	"" \
+	[list provide-hidden-3.s] \
+	[list "readelf -s provide-hidden-dynabs.nd"] \
+	"provide-hidden-10"] \
+    [list \
+	"$testname 11" \
+	"-T provide-hidden-2.ld" "" \
+	"" \
+	[list provide-hidden-4.s] \
+	[list \
+	    [list readelf -s provide-hidden-abs.nd] \
+	    [list readelf -s provide-hidden-dyn.nd]] \
+	"provide-hidden-11"] \
+    [list \
+	"$testname 12" \
+	"-T provide-hidden-2.ld" "tmpdir/provide-hidden-s.so" \
+	"" \
+	[list provide-hidden-4.s] \
+	[list \
+	    [list readelf -s provide-hidden-abs.nd] \
+	    [list readelf -s provide-hidden-dyn.nd]] \
+	"provide-hidden-12"]]
diff --git a/ld/testsuite/ld-elf/sec64k.exp b/ld/testsuite/ld-elf/sec64k.exp
index 7c04c9b..7c9f292 100644
--- a/ld/testsuite/ld-elf/sec64k.exp
+++ b/ld/testsuite/ld-elf/sec64k.exp
@@ -34,6 +34,7 @@
      || [istarget "d30v-*-*"]
      || [istarget "dlx-*-*"]
      || [istarget "i960-*-*"]
+     || [istarget "msp430*-*-*"]
      || [istarget "or32-*-*"]
      || [istarget "pj*-*-*"]
      || [istarget "m32r-*-*"] } {
diff --git a/ld/testsuite/ld-gc/pr13683.d b/ld/testsuite/ld-gc/pr13683.d
index 19b2598..b38b9d1 100644
--- a/ld/testsuite/ld-gc/pr13683.d
+++ b/ld/testsuite/ld-gc/pr13683.d
@@ -2,7 +2,7 @@
 #source: dummy.s
 #ld: --gc-sections -e main --defsym foo=foo2 tmpdir/pr13683.o
 #nm: --format=bsd
-#xfail: sh64*-*-* iq2000-*-* lm32-*-* epiphany-*-* mips64vr-*-* frv-*-* m32c-*-* rl78-*-* rx-*-* sh-*-* powerpc*-*-eabivle
+#xfail: sh64*-*-* iq2000-*-* lm32-*-* epiphany-*-* mips64vr-*-* frv-*-* m32c-*-* rl78-*-* rx-*-* sh-*-* powerpc*-*-eabivle msp430-*-*
 
 # Note - look for both "foo" and "foo2" being defined, non-zero function symbols
 
diff --git a/ld/testsuite/ld-mips-elf/ehdr_start-1.ld b/ld/testsuite/ld-mips-elf/ehdr_start-1.ld
new file mode 100644
index 0000000..0485b05
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ehdr_start-1.ld
@@ -0,0 +1,9 @@
+ENTRY (__start)
+SECTIONS
+{
+  . = 0x12300000 + SIZEOF_HEADERS;
+  .text : { *(.text) }
+  . = 0x23400000;
+  HIDDEN (_gp = ALIGN (16) + 0x7ff0);
+  .got : { *(.got) }
+}
diff --git a/ld/testsuite/ld-mips-elf/ehdr_start-1.nd b/ld/testsuite/ld-mips-elf/ehdr_start-1.nd
new file mode 100644
index 0000000..9496b7d
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ehdr_start-1.nd
@@ -0,0 +1,4 @@
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*12300000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +[0-9]+ __ehdr_start
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ehdr_start-2.ld b/ld/testsuite/ld-mips-elf/ehdr_start-2.ld
new file mode 100644
index 0000000..5d5e183
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ehdr_start-2.ld
@@ -0,0 +1,10 @@
+ENTRY (__start)
+SECTIONS
+{
+  . = 0x12300000 + SIZEOF_HEADERS;
+  .text : { *(.text) }
+  . = 0x23400000;
+  __ehdr_start = .;
+  HIDDEN (_gp = ALIGN (16) + 0x7ff0);
+  .got : { *(.got) }
+}
diff --git a/ld/testsuite/ld-mips-elf/ehdr_start-2.nd b/ld/testsuite/ld-mips-elf/ehdr_start-2.nd
new file mode 100644
index 0000000..986c2a2
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ehdr_start-2.nd
@@ -0,0 +1,4 @@
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +[0-9]+ __ehdr_start
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ehdr_start-new.s b/ld/testsuite/ld-mips-elf/ehdr_start-new.s
new file mode 100644
index 0000000..5ee00dc
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ehdr_start-new.s
@@ -0,0 +1,13 @@
+	.abicalls
+	.text
+	.weak	__ehdr_start
+	.globl	__start
+	.ent	__start
+	.frame	$29, 0, $31
+	.mask	0x00000000, 0
+__start:
+	.cplocal $2
+	.cpsetup $t9, $zero, __start
+	lw	$2, __ehdr_start
+	jr	$31
+	.end	__start
diff --git a/ld/testsuite/ld-mips-elf/ehdr_start-o32.s b/ld/testsuite/ld-mips-elf/ehdr_start-o32.s
new file mode 100644
index 0000000..0973447
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ehdr_start-o32.s
@@ -0,0 +1,14 @@
+	.abicalls
+	.text
+	.weak	__ehdr_start
+	.globl	__start
+	.ent	__start
+	.frame	$29, 0, $31
+	.mask	0x00000000, 0
+__start:
+	.set	noreorder
+	.cpload	$25
+	.set	reorder
+	lw	$2, __ehdr_start
+	jr	$31
+	.end	__start
diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp
index 902ae00..97e0c2c 100644
--- a/ld/testsuite/ld-mips-elf/mips-elf.exp
+++ b/ld/testsuite/ld-mips-elf/mips-elf.exp
@@ -709,3 +709,28 @@
 		"readelf -A export-class-call16-${abi}.gd"] \
 	    "export-class-call16-${abi}.so"]]
 }
+
+# Magic __ehdr_start symbol tests.
+set abis [concat o32 [expr {$has_newabi ? "n32 n64" : ""}]]
+foreach { abi } $abis {
+    set suff [string map {o32 o32 n32 new n64 new} $abi]
+    run_ld_link_tests [list \
+        [list \
+            "MIPS magic __ehdr_start symbol test 1 ($abi)" \
+            "$abi_ldflags($abi) -T ehdr_start-1.ld" "" \
+            "$abi_asflags($abi)" \
+            [list ehdr_start-${suff}.s] \
+            [list "readelf -s ehdr_start-1.nd"] \
+            "ehdr_start-1-${abi}"]]
+    if [regexp "(?:n32|n64)" "$abi"] {
+	setup_kfail "mips*-*-*" "ld/15428"
+    }
+    run_ld_link_tests [list \
+        [list \
+            "MIPS magic __ehdr_start symbol test 2 ($abi)" \
+            "$abi_ldflags($abi) -T ehdr_start-2.ld" "" \
+            "$abi_asflags($abi)" \
+            [list ehdr_start-${suff}.s] \
+            [list "readelf -s ehdr_start-2.nd"] \
+            "ehdr_start-2-${abi}"]]
+}
diff --git a/ld/testsuite/ld-plugin/pr12982.d b/ld/testsuite/ld-plugin/pr12982.d
index f536d5b..9b01a58 100644
--- a/ld/testsuite/ld-plugin/pr12982.d
+++ b/ld/testsuite/ld-plugin/pr12982.d
@@ -1,3 +1,4 @@
+#failif
 #...
-[ \t]+GNU_STACK[ \t]+0x[0-9a-f]+ +0x[0-9a-f]+ +0x[0-9a-f]+ +0x[0-9a-f]+ +0x[0-9a-f]+ +RW +0x[0-9a-f]+
+ +GNU_STACK .* RWE .*
 #pass
diff --git a/ld/testsuite/ld-powerpc/aix-core-sec-1.hd b/ld/testsuite/ld-powerpc/aix-core-sec-1.hd
index 19d09e4..8d81e50 100644
--- a/ld/testsuite/ld-powerpc/aix-core-sec-1.hd
+++ b/ld/testsuite/ld-powerpc/aix-core-sec-1.hd
@@ -8,4 +8,4 @@
  * 2 * \.bss * 0+0 .*
  * ALLOC
  * 3 * \.loader .*
- * CONTENTS, ALLOC, LOAD
+ * CONTENTS, LOAD
diff --git a/ld/testsuite/ld-powerpc/aix-core-sec-2.hd b/ld/testsuite/ld-powerpc/aix-core-sec-2.hd
index 39facd8..1152013 100644
--- a/ld/testsuite/ld-powerpc/aix-core-sec-2.hd
+++ b/ld/testsuite/ld-powerpc/aix-core-sec-2.hd
@@ -8,4 +8,4 @@
  * 2 * \.bss * 0+0 .*
  * ALLOC
  * 3 * \.loader .*
- * CONTENTS, ALLOC, LOAD
+ * CONTENTS, LOAD
diff --git a/ld/testsuite/ld-powerpc/aix-core-sec-3.hd b/ld/testsuite/ld-powerpc/aix-core-sec-3.hd
index f7acc39..61a93ae 100644
--- a/ld/testsuite/ld-powerpc/aix-core-sec-3.hd
+++ b/ld/testsuite/ld-powerpc/aix-core-sec-3.hd
@@ -8,4 +8,4 @@
  * 2 * \.bss * 0+8 .*
  * ALLOC
  * 3 * \.loader .*
- * CONTENTS, ALLOC, LOAD
+ * CONTENTS, LOAD
diff --git a/ld/testsuite/ld-powerpc/export-class.exp b/ld/testsuite/ld-powerpc/export-class.exp
index 5b721fc..6171d13 100644
--- a/ld/testsuite/ld-powerpc/export-class.exp
+++ b/ld/testsuite/ld-powerpc/export-class.exp
@@ -30,22 +30,11 @@
     return
 }
 
-proc supports_ppc64 { } {
-    global ld
+proc powerpc_export_class_test { abi endian emul } {
 
-    catch "exec $ld --help | grep emulations" tmp
-    if [string match "*elf64ppc*" $tmp] then {
-	return 1
-    } else {
-	return 0
-    }
-}
+    set testname "PowerPC $abi $endian symbol export class test"
 
-proc powerpc_export_class_test { abi emul } {
-
-    set testname "PowerPC $abi symbol export class test"
-
-    set AFLAGS "-a$abi -be"
+    set AFLAGS "-a$abi -$endian"
     set LDFLAGS "-m$emul"
 
     # Build an auxiliary shared object with conflicting versioned symbol
@@ -96,11 +85,13 @@
     ]
 }
 
-if { [supports_ppc64] } {
-    set abis { 32 elf32ppclinux 64 elf64ppc }
-} else {
-    set abis { 32 elf32ppclinux }
-}
-foreach { abi emul } $abis {
-    powerpc_export_class_test $abi $emul
+set abis { 32 be elf32ppclinux 32 le elf32lppclinux 64 be elf64ppc 64 le elf64lppc }
+
+global ld
+catch "exec $ld --help | grep emulations" ldemul
+
+foreach { abi endian emul } $abis {
+    if { [string first $emul $ldemul] != -1 } then {
+	powerpc_export_class_test $abi $endian $emul
+    }
 }
diff --git a/ld/testsuite/ld-powerpc/powerpc-64-export-class.xd b/ld/testsuite/ld-powerpc/powerpc-64-export-class.xd
index d0388ad..264803c 100644
--- a/ld/testsuite/ld-powerpc/powerpc-64-export-class.xd
+++ b/ld/testsuite/ld-powerpc/powerpc-64-export-class.xd
@@ -1,11 +1,11 @@
 Hex dump of section '\.data':
-  0x12340000 00000000 123400a0 00000000 00000000 .*
-  0x12340010 00000000 123400a0 00000000 00000000 .*
-  0x12340020 00000000 123400a0 00000000 00000000 .*
-  0x12340030 00000000 00000000 00000000 00000000 .*
-  0x12340040 00000000 123400a0 00000000 00000000 .*
-  0x12340050 00000000 123400a0 00000000 00000000 .*
-  0x12340060 00000000 123400a0 00000000 00000000 .*
-  0x12340070 00000000 123400a0 00000000 00000000 .*
-  0x12340080 00000000 123400a0 00000000 00000000 .*
-  0x12340090 00000000 123400a0 00000000 00000000 .*
+  0x12340000 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+  0x12340010 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+  0x12340020 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+  0x12340030 (00000000|00000000) (00000000|00000000) 00000000 00000000 .*
+  0x12340040 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+  0x12340050 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+  0x12340060 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+  0x12340070 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+  0x12340080 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+  0x12340090 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
diff --git a/ld/testsuite/ld-srec/srec.exp b/ld/testsuite/ld-srec/srec.exp
index 001fb2e..4a433d1 100644
--- a/ld/testsuite/ld-srec/srec.exp
+++ b/ld/testsuite/ld-srec/srec.exp
@@ -1,7 +1,6 @@
 # Test linking directly to S-records.
 # By Ian Lance Taylor, Cygnus Support.
-#   Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009, 2011, 2012
-#   Free Software Foundation, Inc.
+#   Copyright 1999-2013 Free Software Foundation, Inc.
 #
 # This file is part of the GNU Binutils.
 #
@@ -269,6 +268,11 @@
 	set flags "$flags -no-relax"
     }
 
+    # MSP430 targets always relax.
+    if [istarget msp430*-*-*] {
+	setup_xfail "msp430*-*-*"
+    }
+
     # Epiphany needs some help too
     if [istarget epiphany*-*-*] {
 	set flags "$flags --defsym _start=00000060"
diff --git a/ld/testsuite/ld-undefined/undefined.exp b/ld/testsuite/ld-undefined/undefined.exp
index 65fbc4b..49af737 100644
--- a/ld/testsuite/ld-undefined/undefined.exp
+++ b/ld/testsuite/ld-undefined/undefined.exp
@@ -128,6 +128,11 @@
 setup_xfail mep-*-*
 setup_xfail mips-sgi-irix6*
 setup_xfail "sh64-*-*"
+# Fails for the MSP430 because it uses SYM_DIFF relocs but it does
+# not provide a special_function for handling them.  If optimization
+# is enabled then this test passes because function()'s prologue is
+# eliminated.
+setup_xfail "msp430-*-*"
 
 # The undefined test fails on 31 bit s/390 because the address of the 
 # function `this_function_is_not_defined' is stored in the literal pool of
diff --git a/ld/testsuite/lib/ld-lib.exp b/ld/testsuite/lib/ld-lib.exp
index 4b88093..ffbfd8b 100644
--- a/ld/testsuite/lib/ld-lib.exp
+++ b/ld/testsuite/lib/ld-lib.exp
@@ -1565,7 +1565,7 @@
 	 && ![istarget arm*-*-elf]
 	 && ![istarget avr-*-*]
 	 && ![istarget cr16-*-*]
-	 && ![istarget cris*-*-*]
+	 && ![istarget cris*-*-elf]
 	 && ![istarget crx-*-*]
 	 && ![istarget d10v-*-*]
 	 && ![istarget d30v-*-*]
@@ -1587,6 +1587,7 @@
 	 && ![istarget mcore*-*-*]
 	 && ![istarget mep-*-*]
 	 && ![istarget microblaze-*-*]
+	 && ![istarget mips*-*-elf]
 	 && ![istarget mn10200-*-*]
 	 && ![istarget moxie-*-*]
 	 && ![istarget msp430-*-*]
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 1420ad4..a30a363 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,11 @@
+2013-05-06  David Edelsohn  <dje.gcc@gmail.com>
+	    Peter Bergner  <bergner@vnet.ibm.com>
+	    Segher Boessenkool  <segher@kernel.crashing.org>
+	    Jakub Jelinek  <jakub@redhat.com>
+
+	* hashtab.c (hash_pointer): Remove conditional and avoid
+	unexecuted shift equal to wordsize.
+
 2013-04-22  Andi Kleen <ak@linux.intel.com>
 
 	* hashtab.c (hash_pointer): Move to end of file and reimplement.
diff --git a/libiberty/hashtab.c b/libiberty/hashtab.c
index a2fe3ee..04607ea 100644
--- a/libiberty/hashtab.c
+++ b/libiberty/hashtab.c
@@ -990,17 +990,8 @@
   unsigned a, b, c;
 
   a = b = 0x9e3779b9;
-  if (sizeof (intptr_t) == 4) 
-    {
-      /* Mix as 16bit for now */
-      a += v >> 16;
-      b += v & 0xffff;
-    }
-  else
-    {
-      a += v >> 32;
-      b += v & 0xffffffff;
-    }
+  a += v >> (sizeof (intptr_t) * CHAR_BIT / 2);
+  b += v & (((intptr_t) 1 << (sizeof (intptr_t) * CHAR_BIT / 2)) - 1);
   c = 0x42135234;
   mix (a, b, c);
   return c;
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 2912765..eb16b0a 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,76 @@
+2013-05-23  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
+	* s390-opc.c: Fix length operand in RSL_LRDFU and RSL_LRDFEU
+	instruction format.
+
+2013-05-22  Jürgen Urban  <JuergenUrban@gmx.de>
+
+	* mips-opc.c (mips_builtin_opcodes): Add R5900 VU0 instructions.
+
+2013-05-20  Peter Bergner <bergner@vnet.ibm.com>
+
+	* ppc-dis.c (powerpc_init_dialect): Set default dialect to power8.
+	* ppc-opc.c (BHRBE, ST, SIX, PS, SXL, VXPS_MASK, XX1RB_MASK,
+	XLS_MASK, PPCVSX2): New defines.
+	(powerpc_opcodes) <bcdadd., bcdsub., bctar, bctar, bctarl, clrbhrb,
+	fmrgew, fmrgow, lqarx, lxsiwax, lxsiwzx, lxsspx, mfbhrbe,
+	mffprd, mffprwz, mfvrd, mfvrwz, mfvsrd, mfvsrwz, msgclrp, msgsndp,
+	mtfprd, mtfprwa, mtfprwz, mtsle, mtvrd, mtvrwa, mtvrwz, mtvsrd,
+	mtvsrwa, mtvsrwz, pbt., rfebb, stqcx., stxsiwx, stxsspx,
+	vaddcuq, vaddecuq, vaddeuqm, vaddudm, vadduqm, vbpermq, vcipher,
+	vcipherlast, vclzb, vclzd, vclzh, vclzw, vcmpequd, vcmpequd.,
+	vcmpgtsd, vcmpgtsd., vcmpgtud, vcmpgtud., veqv, vgbbd, vmaxsd,
+	vmaxud, vminsd, vminud, vmrgew, vmrgow, vmulesw, vmuleuw, vmulosw,
+	vmulouw, vmuluwm, vnand, vncipher, vncipherlast, vorc, vpermxor,
+	vpksdss, vpksdus, vpkudum, vpkudus, vpmsumb, vpmsumd, vpmsumh,
+	vpmsumw, vpopcntb, vpopcntd, vpopcnth, vpopcntw, vrld, vsbox,
+	vshasigmad, vshasigmaw, vsld, vsrad, vsrd, vsubcuq, vsubecuq,
+	vsubeuqm, vsubudm, vsubuqm, vupkhsw, vupklsw, waitasec, xsaddsp,
+	xscvdpspn, xscvspdpn, xscvsxdsp, xscvuxdsp, xsdivsp, xsmaddasp,
+	xsmaddmsp, xsmsubasp, xsmsubmsp, xsmulsp, xsnmaddasp, xsnmaddmsp,
+	xsnmsubasp, xsnmsubmsp, xsresp, xsrsp, xsrsqrtesp, xssqrtsp,
+	xssubsp, xxleqv, xxlnand, xxlorc>: New instructions.
+	<lxvx, stxvx>: New extended mnemonics.
+
+2013-05-17  Alan Modra  <amodra@gmail.com>
+
+	* ia64-raw.tbl: Replace non-ASCII char.
+	* ia64-waw.tbl: Likewise.
+	* ia64-asmtab.c: Regenerate.
+
+2013-05-15  Saravanan Ekanathan <saravanan.ekanathan@amd.com>
+
+	* i386-gen.c (cpu_flag_init): Add CpuFSGSBase in CPU_BDVER3_FLAGS.
+	* i386-init.h: Regenerated.
+
+2013-05-13  Yufeng Zhang  <yufeng.zhang@arm.com>
+
+	* aarch64-asm.c (aarch64_ins_advsimd_imm_modified): Remove assertion.
+	* aarch64-opc.c (operand_general_constraint_met_p): Relax the range
+	check from [0, 255] to [-128, 255].
+
+2013-05-09  Andrew Pinski  <apinski@cavium.com>
+
+	* mips-dis.c (mips_arch_choices): Add INSN_VIRT to mips32r2.
+	Add INSN_VIRT and INSN_VIRT64 to mips64r2.
+	(parse_mips_dis_option): Handle the virt option.
+	(print_insn_args): Handle "+J".
+	(print_mips_disassembler_options): Print out message about virt64.
+	* mips-opc.c (IVIRT): New define.
+	(IVIRT64): New define.
+	(mips_builtin_opcodes): Add dmfgc0, dmtgc0, hypcall, mfgc0, mtgc0,
+	tlbgr, tlbgwi, tlbginv, tlbginvf, tlbgwr, tlbgp VIRT instructions.
+	Move rfe to the bottom as it conflicts with tlbgp.
+
+2013-05-09  Alan Modra  <amodra@gmail.com>
+
+	* ppc-opc.c (extract_vlesi): Properly sign extend.
+	(extract_vlensi): Likewise.  Comment reason for setting invalid.
+
+2013-05-02  Nick Clifton  <nickc@redhat.com>
+
+	* msp430-dis.c: Add support for MSP430X instructions.
+
 2013-04-24  Sandra Loosemore  <sandra@codesourcery.com>
 
 	* nios2-opc.c (nios2_builtin_reg): Rename "fstatus" control register
diff --git a/opcodes/aarch64-asm.c b/opcodes/aarch64-asm.c
index 7a92b49..96396e8 100644
--- a/opcodes/aarch64-asm.c
+++ b/opcodes/aarch64-asm.c
@@ -370,7 +370,6 @@
       imm = aarch64_shrink_expanded_imm8 (imm);
       assert ((int)imm >= 0);
     }
-  assert (imm <= 255);
   insert_fields (code, imm, 0, 2, FLD_defgh, FLD_abc);
 
   if (kind == AARCH64_MOD_NONE)
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index b7b1b4a..74f2826 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -1724,10 +1724,10 @@
 	  assert (idx == 1);
 	  if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
 	    {
-	      /* uimm8 */
-	      if (!value_in_range_p (opnd->imm.value, 0, 255))
+	      /* uimm8 or simm8 */
+	      if (!value_in_range_p (opnd->imm.value, -128, 255))
 		{
-		  set_imm_out_of_range_error (mismatch_detail, idx, 0, 255);
+		  set_imm_out_of_range_error (mismatch_detail, idx, -128, 255);
 		  return 0;
 		}
 	    }
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index 3e7481b..7aff3fa 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -93,7 +93,7 @@
   { "CPU_BDVER2_FLAGS",
     "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
   { "CPU_BDVER3_FLAGS",
-    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt" },
+    "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt|CpuFSGSBase" },
   { "CPU_BTVER1_FLAGS",
     "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuABM|CpuLM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
   { "CPU_BTVER2_FLAGS",
diff --git a/opcodes/i386-init.h b/opcodes/i386-init.h
index 3d48411..d5b9c15 100644
--- a/opcodes/i386-init.h
+++ b/opcodes/i386-init.h
@@ -172,7 +172,7 @@
 #define CPU_BDVER3_FLAGS \
   { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1,  \
       0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,  \
-      1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1,  \
+      1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1,  \
       0, 0, 0, 0 } }
 
 #define CPU_BTVER1_FLAGS \
diff --git a/opcodes/ia64-asmtab.c b/opcodes/ia64-asmtab.c
index f17dc91..92e958c 100644
--- a/opcodes/ia64-asmtab.c
+++ b/opcodes/ia64-asmtab.c
@@ -102,7 +102,7 @@
   { "CPUID#", 7, 0, 5, -1, NULL, },
   { "CR[CMCV]", 29, 0, 3, 74, NULL, },
   { "CR[DCR]", 29, 0, 3, 0, NULL, },
-  { "CR[EOI]", 29, 0, 7, 67, "SC Section 5.8.3.4, \"End of External Interrupt Register (EOI Ð CR67)\" on page 2:119", },
+  { "CR[EOI]", 29, 0, 7, 67, "SC Section 5.8.3.4, \"End of External Interrupt Register (EOI - CR67)\" on page 2:119", },
   { "CR[GPTA]", 29, 0, 3, 9, NULL, },
   { "CR[IFA]", 29, 0, 1, 20, NULL, },
   { "CR[IFA]", 29, 0, 3, 20, NULL, },
@@ -124,13 +124,13 @@
   { "CR[ITM]", 29, 0, 3, 1, NULL, },
   { "CR[ITV]", 29, 0, 3, 72, NULL, },
   { "CR[IVA]", 29, 0, 4, 2, NULL, },
-  { "CR[IVR]", 29, 0, 7, 65, "SC Section 5.8.3.2, \"External Interrupt Vector Register (IVR Ð CR65)\" on page 2:118", },
-  { "CR[LID]", 29, 0, 7, 64, "SC Section 5.8.3.1, \"Local ID (LID Ð CR64)\" on page 2:117", },
+  { "CR[IVR]", 29, 0, 7, 65, "SC Section 5.8.3.2, \"External Interrupt Vector Register (IVR - CR65)\" on page 2:118", },
+  { "CR[LID]", 29, 0, 7, 64, "SC Section 5.8.3.1, \"Local ID (LID - CR64)\" on page 2:117", },
   { "CR[LRR%], % in 0 - 1", 10, 0, 3, -1, NULL, },
   { "CR[PMV]", 29, 0, 3, 73, NULL, },
   { "CR[PTA]", 29, 0, 3, 8, NULL, },
   { "CR[TPR]", 29, 0, 3, 66, NULL, },
-  { "CR[TPR]", 29, 0, 7, 66, "SC Section 5.8.3.3, \"Task Priority Register (TPR Ð CR66)\" on page 2:119", },
+  { "CR[TPR]", 29, 0, 7, 66, "SC Section 5.8.3.3, \"Task Priority Register (TPR - CR66)\" on page 2:119", },
   { "CR[TPR]", 29, 0, 1, 66, NULL, },
   { "CR%, % in 3-7, 10-15, 18, 28-63, 75-79, 82-127", 11, 0, 0, -1, NULL, },
   { "DAHR%, % in 0-7", 12, 0, 1, -1, NULL, },
@@ -305,7 +305,7 @@
   { "CPUID#", 7, 1, 0, -1, NULL, },
   { "CR[CMCV]", 29, 1, 2, 74, NULL, },
   { "CR[DCR]", 29, 1, 2, 0, NULL, },
-  { "CR[EOI]", 29, 1, 7, 67, "SC Section 5.8.3.4, \"End of External Interrupt Register (EOI Ð CR67)\" on page 2:119", },
+  { "CR[EOI]", 29, 1, 7, 67, "SC Section 5.8.3.4, \"End of External Interrupt Register (EOI - CR67)\" on page 2:119", },
   { "CR[GPTA]", 29, 1, 2, 9, NULL, },
   { "CR[IFA]", 29, 1, 2, 20, NULL, },
   { "CR[IFS]", 29, 1, 2, 23, NULL, },
diff --git a/opcodes/ia64-raw.tbl b/opcodes/ia64-raw.tbl
index 88d6ec5..1dcb908 100644
--- a/opcodes/ia64-raw.tbl
+++ b/opcodes/ia64-raw.tbl
@@ -45,7 +45,7 @@
 CPUID#;	IC:none;	IC:mov-from-IND-CPUID+3;	specific
 CR[CMCV];	IC:mov-to-CR-CMCV;	IC:mov-from-CR-CMCV;	data
 CR[DCR];	IC:mov-to-CR-DCR;	IC:mov-from-CR-DCR, IC:mem-readers-spec;	data
-CR[EOI];	IC:mov-to-CR-EOI;	IC:none;	SC Section 5.8.3.4, "End of External Interrupt Register (EOI Ð CR67)" on page 2:119
+CR[EOI];	IC:mov-to-CR-EOI;	IC:none;	SC Section 5.8.3.4, "End of External Interrupt Register (EOI - CR67)" on page 2:119
 CR[GPTA];	IC:mov-to-CR-GPTA;	IC:mov-from-CR-GPTA, thash;	data
 CR[IFA];	IC:mov-to-CR-IFA;	itc.i, itc.d, itr.i, itr.d;	implied
 CR[IFA];	IC:mov-to-CR-IFA;	IC:mov-from-CR-IFA;	data
@@ -67,13 +67,13 @@
 CR[ITM];	IC:mov-to-CR-ITM;	IC:mov-from-CR-ITM;	data
 CR[ITV];	IC:mov-to-CR-ITV;	IC:mov-from-CR-ITV;	data
 CR[IVA];	IC:mov-to-CR-IVA;	IC:mov-from-CR-IVA;	instr
-CR[IVR];	IC:none;	IC:mov-from-CR-IVR;	SC Section 5.8.3.2, "External Interrupt Vector Register (IVR Ð CR65)" on page 2:118
-CR[LID];	IC:mov-to-CR-LID;	IC:mov-from-CR-LID;	SC Section 5.8.3.1, "Local ID (LID Ð CR64)" on page 2:117
+CR[IVR];	IC:none;	IC:mov-from-CR-IVR;	SC Section 5.8.3.2, "External Interrupt Vector Register (IVR - CR65)" on page 2:118
+CR[LID];	IC:mov-to-CR-LID;	IC:mov-from-CR-LID;	SC Section 5.8.3.1, "Local ID (LID - CR64)" on page 2:117
 CR[LRR%], % in 0 - 1;	IC:mov-to-CR-LRR+1;	IC:mov-from-CR-LRR+1;	data
 CR[PMV];	IC:mov-to-CR-PMV;	IC:mov-from-CR-PMV;	data
 CR[PTA];	IC:mov-to-CR-PTA;	IC:mov-from-CR-PTA, IC:mem-readers, IC:mem-writers, IC:non-access, thash;	data
 CR[TPR];	IC:mov-to-CR-TPR;	IC:mov-from-CR-TPR, IC:mov-from-CR-IVR;	data
-CR[TPR];	IC:mov-to-CR-TPR;	IC:mov-to-PSR-l+17, ssm+17;	SC Section 5.8.3.3, "Task Priority Register (TPR Ð CR66)" on page 2:119
+CR[TPR];	IC:mov-to-CR-TPR;	IC:mov-to-PSR-l+17, ssm+17;	SC Section 5.8.3.3, "Task Priority Register (TPR - CR66)" on page 2:119
 CR[TPR];	IC:mov-to-CR-TPR;	rfi;	implied
 CR%, % in 3-7, 10-15, 18, 28-63, 75-79, 82-127;	IC:none;	IC:mov-from-CR-rv+1;	none
 DAHR%, % in 0-7;	br.call, brl.call, br.ret, IC:mov-to-DAHR;	br.call, IC:mem-readers, IC:mem-writers, IC:mov-from-DAHR;	implied
diff --git a/opcodes/ia64-waw.tbl b/opcodes/ia64-waw.tbl
index 44efaa8..6fe9a84 100644
--- a/opcodes/ia64-waw.tbl
+++ b/opcodes/ia64-waw.tbl
@@ -44,7 +44,7 @@
 CPUID#;	IC:none;	IC:none;	none
 CR[CMCV];	IC:mov-to-CR-CMCV;	IC:mov-to-CR-CMCV;	impliedF
 CR[DCR];	IC:mov-to-CR-DCR;	IC:mov-to-CR-DCR;	impliedF
-CR[EOI];	IC:mov-to-CR-EOI;	IC:mov-to-CR-EOI;	SC Section 5.8.3.4, "End of External Interrupt Register (EOI Ð CR67)" on page 2:119
+CR[EOI];	IC:mov-to-CR-EOI;	IC:mov-to-CR-EOI;	SC Section 5.8.3.4, "End of External Interrupt Register (EOI - CR67)" on page 2:119
 CR[GPTA];	IC:mov-to-CR-GPTA;	IC:mov-to-CR-GPTA;	impliedF
 CR[IFA];	IC:mov-to-CR-IFA;	IC:mov-to-CR-IFA;	impliedF
 CR[IFS];	IC:mov-to-CR-IFS, cover;	IC:mov-to-CR-IFS, cover;	impliedF
diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
index 018ac94..834fd5c 100644
--- a/opcodes/mips-dis.c
+++ b/opcodes/mips-dis.c
@@ -590,7 +590,7 @@
 
   { "mips32r2",	1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
     (ISA_MIPS32R2 | INSN_SMARTMIPS | INSN_DSP | INSN_DSPR2
-     | INSN_MIPS3D | INSN_MT | INSN_MCU),
+     | INSN_MIPS3D | INSN_MT | INSN_MCU | INSN_VIRT),
     mips_cp0_names_mips3264r2,
     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
     mips_hwr_names_mips3264r2 },
@@ -604,7 +604,7 @@
 
   { "mips64r2",	1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
     (ISA_MIPS64R2 | INSN_MIPS3D | INSN_DSP | INSN_DSPR2
-     | INSN_DSP64 | INSN_MT | INSN_MDMX | INSN_MCU),
+     | INSN_DSP64 | INSN_MT | INSN_MDMX | INSN_MCU | INSN_VIRT | INSN_VIRT64),
     mips_cp0_names_mips3264r2,
     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
     mips_hwr_names_mips3264r2 },
@@ -824,6 +824,14 @@
       no_aliases = 1;
       return;
     }
+
+  if (CONST_STRNEQ (option, "virt"))
+    {
+      mips_isa |= INSN_VIRT;
+      if (mips_isa & ISA_MIPS64R2)
+	mips_isa |= INSN_VIRT64;
+      return;
+    }
   
   /* Look for the = that delimits the end of the option name.  */
   for (i = 0; i < len; i++)
@@ -1066,6 +1074,10 @@
 	      infprintf (is, "0x%x", msbd + 1);
 	      break;
 
+	    case 'J':		/* hypcall operand */
+	      infprintf (is, "0x%x", GET_OP (l, CODE10));
+	      break;
+
 	    case 't': /* Coprocessor 0 reg name */
 	      infprintf (is, "%s", mips_cp0_names[GET_OP (l, RT)]);
 	      break;
@@ -3034,6 +3046,9 @@
 with the -M switch (multiple options should be separated by commas):\n"));
 
   fprintf (stream, _("\n\
+  virt            Recognize the virtualization ASE instructions.\n"));
+
+  fprintf (stream, _("\n\
   gpr-names=ABI            Print GPR names according to  specified ABI.\n\
                            Default: based on binary being disassembled.\n"));
 
diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c
index ee189c2..c22156d 100644
--- a/opcodes/mips-opc.c
+++ b/opcodes/mips-opc.c
@@ -128,6 +128,8 @@
 #define IOCTP	(INSN_OCTEONP | INSN_OCTEON2)
 #define IOCT2	INSN_OCTEON2
 #define XLR     INSN_XLR
+#define IVIRT	INSN_VIRT
+#define IVIRT64	INSN_VIRT64
 
 #define G1      (T3             \
                  |EE            \
@@ -718,11 +720,17 @@
 {"dmfc0",   "t,G",	0x40200000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I3,	EE	},
 {"dmfc0",   "t,+D",	0x40200000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I64	},
 {"dmfc0",   "t,G,H",	0x40200000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I64	},
+{"dmfgc0",   "t,G",	0x40600100, 0xffe007ff, LCD|WR_t|RD_C0,		0,		IVIRT64	},
+{"dmfgc0",   "t,+D",	0x40600100, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		IVIRT64	},
+{"dmfgc0",   "t,G,H",	0x40600100, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		IVIRT64	},
 {"dmt",     "",		0x41600bc1, 0xffffffff, TRAP,			0,		MT32	},
 {"dmt",     "t",	0x41600bc1, 0xffe0ffff, TRAP|WR_t,		0,		MT32	},
 {"dmtc0",   "t,G",	0x40a00000, 0xffe007ff,	COD|RD_t|WR_C0|WR_CC,	0,		I3,	EE	},
 {"dmtc0",   "t,+D",	0x40a00000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I64	},
 {"dmtc0",   "t,G,H",	0x40a00000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I64	},
+{"dmtgc0",  "t,G",	0x40600300, 0xffe007ff, COD|RD_t|WR_C0|WR_CC,	0,		IVIRT64	},
+{"dmtgc0",  "t,+D",     0x40600300, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		IVIRT64	},
+{"dmtgc0",  "t,G,H",    0x40600300, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		IVIRT64	},
 {"dmfc1",   "t,S",	0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D,	0,		I3,	SF	},
 {"dmfc1",   "t,G",      0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D,     0,		I3,	SF	},
 {"dmtc1",   "t,S",	0x44a00000, 0xffe007ff, COD|RD_t|WR_S|FP_D,	0,		I3,	SF	},
@@ -811,6 +819,8 @@
 {"floor.w.d", "D,S",	0x4620000f, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I2,	SF	},
 {"floor.w.s", "D,S",	0x4600000f, 0xffff003f, WR_D|RD_S|FP_S,		0,		I2	},
 {"hibernate","",        0x42000023, 0xffffffff,	0, 			0,		V1	},
+{"hypcall", "",		0x42000028, 0xffffffff, TRAP,			0,		IVIRT	},
+{"hypcall", "+J",	0x42000028, 0xffe007ff, TRAP,			0,		IVIRT	},
 {"ins",     "t,r,+A,+B", 0x7c000004, 0xfc00003f, WR_t|RD_s,    		0,		I33	},
 {"iret",    "",		0x42000038, 0xffffffff,	NODS,			0,		MC	},
 {"jr",      "s",	0x00000008, 0xfc1fffff,	UBD|RD_s,		0,		I1	},
@@ -904,6 +914,8 @@
 {"lld",     "t,A(b)",	0,    (int) M_LLD_AB,	INSN_MACRO,		0,		I3,	EE	},
 {"lq",      "t,o(b)",	0x78000000, 0xfc000000, WR_t|RD_b,		0,		MMI	},
 {"lq",      "t,A(b)",	0,    (int) M_LQ_AB,	INSN_MACRO,		0,		MMI	},
+{"lqc2",    "E,o(b)",	0xd8000000, 0xfc000000,	RD_b|WR_C2,		0,		EE	},
+{"lqc2",    "E,A(b)",	0,    (int) M_LQC2_AB,	INSN_MACRO,		0,		EE	},
 {"lui",     "t,u",	0x3c000000, 0xffe00000,	WR_t,			0,		I1	},
 {"luxc1",   "D,t(b)",	0x4c000005, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0,		I5_33|N55},
 {"lw",      "t,o(b)",	0x8c000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I1	},
@@ -1010,6 +1022,9 @@
 {"mfc0",    "t,G",	0x40000000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1	},
 {"mfc0",    "t,+D",0x40000000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I32	},
 {"mfc0",    "t,G,H",	0x40000000, 0xffe007f8,	LCD|WR_t|RD_C0,		0,		I32	},
+{"mfgc0",    "t,G",	0x40600000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		IVIRT	},
+{"mfgc0",    "t,+D",	0x40600000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		IVIRT	},
+{"mfgc0",    "t,G,H",	0x40600000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		IVIRT	},
 {"mfc1",    "t,S",	0x44000000, 0xffe007ff,	LCD|WR_t|RD_S|FP_S,	0,		I1	},
 {"mfc1",    "t,G",	0x44000000, 0xffe007ff,	LCD|WR_t|RD_S|FP_S,	0,		I1	},
 {"mfhc1",   "t,S",	0x44600000, 0xffe007ff,	LCD|WR_t|RD_S|FP_D,	0,		I33	},
@@ -1104,6 +1119,9 @@
 {"mtc0",    "t,G",	0x40800000, 0xffe007ff,	COD|RD_t|WR_C0|WR_CC,	0,		I1	},
 {"mtc0",    "t,+D",	0x40800000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I32	},
 {"mtc0",    "t,G,H",	0x40800000, 0xffe007f8,	COD|RD_t|WR_C0|WR_CC,	0,		I32	},
+{"mtgc0",   "t,G",	0x40600200, 0xffe007ff,	COD|RD_t|WR_C0|WR_CC,	0,		IVIRT	},
+{"mtgc0",   "t,+D",	0x40600200, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		IVIRT	},
+{"mtgc0",   "t,G,H",	0x40600200, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		IVIRT	},
 {"mtc1",    "t,S",	0x44800000, 0xffe007ff,	COD|RD_t|WR_S|FP_S,	0,		I1	},
 {"mtc1",    "t,G",	0x44800000, 0xffe007ff,	COD|RD_t|WR_S|FP_S,	0,		I1	},
 {"mthc1",   "t,S",	0x44e00000, 0xffe007ff,	COD|RD_t|WR_S|FP_D,	0,		I33	},
@@ -1379,7 +1397,7 @@
 {"remu",    "d,v,I",	0,    (int) M_REMU_3I,	INSN_MACRO,		0,		I1	},
 {"rdhwr",   "t,K",	0x7c00003b, 0xffe007ff, WR_t,			0,		I33	},
 {"rdpgpr",  "d,w",	0x41400000, 0xffe007ff, WR_d,			0,		I33	},
-{"rfe",     "",		0x42000010, 0xffffffff,	0,			0,		I1|T3	},
+/* rfe is moved below as it now conflicts with tlbgp */
 {"rnas.qh", "X,Q",	0x78200025, 0xfc20f83f,	WR_D|RD_T|FP_D,		RD_MACC,	MX	},
 {"rnau.ob", "X,Q",	0x78000021, 0xfc20f83f,	WR_D|RD_T|FP_D,		RD_MACC,	MX|SB1	},
 {"rnau.qh", "X,Q",	0x78200021, 0xfc20f83f,	WR_D|RD_T|FP_D,		RD_MACC,	MX	},
@@ -1519,6 +1537,8 @@
 {"snei",    "t,r,+Q",	0x7000002f, 0xfc00003f, WR_t|RD_s,		0,		IOCT	},
 {"sq",      "t,o(b)",	0x7c000000, 0xfc000000,	SM|RD_t|RD_b,		0,		MMI	},
 {"sq",      "t,A(b)",	0,    (int) M_SQ_AB,	INSN_MACRO,		0,		MMI	},
+{"sqc2",    "E,o(b)",	0xf8000000, 0xfc000000,	SM|RD_C2|RD_b,		0,		EE	},
+{"sqc2",    "E,A(b)",	0,    (int) M_SQC2_AB,	INSN_MACRO,		0,		EE	},
 {"sqrt.d",  "D,S",	0x46200004, 0xffff003f, WR_D|RD_S|FP_D,		0,		I2,	SF	},
 {"sqrt.s",  "D,S",	0x46000004, 0xffff003f, WR_D|RD_S|FP_S,		0,		I2	},
 {"sqrt.ps", "D,S",	0x46c00004, 0xffff003f, WR_D|RD_S|FP_D,		0,		SB1	},
@@ -1624,6 +1644,12 @@
 {"tlbr",    "",         0x42000001, 0xffffffff, INSN_TLB,       	0,		I1   	},
 {"tlbwi",   "",         0x42000002, 0xffffffff, INSN_TLB,       	0,		I1   	},
 {"tlbwr",   "",         0x42000006, 0xffffffff, INSN_TLB,       	0,		I1   	},
+{"tlbgr",   "",         0x42000009, 0xffffffff, INSN_TLB,       	0,		IVIRT  	},
+{"tlbgwi",  "",         0x4200000a, 0xffffffff, INSN_TLB,       	0,		IVIRT  	},
+{"tlbginv", "",         0x4200000b, 0xffffffff, INSN_TLB,       	0,		IVIRT  	},
+{"tlbginvf","",         0x4200000c, 0xffffffff, INSN_TLB,       	0,		IVIRT  	},
+{"tlbgwr",  "",         0x4200000e, 0xffffffff, INSN_TLB,       	0,		IVIRT  	},
+{"tlbgp",   "",         0x42000010, 0xffffffff, INSN_TLB,       	0,		IVIRT  	},
 {"tlti",    "s,j",	0x040a0000, 0xfc1f0000,	RD_s|TRAP,		0,		I2	},
 {"tlt",     "s,t",	0x00000032, 0xfc00ffff, RD_s|RD_t|TRAP,		0,		I2	},
 {"tlt",     "s,t,q",	0x00000032, 0xfc00003f, RD_s|RD_t|TRAP,		0,		I2	},
@@ -1759,16 +1785,20 @@
 
 /* Coprocessor 2 move/branch operations overlap with VR5400 .ob format
    instructions so they are here for the latters to take precedence.  */
-{"bc2f",    "p",	0x49000000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT|IOCTP|IOCT2|EE	},
+{"bc2f",    "p",	0x49000000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT|IOCTP|IOCT2	},
 {"bc2f",    "N,p",	0x49000000, 0xffe30000,	CBD|RD_CC,		0,		I32,		IOCT|IOCTP|IOCT2	},
-{"bc2fl",   "p",	0x49020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT|IOCTP|IOCT2|EE	},
+{"bc2fl",   "p",	0x49020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT|IOCTP|IOCT2	},
 {"bc2fl",   "N,p",	0x49020000, 0xffe30000,	CBL|RD_CC,		0,		I32,		IOCT|IOCTP|IOCT2	},
-{"bc2t",    "p",	0x49010000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT|IOCTP|IOCT2|EE	},
+{"bc2t",    "p",	0x49010000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT|IOCTP|IOCT2	},
 {"bc2t",    "N,p",	0x49010000, 0xffe30000,	CBD|RD_CC,		0,		I32,		IOCT|IOCTP|IOCT2	},
-{"bc2tl",   "p",	0x49030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT|IOCTP|IOCT2|EE	},
+{"bc2tl",   "p",	0x49030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3,		IOCT|IOCTP|IOCT2	},
 {"bc2tl",   "N,p",	0x49030000, 0xffe30000,	CBL|RD_CC,		0,		I32,		IOCT|IOCTP|IOCT2	},
-{"cfc2",    "t,G",	0x48400000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1,		IOCT|IOCTP|IOCT2|EE	},
-{"ctc2",    "t,G",	0x48c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1,		IOCT|IOCTP|IOCT2|EE	},
+{"cfc2",    "t,G",	0x48400000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"cfc2.i",  "t,G",	0x48400001, 0xffe007ff, LCD|WR_t|RD_C2,		0,		EE	},
+{"cfc2.ni", "t,G",	0x48400000, 0xffe007ff, LCD|WR_t|RD_C2,		0,		EE	},
+{"ctc2",    "t,G",	0x48c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1,		IOCT|IOCTP|IOCT2	},
+{"ctc2.i",  "t,G",	0x48c00001, 0xffe007ff, COD|RD_t|WR_CC,		0,		EE	},
+{"ctc2.ni", "t,G",	0x48c00000, 0xffe007ff, COD|RD_t|WR_CC,		0,		EE	},
 {"dmfc2",   "t,i",	0x48200000, 0xffe00000,	LCD|WR_t|RD_C2,		0,		IOCT	},
 {"dmfc2",   "t,G",	0x48200000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I3,		IOCT|IOCTP|IOCT2|EE	},
 {"dmfc2",   "t,G,H",	0x48200000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I64,		IOCT|IOCTP|IOCT2	},
@@ -1785,7 +1815,12 @@
 {"mthc2",   "t,G",	0x48e00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I33,		IOCT|IOCTP|IOCT2	},
 {"mthc2",   "t,G,H",	0x48e00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I33,		IOCT|IOCTP|IOCT2	},
 {"mthc2",   "t,i",	0x48e00000, 0xffe00000,	COD|RD_t|WR_C2|WR_CC,	0,		I33,		IOCT|IOCTP|IOCT2	},
-
+{"qmfc2",   "t,G",	0x48200000, 0xffe007ff, WR_t|RD_C2,		0,		EE	},
+{"qmfc2.i", "t,G",	0x48200001, 0xffe007ff,	WR_t|RD_C2,		0,		EE	},
+{"qmfc2.ni","t,G",	0x48200000, 0xffe007ff,	WR_t|RD_C2,		0,		EE	},
+{"qmtc2",   "t,G",	0x48a00000, 0xffe007ff,	RD_t|WR_C2,		0,		EE	},
+{"qmtc2.i", "t,G",	0x48a00001, 0xffe007ff,	RD_t|WR_C2,		0,		EE	},
+{"qmtc2.ni","t,G",	0x48a00000, 0xffe007ff,	RD_t|WR_C2,		0,		EE	},
 /* Coprocessor 3 move/branch operations overlap with MIPS IV COP1X 
    instructions, so they are here for the latters to take precedence.  */
 {"bc3f",    "p",	0x4d000000, 0xffff0000,	CBD|RD_CC,		0,		I1,		IOCT|IOCTP|IOCT2|EE	},
@@ -2273,6 +2308,8 @@
 {"cop1",     "C",	0,    (int) M_COP1,	INSN_MACRO,		INSN2_M_FP_S,	I1	},
 {"cop2",     "C",	0,    (int) M_COP2,	INSN_MACRO,		0,		I1,		IOCT|IOCTP|IOCT2	},
 {"cop3",     "C",	0,    (int) M_COP3,	INSN_MACRO,		0,		I1,		IOCT|IOCTP|IOCT2	},
+/* RFE conflicts with the new Virt spec instruction tlbgp. */
+{"rfe",     "",		0x42000010, 0xffffffff,	0,			0,		I1|T3	},
 };
 
 #define MIPS_NUM_OPCODES \
diff --git a/opcodes/msp430-dis.c b/opcodes/msp430-dis.c
index 71690a3..46da3cc 100644
--- a/opcodes/msp430-dis.c
+++ b/opcodes/msp430-dis.c
@@ -1,7 +1,6 @@
 /* Disassemble MSP430 instructions.
-   Copyright (C) 2002, 2004, 2005, 2007, 2009, 2010, 2012
-   Free Software Foundation, Inc.
-   
+   Copyright (C) 2002-2013 Free Software Foundation, Inc.
+
    Contributed by Dmitry Diky <diwil@mail.ru>
         
    This file is part of the GNU opcodes library.
@@ -83,26 +82,80 @@
 }
 
 static int
+print_as2_reg_name (int regno, char * op1, char * comm1,
+		    int c2, int c3, int cd)
+{
+  switch (regno)
+    {
+    case 2:
+      sprintf (op1, "#4");
+      sprintf (comm1, "r2 As==10");
+      return c2;
+
+    case 3:
+      sprintf (op1, "#2");
+      sprintf (comm1, "r3 As==10");
+      return c3;
+
+    default:
+      /* Indexed register mode @Rn.  */
+      sprintf (op1, "@r%d", regno);
+      return cd;
+    }
+}
+
+static int
+print_as3_reg_name (int regno, char * op1, char * comm1,
+		    int c2, int c3, int cd)
+{
+  switch (regno)
+    {
+    case 2:
+      sprintf (op1, "#8");
+      sprintf (comm1, "r2 As==11");
+      return c2;
+
+    case 3:
+      sprintf (op1, "#-1");
+      sprintf (comm1, "r3 As==11");
+      return c3;
+
+    default:
+      /* Post incremented @Rn+.  */
+      sprintf (op1, "@r%d+", regno);
+      return cd;
+    }
+}
+
+static int
 msp430_singleoperand (disassemble_info *info,
 		      struct msp430_opcode_s *opcode,
 		      bfd_vma addr,
 		      unsigned short insn,
 		      char *op,
 		      char *comm,
+		      unsigned short extension_word,
 		      int *cycles)
 {
   int regs = 0, regd = 0;
   int ad = 0, as = 0;
   int where = 0;
   int cmd_len = 2;
-  short dst = 0;
+  int dst = 0;
+  int fmt;
+  int extended_dst = extension_word & 0xf;
 
   regd = insn & 0x0f;
   regs = (insn & 0x0f00) >> 8;
   as = (insn & 0x0030) >> 4;
   ad = (insn & 0x0080) >> 7;
 
-  switch (opcode->fmt)
+  if (opcode->fmt < 0)
+    fmt = (- opcode->fmt) - 1;
+  else
+    fmt = opcode->fmt;
+
+  switch (fmt)
     {
     case 0:			/* Emulated work with dst register.  */
       if (regs != 2 && regs != 3 && regs != 1)
@@ -146,6 +199,13 @@
 	      sprintf (op, "0x%04x", dst);
 	      sprintf (comm, "PC rel. abs addr 0x%04x",
 		       PS ((short) (addr + 2) + dst));
+	      if (extended_dst)
+		{
+		  dst |= extended_dst << 16;
+		  sprintf (op, "0x%05x", dst);
+		  sprintf (comm, "PC rel. abs addr 0x%05lx",
+			   (long)((addr + 2 + dst) & 0xfffff));
+		}
 	    }
 	  else if (regd == 2)
 	    {
@@ -154,12 +214,25 @@
 	      cmd_len += 2;
 	      *cycles = 4;
 	      sprintf (op, "&0x%04x", PS (dst));
+	      if (extended_dst)
+		{
+		  dst |= extended_dst << 16;
+		  sprintf (op, "&0x%05x", dst & 0xfffff);
+		}
 	    }
 	  else
 	    {
 	      dst = msp430dis_opcode (addr + 2, info);
 	      cmd_len += 2;
 	      *cycles = 4;
+	      if (extended_dst)
+		{
+		  dst |= extended_dst << 16;
+		  if (dst & 0x80000)
+		    dst |= -1 << 20;
+		}
+	      else if (dst & 0x8000)
+		dst |= -1 << 16;
 	      sprintf (op, "%d(r%d)", dst, regd);
 	    }
 	}
@@ -183,51 +256,31 @@
 	}
       else if (as == 2)
 	{
-	  *cycles = 1;
-	  if (regd == 2)
-	    {
-	      sprintf (op, "#4");
-	      sprintf (comm, "r2 As==10");
-	    }
-	  else if (regd == 3)
-	    {
-	      sprintf (op, "#2");
-	      sprintf (comm, "r3 As==10");
-	    }
-	  else
-	    {
-	      *cycles = 3;
-	      /* Indexed register mode @Rn.  */
-	      sprintf (op, "@r%d", regd);
-	    }
+	  * cycles = print_as2_reg_name (regd, op, comm, 1, 1, 3);
 	}
       else if (as == 3)
 	{
-	  *cycles = 1;
-	  if (regd == 2)
-	    {
-	      sprintf (op, "#8");
-	      sprintf (comm, "r2 As==11");
-	    }
-	  else if (regd == 3)
-	    {
-	      sprintf (op, "#-1");
-	      sprintf (comm, "r3 As==11");
-	    }
-	  else if (regd == 0)
+	  if (regd == 0)
 	    {
 	      *cycles = 3;
 	      /* absolute. @pc+ */
 	      dst = msp430dis_opcode (addr + 2, info);
 	      cmd_len += 2;
 	      sprintf (op, "#%d", dst);
-	      sprintf (comm, "#0x%04x", PS (dst));
+	      if (dst > 9 || dst < 0)
+		sprintf (comm, "#0x%04x", PS (dst));
+	      if (extended_dst)
+		{
+		  dst |= extended_dst << 16;
+		  if (dst & 0x80000)
+		    dst |= -1 << 20;
+		  sprintf (op, "#%d", dst);
+		  if (dst > 9 || dst < 0)
+		    sprintf (comm, "#0x%05x", dst);
+		}
 	    }
 	  else
-	    {
-	      *cycles = 3;
-	      sprintf (op, "@r%d+", regd);
-	    }
+	    * cycles = print_as3_reg_name (regd, op, comm, 1, 1, 3);
 	}
       else if (as == 1)
 	{
@@ -240,6 +293,13 @@
 	      sprintf (op, "0x%04x", PS (dst));
 	      sprintf (comm, "PC rel. 0x%04x",
 		       PS ((short) addr + 2 + dst));
+	      if (extended_dst)
+		{
+		  dst |= extended_dst << 16;
+		  sprintf (op, "0x%05x", dst & 0xffff);
+		  sprintf (comm, "PC rel. 0x%05lx",
+			   (long)((addr + 2 + dst) & 0xfffff));
+		}
 	    }
 	  else if (regd == 2)
 	    {
@@ -247,6 +307,11 @@
 	      dst = msp430dis_opcode (addr + 2, info);
 	      cmd_len += 2;
 	      sprintf (op, "&0x%04x", PS (dst));
+	      if (extended_dst)
+		{
+		  dst |= extended_dst << 16;
+		  sprintf (op, "&0x%05x", dst & 0xfffff);
+		}
 	    }
 	  else if (regd == 3)
 	    {
@@ -256,10 +321,20 @@
 	    }
 	  else
 	    {
-	      /* Indexd.  */
+	      /* Indexed.  */
 	      dst = msp430dis_opcode (addr + 2, info);
 	      cmd_len += 2;
+	      if (extended_dst)
+		{
+		  dst |= extended_dst << 16;
+		  if (dst & 0x80000)
+		    dst |= -1 << 20;
+		}
+	      else if (dst & 0x8000)
+		dst |= -1 << 16;
 	      sprintf (op, "%d(r%d)", dst, regd);
+	      if (dst > 9 || dst < 0)
+		sprintf (comm, "%05x", dst);
 	    }
 	}
       break;
@@ -273,7 +348,7 @@
 
       where *= 2;
       sprintf (op, "$%+-8d", where + 2);
-      sprintf (comm, "abs 0x%x", PS ((short) (addr) + 2 + where));
+      sprintf (comm, "abs 0x%lx", (long) (addr + 2 + where));
       *cycles = 2;
       return 2;
       break;
@@ -293,19 +368,28 @@
 		      char *op2,
 		      char *comm1,
 		      char *comm2,
+		      unsigned short extension_word,
 		      int *cycles)
 {
   int regs = 0, regd = 0;
   int ad = 0, as = 0;
   int cmd_len = 2;
-  short dst = 0;
+  int dst = 0;
+  int fmt;
+  int extended_dst = extension_word & 0xf;
+  int extended_src = (extension_word >> 7) & 0xf;
 
   regd = insn & 0x0f;
   regs = (insn & 0x0f00) >> 8;
   as = (insn & 0x0030) >> 4;
   ad = (insn & 0x0080) >> 7;
 
-  if (opcode->fmt == 0)
+  if (opcode->fmt < 0)
+    fmt = (- opcode->fmt) - 1;
+  else
+    fmt = opcode->fmt;
+
+  if (fmt == 0)
     {
       /* Special case: rla and rlc are the only 2 emulated instructions that
 	 fall into two operand instructions.  */
@@ -343,7 +427,15 @@
 	      sprintf (op1, "0x%04x", PS (dst));
 	      sprintf (comm1, "PC rel. 0x%04x",
 		       PS ((short) addr + 2 + dst));
-
+	      if (extended_dst)
+		{
+		  dst |= extended_dst << 16;
+		  if (dst & 0x80000)
+		    dst |= -1 << 20;
+		  sprintf (op1, "0x%05x", dst & 0xfffff);
+		  sprintf (comm1, "PC rel. 0x%05lx",
+			   (long)((addr + 2 + dst) & 0xfffff));
+		}
 	    }
 	  else if (regd == 2)
 	    {
@@ -356,19 +448,35 @@
 	      cmd_len += 4;
 	      *cycles = 6;
 	      sprintf (op1, "&0x%04x", PS (dst));
+	      if (extended_dst)
+		{
+		  dst |= extended_dst << 16;
+		  sprintf (op1, "&0x%05x", dst & 0xfffff);
+		}
 	    }
 	  else
 	    {
 	      /* Indexed.  */
 	      dst = msp430dis_opcode (addr + 2, info);
+	      if (extended_dst)
+		{
+		  dst |= extended_dst << 16;
+		  if (dst & 0x80000)
+		    dst |= -1 << 20;
+		}
+	      else if (dst & 0x8000)
+		dst |= -1 << 16;
 	      cmd_len += 4;
 	      *cycles = 6;
 	      sprintf (op1, "%d(r%d)", dst, regd);
+	      if (dst > 9 || dst < -9)
+		sprintf (comm1, "#0x%05x", dst);
 	    }
 	}
 
       *op2 = 0;
       *comm2 = 0;
+
       return cmd_len;
     }
 
@@ -386,7 +494,7 @@
       *cycles = 1;
       if (regs == 3)
 	{
-	  /* Constsnts.  */
+	  /* Constants.  */
 	  sprintf (op1, "#0");
 	  sprintf (comm1, "r3 As==00");
 	}
@@ -398,56 +506,31 @@
     }
   else if (as == 2)
     {
-      *cycles = 1;
-
-      if (regs == 2)
-	{
-	  sprintf (op1, "#4");
-	  sprintf (comm1, "r2 As==10");
-	}
-      else if (regs == 3)
-	{
-	  sprintf (op1, "#2");
-	  sprintf (comm1, "r3 As==10");
-	}
-      else
-	{
-	  *cycles = 2;
-
-	  /* Indexed register mode @Rn.  */
-	  sprintf (op1, "@r%d", regs);
-	}
-      if (!regs)
-	*cycles = 3;
+      * cycles = print_as2_reg_name (regs, op1, comm1, 1, 1, regs == 0 ? 3 : 2);
     }
   else if (as == 3)
     {
-      if (regs == 2)
-	{
-	  sprintf (op1, "#8");
-	  sprintf (comm1, "r2 As==11");
-	  *cycles = 1;
-	}
-      else if (regs == 3)
-	{
-	  sprintf (op1, "#-1");
-	  sprintf (comm1, "r3 As==11");
-	  *cycles = 1;
-	}
-      else if (regs == 0)
+      if (regs == 0)
 	{
 	  *cycles = 3;
 	  /* Absolute. @pc+.  */
 	  dst = msp430dis_opcode (addr + 2, info);
 	  cmd_len += 2;
 	  sprintf (op1, "#%d", dst);
-	  sprintf (comm1, "#0x%04x", PS (dst));
+	  if (dst > 9 || dst < 0)
+	    sprintf (comm1, "#0x%04x", PS (dst));
+	  if (extended_src)
+	    {
+	      dst |= extended_src << 16;
+	      if (dst & 0x80000)
+		dst |= -1 << 20;
+	      sprintf (op1, "#%d", dst);
+	      if (dst > 9 || dst < 0)
+		sprintf (comm1, "0x%05x", dst & 0xfffff);
+	    }
 	}
       else
-	{
-	  *cycles = 2;
-	  sprintf (op1, "@r%d+", regs);
-	}
+	* cycles = print_as3_reg_name (regs, op1, comm1, 1, 1, 2);
     }
   else if (as == 1)
     {
@@ -460,6 +543,15 @@
 	  sprintf (op1, "0x%04x", PS (dst));
 	  sprintf (comm1, "PC rel. 0x%04x",
 		   PS ((short) addr + 2 + dst));
+	  if (extended_src)
+	    {
+	      dst |= extended_src << 16;
+	      if (dst & 0x80000)
+		dst |= -1 << 20;
+	      sprintf (op1, "0x%05x", dst & 0xfffff);
+	      sprintf (comm1, "PC rel. 0x%05lx",
+		       (long) ((addr + 2 + dst) & 0xfffff));
+	    }
 	}
       else if (regs == 2)
 	{
@@ -469,6 +561,12 @@
 	  cmd_len += 2;
 	  sprintf (op1, "&0x%04x", PS (dst));
 	  sprintf (comm1, "0x%04x", PS (dst));
+	  if (extended_src)
+	    {
+	      dst |= extended_src << 16;
+	      sprintf (op1, "&0x%05x", dst & 0xfffff);
+	      * comm1 = 0;
+	    }
 	}
       else if (regs == 3)
 	{
@@ -482,7 +580,17 @@
 	  /* Indexed.  */
 	  dst = msp430dis_opcode (addr + 2, info);
 	  cmd_len += 2;
+	  if (extended_src)
+	    {
+	      dst |= extended_src << 16;
+	      if (dst & 0x80000)
+		dst |= -1 << 20;
+	    }
+	  else if (dst & 0x8000)
+	    dst |= -1 << 16;
 	  sprintf (op1, "%d(r%d)", dst, regs);
+	  if (dst > 9 || dst < -9)
+	    sprintf (comm1, "0x%05x", dst);
 	}
     }
 
@@ -517,6 +625,15 @@
 	  sprintf (op2, "0x%04x", PS (dst));
 	  sprintf (comm2, "PC rel. 0x%04x",
 		   PS ((short) addr + cmd_len + dst));
+	  if (extended_dst)
+	    {
+	      dst |= extended_dst << 16;
+	      if (dst & 0x80000)
+		dst |= -1 << 20;
+	      sprintf (op2, "0x%05x", dst & 0xfffff);
+	      sprintf (comm2, "PC rel. 0x%05lx",
+		       (long)((addr + cmd_len + dst) & 0xfffff));
+	    }
 	  cmd_len += 2;
 	}
       else if (regd == 2)
@@ -525,11 +642,28 @@
 	  dst = msp430dis_opcode (addr + cmd_len, info);
 	  cmd_len += 2;
 	  sprintf (op2, "&0x%04x", PS (dst));
+	  if (extended_dst)
+	    {
+	      dst |= extended_dst << 16;
+	      sprintf (op2, "&0x%05x", dst & 0xfffff);
+	    }
 	}
       else
 	{
 	  dst = msp430dis_opcode (addr + cmd_len, info);
 	  cmd_len += 2;
+	  if (dst & 0x8000)
+	    dst |= -1 << 16;
+	  if (dst > 9 || dst < 0)
+	    sprintf (comm2, "0x%04x", PS (dst));
+	  if (extended_dst)
+	    {
+	      dst |= extended_dst << 16;
+	      if (dst & 0x80000)
+		dst |= -1 << 20;
+	      if (dst > 9 || dst < 0)
+		sprintf (comm2, "0x%05x", dst & 0xfffff);
+	    }
 	  sprintf (op2, "%d(r%d)", dst, regd);
 	}
     }
@@ -577,40 +711,11 @@
     }
   else if (as == 2)
     {
-      if (regs == 2)
-	{
-	  *cycles = 2;
-	  sprintf (op1, "#4");
-	  sprintf (comm1, "r2 As==10");
-	}
-      else if (regs == 3)
-	{
-	  *cycles = 1;
-	  sprintf (op1, "#2");
-	  sprintf (comm1, "r3 As==10");
-	}
-      else
-	{
-	  /* Indexed register mode @Rn.  */
-	  *cycles = 2;
-	  sprintf (op1, "@r%d", regs);
-	}
+      * cycles = print_as2_reg_name (regs, op1, comm1, 2, 1, 2);
     }
   else if (as == 3)
     {
-      if (regs == 2)
-	{
-	  *cycles = 1;
-	  sprintf (op1, "#8");
-	  sprintf (comm1, "r2 As==11");
-	}
-      else if (regs == 3)
-	{
-	  *cycles = 1;
-	  sprintf (op1, "#-1");
-	  sprintf (comm1, "r3 As==11");
-	}
-      else if (regs == 0)
+      if (regs == 0)
 	{
 	  /* Absolute. @pc+  */
 	  *cycles = 3;
@@ -619,10 +724,7 @@
 	  sprintf (op1, "#0x%04x", PS (dst));
 	}
       else
-	{
-	  *cycles = 2;
-	  sprintf (op1, "@r%d+", regs);
-	}
+	* cycles = print_as3_reg_name (regs, op1, comm1, 1, 1, 2);
     }
   else if (as == 1)
     {
@@ -653,9 +755,11 @@
 	}
       else
 	{
-	  /* Indexd.  */
+	  /* Indexed.  */
 	  dst = msp430dis_opcode (addr + 2, info);
 	  cmd_len += 2;
+	  if (dst & 0x8000)
+	    dst |= -1 << 16;
 	  sprintf (op1, "%d(r%d)", dst, regs);
 	}
     }
@@ -663,6 +767,82 @@
   return cmd_len;
 }
 
+static int
+msp430x_calla_instr (disassemble_info * info,
+		     bfd_vma            addr,
+		     unsigned short     insn,
+		     char *             op1,
+		     char *             comm1,
+		     int *              cycles)
+{
+  unsigned int   ureg = insn & 0xf;
+  int            reg = insn & 0xf;
+  int            am = (insn & 0xf0) >> 4;
+  int            cmd_len = 2;
+  unsigned short udst = 0;
+  short          dst = 0;
+
+  switch (am)
+    {
+    case 4: /* CALLA Rdst */
+      *cycles = 1;
+      sprintf (op1, "r%d", reg);
+      break;
+
+    case 5: /* CALLA x(Rdst) */
+      *cycles = 3;
+      dst = msp430dis_opcode (addr + 2, info);
+      cmd_len += 2;
+      sprintf (op1, "%d(r%d)", dst, reg);
+      if (reg == 0)
+	sprintf (comm1, "PC rel. 0x%05lx", (long) (addr + 2 + dst));
+      else
+	sprintf (comm1, "0x%05x", dst);
+      break;
+
+    case 6: /* CALLA @Rdst */
+      *cycles = 2;
+      sprintf (op1, "@r%d", reg);
+      break;
+
+    case 7: /* CALLA @Rdst+ */
+      *cycles = 2;
+      sprintf (op1, "@r%d+", reg);
+      break;
+
+    case 8: /* CALLA &abs20 */
+      udst = msp430dis_opcode (addr + 2, info);
+      cmd_len += 2;
+      *cycles = 4;
+      sprintf (op1, "&%d", (ureg << 16) + udst);
+      sprintf (comm1, "0x%05x", (ureg << 16) + udst);
+      break;
+
+    case 9: /* CALLA pcrel-sym */
+      dst = msp430dis_opcode (addr + 2, info);
+      cmd_len += 2;
+      *cycles = 4;
+      sprintf (op1, "%d(PC)", (reg << 16) + dst);
+      sprintf (comm1, "PC rel. 0x%05lx",
+	       (long) (addr + 2 + dst + (reg << 16)));
+      break;
+
+    case 11: /* CALLA #imm20 */
+      udst = msp430dis_opcode (addr + 2, info);
+      cmd_len += 2;
+      *cycles = 4;
+      sprintf (op1, "#%d", (ureg << 16) + udst);
+      sprintf (comm1, "0x%05x", (ureg << 16) + udst);
+      break;
+
+    default:
+      strcpy (comm1, _("unercognised CALLA addressing mode"));
+      return -1;
+    }
+
+  return cmd_len;
+}
+
 int
 print_insn_msp430 (bfd_vma addr, disassemble_info *info)
 {
@@ -674,10 +854,14 @@
   unsigned short insn;
   int cycles = 0;
   char *bc = "";
-  char dinfo[32];		/* Debug purposes.  */
+  unsigned short extension_word = 0;
 
   insn = msp430dis_opcode (addr, info);
-  sprintf (dinfo, "0x%04x", insn);
+  if (insn == (unsigned short) -1)
+    {
+      prin (stream, ".word	0xffff;	????");
+      return 2;
+    }
 
   if (((int) addr & 0xffff) > 0xffdf)
     {
@@ -688,6 +872,20 @@
   *comm1 = 0;
   *comm2 = 0;
 
+  /* Check for an extension word.  */
+  if ((insn & 0xf800) == 0x1800)
+    {
+      extension_word = insn;
+      addr += 2;
+      insn = msp430dis_opcode (addr, info);
+      if (insn == (unsigned short) -1)
+	{
+	  prin (stream, ".word	0x%04x, 0xffff;	????",
+		extension_word);
+	  return 4;
+	}
+   }
+
   for (opcode = msp430_opcodes; opcode->name; opcode++)
     {
       if ((insn & opcode->bin_mask) == opcode->bin_opcode
@@ -699,10 +897,11 @@
 	  *comm2 = 0;
 
 	  /* r0 as destination. Ad should be zero.  */
-	  if (opcode->insn_opnumb == 3 && (insn & 0x000f) == 0
-	      && (0x0080 & insn) == 0)
+	  if (opcode->insn_opnumb == 3
+	      && (insn & 0x000f) == 0
+	      && (insn & 0x0080) == 0)
 	    {
-	      cmd_len =
+	      cmd_len +=
 		msp430_branchinstr (info, opcode, addr, insn, op1, comm1,
 				    &cycles);
 	      if (cmd_len)
@@ -711,22 +910,244 @@
 
 	  switch (opcode->insn_opnumb)
 	    {
+	      int n;
+	      int reg;
+
+	    case 4:
+	      cmd_len += msp430x_calla_instr (info, addr, insn,
+					      op1, comm1, & cycles);
+	      break;
+
+	    case 5: /* PUSHM/POPM */
+	      n = (insn & 0xf0) >> 4;
+	      reg = (insn & 0xf);
+
+	      sprintf (op1, "#%d", n + 1);
+	      if (opcode->bin_opcode == 0x1400)
+		/* PUSHM */
+		sprintf (op2, "r%d", reg);
+	      else
+		/* POPM */
+		sprintf (op2, "r%d", reg + n);
+	      if (insn & 0x100)
+		sprintf (comm1, "16-bit words");
+	      else
+		{
+		  sprintf (comm1, "20-bit words");
+		  bc =".a";
+		}
+	      
+	      cycles = 2; /*FIXME*/
+	      cmd_len = 2;
+	      break;
+
+	    case 6: /* RRAM, RRCM, RRUM, RLAM.  */
+	      n = ((insn >> 10) & 0x3) + 1;
+	      reg = (insn & 0xf);
+	      if ((insn & 0x10) == 0)
+		bc =".a";
+	      sprintf (op1, "#%d", n);
+	      sprintf (op2, "r%d", reg);
+	      cycles = 2; /*FIXME*/
+	      cmd_len = 2;
+	      break;
+
+	    case 8: /* ADDA, CMPA, SUBA.  */
+	      reg = (insn & 0xf);
+	      n = (insn >> 8) & 0xf;
+	      if (insn & 0x40)
+		{
+		  sprintf (op1, "r%d", n);
+		  cmd_len = 2;
+		}
+	      else
+		{
+		  n <<= 16;
+		  n |= msp430dis_opcode (addr + 2, info);
+		  sprintf (op1, "#%d", n);
+		  if (n > 9 || n < 0)
+		    sprintf (comm1, "0x%05x", n);
+		  cmd_len = 4;
+		}
+	      sprintf (op2, "r%d", reg);
+	      cycles = 2; /*FIXME*/
+	      break;
+
+	    case 9: /* MOVA */
+	      reg = (insn & 0xf);
+	      n = (insn >> 8) & 0xf;
+	      switch ((insn >> 4) & 0xf)
+		{
+		case 0: /* MOVA @Rsrc, Rdst */
+		  cmd_len = 2;
+		  sprintf (op1, "@r%d", n);
+		  if (strcmp (opcode->name, "bra") != 0)
+		    sprintf (op2, "r%d", reg);
+		  break;
+		  
+		case 1: /* MOVA @Rsrc+, Rdst */
+		  cmd_len = 2;
+		  if (strcmp (opcode->name, "reta") != 0)
+		    {
+		      sprintf (op1, "@r%d+", n);
+		      if (strcmp (opcode->name, "bra") != 0)
+			sprintf (op2, "r%d", reg);
+		    }
+		  break;
+		  
+		case 2: /* MOVA &abs20, Rdst */
+		  cmd_len = 4;
+		  n <<= 16;
+		  n |= msp430dis_opcode (addr + 2, info);
+		  sprintf (op1, "&%d", n);
+		  if (n > 9 || n < 0)
+		    sprintf (comm1, "0x%05x", n);
+		  if (strcmp (opcode->name, "bra") != 0)
+		    sprintf (op2, "r%d", reg);
+		  break;
+		  
+		case 3: /* MOVA x(Rsrc), Rdst */
+		  cmd_len = 4;
+		  if (strcmp (opcode->name, "bra") != 0)
+		    sprintf (op2, "r%d", reg);
+		  reg = n;
+		  n = msp430dis_opcode (addr + 2, info);
+		  if (n & 0x8000)
+		    n |= -1 << 16;
+		  sprintf (op1, "%d(r%d)", n, reg);
+		  if (n > 9 || n < 0)
+		    {
+		      if (reg == 0)
+			sprintf (comm1, "PC rel. 0x%05lx",
+				 (long) (addr + 2 + n));
+		      else
+			sprintf (comm1, "0x%05x", n);
+		    }
+		  break;
+
+		case 6: /* MOVA Rsrc, &abs20 */
+		  cmd_len = 4;
+		  reg <<= 16;
+		  reg |= msp430dis_opcode (addr + 2, info);
+		  sprintf (op1, "r%d", n);
+		  sprintf (op2, "&%d", reg);
+		  if (reg > 9 || reg < 0)
+		    sprintf (comm2, "0x%05x", reg);
+		  break;
+
+		case 7: /* MOVA Rsrc, x(Rdst) */
+		  cmd_len = 4;
+		  sprintf (op1, "r%d", n);
+		  n = msp430dis_opcode (addr + 2, info);
+		  if (n & 0x8000)
+		    n |= -1 << 16;
+		  sprintf (op2, "%d(r%d)", n, reg);
+		  if (n > 9 || n < 0)
+		    {
+		      if (reg == 0)
+			sprintf (comm2, "PC rel. 0x%05lx",
+				 (long) (addr + 2 + n));
+		      else
+			sprintf (comm2, "0x%05x", n);
+		    }
+		  break;
+		  
+		case 8: /* MOVA #imm20, Rdst */
+		  cmd_len = 4;
+		  n <<= 16;
+		  n |= msp430dis_opcode (addr + 2, info);
+		  if (n & 0x80000)
+		    n |= -1 << 20;
+		  sprintf (op1, "#%d", n);
+		  if (n > 9 || n < 0)
+		    sprintf (comm1, "0x%05x", n);
+		  if (strcmp (opcode->name, "bra") != 0)
+		    sprintf (op2, "r%d", reg);
+		  break;
+		  
+		case 12: /* MOVA Rsrc, Rdst */
+		  cmd_len = 2;
+		  sprintf (op1, "r%d", n);
+		  if (strcmp (opcode->name, "bra") != 0)
+		    sprintf (op2, "r%d", reg);
+		  break;
+
+		default:
+		  break;
+		}
+	      cycles = 2; /* FIXME */
+	      break;
+	    }
+
+	  if (cmd_len)
+	    break;
+
+	  switch (opcode->insn_opnumb)
+	    {
 	    case 0:
-	      cmd_len = msp430_nooperands (opcode, addr, insn, comm1, &cycles);
+	      cmd_len += msp430_nooperands (opcode, addr, insn, comm1, &cycles);
 	      break;
 	    case 2:
-	      cmd_len =
+	      cmd_len +=
 		msp430_doubleoperand (info, opcode, addr, insn, op1, op2,
-				      comm1, comm2, &cycles);
+				      comm1, comm2,
+				      extension_word,
+				      &cycles);
 	      if (insn & BYTE_OPERATION)
-		bc = ".b";
+		{
+		  if (extension_word != 0 && ((extension_word & BYTE_OPERATION) == 0))
+		    bc = ".a";
+		  else
+		    bc = ".b";
+		}
+	      else if (extension_word)
+		{
+		  if (extension_word & (1 << 6))
+		    bc = ".w";
+		  else
+		    {
+		      bc = ".?";
+		      sprintf (comm2, _("Reserved use of A/L and B/W bits detected"));
+		    }
+		}
+	      
 	      break;
 	    case 1:
-	      cmd_len =
+	      cmd_len +=
 		msp430_singleoperand (info, opcode, addr, insn, op1, comm1,
+				      extension_word,
 				      &cycles);
-	      if (insn & BYTE_OPERATION && opcode->fmt != 3)
-		bc = ".b";
+	      if (extension_word
+		  && (strcmp (opcode->name, "swpb") == 0
+		      || strcmp (opcode->name, "sxt") == 0))
+		{
+		  if (insn & BYTE_OPERATION)
+		    {
+		      bc = ".?";
+		      sprintf (comm2, _("Reserved use of A/L and B/W bits detected"));
+		    }
+		  else if (extension_word & BYTE_OPERATION)
+		    bc = ".w";
+		  else
+		    bc = ".a";
+		}
+	      else if (insn & BYTE_OPERATION && opcode->fmt != 3)
+		{
+		  if (extension_word != 0 && ((extension_word & BYTE_OPERATION) == 0))
+		    bc = ".a";
+		  else
+		    bc = ".b";
+		}
+	      else if (extension_word)
+		{
+		  if (extension_word & (1 << 6))
+		    bc = ".w";
+		  else
+		    {
+		      bc = ".?";
+		      sprintf (comm2, _("Reserved use of A/L and B/W bits detected"));
+		    }
+		}
 	      break;
 	    default:
 	      break;
@@ -737,16 +1158,33 @@
 	break;
     }
 
-  dinfo[5] = 0;
-
   if (cmd_len < 1)
     {
       /* Unknown opcode, or invalid combination of operands.  */
+      if (extension_word)
+	{
+	  prin (stream, ".word	0x%04x, 0x%04x;	????", extension_word, PS (insn));
+	  if (*comm1)
+	    prin (stream, "\t %s", comm1);
+	  return 4;
+	}
       (*prin) (stream, ".word	0x%04x;	????", PS (insn));
       return 2;
     }
 
-  (*prin) (stream, "%s%s", opcode->name, bc);
+  /* Display the repeat count (if set) for extended register mode.  */
+  if (cmd_len == 2 && ((extension_word & 0xf) != 0))
+    {
+      if (extension_word & (1 << 7))
+	prin (stream, "rpt r%d { ", extension_word & 0xf);
+      else
+	prin (stream, "rpt #%d { ", (extension_word & 0xf) + 1);
+    }
+
+  if (extension_word && opcode->name[strlen (opcode->name) - 1] != 'x')
+    (*prin) (stream, "%sx%s", opcode->name, bc);
+  else
+    (*prin) (stream, "%s%s", opcode->name, bc);
 
   if (*op1)
     (*prin) (stream, "\t%s", op1);
@@ -783,5 +1221,9 @@
     (*prin) (stream, ",");
   if (*comm2)
     (*prin) (stream, " %s", comm2);
+
+  if (extension_word)
+    cmd_len += 2;
+
   return cmd_len;
 }
diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c
index 2c6869e..4e2bcd7 100644
--- a/opcodes/ppc-dis.c
+++ b/opcodes/ppc-dis.c
@@ -315,10 +315,7 @@
       dialect = (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_VLE);
       break;
     default:
-      dialect = (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
-		 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
-		 | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX
-		 | PPC_OPCODE_ANY);
+      dialect = ppc_parse_cpu (dialect, &sticky, "power8") | PPC_OPCODE_ANY;
     }
 
   arg = info->disassembler_options;
diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c
index 80dfa24..a257f86 100644
--- a/opcodes/ppc-opc.c
+++ b/opcodes/ppc-opc.c
@@ -315,14 +315,18 @@
   { 0xfffc, 0, NULL, NULL,
     PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DS },
 
-  /* The DUIS field in a XFX form instruction, 10 bits unsigned imediate */
+  /* The DUIS or BHRBE fields in a XFX form instruction, 10 bits
+     unsigned imediate */
 #define DUIS DS + 1
+#define BHRBE DUIS
   { 0x3ff, 11, NULL, NULL, 0 },
 
   /* The E field in a wrteei instruction.  */
   /* And the W bit in the pair singles instructions.  */
+  /* And the ST field in a VX form instruction.  */
 #define E DUIS + 1
 #define PSW E
+#define ST E
   { 0x1, 15, NULL, NULL, 0 },
 
   /* The FL1 field in a POWER SC form instruction.  */
@@ -695,8 +699,16 @@
 #define UIMM3 UIMM + 1
   { 0x7, 16, NULL, NULL, 0 },
 
+  /* The SIX field in a VX form instruction.  */
+#define SIX UIMM3 + 1
+  { 0xf, 11, NULL, NULL, 0 },
+
+  /* The PS field in a VX form instruction.  */
+#define PS SIX + 1
+  { 0x1, 9, NULL, NULL, 0 },
+
   /* The SHB field in a VA form instruction.  */
-#define SHB UIMM3 + 1
+#define SHB PS + 1
   { 0xf, 6, NULL, NULL, 0 },
 
   /* The other UIMM field in a half word EVX form instruction.  */
@@ -751,8 +763,12 @@
 #define S SP + 1
   { 0x1, 20, NULL, NULL, 0 },
 
+  /* The S field in a XL form instruction.  */
+#define SXL S + 1
+  { 0x1, 11, NULL, NULL, PPC_OPERAND_OPTIONAL },
+
   /* SH field starting at bit position 16.  */
-#define SH16 S + 1
+#define SH16 SXL + 1
   /* The DCM and DGM fields in a Z form instruction.  */
 #define DCM SH16
 #define DGM DCM
@@ -2022,11 +2038,8 @@
              ppc_cpu_t dialect ATTRIBUTE_UNUSED,
              int *invalid ATTRIBUTE_UNUSED)
 {
-  /* RWRW Because I don't know how to make int be 16 and long be 32 */
-  /* I can't rely on casting an int to long to get sign extension. */
   long value = ((insn >> 10) & 0xf800) | (insn & 0x7ff);
-  if (value & 0x8000)
-    value |= 0xffff0000;
+  value = (value ^ 0x8000) - 0x8000;
   return value;
 }
 
@@ -2045,8 +2058,8 @@
              int *invalid ATTRIBUTE_UNUSED)
 {
   long value = ((insn >> 10) & 0xf800) | (insn & 0x7ff);
-  if (value & 0x8000)
-    value |= 0xffff0000;
+  value = (value ^ 0x8000) - 0x8000;
+  /* Don't use for disassembly.  */
   *invalid = 1;
   return -value;
 }
@@ -2328,6 +2341,9 @@
 /* A VX_MASK with a UIMM2 field.  */
 #define VXUIMM2_MASK (VX_MASK | (0x7 << 18))
 
+/* A VX_MASK with a PS field.  */
+#define VXPS_MASK (VX_MASK & ~(0x1 << 9))
+
 /* A VA form instruction.  */
 #define VXA(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x03f))
 
@@ -2382,6 +2398,9 @@
 /* The mask for an XX1 form instruction.  */
 #define XX1_MASK X (0x3f, 0x3ff)
 
+/* An XX1_MASK with the RB field fixed.  */
+#define XX1RB_MASK (XX1_MASK | RB_MASK)
+
 /* The mask for an XX2 form instruction.  */
 #define XX2_MASK (XX2 (0x3f, 0x1ff) | (0x1f << 16))
 
@@ -2519,6 +2538,9 @@
 /* The mask for an XL form instruction.  */
 #define XL_MASK XLLK (0x3f, 0x3ff, 1)
 
+/* An XL_MASK with the RT, RA and RB fields fixed, but S bit clear.  */
+#define XLS_MASK ((XL_MASK | RT_MASK | RA_MASK | RB_MASK) & ~(1 << 11))
+
 /* An XL form instruction which explicitly sets the BO field.  */
 #define XLO(op, bo, xop, lk) \
   (XLLK ((op), (xop), (lk)) | ((((unsigned long)(bo)) & 0x1f) << 21))
@@ -2702,6 +2724,7 @@
 #define PPCVEC	PPC_OPCODE_ALTIVEC
 #define PPCVEC2	PPC_OPCODE_ALTIVEC2
 #define PPCVSX	PPC_OPCODE_VSX
+#define PPCVSX2	PPC_OPCODE_VSX
 #define POWER	PPC_OPCODE_POWER
 #define POWER2	PPC_OPCODE_POWER | PPC_OPCODE_POWER2
 #define PWR2COM PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_COMMON
@@ -2848,6 +2871,7 @@
 {"vperm",	VXA(4,	43),	VXA_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB, VC}},
 {"vsldoi",	VXA(4,	44),	VXASHB_MASK, PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB, SHB}},
 {"ps_sel",	A  (4,	23,0),	A_MASK,      PPCPS,	PPCNONE,	{FRT, FRA, FRC, FRB}},
+{"vpermxor",	VXA(4,	45),	VXA_MASK,    PPCVEC2,	PPCNONE,	{VD, VA, VB, VC}},
 {"vmaddfp",	VXA(4,	46),	VXA_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VC, VB}},
 {"ps_sel.",	A  (4,	23,1),	A_MASK,      PPCPS,	PPCNONE,	{FRT, FRA, FRC, FRB}},
 {"vnmsubfp",	VXA(4,	47),	VXA_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VC, VB}},
@@ -2866,6 +2890,10 @@
 {"ps_nmadd",	A  (4,	31,0),	A_MASK,      PPCPS,	PPCNONE,	{FRT, FRA, FRC, FRB}},
 {"ps_nmadd.",	A  (4,	31,1),	A_MASK,      PPCPS,	PPCNONE,	{FRT, FRA, FRC, FRB}},
 {"ps_cmpo0",	X  (4,	32), X_MASK|(3<<21), PPCPS,	PPCNONE,	{BF, FRA, FRB}},
+{"vaddeuqm",	VXA(4,	60),	VXA_MASK,    PPCVEC2,	PPCNONE,	{VD, VA, VB, VC}},
+{"vaddecuq",	VXA(4,	61),	VXA_MASK,    PPCVEC2,	PPCNONE,	{VD, VA, VB, VC}},
+{"vsubeuqm",	VXA(4,	62),	VXA_MASK,    PPCVEC2,	PPCNONE,	{VD, VA, VB, VC}},
+{"vsubecuq",	VXA(4,	63),	VXA_MASK,    PPCVEC2,	PPCNONE,	{VD, VA, VB, VC}},
 {"vadduhm",	VX (4,	64),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vmaxuh",	VX (4,	66),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vrlh",	VX (4,	68),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
@@ -2889,6 +2917,8 @@
 {"vmaxuw",	VX (4,	130),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vrlw",	VX (4,	132),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vcmpequw",	VXR(4,	134,0), VXR_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"vmulouw",	VX (4,  136),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
+{"vmuluwm",	VX (4,  137),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"vmrghw",	VX (4,	140),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vpkuhus",	VX (4,	142),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"ps_mr",	XRC(4,	72,0),	XRA_MASK,    PPCPS,	PPCNONE,	{FRT, FRB}},
@@ -2896,12 +2926,17 @@
 {"machhwsu",	XO (4,	76,0,0),XO_MASK,     MULHW|PPCVLE,  PPCNONE,	{RT, RA, RB}},
 {"machhwsu.",	XO (4,	76,0,1),XO_MASK,     MULHW|PPCVLE,  PPCNONE,	{RT, RA, RB}},
 {"ps_cmpo1",	X  (4,	96), X_MASK|(3<<21), PPCPS,	PPCNONE,	{BF, FRA, FRB}},
+{"vaddudm",	VX (4, 192),	VX_MASK,     PPCVEC2,	PPCNONE,	{VD, VA, VB}},
+{"vmaxud",	VX (4, 194),	VX_MASK,     PPCVEC2,	PPCNONE,	{VD, VA, VB}},
+{"vrld",	VX (4, 196),	VX_MASK,     PPCVEC2,	PPCNONE,	{VD, VA, VB}},
 {"vcmpeqfp",	VXR(4, 198,0),	VXR_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"vcmpequd",	VXR(4, 199,0),	VXR_MASK,    PPCVEC2,	PPCNONE,	{VD, VA, VB}},
 {"vpkuwus",	VX (4, 206),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"machhws",	XO (4, 108,0,0),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"machhws.",	XO (4, 108,0,1),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"nmachhws",	XO (4, 110,0,0),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"nmachhws.",	XO (4, 110,0,1),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
+{"vadduqm",	VX (4, 256),	VX_MASK,     PPCVEC2,	PPCNONE,	{VD, VA, VB}},
 {"vmaxsb",	VX (4, 258),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vslb",	VX (4, 260),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vmulosb",	VX (4, 264),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
@@ -2914,6 +2949,7 @@
 {"mulchwu.",	XRC(4, 136,1),	X_MASK,      MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"macchwu",	XO (4, 140,0,0),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"macchwu.",	XO (4, 140,0,1),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
+{"vaddcuq",	VX (4, 320),	VX_MASK,     PPCVEC2,      PPCNONE,	{VD, VA, VB}},
 {"vmaxsh",	VX (4, 322),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vslh",	VX (4, 324),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vmulosh",	VX (4, 328),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
@@ -2929,11 +2965,13 @@
 {"vaddcuw",	VX (4, 384),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vmaxsw",	VX (4, 386),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vslw",	VX (4, 388),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"vmulosw",	VX (4, 392),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"vexptefp",	VX (4, 394),	VXVA_MASK,   PPCVEC|PPCVLE, PPCNONE,	{VD, VB}},
 {"vmrglw",	VX (4, 396),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vpkshss",	VX (4, 398),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"macchwsu",	XO (4, 204,0,0),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"macchwsu.",	XO (4, 204,0,1),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
+{"vmaxsd",	VX (4, 450),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"vsl",		VX (4, 452),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vcmpgefp",	VXR(4, 454,0),	VXR_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vlogefp",	VX (4, 458),	VXVA_MASK,   PPCVEC|PPCVLE, PPCNONE,	{VD, VB}},
@@ -3017,6 +3055,7 @@
 {"evfsnabs",	VX (4, 645),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA}},
 {"evfsneg",	VX (4, 646),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA}},
 {"vcmpgtuw",	VXR(4, 646,0),	VXR_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"vmuleuw",	VX (4, 648),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"evfsmul",	VX (4, 648),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evfsdiv",	VX (4, 649),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"vrfip",	VX (4, 650),	VXVA_MASK,   PPCVEC|PPCVLE, PPCNONE,	{VD, VB}},
@@ -3042,11 +3081,13 @@
 {"cput",	APU(4, 348,0),	APU_RT_MASK, PPC405,	PPCNONE,	{RA, FSL}},
 {"efsadd",	VX (4, 704),	VX_MASK,     PPCEFS|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"efssub",	VX (4, 705),	VX_MASK,     PPCEFS|PPCVLE, PPCNONE,	{RS, RA, RB}},
+{"vminud",	VX (4, 706),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"efsabs",	VX (4, 708),	VX_MASK,     PPCEFS|PPCVLE, PPCNONE,	{RS, RA}},
 {"vsr",		VX (4, 708),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"efsnabs",	VX (4, 709),	VX_MASK,     PPCEFS|PPCVLE, PPCNONE,	{RS, RA}},
 {"efsneg",	VX (4, 710),	VX_MASK,     PPCEFS|PPCVLE, PPCNONE,	{RS, RA}},
 {"vcmpgtfp",	VXR(4, 710,0),	VXR_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"vcmpgtud",	VXR(4, 711,0),	VXR_MASK,    PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"efsmul",	VX (4, 712),	VX_MASK,     PPCEFS|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"efsdiv",	VX (4, 713),	VX_MASK,     PPCEFS|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"vrfim",	VX (4, 714),	VXVA_MASK,   PPCVEC|PPCVLE, PPCNONE,	{VD, VB}},
@@ -3166,12 +3207,16 @@
 {"vminsw",	VX (4, 898),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vsraw",	VX (4, 900),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vcmpgtsw",	VXR(4, 902,0),	VXR_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"vmulesw",	VX (4, 904),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"vctuxs",	VX (4, 906),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VB, UIMM}},
 {"vcfpuxws",	VX (4, 906),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VB, UIMM}},
 {"vspltisw",	VX (4, 908),	VXVB_MASK,   PPCVEC|PPCVLE, PPCNONE,	{VD, SIMM}},
 {"maclhwsu",	XO (4, 460,0,0),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"maclhwsu.",	XO (4, 460,0,1),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
+{"vminsd",	VX (4, 962),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
+{"vsrad",	VX (4, 964),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"vcmpbfp",	VXR(4, 966,0),	VXR_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"vcmpgtsd",	VXR(4, 967,0),	VXR_MASK,    PPCVEC2,	PPCNONE,	{VD, VA, VB}},
 {"vctsxs",	VX (4, 970),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VB, UIMM}},
 {"vcfpsxws",	VX (4, 970),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VB, UIMM}},
 {"vupklpx",	VX (4, 974),	VXVA_MASK,   PPCVEC|PPCVLE, PPCNONE,	{VD, VB}},
@@ -3180,6 +3225,7 @@
 {"nmaclhws",	XO (4, 494,0,0),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"nmaclhws.",	XO (4, 494,0,1),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"vsububm",	VX (4,1024),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"bcdadd.",	VX (4,1025),	VXPS_MASK,   PPCVEC2,	    PPCNONE,	{VD, VA, VB, PS}},
 {"vavgub",	VX (4,1026),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vabsdub",	VX (4,1027),	VX_MASK,     PPCVEC2,	PPCNONE,	{VD, VA, VB}},
 {"evmhessf",	VX (4,1027),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
@@ -3188,6 +3234,7 @@
 {"udi0fcm.",	APU(4, 515,0), APU_MASK, PPC405|PPC440, PPC476,		{URT, URA, URB}},
 {"udi0fcm",	APU(4, 515,1), APU_MASK, PPC405|PPC440, PPC476,		{URT, URA, URB}},
 {"evmhossf",	VX (4,1031),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
+{"vpmsumb",	VX (4,1032),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"evmheumi",	VX (4,1032),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evmhesmi",	VX (4,1033),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"vmaxfp",	VX (4,1034),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
@@ -3209,6 +3256,7 @@
 {"evmhosmia",	VX (4,1069),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evmhosmfa",	VX (4,1071),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"vsubuhm",	VX (4,1088),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"bcdsub.",	VX (4,1089),	VXPS_MASK,   PPCVEC2,	    PPCNONE,	{VD, VA, VB, PS}},
 {"vavguh",	VX (4,1090),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"vabsduh",	VX (4,1091),	VX_MASK,     PPCVEC2,	PPCNONE,	{VD, VA, VB}},
 {"vandc",	VX (4,1092),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
@@ -3216,11 +3264,13 @@
 {"udi1fcm.",	APU(4, 547,0), APU_MASK, PPC405|PPC440, PPC476,		{URT, URA, URB}},
 {"udi1fcm",	APU(4, 547,1), APU_MASK, PPC405|PPC440, PPC476,		{URT, URA, URB}},   
 {"evmwhssf",	VX (4,1095),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
+{"vpmsumh",	VX (4,1096),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"evmwlumi",	VX (4,1096),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"vminfp",	VX (4,1098),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"evmwhumi",	VX (4,1100),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"vsro",	VX (4,1100),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"evmwhsmi",	VX (4,1101),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
+{"vpkudum",	VX (4,1102),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"evmwhsmf",	VX (4,1103),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evmwssf",	VX (4,1107),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"machhwo",	XO (4,	44,1,0),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
@@ -3246,6 +3296,7 @@
 {"vabsduw",	VX (4,1155),	VX_MASK,     PPCVEC2,	PPCNONE,	{VD, VA, VB}},
 {"vmr",		VX (4,1156),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VBA}},
 {"vor",		VX (4,1156),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"vpmsumw",	VX (4,1160),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"vcmpequw.",	VXR(4, 134,1),	VXR_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"udi2fcm.",	APU(4, 579,0), APU_MASK, PPC405|PPC440, PPC476,		{URT, URA, URB}},
 {"udi2fcm",	APU(4, 579,1), APU_MASK, PPC405|PPC440, PPC476,		{URT, URA, URB}},   
@@ -3253,6 +3304,7 @@
 {"machhwsuo.",	XO (4,	76,1,1),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"ps_merge10",	XOPS(4,592,0),	XOPS_MASK,   PPCPS,	PPCNONE,	{FRT, FRA, FRB}},
 {"ps_merge10.",	XOPS(4,592,1),	XOPS_MASK,   PPCPS,	PPCNONE,	{FRT, FRA, FRB}},
+{"vsubudm",	VX (4,1216),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"evaddusiaaw",	VX (4,1216),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA}},
 {"evaddssiaaw",	VX (4,1217),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA}},
 {"evsubfusiaaw",VX (4,1218),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA}},
@@ -3262,18 +3314,22 @@
 {"evdivws",	VX (4,1222),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"vcmpeqfp.",	VXR(4, 198,1),	VXR_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"udi3fcm.",	APU(4, 611,0), APU_MASK, PPC405|PPC440, PPC476,		{URT, URA, URB}},
+{"vcmpequd.",	VXR(4, 199,1),	VXR_MASK,    PPCVEC2,	PPCNONE,	{VD, VA, VB}},
 {"udi3fcm",	APU(4, 611,1), APU_MASK, PPC405|PPC440, PPC476,		{URT, URA, URB}},   
 {"evdivwu",	VX (4,1223),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
+{"vpmsumd",	VX (4,1224),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"evaddumiaaw",	VX (4,1224),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA}},
 {"evaddsmiaaw",	VX (4,1225),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA}},
 {"evsubfumiaaw",VX (4,1226),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA}},
 {"evsubfsmiaaw",VX (4,1227),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA}},
+{"vpkudus",	VX (4,1230),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"machhwso",	XO (4, 108,1,0),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"machhwso.",	XO (4, 108,1,1),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"nmachhwso",	XO (4, 110,1,0),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"nmachhwso.",	XO (4, 110,1,1),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"ps_merge11",	XOPS(4,624,0),	XOPS_MASK,   PPCPS,	PPCNONE,	{FRT, FRA, FRB}},
 {"ps_merge11.",	XOPS(4,624,1),	XOPS_MASK,   PPCPS,	PPCNONE,	{FRT, FRA, FRB}},
+{"vsubuqm",	VX (4,1280),	VX_MASK,     PPCVEC2,	PPCNONE,	{VD, VA, VB}},
 {"evmheusiaaw",	VX (4,1280),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evmhessiaaw",	VX (4,1281),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"vavgsb",	VX (4,1282),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
@@ -3286,8 +3342,11 @@
 {"udi4fcm",	APU(4, 643,1), APU_MASK, PPC405|PPC440, PPC476,		{URT, URA, URB}},
 {"evmhossfaaw",	VX (4,1287),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evmheumiaaw",	VX (4,1288),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
+{"vcipher",	VX (4,1288),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
+{"vcipherlast",	VX (4,1289),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"evmhesmiaaw",	VX (4,1289),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evmhesmfaaw",	VX (4,1291),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
+{"vgbbd",	VX (4,1292),	VXVA_MASK,   PPCVEC2,	    PPCNONE,	{VD, VB}},
 {"evmhoumiaaw",	VX (4,1292),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evmhosmiaaw",	VX (4,1293),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evmhosmfaaw",	VX (4,1295),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
@@ -3299,13 +3358,19 @@
 {"evmhogumiaa",	VX (4,1324),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evmhogsmiaa",	VX (4,1325),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evmhogsmfaa",	VX (4,1327),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
+{"vsubcuq",	VX (4,1344),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"evmwlusiaaw",	VX (4,1344),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evmwlssiaaw",	VX (4,1345),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"vavgsh",	VX (4,1346),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"vorc",	VX (4,1348),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"udi5fcm.",	APU(4, 675,0), APU_MASK, PPC405|PPC440, PPC476,		{URT, URA, URB}},
 {"udi5fcm",	APU(4, 675,1), APU_MASK, PPC405|PPC440, PPC476,		{URT, URA, URB}},
+{"vncipher",	VX (4,1352),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"evmwlumiaaw",	VX (4,1352),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
+{"vncipherlast",VX (4,1353),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"evmwlsmiaaw",	VX (4,1353),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
+{"vbpermq",	VX (4,1356),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
+{"vpksdus",	VX (4,1358),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"evmwssfaa",	VX (4,1363),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"macchwo",	XO (4, 172,1,0),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"evmwumiaa",	VX (4,1368),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
@@ -3319,6 +3384,7 @@
 {"evmhessianw",	VX (4,1409),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"vavgsw",	VX (4,1410),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"evmhessfanw",	VX (4,1411),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
+{"vnand",	VX (4,1412),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"evmhousianw",	VX (4,1412),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evmhossianw",	VX (4,1413),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"udi6fcm.",	APU(4, 707,0), APU_MASK, PPC405|PPC440, PPC476,		{URT, URA, URB}},
@@ -3340,11 +3406,14 @@
 {"evmhogsmfan",	VX (4,1455),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evmwlusianw",	VX (4,1472),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evmwlssianw",	VX (4,1473),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
+{"vsld",	VX (4,1476),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"vcmpgefp.",	VXR(4, 454,1),	VXR_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"udi7fcm.",	APU(4, 739,0), APU_MASK, PPC405|PPC440, PPC476,		{URT, URA, URB}},
 {"udi7fcm",	APU(4, 739,1), APU_MASK, PPC405|PPC440, PPC476,		{URT, URA, URB}},
+{"vsbox",	VX (4,1480),	VXVB_MASK,   PPCVEC2,	    PPCNONE,	{VD, VA}},
 {"evmwlumianw",	VX (4,1480),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"evmwlsmianw",	VX (4,1481),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
+{"vpksdss",	VX (4,1486),	VX_MASK,     PPCVEC2,	    PPCNONE,	{VD, VA, VB}},
 {"evmwssfan",	VX (4,1491),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
 {"macchwso",	XO (4, 236,1,0),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"evmwumian",	VX (4,1496),	VX_MASK,     PPCSPE|PPCVLE, PPCNONE,	{RS, RA, RB}},
@@ -3365,15 +3434,25 @@
 {"vsum4shs",	VX (4,1608),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"udi9fcm.",	APU(4, 804,0),	APU_MASK,    PPC440,	PPC476,		{URT, URA, URB}},
 {"udi9fcm",	APU(4, 804,1),	APU_MASK,    PPC440,	PPC476,		{URT, URA, URB}},
+{"vupkhsw",	VX (4,1614),	VXVA_MASK,   PPCVEC2,	    PPCNONE,	{VD, VB}},
 {"vsubuws",	VX (4,1664),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"vshasigmaw",	VX (4,1666),	VX_MASK,     PPCVEC2,	PPCNONE,	{VD, VA, ST, SIX}},
+{"veqv",	VX (4,1668),	VX_MASK,     PPCVEC2,	PPCNONE,	{VD, VA, VB}},
 {"vcmpgtuw.",	VXR(4, 646,1),	VXR_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"udi10fcm.",	APU(4, 835,0),	APU_MASK,    PPC440,	PPC476,		{URT, URA, URB}},
 {"udi10fcm",	APU(4, 835,1),	APU_MASK,    PPC440,	PPC476,		{URT, URA, URB}},
 {"vsum2sws",	VX (4,1672),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"vmrgow",	VX (4,1676),	VX_MASK,     PPCVEC2,	PPCNONE,	{VD, VA, VB}},
+{"vshasigmad",	VX (4,1730),	VX_MASK,     PPCVEC2,	PPCNONE,	{VD, VA, ST, SIX}},
+{"vsrd",	VX (4,1732),	VX_MASK,     PPCVEC2,	PPCNONE,	{VD, VA, VB}},
 {"vcmpgtfp.",	VXR(4, 710,1),	VXR_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"udi11fcm.",	APU(4, 867,0),	APU_MASK,    PPC440,	PPC476,		{URT, URA, URB}},
+{"vcmpgtud.",	VXR(4, 711,1),	VXR_MASK,    PPCVEC2,	PPCNONE,	{VD, VA, VB}},
 {"udi11fcm",	APU(4, 867,1),	APU_MASK,    PPC440,	PPC476,		{URT, URA, URB}},
+{"vupklsw",	VX (4,1742),	VXVA_MASK,   PPCVEC2,	PPCNONE,	{VD, VB}},
 {"vsubsbs",	VX (4,1792),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"vclzb",	VX (4,1794),	VXVA_MASK,   PPCVEC2,	PPCNONE,	{VD, VB}},
+{"vpopcntb",	VX (4,1795),	VXVA_MASK,   PPCVEC2,	PPCNONE,	{VD, VB}},
 {"vcmpgtsb.",	VXR(4, 774,1),	VXR_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"udi12fcm.",	APU(4, 899,0),	APU_MASK,    PPC440,	PPC476,		{URT, URA, URB}},
 {"udi12fcm",	APU(4, 899,1),	APU_MASK,    PPC440,	PPC476,		{URT, URA, URB}},
@@ -3381,6 +3460,8 @@
 {"maclhwuo",	XO (4, 396,1,0),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"maclhwuo.",	XO (4, 396,1,1),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"vsubshs",	VX (4,1856),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"vclzh",	VX (4,1858),	VXVA_MASK,   PPCVEC2,	PPCNONE,	{VD, VB}},
+{"vpopcnth",	VX (4,1859),	VXVA_MASK,   PPCVEC2,	PPCNONE,	{VD, VB}},
 {"vcmpgtsh.",	VXR(4, 838,1),	VXR_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"udi13fcm.",	APU(4, 931,0),	APU_MASK,    PPC440,	PPC476,		{URT, URA, URB}},
 {"udi13fcm",	APU(4, 931,1),	APU_MASK,    PPC440,	PPC476,		{URT, URA, URB}},
@@ -3389,14 +3470,20 @@
 {"nmaclhwo",	XO (4, 430,1,0),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"nmaclhwo.",	XO (4, 430,1,1),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"vsubsws",	VX (4,1920),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"vclzw",	VX (4,1922),	VXVA_MASK,   PPCVEC2,	PPCNONE,	{VD, VB}},
+{"vpopcntw",	VX (4,1923),	VXVA_MASK,   PPCVEC2,	PPCNONE,	{VD, VB}},
 {"vcmpgtsw.",	VXR(4, 902,1),	VXR_MASK,    PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
 {"udi14fcm.",	APU(4, 963,0),	APU_MASK,    PPC440,	PPC476,		{URT, URA, URB}},
 {"udi14fcm",	APU(4, 963,1),	APU_MASK,    PPC440,	PPC476,		{URT, URA, URB}},
 {"vsumsws",	VX (4,1928),	VX_MASK,     PPCVEC|PPCVLE, PPCNONE,	{VD, VA, VB}},
+{"vmrgew",	VX (4,1932),	VX_MASK,     PPCVEC2,	PPCNONE,	{VD, VA, VB}},
 {"maclhwsuo",	XO (4, 460,1,0),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"maclhwsuo.",	XO (4, 460,1,1),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
+{"vclzd",	VX (4,1986),	VXVA_MASK,   PPCVEC2,	PPCNONE,	{VD, VB}},
+{"vpopcntd",	VX (4,1987),	VXVA_MASK,   PPCVEC2,	PPCNONE,	{VD, VB}},
 {"vcmpbfp.",	VXR(4, 966,1),	VXR_MASK,    PPCVEC,	PPCNONE,	{VD, VA, VB}},
 {"udi15fcm.",	APU(4, 995,0),	APU_MASK,    PPC440,	PPC476,		{URT, URA, URB}},
+{"vcmpgtsd.",	VXR(4, 967,1),	VXR_MASK,    PPCVEC2,	PPCNONE,	{VD, VA, VB}},
 {"udi15fcm",	APU(4, 995,1),	APU_MASK,    PPC440,	PPC476,		{URT, URA, URB}},
 {"maclhwso",	XO (4, 492,1,0),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"maclhwso.",	XO (4, 492,1,1),XO_MASK,     MULHW|PPCVLE, PPCNONE,	{RT, RA, RB}},
@@ -3968,6 +4055,8 @@
 
 {"crandc",	XL(19,129),	XL_MASK,     COM,	PPCNONE,	{BT, BA, BB}},
 
+{"rfebb",	XL(19,146),	XLS_MASK,    POWER8,	PPCNONE,	{SXL}},
+
 {"isync",	XL(19,150),	0xffffffff,  PPCCOM,	PPCNONE,	{0}},
 {"ics",		XL(19,150),	0xffffffff,  PWRCOM,	PPCNONE,	{0}},
 
@@ -4151,6 +4240,13 @@
 {"bcctrl",  XLLK(19,528,1),		XLBH_MASK,     PPCCOM,	 PPCNONE,	{BO, BI, BH}},
 {"bccl",    XLLK(19,528,1),		XLBB_MASK,     PWRCOM,	 PPCNONE,	{BO, BI}},
 
+{"bctar-",  XLYLK(19,560,0,0),		XLYBB_MASK,    POWER8,	 PPCNONE,	{BOE, BI}},
+{"bctarl-", XLYLK(19,560,0,1),		XLYBB_MASK,    POWER8,	 PPCNONE,	{BOE, BI}},
+{"bctar+",  XLYLK(19,560,1,0),		XLYBB_MASK,    POWER8,	 PPCNONE,	{BOE, BI}},
+{"bctarl+", XLYLK(19,560,1,1),		XLYBB_MASK,    POWER8,	 PPCNONE,	{BOE, BI}},
+{"bctar",   XLLK(19,560,0),		XLBH_MASK,     POWER8,	 PPCNONE,	{BO, BI, BH}},
+{"bctarl",  XLLK(19,560,1),		XLBH_MASK,     POWER8,	 PPCNONE,	{BO, BI, BH}},
+
 {"rlwimi",	M(20,0),	M_MASK,      PPCCOM,	PPCNONE,	{RA, RS, SH, MBE, ME}},
 {"rlimi",	M(20,0),	M_MASK,      PWRCOM,	PPCNONE,	{RA, RS, SH, MBE, ME}},
 
@@ -4279,6 +4375,8 @@
 {"mulhwu",	XO(31,11,0,0),	XO_MASK,     PPC|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"mulhwu.",	XO(31,11,0,1),	XO_MASK,     PPC|PPCVLE, PPCNONE,	{RT, RA, RB}},
 
+{"lxsiwzx",	X(31,12),	XX1_MASK,    PPCVSX2,	PPCNONE,	{XT6, RA0, RB}},
+
 {"isellt",	X(31,15),	X_MASK,      PPCISEL,	PPCNONE,	{RT, RA0, RB}},
 
 {"tlbilxlpid",	XTO(31,18,0),	XTO_MASK, E500MC|PPCA2,	PPCNONE,	{0}},
@@ -4319,6 +4417,9 @@
 {"maskg.",	XRC(31,29,1),	X_MASK,      M601,	PPCA2,		{RA, RS, RB}},
 
 {"ldepx",	X(31,29),	X_MASK,      E500MC|PPCA2|PPCVLE, PPCNONE, {RT, RA0, RB}},
+
+{"waitasec",	X(31,30),	XRTRARB_MASK,POWER8,	PPCNONE,	{0}},
+
 {"lwepx",	X(31,31),	X_MASK,	     E500MC|PPCA2|PPCVLE, PPCNONE, {RT, RA0, RB}},
 
 {"cmplw",	XOPL(31,32,0),	XCMPL_MASK,  PPCCOM|PPCVLE, PPCNONE,	{OBF, RA, RB}},
@@ -4338,6 +4439,8 @@
 
 {"addg6s",	XO(31,74,0,0),	XO_MASK,     POWER6,	PPCNONE,	{RT, RA, RB}},
 
+{"lxsiwax",	X(31,76),	XX1_MASK,    PPCVSX2,	PPCNONE,	{XT6, RA0, RB}},
+
 {"iseleq",	X(31,79),	X_MASK,      PPCISEL,	PPCNONE,	{RT, RA0, RB}},
 
 {"isel",	XISEL(31,15), XISEL_MASK, PPCISEL|TITAN|PPCVLE, PPCNONE, {RT, RA0, RB, CRB}},
@@ -4347,6 +4450,9 @@
 {"subf.",	XO(31,40,0,1),	XO_MASK,     PPC|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"sub.",	XO(31,40,0,1),	XO_MASK,     PPC|PPCVLE, PPCNONE,	{RT, RB, RA}},
 
+{"mfvsrd",	X(31,51),	XX1RB_MASK,   PPCVSX2,	PPCNONE,	{RA, XS6}},
+{"mffprd",	X(31,51),	XX1RB_MASK|1, PPCVSX2,	PPCNONE,	{RA, FRS}},
+{"mfvrd",	X(31,51)|1,	XX1RB_MASK|1, PPCVSX2,	PPCNONE,	{RA, VS}},
 {"eratilx",	X(31,51),	X_MASK,	     PPCA2,	PPCNONE,	{ERAT_T, RA, RB}},
 
 {"lbarx",	X(31,52),	XEH_MASK,    POWER7|PPCVLE, PPCNONE,	{RT, RA0, RB, EH}},
@@ -4424,6 +4530,10 @@
 
 {"mtsrdin",	X(31,114),	XRA_MASK,    PPC64,	PPCNONE,	{RS, RB}},
 
+{"mffprwz",	X(31,115),	XX1RB_MASK|1, PPCVSX2,	PPCNONE,	{RA, FRS}},
+{"mfvrwz",	X(31,115)|1,	XX1RB_MASK|1, PPCVSX2,	PPCNONE,	{RA, VS}},
+{"mfvsrwz",	X(31,115),	XX1RB_MASK,   PPCVSX2,	PPCNONE,	{RA, XS6}},
+
 {"lharx",	X(31,116),	XEH_MASK,    POWER7|PPCVLE, PPCNONE,	{RT, RA0, RB, EH}},
 
 {"clf",		X(31,118),	XTO_MASK,    POWER,	PPCNONE,	{RA, RB}},
@@ -4456,6 +4566,9 @@
 {"adde.",	XO(31,138,0,1),	XO_MASK,     PPCCOM|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"ae.",		XO(31,138,0,1),	XO_MASK,     PWRCOM,	PPCNONE,	{RT, RA, RB}},
 
+{"stxsiwx",	X(31,140),	XX1_MASK,    PPCVSX2,	PPCNONE,	{XS6, RA0, RB}},
+
+{"msgsndp",	XRTRA(31,142,0,0), XRTRA_MASK, POWER8,	PPCNONE,	{RB}},
 {"dcbtstlse",	X(31,142),	X_MASK,      PPCCHLK,	E500MC,		{CT, RA0, RB}},
 
 {"mtcr",	XFXM(31,144,0xff,0), XRARB_MASK, COM,	PPCNONE,	{RS}},
@@ -4464,6 +4577,8 @@
 
 {"mtmsr",	X(31,146),	XRLARB_MASK, COM|PPCVLE, PPCNONE,	{RS, A_L}},
 
+{"mtsle",	X(31,147),    XRTLRARB_MASK, POWER8,	PPCNONE,	{L}},
+
 {"eratsx",	XRC(31,147,0),	X_MASK,	     PPCA2,	PPCNONE,	{RT, RA0, RB}},
 {"eratsx.",	XRC(31,147,1),	X_MASK,	     PPCA2,	PPCNONE,	{RT, RA0, RB}},
 
@@ -4493,14 +4608,19 @@
 {"stvehx",	X(31,167),	X_MASK,      PPCVEC,	PPCNONE,	{VS, RA0, RB}},
 {"sthfcmx",	APU(31,167,0), 	APU_MASK,    PPC405,	PPCNONE,	{FCRT, RA, RB}},
 
+{"msgclrp",	XRTRA(31,174,0,0), XRTRA_MASK, POWER8,	PPCNONE,	{RB}},
 {"dcbtlse",	X(31,174),	X_MASK,      PPCCHLK,	E500MC,		{CT, RA0, RB}},
 
 {"mtmsrd",	X(31,178),	XRLARB_MASK, PPC64,	PPCNONE,	{RS, A_L}},
 
+{"mtvsrd",	X(31,179),	XX1RB_MASK,   PPCVSX2,	PPCNONE,	{XT6, RA}},
+{"mtfprd",	X(31,179),	XX1RB_MASK|1, PPCVSX2,	PPCNONE,	{FRT, RA}},
+{"mtvrd",	X(31,179)|1,	XX1RB_MASK|1, PPCVSX2,	PPCNONE,	{VD, RA}},
 {"eratre",	X(31,179),	X_MASK,	     PPCA2,	PPCNONE,	{RT, RA, WS}},
 
 {"stdux",	X(31,181),	X_MASK,      PPC64|PPCVLE, PPCNONE,	{RS, RAS, RB}},
 
+{"stqcx.",	XRC(31,182,1),	X_MASK,      POWER8,	PPCNONE,	{RSQ, RA0, RB}},
 {"wchkall",	X(31,182),	X_MASK,      PPCA2,	PPCNONE,	{OBF}},
 
 {"stwux",	X(31,183),	X_MASK,      PPCCOM|PPCVLE, PPCNONE,	{RS, RAS, RB}},
@@ -4530,6 +4650,9 @@
 
 {"mtsr",	X(31,210), XRB_MASK|(1<<20), COM,	NON32,  	{SR, RS}},
 
+{"mtfprwa",	X(31,211),	XX1RB_MASK|1, PPCVSX2,	PPCNONE,	{FRT, RA}},
+{"mtvrwa",	X(31,211)|1,	XX1RB_MASK|1, PPCVSX2,	PPCNONE,	{VD, RA}},
+{"mtvsrwa",	X(31,211),	XX1RB_MASK,   PPCVSX2,	PPCNONE,	{XT6, RA}},
 {"eratwe",	X(31,211),	X_MASK,	     PPCA2,	PPCNONE,	{RS, RA, WS}},
 
 {"ldawx.",	XRC(31,212,1),	X_MASK,	     PPCA2,	PPCNONE,	{RT, RA0, RB}},
@@ -4574,6 +4697,10 @@
 {"mtsrin",	X(31,242),	XRA_MASK,    PPC,	NON32,  	{RS, RB}},
 {"mtsri",	X(31,242),	XRA_MASK,    POWER,	NON32,		{RS, RB}},
 
+{"mtfprwz",	X(31,243),	XX1RB_MASK|1, PPCVSX2,	PPCNONE,	{FRT, RA}},
+{"mtvrwz",	X(31,243)|1,	XX1RB_MASK|1, PPCVSX2,	PPCNONE,	{VD, RA}},
+{"mtvsrwz",	X(31,243),	XX1RB_MASK,   PPCVSX2,	PPCNONE,	{XT6, RA}},
+
 {"dcbtstt",	XRT(31,246,0x10), XRT_MASK,  POWER7,	PPCNONE,	{RA0, RB}},
 {"dcbtst",	X(31,246),	X_MASK,      POWER4,	PPCNONE,	{RA0, RB, CT}},
 {"dcbtst",	X(31,246),	X_MASK,      PPC|PPCVLE, POWER4,	{CT, RA0, RB}},
@@ -4611,6 +4738,8 @@
 
 {"mfapidi",	X(31,275),	X_MASK,      BOOKE,	TITAN,  	{RT, RA}},
 
+{"lqarx",	X(31,276),	XEH_MASK,    POWER8,	PPCNONE,	{RTQ, RAX, RBX, EH}},
+
 {"lscbx",	XRC(31,277,0),	X_MASK,      M601,	PPCNONE,	{RT, RA, RB}},
 {"lscbx.",	XRC(31,277,1),	X_MASK,      M601,	PPCNONE,	{RT, RA, RB}},
 
@@ -4632,6 +4761,8 @@
 {"lvexhx",	X(31,293),	X_MASK,      PPCVEC2,	PPCNONE,	{VD, RA0, RB}},
 {"lvepx",	X(31,295),	X_MASK,      PPCVEC2|PPCVLE, PPCNONE,	{VD, RA0, RB}},
 
+{"mfbhrbe",	X(31,302),	X_MASK,      POWER8,	PPCNONE,	{RT, BHRBE}},
+
 {"tlbie",	X(31,306),	XRTLRA_MASK, PPC,	TITAN,  	{RB, L}},
 {"tlbi",	X(31,306),	XRT_MASK,    POWER,	PPCNONE,	{RA0, RB}},
 
@@ -4940,6 +5071,8 @@
 
 {"slbmte",	X(31,402),	XRA_MASK,    PPC64,	PPCNONE,	{RS, RB}},
 
+{"pbt.",	XRC(31,404,1),	X_MASK,      POWER8,	PPCNONE,	{RS, RA0, RB}},
+
 {"icswx",	XRC(31,406,0),	X_MASK,   POWER7|PPCA2,	PPCNONE,	{RS, RA, RB}},
 {"icswx.",	XRC(31,406,1),	X_MASK,   POWER7|PPCA2,	PPCNONE,	{RS, RA, RB}},
 
@@ -4961,6 +5094,8 @@
 {"divwe",	XO(31,427,0,0),	XO_MASK,  POWER7|PPCA2,	PPCNONE,	{RT, RA, RB}},
 {"divwe.",	XO(31,427,0,1),	XO_MASK,  POWER7|PPCA2,	PPCNONE,	{RT, RA, RB}},
 
+{"clrbhrb",	X(31,430),	0xffffffff,  POWER8,	PPCNONE,	{0}},
+
 {"slbie",	X(31,434),	XRTRA_MASK,  PPC64,	PPCNONE,	{RB}},
 
 {"ecowx",	X(31,438),	X_MASK,      PPC,	TITAN,  	{RT, RA0, RB}},
@@ -5249,6 +5384,8 @@
 {"addco.",	XO(31,10,1,1),	XO_MASK,     PPCCOM|PPCVLE, PPCNONE,	{RT, RA, RB}},
 {"ao.",		XO(31,10,1,1),	XO_MASK,     PWRCOM,	PPCNONE,	{RT, RA, RB}},
 
+{"lxsspx",	X(31,524),	XX1_MASK,    PPCVSX2,	PPCNONE,	{XT6, RA0, RB}},
+
 {"clcs",	X(31,531),	XRB_MASK,    M601,	PPCNONE,	{RT, RA}},
 
 {"ldbrx",	X(31,532),	X_MASK, CELL|POWER7|PPCA2, PPCNONE,	{RT, RA0, RB}},
@@ -5343,6 +5480,8 @@
 {"stvlx",	X(31,647),	X_MASK,      CELL,	PPCNONE,	{VS, RA0, RB}},
 {"stbfcmux",	APU(31,647,0), 	APU_MASK,    PPC405,	PPCNONE,	{FCRT, RA, RB}},
 
+{"stxsspx",	X(31,652),	XX1_MASK,    PPCVSX2,	PPCNONE,	{XS6, RA0, RB}},
+
 {"tbegin.",	XRC(31,654,1), XRTLRARB_MASK,PPCHTM,	PPCNONE,	{HTM_R}},
 
 {"subfeo",	XO(31,136,1,0),	XO_MASK, PPCCOM|PPCVLE, PPCNONE,	{RT, RA, RB}},
@@ -5528,6 +5667,7 @@
 {"divo.",	XO(31,331,1,1),	XO_MASK,     M601,	PPCNONE,	{RT, RA, RB}},
 
 {"lxvd2x",	X(31,844),	XX1_MASK,    PPCVSX,	PPCNONE,	{XT6, RA0, RB}},
+{"lxvx",	X(31,844),	XX1_MASK,    PPCVSX,	PPCNONE,	{XT6, RA0, RB}},
 
 {"tabortwci.",	XRC(31,846,1),	X_MASK,      PPCHTM,	PPCNONE,	{TO, RA, HTM_SI}},
 
@@ -5639,6 +5779,7 @@
 {"divwuo.",	XO(31,459,1,1),	XO_MASK,     PPC|PPCVLE, PPCNONE,	{RT, RA, RB}},
 
 {"stxvd2x",	X(31,972),	XX1_MASK,    PPCVSX,	PPCNONE,	{XS6, RA0, RB}},
+{"stxvx",	X(31,972),	XX1_MASK,    PPCVSX,	PPCNONE,	{XS6, RA0, RB}},
 
 {"tlbld",	X(31,978),	XRTRA_MASK,  PPC, PPC403|BOOKE|PPCA2|PPC476, {RB}},
 {"tlbwehi",	XTLB(31,978,0),	XTLB_MASK,   PPC403,	PPCNONE,	{RT, RA}},
@@ -5871,14 +6012,25 @@
 {"fcfidus",	XRC(59,974,0),	XRA_MASK, POWER7|PPCA2,	PPCNONE,	{FRT, FRB}},
 {"fcfidus.",	XRC(59,974,1),	XRA_MASK, POWER7|PPCA2,	PPCNONE,	{FRT, FRB}},
 
+{"xsaddsp",	XX3(60,0),	XX3_MASK,    PPCVSX2,	PPCNONE,	{XT6, XA6, XB6}},
+{"xsmaddasp",	XX3(60,1),	XX3_MASK,    PPCVSX2,	PPCNONE,	{XT6, XA6, XB6}},
 {"xxsldwi",	XX3(60,2),	XX3SHW_MASK, PPCVSX,	PPCNONE,	{XT6, XA6, XB6, SHW}},
 {"xxsel",	XX4(60,3),	XX4_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6, XC6}},
+{"xssubsp",	XX3(60,8),	XX3_MASK,    PPCVSX2,	PPCNONE,	{XT6, XA6, XB6}},
+{"xsmaddmsp",	XX3(60,9),	XX3_MASK,    PPCVSX2,	PPCNONE,	{XT6, XA6, XB6}},
 {"xxspltd",	XX3(60,10),	XX3DM_MASK,  PPCVSX,	PPCNONE,	{XT6, XA6, XB6S, DMEX}},
 {"xxmrghd",	XX3(60,10),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
 {"xxswapd",	XX3(60,10)|(2<<8), XX3_MASK, PPCVSX,	PPCNONE,	{XT6, XA6, XB6S}},
 {"xxmrgld",	XX3(60,10)|(3<<8), XX3_MASK, PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
 {"xxpermdi",	XX3(60,10),	XX3DM_MASK,  PPCVSX,	PPCNONE,	{XT6, XA6, XB6, DM}},
+{"xsrsqrtesp",	XX2(60,10),	XX2_MASK,    PPCVSX2,	PPCNONE,	{XT6, XB6}},
+{"xssqrtsp",	XX2(60,11),	XX2_MASK,    PPCVSX2,	PPCNONE,	{XT6, XB6}},
+{"xsmulsp",	XX3(60,16),	XX3_MASK,    PPCVSX2,	PPCNONE,	{XT6, XA6, XB6}},
+{"xsmsubasp",	XX3(60,17),	XX3_MASK,    PPCVSX2,	PPCNONE,	{XT6, XA6, XB6}},
 {"xxmrghw",	XX3(60,18),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
+{"xsdivsp",	XX3(60,24),	XX3_MASK,    PPCVSX2,	PPCNONE,	{XT6, XA6, XB6}},
+{"xsmsubmsp",	XX3(60,25),	XX3_MASK,    PPCVSX2,	PPCNONE,	{XT6, XA6, XB6}},
+{"xsresp",	XX2(60,26),	XX2_MASK,    PPCVSX2,	PPCNONE,	{XT6, XB6}},
 {"xsadddp",	XX3(60,32),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
 {"xsmaddadp",	XX3(60,33),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
 {"xscmpudp",	XX3(60,35),	XX3BF_MASK,  PPCVSX,	PPCNONE,	{BF, XA6, XB6}},
@@ -5932,14 +6084,18 @@
 {"xvmsubmdp",	XX3(60,121),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
 {"xsrdpim",	XX2(60,121),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
 {"xvtdivdp",	XX3(60,125),	XX3BF_MASK,  PPCVSX,	PPCNONE,	{BF, XA6, XB6}},
+{"xsnmaddasp",	XX3(60,129),	XX3_MASK,    PPCVSX2,	PPCNONE,	{XT6, XA6, XB6}},
 {"xxland",	XX3(60,130),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
 {"xvcvspuxws",	XX2(60,136),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
+{"xsnmaddmsp",	XX3(60,137),	XX3_MASK,    PPCVSX2,	PPCNONE,	{XT6, XA6, XB6}},
 {"xvrspi",	XX2(60,137),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
 {"xxlandc",	XX3(60,138),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
 {"xvrsqrtesp",	XX2(60,138),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
 {"xvsqrtsp",	XX2(60,139),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
+{"xsnmsubasp",	XX3(60,145),	XX3_MASK,    PPCVSX2,	PPCNONE,	{XT6, XA6, XB6}},
 {"xxlor",	XX3(60,146),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
 {"xvcvspsxws",	XX2(60,152),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
+{"xsnmsubmsp",	XX3(60,153),	XX3_MASK,    PPCVSX2,	PPCNONE,	{XT6, XA6, XB6}},
 {"xvrspiz",	XX2(60,153),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
 {"xxlxor",	XX3(60,154),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
 {"xvresp",	XX2(60,154),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
@@ -5952,12 +6108,15 @@
 {"xsnmaddmdp",	XX3(60,169),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
 {"xvrspip",	XX2(60,169),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
 {"xvtsqrtsp",	XX2(60,170),	XX2BF_MASK,  PPCVSX,	PPCNONE,	{BF, XB6}},
+{"xxlorc",	XX3(60,170),	XX3_MASK,    PPCVSX2,	PPCNONE,	{XT6, XA6, XB6}},
 {"xvrspic",	XX2(60,171),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
 {"xscpsgndp",	XX3(60,176),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
 {"xsnmsubadp",	XX3(60,177),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
+{"xxlnand",	XX3(60,178),	XX3_MASK,    PPCVSX2,	PPCNONE,	{XT6, XA6, XB6}},
 {"xvcvsxwsp",	XX2(60,184),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
 {"xsnmsubmdp",	XX3(60,185),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
 {"xvrspim",	XX2(60,185),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
+{"xxleqv",	XX3(60,186),	XX3_MASK,    PPCVSX2,	PPCNONE,	{XT6, XA6, XB6}},
 {"xvmaxsp",	XX3(60,192),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
 {"xvnmaddasp",	XX3(60,193),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
 {"xvminsp",	XX3(60,200),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
@@ -5988,8 +6147,13 @@
 {"xvnmsubmdp",	XX3(60,249),	XX3_MASK,    PPCVSX,	PPCNONE,	{XT6, XA6, XB6}},
 {"xvrdpim",	XX2(60,249),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
 {"xscvdpsp",	XX2(60,265),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
+{"xscvdpspn",	XX2(60,267),	XX2_MASK,    PPCVSX2,	PPCNONE,	{XT6, XB6}},
+{"xsrsp",	XX2(60,281),	XX2_MASK,    PPCVSX2,	PPCNONE,	{XT6, XB6}},
+{"xscvuxdsp",	XX2(60,296),	XX2_MASK,    PPCVSX2,	PPCNONE,	{XT6, XB6}},
+{"xscvsxdsp",	XX2(60,312),	XX2_MASK,    PPCVSX2,	PPCNONE,	{XT6, XB6}},
 {"xscvdpuxds",	XX2(60,328),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
 {"xscvspdp",	XX2(60,329),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
+{"xscvspdpn",	XX2(60,331),	XX2_MASK,    PPCVSX2,	PPCNONE,	{XT6, XB6}},
 {"xscvdpsxds",	XX2(60,344),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
 {"xsabsdp",	XX2(60,345),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
 {"xscvuxddp",	XX2(60,360),	XX2_MASK,    PPCVSX,	PPCNONE,	{XT6, XB6}},
@@ -6225,6 +6389,8 @@
 {"denbcdq",	XRC(63,834,0),	X_MASK,      POWER6,	PPCNONE,	{S, FRTp, FRBp}},
 {"denbcdq.",	XRC(63,834,1),	X_MASK,      POWER6,	PPCNONE,	{S, FRTp, FRBp}},
 
+{"fmrgow",	X(63,838),	X_MASK,      PPCVSX2,	PPCNONE,	{FRT, FRA, FRB}},
+
 {"fcfid",	XRC(63,846,0),	XRA_MASK,    PPC64,	PPCNONE,	{FRT, FRB}},
 {"fcfid",	XRC(63,846,0),	XRA_MASK,    PPC476,	PPCNONE,	{FRT, FRB}},
 {"fcfid.",	XRC(63,846,1),	XRA_MASK,    PPC64,	PPCNONE,	{FRT, FRB}},
@@ -6239,6 +6405,8 @@
 {"fctiduz",	XRC(63,943,0),	XRA_MASK, POWER7|PPCA2,	PPCNONE,	{FRT, FRB}},
 {"fctiduz.",	XRC(63,943,1),	XRA_MASK, POWER7|PPCA2,	PPCNONE,	{FRT, FRB}},
 
+{"fmrgew",	X(63,966),	X_MASK,      PPCVSX2,	PPCNONE,	{FRT, FRA, FRB}},
+
 {"fcfidu",	XRC(63,974,0),	XRA_MASK, POWER7|PPCA2,	PPCNONE,	{FRT, FRB}},
 {"fcfidu.",	XRC(63,974,1),	XRA_MASK, POWER7|PPCA2,	PPCNONE,	{FRT, FRB}},
 };
diff --git a/opcodes/s390-opc.c b/opcodes/s390-opc.c
index 0ae5603..adfc5b4 100644
--- a/opcodes/s390-opc.c
+++ b/opcodes/s390-opc.c
@@ -388,8 +388,8 @@
 #define INSTR_RSE_CCRD   6, { C_8,C_12,D_20,B_16,0,0 }         /* e.g. lmh   */
 #define INSTR_RSE_RURD   6, { R_8,U4_12,D_20,B_16,0,0 }        /* e.g. icmh  */
 #define INSTR_RSL_R0RD   6, { D_20,L4_8,B_16,0,0,0 }           /* e.g. tp    */
-#define INSTR_RSL_LRDFU  6, { F_32,D_20,L4_8,B_16,U4_36,0 }    /* e.g. cdzt  */
-#define INSTR_RSL_LRDFEU 6, { FE_32,D_20,L4_8,B_16,U4_36,0 }   /* e.g. cxzt  */
+#define INSTR_RSL_LRDFU  6, { F_32,D_20,L8_8,B_16,U4_36,0 }    /* e.g. cdzt  */
+#define INSTR_RSL_LRDFEU 6, { FE_32,D_20,L8_8,B_16,U4_36,0 }   /* e.g. cxzt  */
 #define INSTR_RSI_RRP    4, { R_8,R_12,J16_16,0,0,0 }          /* e.g. brxh  */
 #define INSTR_RSY_RRRD   6, { R_8,R_12,D20_20,B_16,0,0 }       /* e.g. stmy  */
 #define INSTR_RSY_RERERD 6, { RE_8,RE_12,D20_20,B_16,0,0 }     /* e.g. cdsy  */