This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] MIPS: Verify the ISA mode and alignment of branch and jump targets


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9d862524f6ae9703fe8e264dd4785756d358570a

commit 9d862524f6ae9703fe8e264dd4785756d358570a
Author: Maciej W. Rozycki <macro@imgtec.com>
Date:   Tue Jul 19 13:59:28 2016 +0100

    MIPS: Verify the ISA mode and alignment of branch and jump targets
    
    Verify that the ISA mode of branch targets is the same as the referring
    relocation, so that an attempt to produce a branch between instructions
    encoded in different ISA modes each causes an error rather than silently
    producing non-functional code.  Make sure that no symbol or addend bits
    are silently truncated: terminate with an error if the relocation value
    calculated cannot be encoded in the relocatable field of a branch; for
    REL targets also applying to any intermediate addend.
    
    Also make jump target's alignment verification consistent with that for
    branches.
    
    This change will require an update to some obscure handcoded assembly
    sources which make branches to labels placed at data objects, however
    for microMIPS code only.  These labels will have to be updated with the
    `.insn' directive for containing code to assemble and link successfully.
    Such code is broken as any such labels have always been required by the
    microMIPS architecture specification[1][2] to be annotated this way for
    correct interpretation, and with our old code missing `.insn' directives
    caused labels to present different semantics depending on whether they
    were referred with branch (ISA bit ignored) or other relocations (ISA
    bit respected).
    
    Enforcing these checks however will ensure errors in building software,
    like mixed regular MIPS and microMIPS code links with branches between,
    will be diagnosed at the build time rather than causing odd run-time
    errors such as intermittent crashes.  It will also let cross-mode BAL
    instructions be converted to JALX instructions, with a separate change.
    
    References:
    
    [1] "MIPS Architecture for Programmers, Volume II-B: The microMIPS32
        Instruction Set", MIPS Technologies, Inc., Document Number: MD00582,
        Revision 5.04, January 15, 2014, Section 7.1 "Assembly-Level
        Compatibility", p. 533
    
    [2] "MIPS Architecture for Programmers, Volume II-B: The microMIPS64
        Instruction Set", MIPS Technologies, Inc., Document Number: MD00594,
        Revision 5.04, January 15, 2014, Section 8.1 "Assembly-Level
        Compatibility", p. 623
    
    	bfd/
    	* elfxx-mips.c (b_reloc_p): Add R_MICROMIPS_PC16_S1,
    	R_MICROMIPS_PC10_S1 and R_MICROMIPS_PC7_S1.
    	(branch_reloc_p): New function.
    	(mips_elf_calculate_relocation): Handle ISA mode determination
    	for relocations against section symbols, against absolute
    	symbols and absolute relocations.  Also set `*cross_mode_jump_p'
    	for branches.
    	<R_MIPS16_26, R_MIPS_26, R_MICROMIPS_26_S1>: Suppress alignment
    	checks for weak undefined symbols.  Also check target alignment
    	within the same ISA mode.
    	<R_MIPS_PC16, R_MIPS_GNU_REL16_S2>: Handle cross-mode branches
    	in the alignment check.
    	<R_MICROMIPS_PC7_S1>: Add an alignment check.
    	<R_MICROMIPS_PC10_S1>: Likewise.
    	<R_MICROMIPS_PC16_S1>: Likewise.
    	(mips_elf_perform_relocation): Report a failure for unsupported
    	same-mode JALX instructions and cross-mode branches.
    	(_bfd_mips_elf_relocate_section) <bfd_reloc_outofrange>: Add
    	error messages for jumps to misaligned addresses.
    
    	gas/
    	* config/tc-mips.c (mips_force_relocation): Also retain branch
    	relocations against MIPS16 and microMIPS symbols.
    	(fix_bad_cross_mode_jump_p): New function.
    	(fix_bad_same_mode_jalx_p): Likewise.
    	(fix_bad_misaligned_jump_p): Likewise.
    	(fix_bad_cross_mode_branch_p): Likewise.
    	(fix_bad_misaligned_branch_p): Likewise.
    	(fix_validate_branch): Likewise.
    	(md_apply_fix) <BFD_RELOC_MIPS_JMP, BFD_RELOC_MIPS16_JMP>
    	<BFD_RELOC_MICROMIPS_JMP>: Separate from BFD_RELOC_MIPS_SHIFT5,
    	etc.  Verify the ISA mode and alignment of the jump target.
    	<BFD_RELOC_MIPS_21_PCREL_S2>: Replace the inline alignment check
    	with a call to `fix_validate_branch'.
    	<BFD_RELOC_MIPS_26_PCREL_S2>: Likewise.
    	<BFD_RELOC_16_PCREL_S2>: Likewise.
    	<BFD_RELOC_MICROMIPS_7_PCREL_S1, BFD_RELOC_MICROMIPS_10_PCREL_S1>
    	<BFD_RELOC_MICROMIPS_16_PCREL_S1>: Retain the original addend.
    	Verify the ISA mode and alignment of the branch target.
    	(md_convert_frag): Verify the ISA mode and alignment of resolved
    	MIPS16 branch targets.
    	* testsuite/gas/mips/branch-misc-1.s: Annotate non-instruction
    	branch targets with `.insn'.
    	* testsuite/gas/mips/branch-misc-5.s: Likewise.
    	* testsuite/gas/mips/micromips@branch-misc-5-64.d: Update
    	accordingly.
    	* testsuite/gas/mips/micromips@branch-misc-5pic-64.d: Likewise.
    	* testsuite/gas/mips/micromips-branch-relax.s: Annotate
    	non-instruction branch target with `.insn'.
    	* testsuite/gas/mips/micromips.s: Replace microMIPS JALX targets
    	with external symbols.
    	* testsuite/gas/mips/micromips-insn32.d: Update accordingly.
    	* testsuite/gas/mips/micromips-noinsn32.d: Likewise.
    	* testsuite/gas/mips/micromips-trap.d: Likewise.
    	* testsuite/gas/mips/micromips.d: Likewise.
    	* testsuite/gas/mips/mips16.s: Annotate non-instruction branch
    	targets with `.insn'.
    	* testsuite/gas/mips/mips16.d: Update accordingly.
    	* testsuite/gas/mips/mips16-64.d: Likewise.
    	* testsuite/gas/mips/mips16-dwarf2.s: Annotate non-instruction
    	branch target with `.insn'.
    	* testsuite/gas/mips/relax-swap3.s: Likewise.
    	* testsuite/gas/mips/branch-local-2.l: New list test.
    	* testsuite/gas/mips/branch-local-3.l: New list test.
    	* testsuite/gas/mips/branch-local-n32-2.l: New list test.
    	* testsuite/gas/mips/branch-local-n32-3.l: New list test.
    	* testsuite/gas/mips/branch-local-n64-2.l: New list test.
    	* testsuite/gas/mips/branch-local-n64-3.l: New list test.
    	* testsuite/gas/mips/unaligned-jump-1.l: New list test.
    	* testsuite/gas/mips/unaligned-jump-2.l: New list test.
    	* testsuite/gas/mips/unaligned-jump-3.d: New test.
    	* testsuite/gas/mips/unaligned-jump-mips16-1.l: New list test.
    	* testsuite/gas/mips/unaligned-jump-mips16-2.l: New list test.
    	* testsuite/gas/mips/unaligned-jump-mips16-3.d: New test.
    	* testsuite/gas/mips/unaligned-jump-micromips-1.l: New list
    	test.
    	* testsuite/gas/mips/unaligned-jump-micromips-2.l: New list
    	test.
    	* testsuite/gas/mips/unaligned-jump-micromips-3.d: New test.
    	* testsuite/gas/mips/unaligned-branch-1.l: New list test.
    	* testsuite/gas/mips/unaligned-branch-2.l: New list test.
    	* testsuite/gas/mips/unaligned-branch-3.d: New test.
    	* testsuite/gas/mips/unaligned-branch-r6-1.l: New list test.
    	* testsuite/gas/mips/unaligned-branch-r6-2.l: New list test.
    	* testsuite/gas/mips/unaligned-branch-r6-3.l: New list test.
    	* testsuite/gas/mips/unaligned-branch-r6-4.l: New list test.
    	* testsuite/gas/mips/unaligned-branch-r6-5.d: New test.
    	* testsuite/gas/mips/unaligned-branch-r6-6.d: New test.
    	* testsuite/gas/mips/unaligned-branch-mips16-1.l: New list test.
    	* testsuite/gas/mips/unaligned-branch-mips16-2.l: New list test.
    	* testsuite/gas/mips/unaligned-branch-mips16-3.d: New test.
    	* testsuite/gas/mips/unaligned-branch-micromips-1.l: New list
    	test.
    	* testsuite/gas/mips/unaligned-branch-micromips-2.l: New list
    	test.
    	* testsuite/gas/mips/unaligned-branch-micromips-3.d: New test.
    	* testsuite/gas/mips/branch-local-2.s: New test source.
    	* testsuite/gas/mips/branch-local-3.s: New test source.
    	* testsuite/gas/mips/branch-local-n32-2.s: New test source.
    	* testsuite/gas/mips/branch-local-n32-3.s: New test source.
    	* testsuite/gas/mips/branch-local-n64-2.s: New test source.
    	* testsuite/gas/mips/branch-local-n64-3.s: New test source.
    	* testsuite/gas/mips/unaligned-jump-1.s: New test source.
    	* testsuite/gas/mips/unaligned-jump-2.s: New test source.
    	* testsuite/gas/mips/unaligned-jump-mips16-1.s: New test source.
    	* testsuite/gas/mips/unaligned-jump-mips16-2.s: New test source.
    	* testsuite/gas/mips/unaligned-jump-micromips-1.s: New test
    	source.
    	* testsuite/gas/mips/unaligned-jump-micromips-2.s: New test
    	source.
    	* testsuite/gas/mips/unaligned-branch-1.s: New test source.
    	* testsuite/gas/mips/unaligned-branch-2.s: New test source.
    	* testsuite/gas/mips/unaligned-branch-r6-1.s: New test source.
    	* testsuite/gas/mips/unaligned-branch-r6-2.s: New test source.
    	* testsuite/gas/mips/unaligned-branch-r6-3.s: New test source.
    	* testsuite/gas/mips/unaligned-branch-r6-4.s: New test source.
    	* testsuite/gas/mips/unaligned-branch-mips16-1.s: New test
    	source.
    	* testsuite/gas/mips/unaligned-branch-mips16-2.s: New test
    	source.
    	* testsuite/gas/mips/unaligned-branch-micromips-1.s: New test
    	source.
    	* testsuite/gas/mips/unaligned-branch-micromips-2.s: New test
    	source.
    	* testsuite/gas/mips/mips.exp: Run the new tests.
    
    	ld/
    	* testsuite/ld-mips-elf/unaligned-jalx-1.d: Update error message
    	expected.
    	* testsuite/ld-mips-elf/unaligned-jalx-addend-1.d: Likewise.
    	* testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-1.d:
    	Likewise.
    	* testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-1.d:
    	Likewise.
    	* testsuite/ld-mips-elf/unaligned-jalx-mips16-1.d: Likewise.
    	* testsuite/ld-mips-elf/unaligned-jalx-micromips-1.d: Likewise.
    	* testsuite/ld-mips-elf/undefweak-overflow.s: Add jumps,
    	microMIPS BAL and MIPS16 instructions.
    	* testsuite/ld-mips-elf/undefweak-overflow.d: Update
    	accordingly.
    	* testsuite/ld-mips-elf/unaligned-branch-2.d: New test.
    	* testsuite/ld-mips-elf/unaligned-branch-r6-1.d: New test.
    	* testsuite/ld-mips-elf/unaligned-branch-r6-2.d: New test.
    	* testsuite/ld-mips-elf/unaligned-branch-mips16.d: New test.
    	* testsuite/ld-mips-elf/unaligned-branch-micromips.d: New test.
    	* testsuite/ld-mips-elf/unaligned-jump-mips16.d: New test.
    	* testsuite/ld-mips-elf/unaligned-jump-micromips.d: New test.
    	* testsuite/ld-mips-elf/unaligned-jump.d: New test.
    	* testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.

Diff:
---
 bfd/ChangeLog                                      |  22 ++
 bfd/elfxx-mips.c                                   | 118 ++++++++-
 gas/ChangeLog                                      | 107 ++++++++
 gas/config/tc-mips.c                               | 280 +++++++++++++++++++--
 gas/testsuite/gas/mips/branch-local-2.l            |   5 +
 gas/testsuite/gas/mips/branch-local-2.s            |  33 +++
 gas/testsuite/gas/mips/branch-local-3.l            |   3 +
 gas/testsuite/gas/mips/branch-local-3.s            |  30 +++
 gas/testsuite/gas/mips/branch-local-n32-2.l        |   5 +
 gas/testsuite/gas/mips/branch-local-n32-2.s        |  33 +++
 gas/testsuite/gas/mips/branch-local-n32-3.l        |   3 +
 gas/testsuite/gas/mips/branch-local-n32-3.s        |  30 +++
 gas/testsuite/gas/mips/branch-local-n64-2.l        |   5 +
 gas/testsuite/gas/mips/branch-local-n64-2.s        |  33 +++
 gas/testsuite/gas/mips/branch-local-n64-3.l        |   3 +
 gas/testsuite/gas/mips/branch-local-n64-3.s        |  30 +++
 gas/testsuite/gas/mips/branch-misc-1.s             |   6 +
 gas/testsuite/gas/mips/branch-misc-5.s             |   1 +
 gas/testsuite/gas/mips/micromips-branch-relax.s    |   1 +
 gas/testsuite/gas/mips/micromips-insn32.d          |   4 +-
 gas/testsuite/gas/mips/micromips-noinsn32.d        |   4 +-
 gas/testsuite/gas/mips/micromips-trap.d            |   4 +-
 gas/testsuite/gas/mips/micromips.d                 |   4 +-
 gas/testsuite/gas/mips/micromips.s                 |   4 +-
 .../gas/mips/micromips@branch-misc-5-64.d          |   2 +-
 .../gas/mips/micromips@branch-misc-5pic-64.d       |   2 +-
 gas/testsuite/gas/mips/mips.exp                    |  68 +++++
 gas/testsuite/gas/mips/mips16-64.d                 |  18 +-
 gas/testsuite/gas/mips/mips16-dwarf2.s             |   4 +-
 gas/testsuite/gas/mips/mips16.d                    |  18 +-
 gas/testsuite/gas/mips/mips16.s                    |  26 +-
 gas/testsuite/gas/mips/relax-swap3.s               |   1 +
 gas/testsuite/gas/mips/unaligned-branch-1.l        |  40 +++
 gas/testsuite/gas/mips/unaligned-branch-1.s        | 137 ++++++++++
 gas/testsuite/gas/mips/unaligned-branch-2.l        |  19 ++
 gas/testsuite/gas/mips/unaligned-branch-2.s        | 139 ++++++++++
 gas/testsuite/gas/mips/unaligned-branch-3.d        | 181 +++++++++++++
 .../gas/mips/unaligned-branch-micromips-1.l        |  56 +++++
 .../gas/mips/unaligned-branch-micromips-1.s        | 201 +++++++++++++++
 .../gas/mips/unaligned-branch-micromips-2.l        |  21 ++
 .../gas/mips/unaligned-branch-micromips-2.s        | 203 +++++++++++++++
 .../gas/mips/unaligned-branch-micromips-3.d        | 277 ++++++++++++++++++++
 gas/testsuite/gas/mips/unaligned-branch-mips16-1.l |  23 ++
 gas/testsuite/gas/mips/unaligned-branch-mips16-1.s | 105 ++++++++
 gas/testsuite/gas/mips/unaligned-branch-mips16-2.l |   9 +
 gas/testsuite/gas/mips/unaligned-branch-mips16-2.s | 107 ++++++++
 gas/testsuite/gas/mips/unaligned-branch-mips16-3.d | 133 ++++++++++
 gas/testsuite/gas/mips/unaligned-branch-r6-1.l     |  40 +++
 gas/testsuite/gas/mips/unaligned-branch-r6-1.s     | 139 ++++++++++
 gas/testsuite/gas/mips/unaligned-branch-r6-2.l     |  31 +++
 gas/testsuite/gas/mips/unaligned-branch-r6-2.s     | 139 ++++++++++
 gas/testsuite/gas/mips/unaligned-branch-r6-3.l     |  19 ++
 gas/testsuite/gas/mips/unaligned-branch-r6-3.s     | 141 +++++++++++
 gas/testsuite/gas/mips/unaligned-branch-r6-4.l     |  19 ++
 gas/testsuite/gas/mips/unaligned-branch-r6-4.s     | 141 +++++++++++
 gas/testsuite/gas/mips/unaligned-branch-r6-5.d     | 181 +++++++++++++
 gas/testsuite/gas/mips/unaligned-branch-r6-6.d     | 181 +++++++++++++
 gas/testsuite/gas/mips/unaligned-jump-1.l          |  37 +++
 gas/testsuite/gas/mips/unaligned-jump-1.s          | 137 ++++++++++
 gas/testsuite/gas/mips/unaligned-jump-2.l          |  19 ++
 gas/testsuite/gas/mips/unaligned-jump-2.s          | 139 ++++++++++
 gas/testsuite/gas/mips/unaligned-jump-3.d          | 181 +++++++++++++
 .../gas/mips/unaligned-jump-micromips-1.l          |  44 ++++
 .../gas/mips/unaligned-jump-micromips-1.s          | 169 +++++++++++++
 .../gas/mips/unaligned-jump-micromips-2.l          |  19 ++
 .../gas/mips/unaligned-jump-micromips-2.s          | 171 +++++++++++++
 .../gas/mips/unaligned-jump-micromips-3.d          | 229 +++++++++++++++++
 gas/testsuite/gas/mips/unaligned-jump-mips16-1.l   |  24 ++
 gas/testsuite/gas/mips/unaligned-jump-mips16-1.s   | 105 ++++++++
 gas/testsuite/gas/mips/unaligned-jump-mips16-2.l   |  13 +
 gas/testsuite/gas/mips/unaligned-jump-mips16-2.s   | 107 ++++++++
 gas/testsuite/gas/mips/unaligned-jump-mips16-3.d   | 133 ++++++++++
 ld/ChangeLog                                       |  25 ++
 ld/testsuite/ld-mips-elf/mips-elf.exp              |  19 ++
 ld/testsuite/ld-mips-elf/unaligned-branch-2.d      | 106 ++++++++
 .../ld-mips-elf/unaligned-branch-micromips.d       | 174 +++++++++++++
 ld/testsuite/ld-mips-elf/unaligned-branch-mips16.d |  72 ++++++
 ld/testsuite/ld-mips-elf/unaligned-branch-r6-1.d   | 114 +++++++++
 ld/testsuite/ld-mips-elf/unaligned-branch-r6-2.d   |  64 +++++
 ld/testsuite/ld-mips-elf/unaligned-jalx-1.d        |   2 +-
 ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.d |  24 +-
 .../unaligned-jalx-addend-micromips-1.d            |  24 +-
 .../ld-mips-elf/unaligned-jalx-addend-mips16-1.d   |  24 +-
 .../ld-mips-elf/unaligned-jalx-micromips-1.d       |   2 +-
 ld/testsuite/ld-mips-elf/unaligned-jalx-mips16-1.d |   2 +-
 .../ld-mips-elf/unaligned-jump-micromips.d         | 118 +++++++++
 ld/testsuite/ld-mips-elf/unaligned-jump-mips16.d   |  58 +++++
 ld/testsuite/ld-mips-elf/unaligned-jump.d          |  96 +++++++
 ld/testsuite/ld-mips-elf/undefweak-overflow.d      |  21 +-
 ld/testsuite/ld-mips-elf/undefweak-overflow.s      |  20 ++
 90 files changed, 5968 insertions(+), 113 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 9be7d89..bb4103f 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,25 @@
+2016-07-19  Maciej W. Rozycki  <macro@imgtec.com>
+
+	* elfxx-mips.c (b_reloc_p): Add R_MICROMIPS_PC16_S1,
+	R_MICROMIPS_PC10_S1 and R_MICROMIPS_PC7_S1.
+	(branch_reloc_p): New function.
+	(mips_elf_calculate_relocation): Handle ISA mode determination
+	for relocations against section symbols, against absolute
+	symbols and absolute relocations.  Also set `*cross_mode_jump_p'
+	for branches.
+	<R_MIPS16_26, R_MIPS_26, R_MICROMIPS_26_S1>: Suppress alignment
+	checks for weak undefined symbols.  Also check target alignment
+	within the same ISA mode.
+	<R_MIPS_PC16, R_MIPS_GNU_REL16_S2>: Handle cross-mode branches
+	in the alignment check.
+	<R_MICROMIPS_PC7_S1>: Add an alignment check.
+	<R_MICROMIPS_PC10_S1>: Likewise.
+	<R_MICROMIPS_PC16_S1>: Likewise.
+	(mips_elf_perform_relocation): Report a failure for unsupported
+	same-mode JALX instructions and cross-mode branches.
+	(_bfd_mips_elf_relocate_section) <bfd_reloc_outofrange>: Add
+	error messages for jumps to misaligned addresses.
+
 2016-07-16  Alan Modra  <amodra@gmail.com>
 
 	* elflink.c: Include plugin-api.h.
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index e47276b..fa99c9d 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -2227,7 +2227,10 @@ b_reloc_p (int r_type)
 	  || r_type == R_MIPS_PC21_S2
 	  || r_type == R_MIPS_PC16
 	  || r_type == R_MIPS_GNU_REL16_S2
-	  || r_type == R_MIPS16_PC16_S1);
+	  || r_type == R_MIPS16_PC16_S1
+	  || r_type == R_MICROMIPS_PC16_S1
+	  || r_type == R_MICROMIPS_PC10_S1
+	  || r_type == R_MICROMIPS_PC7_S1);
 }
 
 static inline bfd_boolean
@@ -2238,6 +2241,16 @@ aligned_pcrel_reloc_p (int r_type)
 }
 
 static inline bfd_boolean
+branch_reloc_p (int r_type)
+{
+  return (r_type == R_MIPS_26
+	  || r_type == R_MIPS_PC26_S2
+	  || r_type == R_MIPS_PC21_S2
+	  || r_type == R_MIPS_PC16
+	  || r_type == R_MIPS_GNU_REL16_S2);
+}
+
+static inline bfd_boolean
 mips16_branch_reloc_p (int r_type)
 {
   return (r_type == R_MIPS16_26
@@ -5322,6 +5335,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
   /* Figure out the value of the symbol.  */
   if (local_p)
     {
+      bfd_boolean micromips_p = MICROMIPS_P (abfd);
       Elf_Internal_Sym *sym;
 
       sym = local_syms + r_symndx;
@@ -5350,8 +5364,26 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
       if (*namep == NULL || **namep == '\0')
 	*namep = bfd_section_name (input_bfd, sec);
 
-      target_is_16_bit_code_p = ELF_ST_IS_MIPS16 (sym->st_other);
-      target_is_micromips_code_p = ELF_ST_IS_MICROMIPS (sym->st_other);
+      /* For relocations against a section symbol and ones against no
+         symbol (absolute relocations) infer the ISA mode from the addend.  */
+      if (section_p || r_symndx == STN_UNDEF)
+	{
+	  target_is_16_bit_code_p = (addend & 1) && !micromips_p;
+	  target_is_micromips_code_p = (addend & 1) && micromips_p;
+	}
+      /* For relocations against an absolute symbol infer the ISA mode
+         from the value of the symbol plus addend.  */
+      else if (bfd_is_abs_section (sec))
+	{
+	  target_is_16_bit_code_p = ((symbol + addend) & 1) && !micromips_p;
+	  target_is_micromips_code_p = ((symbol + addend) & 1) && micromips_p;
+	}
+      /* Otherwise just use the regular symbol annotation available.  */
+      else
+	{
+	  target_is_16_bit_code_p = ELF_ST_IS_MIPS16 (sym->st_other);
+	  target_is_micromips_code_p = ELF_ST_IS_MICROMIPS (sym->st_other);
+	}
     }
   else
     {
@@ -5591,10 +5623,12 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
      acceptable.  */
   *cross_mode_jump_p = (!bfd_link_relocatable (info)
 			&& !(h && h->root.root.type == bfd_link_hash_undefweak)
-			&& ((r_type == R_MIPS16_26 && !target_is_16_bit_code_p)
-			    || (r_type == R_MICROMIPS_26_S1
+			&& ((mips16_branch_reloc_p (r_type)
+			     && !target_is_16_bit_code_p)
+			    || (micromips_branch_reloc_p (r_type)
 				&& !target_is_micromips_code_p)
-			    || ((r_type == R_MIPS_26 || r_type == R_MIPS_JALR)
+			    || ((branch_reloc_p (r_type)
+				 || r_type == R_MIPS_JALR)
 				&& (target_is_16_bit_code_p
 				    || target_is_micromips_code_p))));
 
@@ -5804,9 +5838,13 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
 	  value = addend;
 	value += symbol;
 
-	/* Make sure the target of JALX is word-aligned.  Bit 0 must be
-	   the correct ISA mode selector and bit 1 must be 0.  */
-	if (*cross_mode_jump_p && (value & 3) != (r_type == R_MIPS_26))
+	/* Make sure the target of a jump is suitably aligned.  Bit 0 must
+	   be the correct ISA mode selector except for weak undefined
+	   symbols.  */
+	if ((was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+	    && (*cross_mode_jump_p
+		? (value & 3) != (r_type == R_MIPS_26)
+	        : (value & ((1 << shift) - 1)) != (r_type != R_MIPS_26)))
 	  return bfd_reloc_outofrange;
 
 	value >>= shift;
@@ -5997,7 +6035,12 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
       if (howto->partial_inplace)
 	addend = _bfd_mips_elf_sign_extend (addend, 18);
 
-      if ((symbol + addend) & 3)
+      /* No need to exclude weak undefined symbols here as they resolve
+         to 0 and never set `*cross_mode_jump_p', so this alignment check
+         will never trigger for them.  */
+      if (*cross_mode_jump_p
+	  ? ((symbol + addend) & 3) != 1
+	  : ((symbol + addend) & 3) != 0)
 	return bfd_reloc_outofrange;
 
       value = symbol + addend - p;
@@ -6012,7 +6055,9 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
 	addend = _bfd_mips_elf_sign_extend (addend, 17);
 
       if ((was_local_p || h->root.root.type != bfd_link_hash_undefweak)
-	  && ((symbol + addend) & 1) == 0)
+	  && (*cross_mode_jump_p
+	      ? ((symbol + addend) & 3) != 0
+	      : ((symbol + addend) & 1) == 0))
 	return bfd_reloc_outofrange;
 
       value = symbol + addend - p;
@@ -6095,6 +6140,13 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
     case R_MICROMIPS_PC7_S1:
       if (howto->partial_inplace)
 	addend = _bfd_mips_elf_sign_extend (addend, 8);
+
+      if ((was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+	  && (*cross_mode_jump_p
+	      ? ((symbol + addend + 2) & 3) != 0
+	      : ((symbol + addend + 2) & 1) == 0))
+	return bfd_reloc_outofrange;
+
       value = symbol + addend - p;
       if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
 	overflowed_p = mips_elf_overflow_p (value, 8);
@@ -6105,6 +6157,13 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
     case R_MICROMIPS_PC10_S1:
       if (howto->partial_inplace)
 	addend = _bfd_mips_elf_sign_extend (addend, 11);
+
+      if ((was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+	  && (*cross_mode_jump_p
+	      ? ((symbol + addend + 2) & 3) != 0
+	      : ((symbol + addend + 2) & 1) == 0))
+	return bfd_reloc_outofrange;
+
       value = symbol + addend - p;
       if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
 	overflowed_p = mips_elf_overflow_p (value, 11);
@@ -6115,6 +6174,13 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
     case R_MICROMIPS_PC16_S1:
       if (howto->partial_inplace)
 	addend = _bfd_mips_elf_sign_extend (addend, 17);
+
+      if ((was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+	  && (*cross_mode_jump_p
+	      ? ((symbol + addend) & 3) != 0
+	      : ((symbol + addend) & 1) == 0))
+	return bfd_reloc_outofrange;
+
       value = symbol + addend - p;
       if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
 	overflowed_p = mips_elf_overflow_p (value, 17);
@@ -6273,7 +6339,21 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
   /* Set the field.  */
   x |= (value & howto->dst_mask);
 
-  /* If required, turn JAL into JALX.  */
+  /* Detect incorrect JALX usage.  If required, turn JAL into JALX.  */
+  if (!cross_mode_jump_p && jal_reloc_p (r_type))
+    {
+      bfd_vma opcode = x >> 26;
+
+      if (r_type == R_MIPS16_26 ? opcode == 0x7
+	  : r_type == R_MICROMIPS_26_S1 ? opcode == 0x3c
+	  : opcode == 0x1d)
+	{
+	  info->callbacks->einfo
+	    (_("%X%H: Unsupported JALX to the same ISA mode\n"),
+	     input_bfd, input_section, relocation->r_offset);
+	  return TRUE;
+	}
+    }
   if (cross_mode_jump_p && jal_reloc_p (r_type))
     {
       bfd_boolean ok;
@@ -6311,6 +6391,13 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
       /* Make this the JALX opcode.  */
       x = (x & ~(0x3f << 26)) | (jalx_opcode << 26);
     }
+  else if (cross_mode_jump_p && b_reloc_p (r_type))
+    {
+      info->callbacks->einfo
+	(_("%X%H: Unsupported branch between ISA modes\n"),
+	 input_bfd, input_section, relocation->r_offset);
+      return TRUE;
+    }
 
   /* Try converting JAL to BAL and J(AL)R to B(AL), if the target is in
      range.  */
@@ -10296,7 +10383,12 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 	case bfd_reloc_outofrange:
 	  msg = NULL;
 	  if (jal_reloc_p (howto->type))
-	    msg = _("JALX to a non-word-aligned address");
+	    msg = (cross_mode_jump_p
+		   ? _("Cannot convert a jump to JALX "
+		       "for a non-word-aligned address")
+		   : (howto->type == R_MIPS16_26
+		      ? _("Jump to a non-word-aligned address")
+		      : _("Jump to a non-instruction-aligned address")));
 	  else if (b_reloc_p (howto->type))
 	    msg = _("Branch to a non-instruction-aligned address");
 	  else if (aligned_pcrel_reloc_p (howto->type))
diff --git a/gas/ChangeLog b/gas/ChangeLog
index c11e2b2..7126569 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,110 @@
+2016-07-19  Maciej W. Rozycki  <macro@imgtec.com>
+
+	* config/tc-mips.c (mips_force_relocation): Also retain branch
+	relocations against MIPS16 and microMIPS symbols.
+	(fix_bad_cross_mode_jump_p): New function.
+	(fix_bad_same_mode_jalx_p): Likewise.
+	(fix_bad_misaligned_jump_p): Likewise.
+	(fix_bad_cross_mode_branch_p): Likewise.
+	(fix_bad_misaligned_branch_p): Likewise.
+	(fix_validate_branch): Likewise.
+	(md_apply_fix) <BFD_RELOC_MIPS_JMP, BFD_RELOC_MIPS16_JMP>
+	<BFD_RELOC_MICROMIPS_JMP>: Separate from BFD_RELOC_MIPS_SHIFT5,
+	etc.  Verify the ISA mode and alignment of the jump target.
+	<BFD_RELOC_MIPS_21_PCREL_S2>: Replace the inline alignment check
+	with a call to `fix_validate_branch'.
+	<BFD_RELOC_MIPS_26_PCREL_S2>: Likewise.
+	<BFD_RELOC_16_PCREL_S2>: Likewise.
+	<BFD_RELOC_MICROMIPS_7_PCREL_S1, BFD_RELOC_MICROMIPS_10_PCREL_S1>
+	<BFD_RELOC_MICROMIPS_16_PCREL_S1>: Retain the original addend.
+	Verify the ISA mode and alignment of the branch target.
+	(md_convert_frag): Verify the ISA mode and alignment of resolved
+	MIPS16 branch targets.
+	* testsuite/gas/mips/branch-misc-1.s: Annotate non-instruction
+	branch targets with `.insn'.
+	* testsuite/gas/mips/branch-misc-5.s: Likewise.
+	* testsuite/gas/mips/micromips@branch-misc-5-64.d: Update
+	accordingly.
+	* testsuite/gas/mips/micromips@branch-misc-5pic-64.d: Likewise.
+	* testsuite/gas/mips/micromips-branch-relax.s: Annotate
+	non-instruction branch target with `.insn'.
+	* testsuite/gas/mips/micromips.s: Replace microMIPS JALX targets
+	with external symbols.
+	* testsuite/gas/mips/micromips-insn32.d: Update accordingly.
+	* testsuite/gas/mips/micromips-noinsn32.d: Likewise.
+	* testsuite/gas/mips/micromips-trap.d: Likewise.
+	* testsuite/gas/mips/micromips.d: Likewise.
+	* testsuite/gas/mips/mips16.s: Annotate non-instruction branch
+	targets with `.insn'.
+	* testsuite/gas/mips/mips16.d: Update accordingly.
+	* testsuite/gas/mips/mips16-64.d: Likewise.
+	* testsuite/gas/mips/mips16-dwarf2.s: Annotate non-instruction
+	branch target with `.insn'.
+	* testsuite/gas/mips/relax-swap3.s: Likewise.
+	* testsuite/gas/mips/branch-local-2.l: New list test.
+	* testsuite/gas/mips/branch-local-3.l: New list test.
+	* testsuite/gas/mips/branch-local-n32-2.l: New list test.
+	* testsuite/gas/mips/branch-local-n32-3.l: New list test.
+	* testsuite/gas/mips/branch-local-n64-2.l: New list test.
+	* testsuite/gas/mips/branch-local-n64-3.l: New list test.
+	* testsuite/gas/mips/unaligned-jump-1.l: New list test.
+	* testsuite/gas/mips/unaligned-jump-2.l: New list test.
+	* testsuite/gas/mips/unaligned-jump-3.d: New test.
+	* testsuite/gas/mips/unaligned-jump-mips16-1.l: New list test.
+	* testsuite/gas/mips/unaligned-jump-mips16-2.l: New list test.
+	* testsuite/gas/mips/unaligned-jump-mips16-3.d: New test.
+	* testsuite/gas/mips/unaligned-jump-micromips-1.l: New list
+	test.
+	* testsuite/gas/mips/unaligned-jump-micromips-2.l: New list
+	test.
+	* testsuite/gas/mips/unaligned-jump-micromips-3.d: New test.
+	* testsuite/gas/mips/unaligned-branch-1.l: New list test.
+	* testsuite/gas/mips/unaligned-branch-2.l: New list test.
+	* testsuite/gas/mips/unaligned-branch-3.d: New test.
+	* testsuite/gas/mips/unaligned-branch-r6-1.l: New list test.
+	* testsuite/gas/mips/unaligned-branch-r6-2.l: New list test.
+	* testsuite/gas/mips/unaligned-branch-r6-3.l: New list test.
+	* testsuite/gas/mips/unaligned-branch-r6-4.l: New list test.
+	* testsuite/gas/mips/unaligned-branch-r6-5.d: New test.
+	* testsuite/gas/mips/unaligned-branch-r6-6.d: New test.
+	* testsuite/gas/mips/unaligned-branch-mips16-1.l: New list test.
+	* testsuite/gas/mips/unaligned-branch-mips16-2.l: New list test.
+	* testsuite/gas/mips/unaligned-branch-mips16-3.d: New test.
+	* testsuite/gas/mips/unaligned-branch-micromips-1.l: New list
+	test.
+	* testsuite/gas/mips/unaligned-branch-micromips-2.l: New list
+	test.
+	* testsuite/gas/mips/unaligned-branch-micromips-3.d: New test.
+	* testsuite/gas/mips/branch-local-2.s: New test source.
+	* testsuite/gas/mips/branch-local-3.s: New test source.
+	* testsuite/gas/mips/branch-local-n32-2.s: New test source.
+	* testsuite/gas/mips/branch-local-n32-3.s: New test source.
+	* testsuite/gas/mips/branch-local-n64-2.s: New test source.
+	* testsuite/gas/mips/branch-local-n64-3.s: New test source.
+	* testsuite/gas/mips/unaligned-jump-1.s: New test source.
+	* testsuite/gas/mips/unaligned-jump-2.s: New test source.
+	* testsuite/gas/mips/unaligned-jump-mips16-1.s: New test source.
+	* testsuite/gas/mips/unaligned-jump-mips16-2.s: New test source.
+	* testsuite/gas/mips/unaligned-jump-micromips-1.s: New test
+	source.
+	* testsuite/gas/mips/unaligned-jump-micromips-2.s: New test
+	source.
+	* testsuite/gas/mips/unaligned-branch-1.s: New test source.
+	* testsuite/gas/mips/unaligned-branch-2.s: New test source.
+	* testsuite/gas/mips/unaligned-branch-r6-1.s: New test source.
+	* testsuite/gas/mips/unaligned-branch-r6-2.s: New test source.
+	* testsuite/gas/mips/unaligned-branch-r6-3.s: New test source.
+	* testsuite/gas/mips/unaligned-branch-r6-4.s: New test source.
+	* testsuite/gas/mips/unaligned-branch-mips16-1.s: New test
+	source.
+	* testsuite/gas/mips/unaligned-branch-mips16-2.s: New test
+	source.
+	* testsuite/gas/mips/unaligned-branch-micromips-1.s: New test
+	source.
+	* testsuite/gas/mips/unaligned-branch-micromips-2.s: New test
+	source.
+	* testsuite/gas/mips/mips.exp: Run the new tests.
+
 2016-07-19  Trevor Saunders  <tbsaunde+binutils@tbsaunde.org>
 
 	* config/tc-nds32.c (struct nds32_pseudo_opcode): Make pseudo_val
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index cca5450..57c2fe9 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -14800,6 +14800,19 @@ mips_force_relocation (fixS *fixp)
       || fixp->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1)
     return 1;
 
+  /* We want to keep R_MIPS_PC26_S2, R_MIPS_PC21_S2, BFD_RELOC_16_PCREL_S2
+     BFD_RELOC_MIPS_21_PCREL_S2 and BFD_RELOC_MIPS_26_PCREL_S2 relocations
+     against MIPS16 and microMIPS symbols so that we do cross-mode branch
+     diagnostics.  */
+  if ((fixp->fx_r_type == R_MIPS_PC26_S2
+       || fixp->fx_r_type == R_MIPS_PC21_S2
+       || fixp->fx_r_type == BFD_RELOC_16_PCREL_S2
+       || fixp->fx_r_type == BFD_RELOC_MIPS_21_PCREL_S2
+       || fixp->fx_r_type == BFD_RELOC_MIPS_26_PCREL_S2)
+      && fixp->fx_addsy
+      && ELF_ST_IS_COMPRESSED (S_GET_OTHER (fixp->fx_addsy)))
+    return 1;
+
   /* We want all PC-relative relocations to be kept for R6 relaxation.  */
   if (ISA_IS_R6 (file_mips_opts.isa)
       && (fixp->fx_r_type == BFD_RELOC_16_PCREL_S2
@@ -14854,6 +14867,186 @@ write_reloc_insn (char *buf, bfd_reloc_code_real_type reloc,
     write_insn (buf, insn);
 }
 
+/* Return TRUE if the instruction pointed to by FIXP is an invalid jump
+   to a symbol in another ISA mode, which cannot be converted to JALX.  */
+
+static bfd_boolean
+fix_bad_cross_mode_jump_p (fixS *fixP)
+{
+  unsigned long opcode;
+  int other;
+  char *buf;
+
+  if (!fixP->fx_addsy || S_FORCE_RELOC (fixP->fx_addsy, TRUE))
+    return FALSE;
+
+  other = S_GET_OTHER (fixP->fx_addsy);
+  buf = fixP->fx_frag->fr_literal + fixP->fx_where;
+  opcode = read_reloc_insn (buf, fixP->fx_r_type) >> 26;
+  switch (fixP->fx_r_type)
+    {
+    case BFD_RELOC_MIPS_JMP:
+      return opcode != 0x1d && opcode != 0x03 && ELF_ST_IS_COMPRESSED (other);
+    case BFD_RELOC_MICROMIPS_JMP:
+      return opcode != 0x3c && opcode != 0x3d && !ELF_ST_IS_MICROMIPS (other);
+    default:
+      return FALSE;
+    }
+}
+
+/* Return TRUE if the instruction pointed to by FIXP is an invalid JALX
+   jump to a symbol in the same ISA mode.  */
+
+static bfd_boolean
+fix_bad_same_mode_jalx_p (fixS *fixP)
+{
+  unsigned long opcode;
+  int other;
+  char *buf;
+
+  if (!fixP->fx_addsy || S_FORCE_RELOC (fixP->fx_addsy, TRUE))
+    return FALSE;
+
+  other = S_GET_OTHER (fixP->fx_addsy);
+  buf = fixP->fx_frag->fr_literal + fixP->fx_where;
+  opcode = read_reloc_insn (buf, fixP->fx_r_type) >> 26;
+  switch (fixP->fx_r_type)
+    {
+    case BFD_RELOC_MIPS_JMP:
+      return opcode == 0x1d && !ELF_ST_IS_COMPRESSED (other);
+    case BFD_RELOC_MIPS16_JMP:
+      return opcode == 0x07 && ELF_ST_IS_COMPRESSED (other);
+    case BFD_RELOC_MICROMIPS_JMP:
+      return opcode == 0x3c && ELF_ST_IS_COMPRESSED (other);
+    default:
+      return FALSE;
+    }
+}
+
+/* Return TRUE if the instruction pointed to by FIXP is an invalid jump
+   to a symbol whose value plus addend is not aligned according to the
+   ultimate (after linker relaxation) jump instruction's immediate field
+   requirement, either to (1 << SHIFT), or, for jumps from microMIPS to
+   regular MIPS code, to (1 << 2).  */
+
+static bfd_boolean
+fix_bad_misaligned_jump_p (fixS *fixP, int shift)
+{
+  bfd_boolean micro_to_mips_p;
+  valueT val;
+  int other;
+
+  if (!fixP->fx_addsy || S_FORCE_RELOC (fixP->fx_addsy, TRUE))
+    return FALSE;
+
+  other = S_GET_OTHER (fixP->fx_addsy);
+  val = S_GET_VALUE (fixP->fx_addsy) | ELF_ST_IS_COMPRESSED (other);
+  val += fixP->fx_offset;
+  micro_to_mips_p = (fixP->fx_r_type == BFD_RELOC_MICROMIPS_JMP
+		     && !ELF_ST_IS_MICROMIPS (other));
+  return ((val & ((1 << (micro_to_mips_p ? 2 : shift)) - 1))
+	  != ELF_ST_IS_COMPRESSED (other));
+}
+
+/* Return TRUE if the instruction pointed to by FIXP is an invalid branch
+   to a symbol whose annotation indicates another ISA mode.  For absolute
+   symbols check the ISA bit instead.  */
+
+static bfd_boolean
+fix_bad_cross_mode_branch_p (fixS *fixP)
+{
+  bfd_boolean absolute_p;
+  unsigned long opcode;
+  asection *symsec;
+  valueT val;
+  int other;
+  char *buf;
+
+  if (!fixP->fx_addsy || S_FORCE_RELOC (fixP->fx_addsy, TRUE))
+    return FALSE;
+
+  symsec = S_GET_SEGMENT (fixP->fx_addsy);
+  absolute_p = bfd_is_abs_section (symsec);
+
+  val = S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset;
+  other = S_GET_OTHER (fixP->fx_addsy);
+
+  buf = fixP->fx_frag->fr_literal + fixP->fx_where;
+  opcode = read_reloc_insn (buf, fixP->fx_r_type) >> 16;
+  switch (fixP->fx_r_type)
+    {
+    case BFD_RELOC_16_PCREL_S2:
+    case BFD_RELOC_MIPS_21_PCREL_S2:
+    case BFD_RELOC_MIPS_26_PCREL_S2:
+      return absolute_p ? val & 1 : ELF_ST_IS_COMPRESSED (other);
+    case BFD_RELOC_MIPS16_16_PCREL_S1:
+      return absolute_p ? !(val & 1) : !ELF_ST_IS_MIPS16 (other);
+    case BFD_RELOC_MICROMIPS_7_PCREL_S1:
+    case BFD_RELOC_MICROMIPS_10_PCREL_S1:
+    case BFD_RELOC_MICROMIPS_16_PCREL_S1:
+      return absolute_p ? !(val & 1) : !ELF_ST_IS_MICROMIPS (other);
+    default:
+      abort ();
+    }
+}
+
+/* Return TRUE if the symbol plus addend associated with a regular MIPS
+   branch instruction pointed to by FIXP is not aligned according to the
+   branch instruction's immediate field requirement.  We need the addend
+   to preserve the ISA bit and also the sum must not have bit 2 set.  We
+   must explicitly OR in the ISA bit from symbol annotation as the bit
+   won't be set in the symbol's value then.  */
+
+static bfd_boolean
+fix_bad_misaligned_branch_p (fixS *fixP)
+{
+  bfd_boolean absolute_p;
+  asection *symsec;
+  valueT isa_bit;
+  valueT val;
+  valueT off;
+  int other;
+
+  if (!fixP->fx_addsy || S_FORCE_RELOC (fixP->fx_addsy, TRUE))
+    return FALSE;
+
+  symsec = S_GET_SEGMENT (fixP->fx_addsy);
+  absolute_p = bfd_is_abs_section (symsec);
+
+  val = S_GET_VALUE (fixP->fx_addsy);
+  other = S_GET_OTHER (fixP->fx_addsy);
+  off = fixP->fx_offset;
+
+  isa_bit = absolute_p ? (val + off) & 1 : ELF_ST_IS_COMPRESSED (other);
+  val |= ELF_ST_IS_COMPRESSED (other);
+  val += off;
+  return (val & 0x3) != isa_bit;
+}
+
+/* Make the necessary checks on a regular MIPS branch pointed to by FIXP
+   and its calculated value VAL.  */
+
+static void
+fix_validate_branch (fixS *fixP, valueT val)
+{
+  if (fixP->fx_done && (val & 0x3) != 0)
+    as_bad_where (fixP->fx_file, fixP->fx_line,
+		  _("branch to misaligned address (0x%lx)"),
+		  (long) (val + md_pcrel_from (fixP)));
+  else if (fix_bad_cross_mode_branch_p (fixP))
+    as_bad_where (fixP->fx_file, fixP->fx_line,
+		  _("branch to a symbol in another ISA mode"));
+  else if (fix_bad_misaligned_branch_p (fixP))
+    as_bad_where (fixP->fx_file, fixP->fx_line,
+		  _("branch to misaligned address (0x%lx)"),
+		  (long) (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset));
+  else if (HAVE_IN_PLACE_ADDENDS && (fixP->fx_offset & 0x3) != 0)
+    as_bad_where (fixP->fx_file, fixP->fx_line,
+		  _("cannot encode misaligned addend "
+		    "in the relocatable field (0x%lx)"),
+		  (long) fixP->fx_offset);
+}
+
 /* Apply a fixup to the object file.  */
 
 void
@@ -14962,6 +15155,40 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       break;
 
     case BFD_RELOC_MIPS_JMP:
+    case BFD_RELOC_MIPS16_JMP:
+    case BFD_RELOC_MICROMIPS_JMP:
+      {
+	int shift;
+
+	gas_assert (!fixP->fx_done);
+
+	/* Shift is 2, unusually, for microMIPS JALX.  */
+	if (fixP->fx_r_type == BFD_RELOC_MICROMIPS_JMP
+	    && (read_compressed_insn (buf, 4) >> 26) != 0x3c)
+	  shift = 1;
+	else
+	  shift = 2;
+
+	if (fix_bad_cross_mode_jump_p (fixP))
+	  as_bad_where (fixP->fx_file, fixP->fx_line,
+			_("jump to a symbol in another ISA mode"));
+	else if (fix_bad_same_mode_jalx_p (fixP))
+	  as_bad_where (fixP->fx_file, fixP->fx_line,
+			_("JALX to a symbol in the same ISA mode"));
+	else if (fix_bad_misaligned_jump_p (fixP, shift))
+	  as_bad_where (fixP->fx_file, fixP->fx_line,
+			_("jump to misaligned address (0x%lx)"),
+			(long) (S_GET_VALUE (fixP->fx_addsy)
+				+ fixP->fx_offset));
+	else if (HAVE_IN_PLACE_ADDENDS
+		 && (fixP->fx_offset & ((1 << shift) - 1)) != 0)
+	  as_bad_where (fixP->fx_file, fixP->fx_line,
+			_("cannot encode misaligned addend "
+			  "in the relocatable field (0x%lx)"),
+			(long) fixP->fx_offset);
+      }
+      /* Fall through.  */
+
     case BFD_RELOC_MIPS_SHIFT5:
     case BFD_RELOC_MIPS_SHIFT6:
     case BFD_RELOC_MIPS_GOT_DISP:
@@ -14997,8 +15224,6 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_MIPS16_HI16:
     case BFD_RELOC_MIPS16_HI16_S:
     case BFD_RELOC_MIPS16_LO16:
-    case BFD_RELOC_MIPS16_JMP:
-    case BFD_RELOC_MICROMIPS_JMP:
     case BFD_RELOC_MICROMIPS_GOT_DISP:
     case BFD_RELOC_MICROMIPS_GOT_PAGE:
     case BFD_RELOC_MICROMIPS_GOT_OFST:
@@ -15072,9 +15297,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       break;
 
     case BFD_RELOC_MIPS_21_PCREL_S2:
-      if ((*valP & 0x3) != 0)
-	as_bad_where (fixP->fx_file, fixP->fx_line,
-		      _("branch to misaligned address (%lx)"), (long) *valP);
+      fix_validate_branch (fixP, *valP);
       if (!fixP->fx_done)
 	break;
 
@@ -15090,9 +15313,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       break;
 
     case BFD_RELOC_MIPS_26_PCREL_S2:
-      if ((*valP & 0x3) != 0)
-	as_bad_where (fixP->fx_file, fixP->fx_line,
-		      _("branch to misaligned address (%lx)"), (long) *valP);
+      fix_validate_branch (fixP, *valP);
       if (!fixP->fx_done)
 	break;
 
@@ -15150,9 +15371,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       break;
 
     case BFD_RELOC_16_PCREL_S2:
-      if ((*valP & 0x3) != 0)
-	as_bad_where (fixP->fx_file, fixP->fx_line,
-		      _("branch to misaligned address (%lx)"), (long) *valP);
+      fix_validate_branch (fixP, *valP);
 
       /* We need to save the bits in the instruction since fixup_segment()
 	 might be deleting the relocation entry (i.e., a branch within
@@ -15205,6 +15424,21 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_MICROMIPS_10_PCREL_S1:
     case BFD_RELOC_MICROMIPS_16_PCREL_S1:
       gas_assert (!fixP->fx_done);
+      if (fix_bad_cross_mode_branch_p (fixP))
+	as_bad_where (fixP->fx_file, fixP->fx_line,
+		      _("branch to a symbol in another ISA mode"));
+      else if (fixP->fx_addsy
+	       && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
+	       && !bfd_is_abs_section (S_GET_SEGMENT (fixP->fx_addsy))
+	       && (fixP->fx_offset & 0x1) != 0)
+	as_bad_where (fixP->fx_file, fixP->fx_line,
+		      _("branch to misaligned address (0x%lx)"),
+		      (long) (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset));
+      else if (HAVE_IN_PLACE_ADDENDS && (fixP->fx_offset & 0x1) != 0)
+	as_bad_where (fixP->fx_file, fixP->fx_line,
+		      _("cannot encode misaligned addend "
+			"in the relocatable field (0x%lx)"),
+		      (long) fixP->fx_offset);
       break;
 
     case BFD_RELOC_VTABLE_INHERIT:
@@ -17814,6 +18048,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
       offsetT val;
       char *buf;
       unsigned int user_length, length;
+      bfd_boolean need_reloc;
       unsigned long insn;
       bfd_boolean ext;
       segT symsec;
@@ -17823,6 +18058,13 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
 
       ext = RELAX_MIPS16_EXTENDED (fragp->fr_subtype);
       val = resolve_symbol_value (fragp->fr_symbol) + fragp->fr_offset;
+
+      symsec = S_GET_SEGMENT (fragp->fr_symbol);
+      need_reloc = (S_FORCE_RELOC (fragp->fr_symbol, TRUE)
+		    || (operand->root.type == OP_PCREL
+			? asec != symsec
+			: !bfd_is_abs_section (symsec)));
+
       if (operand->root.type == OP_PCREL)
 	{
 	  const struct mips_pcrel_operand *pcrel_op;
@@ -17835,6 +18077,16 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
              complicated; see mips16_extended_frag.  */
 	  if (pcrel_op->include_isa_bit)
 	    {
+	      if (!need_reloc)
+		{
+		  if (!ELF_ST_IS_MIPS16 (S_GET_OTHER (fragp->fr_symbol)))
+		    as_bad_where (fragp->fr_file, fragp->fr_line,
+				  _("branch to a symbol in another ISA mode"));
+		  else if ((fragp->fr_offset & 0x1) != 0)
+		    as_bad_where (fragp->fr_file, fragp->fr_line,
+				  _("branch to misaligned address (0x%lx)"),
+				  (long) val);
+		}
 	      addr += 2;
 	      if (ext)
 		addr += 2;
@@ -17875,11 +18127,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
       else
 	user_length = 0;
 
-      symsec = S_GET_SEGMENT (fragp->fr_symbol);
-      if (S_FORCE_RELOC (fragp->fr_symbol, TRUE)
-	  || (operand->root.type == OP_PCREL
-	      ? asec != symsec
-	      : !bfd_is_abs_section (symsec)))
+      if (need_reloc)
 	{
 	  bfd_reloc_code_real_type reloc = BFD_RELOC_NONE;
 	  expressionS exp;
diff --git a/gas/testsuite/gas/mips/branch-local-2.l b/gas/testsuite/gas/mips/branch-local-2.l
new file mode 100644
index 0000000..4f93bf3
--- /dev/null
+++ b/gas/testsuite/gas/mips/branch-local-2.l
@@ -0,0 +1,5 @@
+.*: Assembler messages:
+.*:19: Error: branch to a symbol in another ISA mode
+.*:21: Error: branch to a symbol in another ISA mode
+.*:23: Error: branch to a symbol in another ISA mode
+.*:25: Error: branch to a symbol in another ISA mode
diff --git a/gas/testsuite/gas/mips/branch-local-2.s b/gas/testsuite/gas/mips/branch-local-2.s
new file mode 100644
index 0000000..42f5e27
--- /dev/null
+++ b/gas/testsuite/gas/mips/branch-local-2.s
@@ -0,0 +1,33 @@
+	.text
+	.set	noreorder
+	.space	0x1000
+
+	.align	4
+	.set	micromips
+	.ent	foo
+foo:
+	nor	$0, $0
+	jalr	$0, $ra
+	 nor	$0, $0
+	.end	foo
+
+	.align	4
+	.set	nomicromips
+	.ent	bar
+bar:
+	nor	$0, $0
+	b	foo
+	 nor	$0, $0
+	bne	$2, $3, foo
+	 nor	$0, $0
+	bgezal	$2, foo
+	 nor	$0, $0
+	bltzal	$2, foo
+	 nor	$0, $0
+	jalr	$0, $ra
+	 nor	$0, $0
+	.end	bar
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	4, 0
+	.space	16
diff --git a/gas/testsuite/gas/mips/branch-local-3.l b/gas/testsuite/gas/mips/branch-local-3.l
new file mode 100644
index 0000000..39fb31f
--- /dev/null
+++ b/gas/testsuite/gas/mips/branch-local-3.l
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:20: Error: branch to a symbol in another ISA mode
+.*:22: Error: branch to a symbol in another ISA mode
diff --git a/gas/testsuite/gas/mips/branch-local-3.s b/gas/testsuite/gas/mips/branch-local-3.s
new file mode 100644
index 0000000..4d1d155
--- /dev/null
+++ b/gas/testsuite/gas/mips/branch-local-3.s
@@ -0,0 +1,30 @@
+	.text
+	.set	noreorder
+	.space	0x1000
+
+	.align	4
+	.set	micromips
+	.ent	foo
+foo:
+	nor	$0, $0
+	jalr	$0, $ra
+	 nor	$0, $0
+	.end	foo
+
+	.align	4
+	.set	nomicromips
+	.set	mips32r6
+	.ent	bar
+bar:
+	nor	$0, $0
+	bc	foo
+	nor	$0, $0
+	beqzc	$2, foo
+	 nor	$0, $0
+	jalr	$0, $ra
+	 nor	$0, $0
+	.end	bar
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	4, 0
+	.space	16
diff --git a/gas/testsuite/gas/mips/branch-local-n32-2.l b/gas/testsuite/gas/mips/branch-local-n32-2.l
new file mode 100644
index 0000000..4f93bf3
--- /dev/null
+++ b/gas/testsuite/gas/mips/branch-local-n32-2.l
@@ -0,0 +1,5 @@
+.*: Assembler messages:
+.*:19: Error: branch to a symbol in another ISA mode
+.*:21: Error: branch to a symbol in another ISA mode
+.*:23: Error: branch to a symbol in another ISA mode
+.*:25: Error: branch to a symbol in another ISA mode
diff --git a/gas/testsuite/gas/mips/branch-local-n32-2.s b/gas/testsuite/gas/mips/branch-local-n32-2.s
new file mode 100644
index 0000000..42f5e27
--- /dev/null
+++ b/gas/testsuite/gas/mips/branch-local-n32-2.s
@@ -0,0 +1,33 @@
+	.text
+	.set	noreorder
+	.space	0x1000
+
+	.align	4
+	.set	micromips
+	.ent	foo
+foo:
+	nor	$0, $0
+	jalr	$0, $ra
+	 nor	$0, $0
+	.end	foo
+
+	.align	4
+	.set	nomicromips
+	.ent	bar
+bar:
+	nor	$0, $0
+	b	foo
+	 nor	$0, $0
+	bne	$2, $3, foo
+	 nor	$0, $0
+	bgezal	$2, foo
+	 nor	$0, $0
+	bltzal	$2, foo
+	 nor	$0, $0
+	jalr	$0, $ra
+	 nor	$0, $0
+	.end	bar
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	4, 0
+	.space	16
diff --git a/gas/testsuite/gas/mips/branch-local-n32-3.l b/gas/testsuite/gas/mips/branch-local-n32-3.l
new file mode 100644
index 0000000..39fb31f
--- /dev/null
+++ b/gas/testsuite/gas/mips/branch-local-n32-3.l
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:20: Error: branch to a symbol in another ISA mode
+.*:22: Error: branch to a symbol in another ISA mode
diff --git a/gas/testsuite/gas/mips/branch-local-n32-3.s b/gas/testsuite/gas/mips/branch-local-n32-3.s
new file mode 100644
index 0000000..09a6fed
--- /dev/null
+++ b/gas/testsuite/gas/mips/branch-local-n32-3.s
@@ -0,0 +1,30 @@
+	.text
+	.set	noreorder
+	.space	0x1000
+
+	.align	4
+	.set	micromips
+	.ent	foo
+foo:
+	nor	$0, $0
+	jalr	$0, $ra
+	 nor	$0, $0
+	.end	foo
+
+	.align	4
+	.set	nomicromips
+	.set	mips64r6
+	.ent	bar
+bar:
+	nor	$0, $0
+	bc	foo
+	nor	$0, $0
+	beqzc	$2, foo
+	 nor	$0, $0
+	jalr	$0, $ra
+	 nor	$0, $0
+	.end	bar
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	4, 0
+	.space	16
diff --git a/gas/testsuite/gas/mips/branch-local-n64-2.l b/gas/testsuite/gas/mips/branch-local-n64-2.l
new file mode 100644
index 0000000..4f93bf3
--- /dev/null
+++ b/gas/testsuite/gas/mips/branch-local-n64-2.l
@@ -0,0 +1,5 @@
+.*: Assembler messages:
+.*:19: Error: branch to a symbol in another ISA mode
+.*:21: Error: branch to a symbol in another ISA mode
+.*:23: Error: branch to a symbol in another ISA mode
+.*:25: Error: branch to a symbol in another ISA mode
diff --git a/gas/testsuite/gas/mips/branch-local-n64-2.s b/gas/testsuite/gas/mips/branch-local-n64-2.s
new file mode 100644
index 0000000..42f5e27
--- /dev/null
+++ b/gas/testsuite/gas/mips/branch-local-n64-2.s
@@ -0,0 +1,33 @@
+	.text
+	.set	noreorder
+	.space	0x1000
+
+	.align	4
+	.set	micromips
+	.ent	foo
+foo:
+	nor	$0, $0
+	jalr	$0, $ra
+	 nor	$0, $0
+	.end	foo
+
+	.align	4
+	.set	nomicromips
+	.ent	bar
+bar:
+	nor	$0, $0
+	b	foo
+	 nor	$0, $0
+	bne	$2, $3, foo
+	 nor	$0, $0
+	bgezal	$2, foo
+	 nor	$0, $0
+	bltzal	$2, foo
+	 nor	$0, $0
+	jalr	$0, $ra
+	 nor	$0, $0
+	.end	bar
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	4, 0
+	.space	16
diff --git a/gas/testsuite/gas/mips/branch-local-n64-3.l b/gas/testsuite/gas/mips/branch-local-n64-3.l
new file mode 100644
index 0000000..39fb31f
--- /dev/null
+++ b/gas/testsuite/gas/mips/branch-local-n64-3.l
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:20: Error: branch to a symbol in another ISA mode
+.*:22: Error: branch to a symbol in another ISA mode
diff --git a/gas/testsuite/gas/mips/branch-local-n64-3.s b/gas/testsuite/gas/mips/branch-local-n64-3.s
new file mode 100644
index 0000000..09a6fed
--- /dev/null
+++ b/gas/testsuite/gas/mips/branch-local-n64-3.s
@@ -0,0 +1,30 @@
+	.text
+	.set	noreorder
+	.space	0x1000
+
+	.align	4
+	.set	micromips
+	.ent	foo
+foo:
+	nor	$0, $0
+	jalr	$0, $ra
+	 nor	$0, $0
+	.end	foo
+
+	.align	4
+	.set	nomicromips
+	.set	mips64r6
+	.ent	bar
+bar:
+	nor	$0, $0
+	bc	foo
+	nor	$0, $0
+	beqzc	$2, foo
+	 nor	$0, $0
+	jalr	$0, $ra
+	 nor	$0, $0
+	.end	bar
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	4, 0
+	.space	16
diff --git a/gas/testsuite/gas/mips/branch-misc-1.s b/gas/testsuite/gas/mips/branch-misc-1.s
index 0f72c693..fa0389b 100644
--- a/gas/testsuite/gas/mips/branch-misc-1.s
+++ b/gas/testsuite/gas/mips/branch-misc-1.s
@@ -2,10 +2,13 @@
 
 	.text
 l1:
+	.insn
 	.space 20
 l2:
+	.insn
 	.space 20
 l3:
+	.insn
 	.space 20
 
 x:
@@ -18,10 +21,13 @@ x:
 
 	.space 20
 l4:
+	.insn
 	.space 20
 l5:
+	.insn
 	.space 20
 l6:
+	.insn
 
 # Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
 	.space	8
diff --git a/gas/testsuite/gas/mips/branch-misc-5.s b/gas/testsuite/gas/mips/branch-misc-5.s
index ac307f5..cc0e493 100644
--- a/gas/testsuite/gas/mips/branch-misc-5.s
+++ b/gas/testsuite/gas/mips/branch-misc-5.s
@@ -18,3 +18,4 @@ g6:
 
 	.data
 .Ldata:
+	.insn
diff --git a/gas/testsuite/gas/mips/micromips-branch-relax.s b/gas/testsuite/gas/mips/micromips-branch-relax.s
index 321bd20..6cf2c47 100644
--- a/gas/testsuite/gas/mips/micromips-branch-relax.s
+++ b/gas/testsuite/gas/mips/micromips-branch-relax.s
@@ -157,6 +157,7 @@ test:
 
 	.skip	511 << 1
 test2:
+	.insn
 
 	.skip	(32767 - 511) << 1
 test3:
diff --git a/gas/testsuite/gas/mips/micromips-insn32.d b/gas/testsuite/gas/mips/micromips-insn32.d
index a56b38f..4db39bf 100644
--- a/gas/testsuite/gas/mips/micromips-insn32.d
+++ b/gas/testsuite/gas/mips/micromips-insn32.d
@@ -1191,7 +1191,7 @@ Disassembly of section \.text:
 [ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	f000 0000 	jalx	[0-9a-f]+ <test>
-[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test2
+[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test4
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	41a2 0000 	lui	v0,0x0
 [ 	]*[0-9a-f]+: R_MICROMIPS_HI16	test
@@ -7616,7 +7616,7 @@ Disassembly of section \.text:
 [ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test_delay_slot
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	f000 0000 	jalx	[0-9a-f]+ <test>
-[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test_delay_slot
+[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test_delay_slot_ext
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	03e2 0f3c 	jalr	v0
 [ 0-9a-f]+:	0000 0000 	nop
diff --git a/gas/testsuite/gas/mips/micromips-noinsn32.d b/gas/testsuite/gas/mips/micromips-noinsn32.d
index 3b4a795..dea5bd4 100644
--- a/gas/testsuite/gas/mips/micromips-noinsn32.d
+++ b/gas/testsuite/gas/mips/micromips-noinsn32.d
@@ -1181,7 +1181,7 @@ Disassembly of section \.text:
 [ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	f000 0000 	jalx	[0-9a-f]+ <test>
-[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test2
+[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test4
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	41a2 0000 	lui	v0,0x0
 [ 	]*[0-9a-f]+: R_MICROMIPS_HI16	test
@@ -7595,7 +7595,7 @@ Disassembly of section \.text:
 [ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test_delay_slot
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	f000 0000 	jalx	[0-9a-f]+ <test>
-[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test_delay_slot
+[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test_delay_slot_ext
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	03e2 0f3c 	jalr	v0
 [ 0-9a-f]+:	0000 0000 	nop
diff --git a/gas/testsuite/gas/mips/micromips-trap.d b/gas/testsuite/gas/mips/micromips-trap.d
index 8f33d9b..bccaa27 100644
--- a/gas/testsuite/gas/mips/micromips-trap.d
+++ b/gas/testsuite/gas/mips/micromips-trap.d
@@ -1186,7 +1186,7 @@ Disassembly of section \.text:
 [ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	f000 0000 	jalx	[0-9a-f]+ <test>
-[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test2
+[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test4
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	41a2 0000 	lui	v0,0x0
 [ 	]*[0-9a-f]+: R_MICROMIPS_HI16	test
@@ -7544,7 +7544,7 @@ Disassembly of section \.text:
 [ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test_delay_slot
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	f000 0000 	jalx	[0-9a-f]+ <test>
-[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test_delay_slot
+[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test_delay_slot_ext
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	45c2      	jalr	v0
 [ 0-9a-f]+:	0000 0000 	nop
diff --git a/gas/testsuite/gas/mips/micromips.d b/gas/testsuite/gas/mips/micromips.d
index 8801c56..be41c2f 100644
--- a/gas/testsuite/gas/mips/micromips.d
+++ b/gas/testsuite/gas/mips/micromips.d
@@ -1201,7 +1201,7 @@ Disassembly of section \.text:
 [ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	f000 0000 	jalx	[0-9a-f]+ <test>
-[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test2
+[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test4
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	41a2 0000 	lui	v0,0x0
 [ 	]*[0-9a-f]+: R_MICROMIPS_HI16	test
@@ -7673,7 +7673,7 @@ Disassembly of section \.text:
 [ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test_delay_slot
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	f000 0000 	jalx	[0-9a-f]+ <test>
-[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test_delay_slot
+[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	test_delay_slot_ext
 [ 0-9a-f]+:	0000 0000 	nop
 [ 0-9a-f]+:	45c2      	jalr	v0
 [ 0-9a-f]+:	0000 0000 	nop
diff --git a/gas/testsuite/gas/mips/micromips.s b/gas/testsuite/gas/mips/micromips.s
index 48c0148..8c901b9 100644
--- a/gas/testsuite/gas/mips/micromips.s
+++ b/gas/testsuite/gas/mips/micromips.s
@@ -755,7 +755,7 @@ test3:
 	jal	test2
 
 	jalx	test
-	jalx	test2
+	jalx	test4
 
 	la	$2, test
 	lca	$2, test
@@ -5563,7 +5563,7 @@ test_delay_slot:
 	bgezall	$3, test_delay_slot
 	bltzall	$3, test_delay_slot
 	jal	test_delay_slot
-	jalx	test_delay_slot
+	jalx	test_delay_slot_ext
 	.ifndef	insn32
 	jalr16	$2
 	.endif
diff --git a/gas/testsuite/gas/mips/micromips@branch-misc-5-64.d b/gas/testsuite/gas/mips/micromips@branch-misc-5-64.d
index 675752d..82b1222 100644
--- a/gas/testsuite/gas/mips/micromips@branch-misc-5-64.d
+++ b/gas/testsuite/gas/mips/micromips@branch-misc-5-64.d
@@ -20,7 +20,7 @@ Disassembly of section \.text:
 			6: R_MIPS_NONE	\*ABS\*\-0x4
 [0-9a-f]+ <[^>]*> 0c00      	nop
 [0-9a-f]+ <[^>]*> 9400 0000 	b	0+0010 <g6\+0x10>
-			c: R_MICROMIPS_PC16_S1	\.data\-0x4
+			c: R_MICROMIPS_PC16_S1	\.Ldata\-0x4
 			c: R_MIPS_NONE	\*ABS\*\-0x4
 			c: R_MIPS_NONE	\*ABS\*\-0x4
 [0-9a-f]+ <[^>]*> 0c00      	nop
diff --git a/gas/testsuite/gas/mips/micromips@branch-misc-5pic-64.d b/gas/testsuite/gas/mips/micromips@branch-misc-5pic-64.d
index 90b2143..ddc9b3c 100644
--- a/gas/testsuite/gas/mips/micromips@branch-misc-5pic-64.d
+++ b/gas/testsuite/gas/mips/micromips@branch-misc-5pic-64.d
@@ -20,7 +20,7 @@ Disassembly of section \.text:
 			6: R_MIPS_NONE	\*ABS\*\-0x4
 [0-9a-f]+ <[^>]*> 0c00      	nop
 [0-9a-f]+ <[^>]*> 9400 0000 	b	0+0010 <g6\+0x10>
-			c: R_MICROMIPS_PC16_S1	\.data\-0x4
+			c: R_MICROMIPS_PC16_S1	\.Ldata\-0x4
 			c: R_MIPS_NONE	\*ABS\*\-0x4
 			c: R_MIPS_NONE	\*ABS\*\-0x4
 [0-9a-f]+ <[^>]*> 0c00      	nop
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 8bdddbf..80e598a 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -607,9 +607,21 @@ if { [istarget mips*-*-vxworks*] } {
     run_dump_test "branch-weak-6"
     run_dump_test "branch-weak-7"
     run_dump_test "branch-local-1"
+    run_list_test "branch-local-2" "-32" \
+				"MIPS branch local symbol relocation 2"
+    run_list_test "branch-local-3" "-32" \
+				"MIPS branch local symbol relocation 3"
     if $has_newabi {
 	run_dump_test "branch-local-n32-1"
+	run_list_test "branch-local-n32-2" "-n32 -march=from-abi" \
+				"MIPS branch local symbol relocation 2 (n32)"
+	run_list_test "branch-local-n32-3" "-n32 -march=from-abi" \
+				"MIPS branch local symbol relocation 3 (n32)"
 	run_dump_test "branch-local-n64-1"
+	run_list_test "branch-local-n64-2" "-64 -march=from-abi" \
+				"MIPS branch local symbol relocation 2 (n64)"
+	run_list_test "branch-local-n64-3" "-64 -march=from-abi" \
+				"MIPS branch local symbol relocation 3 (n64)"
     }
     run_dump_test "branch-absolute"
     run_dump_test "branch-absolute-addend"
@@ -847,6 +859,62 @@ if { [istarget mips*-*-vxworks*] } {
 	run_dump_test "jalx-addend-n64"
 	run_dump_test "jalx-local-n64"
     }
+
+    run_list_test "unaligned-jump-1" "-32" \
+				"MIPS jump to unaligned symbol 1"
+    run_list_test "unaligned-jump-2" "-32" \
+				"MIPS jump to unaligned symbol 2"
+    if $has_newabi {
+	run_dump_test "unaligned-jump-3"
+    }
+    run_list_test "unaligned-jump-mips16-1" "-32" \
+				"MIPS16 jump to unaligned symbol 1"
+    run_list_test "unaligned-jump-mips16-2" "-32" \
+				"MIPS16 jump to unaligned symbol 2"
+    if $has_newabi {
+	run_dump_test "unaligned-jump-mips16-3"
+    }
+    run_list_test "unaligned-jump-micromips-1" "-32" \
+				"microMIPS jump to unaligned symbol 1"
+    run_list_test "unaligned-jump-micromips-2" "-32" \
+				"microMIPS jump to unaligned symbol 2"
+    if $has_newabi {
+	run_dump_test "unaligned-jump-micromips-3"
+    }
+    run_list_test "unaligned-branch-1" "-32" \
+				"MIPS branch to unaligned symbol 1"
+    run_list_test "unaligned-branch-2" "-32" \
+				"MIPS branch to unaligned symbol 2"
+    if $has_newabi {
+	run_dump_test "unaligned-branch-3"
+    }
+    run_list_test "unaligned-branch-r6-1" "-32" \
+				"MIPSr6 branch to unaligned symbol 1"
+    run_list_test "unaligned-branch-r6-2" "-32 -mips64r6" \
+				"MIPSr6 branch to unaligned symbol 2"
+    run_list_test "unaligned-branch-r6-3" "-32" \
+				"MIPSr6 branch to unaligned symbol 3"
+    run_list_test "unaligned-branch-r6-4" "-32 -mips64r6" \
+				"MIPSr6 branch to unaligned symbol 4"
+    if $has_newabi {
+	run_dump_test "unaligned-branch-r6-5"
+	run_dump_test "unaligned-branch-r6-6"
+    }
+    run_list_test "unaligned-branch-mips16-1" "-32" \
+				"MIPS16 branch to unaligned symbol 1"
+    run_list_test "unaligned-branch-mips16-2" "-32" \
+				"MIPS16 branch to unaligned symbol 2"
+    if $has_newabi {
+	run_dump_test "unaligned-branch-mips16-3"
+    }
+    run_list_test "unaligned-branch-micromips-1" "-32" \
+				"microMIPS branch to unaligned symbol 1"
+    run_list_test "unaligned-branch-micromips-2" "-32" \
+				"microMIPS branch to unaligned symbol 2"
+    if $has_newabi {
+	run_dump_test "unaligned-branch-micromips-3"
+    }
+
     # Check MIPS16 HI16/LO16 relocations
     run_dump_test "mips16-hilo"
     if $has_newabi {
diff --git a/gas/testsuite/gas/mips/mips16-64.d b/gas/testsuite/gas/mips/mips16-64.d
index 95d7001..e21f7fc 100644
--- a/gas/testsuite/gas/mips/mips16-64.d
+++ b/gas/testsuite/gas/mips/mips16-64.d
@@ -43,7 +43,7 @@ Disassembly of section .text:
   64:	f7bf fc40 	ld	v0,0 <data1>
   68:	f6a0 fc54 	ld	v0,71c <data2>
   6c:	f001 fc40 	ld	v0,868 <bar>
-  70:	f0c1 fc40 	ld	v0,930 <quux>
+  70:	f0c1 fc40 	ld	v0,930 <iuux>
   74:	f840      	ld	v0,0\(sp\)
   76:	f000 f841 	ld	v0,1\(sp\)
   7a:	f000 f842 	ld	v0,2\(sp\)
@@ -128,7 +128,7 @@ Disassembly of section .text:
  194:	f67f b20c 	lw	v0,0 <data1>
  198:	f580 b204 	lw	v0,71c <data2>
  19c:	f6c0 b20c 	lw	v0,868 <bar>
- 1a0:	f780 b210 	lw	v0,930 <quux>
+ 1a0:	f780 b210 	lw	v0,930 <iuux>
  1a4:	9200      	lw	v0,0\(sp\)
  1a6:	f000 9201 	lw	v0,1\(sp\)
  1aa:	f000 9202 	lw	v0,2\(sp\)
@@ -501,7 +501,7 @@ Disassembly of section .text:
  698:	f17f fe48 	dla	v0,0 <data1>
  69c:	f080 fe40 	dla	v0,71c <data2>
  6a0:	f1c0 fe48 	dla	v0,868 <bar>
- 6a4:	f280 fe4c 	dla	v0,930 <quux>
+ 6a4:	f280 fe4c 	dla	v0,930 <iuux>
  6a8:	fb00      	daddiu	sp,0
  6aa:	f000 fb01 	daddiu	sp,1
  6ae:	f7ff fb1f 	daddiu	sp,-1
@@ -530,7 +530,7 @@ Disassembly of section .text:
  6ee:	f11f 0a14 	la	v0,0 <data1>
  6f2:	0a0b      	la	v0,71c <data2>
  6f4:	0a5d      	la	v0,868 <bar>
- 6f6:	0a8f      	la	v0,930 <quux>
+ 6f6:	0a8f      	la	v0,930 <iuux>
  6f8:	6300      	addiu	sp,0
  6fa:	f000 6301 	addiu	sp,1
  6fe:	f7ff 631f 	addiu	sp,-1
@@ -645,23 +645,23 @@ Disassembly of section .text:
  80a:	f3ff 221b 	beqz	v0,4 <insns1>
  80e:	2288      	beqz	v0,720 <insns2>
  810:	222b      	beqz	v0,868 <bar>
- 812:	f080 220d 	beqz	v0,930 <quux>
+ 812:	f080 220d 	beqz	v0,930 <iuux>
  816:	f3ff 2a15 	bnez	v0,4 <insns1>
  81a:	2a82      	bnez	v0,720 <insns2>
  81c:	2a25      	bnez	v0,868 <bar>
- 81e:	f080 2a07 	bnez	v0,930 <quux>
+ 81e:	f080 2a07 	bnez	v0,930 <iuux>
  822:	f3ff 600f 	bteqz	4 <insns1>
  826:	f77f 601b 	bteqz	720 <insns2>
  82a:	601e      	bteqz	868 <bar>
- 82c:	f080 6000 	bteqz	930 <quux>
+ 82c:	f080 6000 	bteqz	930 <iuux>
  830:	f3ff 6108 	btnez	4 <insns1>
  834:	f77f 6114 	btnez	720 <insns2>
  838:	6117      	btnez	868 <bar>
- 83a:	617a      	btnez	930 <quux>
+ 83a:	617a      	btnez	930 <iuux>
  83c:	f3ff 1002 	b	4 <insns1>
  840:	176f      	b	720 <insns2>
  842:	1012      	b	868 <bar>
- 844:	1075      	b	930 <quux>
+ 844:	1075      	b	930 <iuux>
  846:	e805      	break	0
  848:	e825      	break	1
  84a:	efe5      	break	63
diff --git a/gas/testsuite/gas/mips/mips16-dwarf2.s b/gas/testsuite/gas/mips/mips16-dwarf2.s
index 7c0a919..98bb168 100644
--- a/gas/testsuite/gas/mips/mips16-dwarf2.s
+++ b/gas/testsuite/gas/mips/mips16-dwarf2.s
@@ -19,7 +19,7 @@ stuff:
 	.loc	1 5 0
 	lw	$2, 1f
 	.loc	1 6 0
-	b	0f
+	b	2f
 	nop
 	.loc	1 7 0
 	b	1f
@@ -27,6 +27,8 @@ stuff:
 	.loc	1 8 0
 
 	.p2align 8
+2:
+	.insn
 0:
 	.space	2048
 1:
diff --git a/gas/testsuite/gas/mips/mips16.d b/gas/testsuite/gas/mips/mips16.d
index b2cc9ae..5df2880 100644
--- a/gas/testsuite/gas/mips/mips16.d
+++ b/gas/testsuite/gas/mips/mips16.d
@@ -42,7 +42,7 @@ Disassembly of section .text:
   64:	f7bf fc40 	ld	v0,0 <data1>
   68:	f6a0 fc54 	ld	v0,71c <data2>
   6c:	f001 fc40 	ld	v0,868 <bar>
-  70:	f0c1 fc40 	ld	v0,930 <quux>
+  70:	f0c1 fc40 	ld	v0,930 <iuux>
   74:	f840      	ld	v0,0\(sp\)
   76:	f000 f841 	ld	v0,1\(sp\)
   7a:	f000 f842 	ld	v0,2\(sp\)
@@ -127,7 +127,7 @@ Disassembly of section .text:
  194:	f67f b20c 	lw	v0,0 <data1>
  198:	f580 b204 	lw	v0,71c <data2>
  19c:	f6c0 b20c 	lw	v0,868 <bar>
- 1a0:	f780 b210 	lw	v0,930 <quux>
+ 1a0:	f780 b210 	lw	v0,930 <iuux>
  1a4:	9200      	lw	v0,0\(sp\)
  1a6:	f000 9201 	lw	v0,1\(sp\)
  1aa:	f000 9202 	lw	v0,2\(sp\)
@@ -500,7 +500,7 @@ Disassembly of section .text:
  698:	f17f fe48 	dla	v0,0 <data1>
  69c:	f080 fe40 	dla	v0,71c <data2>
  6a0:	f1c0 fe48 	dla	v0,868 <bar>
- 6a4:	f280 fe4c 	dla	v0,930 <quux>
+ 6a4:	f280 fe4c 	dla	v0,930 <iuux>
  6a8:	fb00      	daddiu	sp,0
  6aa:	f000 fb01 	daddiu	sp,1
  6ae:	f7ff fb1f 	daddiu	sp,-1
@@ -529,7 +529,7 @@ Disassembly of section .text:
  6ee:	f11f 0a14 	la	v0,0 <data1>
  6f2:	0a0b      	la	v0,71c <data2>
  6f4:	0a5d      	la	v0,868 <bar>
- 6f6:	0a8f      	la	v0,930 <quux>
+ 6f6:	0a8f      	la	v0,930 <iuux>
  6f8:	6300      	addiu	sp,0
  6fa:	f000 6301 	addiu	sp,1
  6fe:	f7ff 631f 	addiu	sp,-1
@@ -644,23 +644,23 @@ Disassembly of section .text:
  80a:	f3ff 221b 	beqz	v0,4 <insns1>
  80e:	2288      	beqz	v0,720 <insns2>
  810:	222b      	beqz	v0,868 <bar>
- 812:	f080 220d 	beqz	v0,930 <quux>
+ 812:	f080 220d 	beqz	v0,930 <iuux>
  816:	f3ff 2a15 	bnez	v0,4 <insns1>
  81a:	2a82      	bnez	v0,720 <insns2>
  81c:	2a25      	bnez	v0,868 <bar>
- 81e:	f080 2a07 	bnez	v0,930 <quux>
+ 81e:	f080 2a07 	bnez	v0,930 <iuux>
  822:	f3ff 600f 	bteqz	4 <insns1>
  826:	f77f 601b 	bteqz	720 <insns2>
  82a:	601e      	bteqz	868 <bar>
- 82c:	f080 6000 	bteqz	930 <quux>
+ 82c:	f080 6000 	bteqz	930 <iuux>
  830:	f3ff 6108 	btnez	4 <insns1>
  834:	f77f 6114 	btnez	720 <insns2>
  838:	6117      	btnez	868 <bar>
- 83a:	617a      	btnez	930 <quux>
+ 83a:	617a      	btnez	930 <iuux>
  83c:	f3ff 1002 	b	4 <insns1>
  840:	176f      	b	720 <insns2>
  842:	1012      	b	868 <bar>
- 844:	1075      	b	930 <quux>
+ 844:	1075      	b	930 <iuux>
  846:	e805      	break	0
  848:	e825      	break	1
  84a:	efe5      	break	63
diff --git a/gas/testsuite/gas/mips/mips16.s b/gas/testsuite/gas/mips/mips16.s
index 6268fb1..d3d9586 100644
--- a/gas/testsuite/gas/mips/mips16.s
+++ b/gas/testsuite/gas/mips/mips16.s
@@ -216,24 +216,24 @@ insns2:
 
 	beqz	$2,insns1
 	beqz	$2,insns2
-	beqz	$2,bar
-	beqz	$2,quux
+	beqz	$2,ibar
+	beqz	$2,iuux
 	bnez	$2,insns1
 	bnez	$2,insns2
-	bnez	$2,bar
-	bnez	$2,quux
+	bnez	$2,ibar
+	bnez	$2,iuux
 	bteqz	insns1
 	bteqz	insns2
-	bteqz	bar
-	bteqz	quux
+	bteqz	ibar
+	bteqz	iuux
 	btnez	insns1
 	btnez	insns2
-	btnez	bar
-	btnez	quux
+	btnez	ibar
+	btnez	iuux
 	b	insns1
 	b	insns2
-	b	bar
-	b	quux
+	b	ibar
+	b	iuux
 
 	break	0
 	break	1
@@ -252,7 +252,11 @@ insns2:
 	exit	$31
 
 	.p2align 3
-bar:	
+ibar:
+	.insn
+bar:
 
 	.skip	200
+iuux:
+	.insn
 quux:	
diff --git a/gas/testsuite/gas/mips/relax-swap3.s b/gas/testsuite/gas/mips/relax-swap3.s
index 497ecf8..ffa31bf 100644
--- a/gas/testsuite/gas/mips/relax-swap3.s
+++ b/gas/testsuite/gas/mips/relax-swap3.s
@@ -8,6 +8,7 @@ foo:
 	la	$2, bar
 	beqz	$3, 0f
 0:
+	.insn
 
 # Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
 	.align	2
diff --git a/gas/testsuite/gas/mips/unaligned-branch-1.l b/gas/testsuite/gas/mips/unaligned-branch-1.l
new file mode 100644
index 0000000..beaab28
--- /dev/null
+++ b/gas/testsuite/gas/mips/unaligned-branch-1.l
@@ -0,0 +1,40 @@
+.*: Assembler messages:
+.*:15: Error: branch to misaligned address \(0x11a1\)
+.*:17: Error: branch to misaligned address \(0x11a1\)
+.*:19: Error: branch to misaligned address \(0x11a1\)
+.*:21: Error: branch to misaligned address \(0x11a2\)
+.*:23: Error: branch to misaligned address \(0x11a2\)
+.*:25: Error: branch to misaligned address \(0x11a2\)
+.*:27: Error: branch to misaligned address \(0x11a3\)
+.*:29: Error: branch to misaligned address \(0x11a3\)
+.*:31: Error: branch to misaligned address \(0x11a3\)
+.*:39: Error: branch to misaligned address \(0x11a5\)
+.*:41: Error: branch to misaligned address \(0x11a5\)
+.*:43: Error: branch to misaligned address \(0x11a5\)
+.*:45: Error: branch to misaligned address \(0x11a6\)
+.*:47: Error: branch to misaligned address \(0x11a6\)
+.*:49: Error: branch to misaligned address \(0x11a6\)
+.*:51: Error: branch to misaligned address \(0x11a7\)
+.*:53: Error: branch to misaligned address \(0x11a7\)
+.*:55: Error: branch to misaligned address \(0x11a7\)
+.*:63: Error: branch to a symbol in another ISA mode
+.*:65: Error: branch to a symbol in another ISA mode
+.*:67: Error: branch to a symbol in another ISA mode
+.*:69: Error: branch to a symbol in another ISA mode
+.*:71: Error: branch to a symbol in another ISA mode
+.*:73: Error: branch to a symbol in another ISA mode
+.*:75: Error: branch to a symbol in another ISA mode
+.*:77: Error: branch to a symbol in another ISA mode
+.*:79: Error: branch to a symbol in another ISA mode
+.*:81: Error: branch to a symbol in another ISA mode
+.*:83: Error: branch to a symbol in another ISA mode
+.*:85: Error: branch to a symbol in another ISA mode
+.*:87: Error: branch to a symbol in another ISA mode
+.*:89: Error: branch to a symbol in another ISA mode
+.*:91: Error: branch to a symbol in another ISA mode
+.*:93: Error: branch to a symbol in another ISA mode
+.*:95: Error: branch to a symbol in another ISA mode
+.*:97: Error: branch to a symbol in another ISA mode
+.*:99: Error: branch to a symbol in another ISA mode
+.*:101: Error: branch to a symbol in another ISA mode
+.*:103: Error: branch to a symbol in another ISA mode
diff --git a/gas/testsuite/gas/mips/unaligned-branch-1.s b/gas/testsuite/gas/mips/unaligned-branch-1.s
new file mode 100644
index 0000000..bc976a2
--- /dev/null
+++ b/gas/testsuite/gas/mips/unaligned-branch-1.s
@@ -0,0 +1,137 @@
+	.text
+	.set	noreorder
+	.space	0x1000
+
+	.align	4
+	.ent	foo
+foo:
+	nor	$0, $0
+	bal	bar0
+	 nor	$0, $0
+	b	bar0
+	 nor	$0, $0
+	bne	$2, $3, bar0
+	 nor	$0, $0
+	bal	bar1
+	 nor	$0, $0
+	b	bar1
+	 nor	$0, $0
+	bne	$2, $3, bar1
+	 nor	$0, $0
+	bal	bar2
+	 nor	$0, $0
+	b	bar2
+	 nor	$0, $0
+	bne	$2, $3, bar2
+	 nor	$0, $0
+	bal	bar3
+	 nor	$0, $0
+	b	bar3
+	 nor	$0, $0
+	bne	$2, $3, bar3
+	 nor	$0, $0
+	bal	bar4
+	 nor	$0, $0
+	b	bar4
+	 nor	$0, $0
+	bne	$2, $3, bar4
+	 nor	$0, $0
+	bal	bar4 + 1
+	 nor	$0, $0
+	b	bar4 + 1
+	 nor	$0, $0
+	bne	$2, $3, bar4 + 1
+	 nor	$0, $0
+	bal	bar4 + 2
+	 nor	$0, $0
+	b	bar4 + 2
+	 nor	$0, $0
+	bne	$2, $3, bar4 + 2
+	 nor	$0, $0
+	bal	bar4 + 3
+	 nor	$0, $0
+	b	bar4 + 3
+	 nor	$0, $0
+	bne	$2, $3, bar4 + 3
+	 nor	$0, $0
+	bal	bar4 + 4
+	 nor	$0, $0
+	b	bar4 + 4
+	 nor	$0, $0
+	bne	$2, $3, bar4 + 4
+	 nor	$0, $0
+	bal	bar16
+	 nor	$0, $0
+	b	bar16
+	 nor	$0, $0
+	bne	$2, $3, bar16
+	 nor	$0, $0
+	bal	bar17
+	 nor	$0, $0
+	b	bar17
+	 nor	$0, $0
+	bne	$2, $3, bar17
+	 nor	$0, $0
+	bal	bar18
+	 nor	$0, $0
+	b	bar18
+	 nor	$0, $0
+	bne	$2, $3, bar18
+	 nor	$0, $0
+	bal	bar18 + 1
+	 nor	$0, $0
+	b	bar18 + 1
+	 nor	$0, $0
+	bne	$2, $3, bar18 + 1
+	 nor	$0, $0
+	bal	bar18 + 2
+	 nor	$0, $0
+	b	bar18 + 2
+	 nor	$0, $0
+	bne	$2, $3, bar18 + 2
+	 nor	$0, $0
+	bal	bar18 + 3
+	 nor	$0, $0
+	b	bar18 + 3
+	 nor	$0, $0
+	bne	$2, $3, bar18 + 3
+	 nor	$0, $0
+	bal	bar18 + 4
+	 nor	$0, $0
+	b	bar18 + 4
+	 nor	$0, $0
+	bne	$2, $3, bar18 + 4
+	 nor	$0, $0
+	jalr	$0, $ra
+	 nor	$0, $0
+	.end	foo
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	4, 0
+	.space	16
+
+	.macro	obj n:req
+	.type	bar\@, @object
+bar\@ :
+	.byte	0
+	.size	bar\@, . - bar\@
+	.if	\n - 1
+	obj	\n - 1
+	.endif
+	.endm
+
+	.macro	fun n:req
+	.type	bar\@, @function
+bar\@ :
+	.insn
+	.hword	0
+	.size	bar\@, . - bar\@
+	.if	\n - 1
+	fun	\n - 1
+	.endif
+	.endm
+
+	.align	4
+	.set	micromips
+	obj	16
+	fun	8
diff --git a/gas/testsuite/gas/mips/unaligned-branch-2.l b/gas/testsuite/gas/mips/unaligned-branch-2.l
new file mode 100644
index 0000000..d076f9b
--- /dev/null
+++ b/gas/testsuite/gas/mips/unaligned-branch-2.l
@@ -0,0 +1,19 @@
+.*: Assembler messages:
+.*:39: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:41: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:43: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:45: Error: cannot encode misaligned addend in the relocatable field \(0x2\)
+.*:47: Error: cannot encode misaligned addend in the relocatable field \(0x2\)
+.*:49: Error: cannot encode misaligned addend in the relocatable field \(0x2\)
+.*:51: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
+.*:53: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
+.*:55: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
+.*:81: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:83: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:85: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:87: Error: cannot encode misaligned addend in the relocatable field \(0x2\)
+.*:89: Error: cannot encode misaligned addend in the relocatable field \(0x2\)
+.*:91: Error: cannot encode misaligned addend in the relocatable field \(0x2\)
+.*:93: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
+.*:95: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
+.*:97: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
diff --git a/gas/testsuite/gas/mips/unaligned-branch-2.s b/gas/testsuite/gas/mips/unaligned-branch-2.s
new file mode 100644
index 0000000..2f892c7
--- /dev/null
+++ b/gas/testsuite/gas/mips/unaligned-branch-2.s
@@ -0,0 +1,139 @@
+	.text
+	.set	noreorder
+	.space	0x1000
+
+	.align	4
+	.ent	foo
+foo:
+	nor	$0, $0
+	bal	bar0
+	 nor	$0, $0
+	b	bar0
+	 nor	$0, $0
+	bne	$2, $3, bar0
+	 nor	$0, $0
+	bal	bar1
+	 nor	$0, $0
+	b	bar1
+	 nor	$0, $0
+	bne	$2, $3, bar1
+	 nor	$0, $0
+	bal	bar2
+	 nor	$0, $0
+	b	bar2
+	 nor	$0, $0
+	bne	$2, $3, bar2
+	 nor	$0, $0
+	bal	bar3
+	 nor	$0, $0
+	b	bar3
+	 nor	$0, $0
+	bne	$2, $3, bar3
+	 nor	$0, $0
+	bal	bar4
+	 nor	$0, $0
+	b	bar4
+	 nor	$0, $0
+	bne	$2, $3, bar4
+	 nor	$0, $0
+	bal	bar4 + 1
+	 nor	$0, $0
+	b	bar4 + 1
+	 nor	$0, $0
+	bne	$2, $3, bar4 + 1
+	 nor	$0, $0
+	bal	bar4 + 2
+	 nor	$0, $0
+	b	bar4 + 2
+	 nor	$0, $0
+	bne	$2, $3, bar4 + 2
+	 nor	$0, $0
+	bal	bar4 + 3
+	 nor	$0, $0
+	b	bar4 + 3
+	 nor	$0, $0
+	bne	$2, $3, bar4 + 3
+	 nor	$0, $0
+	bal	bar4 + 4
+	 nor	$0, $0
+	b	bar4 + 4
+	 nor	$0, $0
+	bne	$2, $3, bar4 + 4
+	 nor	$0, $0
+	bal	bar16
+	 nor	$0, $0
+	b	bar16
+	 nor	$0, $0
+	bne	$2, $3, bar16
+	 nor	$0, $0
+	bal	bar17
+	 nor	$0, $0
+	b	bar17
+	 nor	$0, $0
+	bne	$2, $3, bar17
+	 nor	$0, $0
+	bal	bar18
+	 nor	$0, $0
+	b	bar18
+	 nor	$0, $0
+	bne	$2, $3, bar18
+	 nor	$0, $0
+	bal	bar18 + 1
+	 nor	$0, $0
+	b	bar18 + 1
+	 nor	$0, $0
+	bne	$2, $3, bar18 + 1
+	 nor	$0, $0
+	bal	bar18 + 2
+	 nor	$0, $0
+	b	bar18 + 2
+	 nor	$0, $0
+	bne	$2, $3, bar18 + 2
+	 nor	$0, $0
+	bal	bar18 + 3
+	 nor	$0, $0
+	b	bar18 + 3
+	 nor	$0, $0
+	bne	$2, $3, bar18 + 3
+	 nor	$0, $0
+	bal	bar18 + 4
+	 nor	$0, $0
+	b	bar18 + 4
+	 nor	$0, $0
+	bne	$2, $3, bar18 + 4
+	 nor	$0, $0
+	jalr	$0, $ra
+	 nor	$0, $0
+	.end	foo
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	4, 0
+	.space	16
+
+	.macro	obj n:req
+	.globl	bar\@
+	.type	bar\@, @object
+bar\@ :
+	.byte	0
+	.size	bar\@, . - bar\@
+	.if	\n - 1
+	obj	\n - 1
+	.endif
+	.endm
+
+	.macro	fun n:req
+	.globl	bar\@
+	.type	bar\@, @function
+bar\@ :
+	.insn
+	.hword	0
+	.size	bar\@, . - bar\@
+	.if	\n - 1
+	fun	\n - 1
+	.endif
+	.endm
+
+	.align	4
+	.set	micromips
+	obj	16
+	fun	8
diff --git a/gas/testsuite/gas/mips/unaligned-branch-3.d b/gas/testsuite/gas/mips/unaligned-branch-3.d
new file mode 100644
index 0000000..72e562f
--- /dev/null
+++ b/gas/testsuite/gas/mips/unaligned-branch-3.d
@@ -0,0 +1,181 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS branch to unaligned symbol 3
+#as: -n32 -march=from-abi
+#source: unaligned-branch-2.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+	\.\.\.
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	00001008 <foo\+0x8>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar0-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	00001010 <foo\+0x10>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar0-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,00001018 <foo\+0x18>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar0-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	00001020 <foo\+0x20>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar1-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	00001028 <foo\+0x28>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar1-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,00001030 <foo\+0x30>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar1-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	00001038 <foo\+0x38>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar2-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	00001040 <foo\+0x40>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar2-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,00001048 <foo\+0x48>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar2-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	00001050 <foo\+0x50>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar3-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	00001058 <foo\+0x58>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar3-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,00001060 <foo\+0x60>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar3-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	00001068 <foo\+0x68>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar4-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	00001070 <foo\+0x70>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar4-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,00001078 <foo\+0x78>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar4-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	00001080 <foo\+0x80>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar4-0x3
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	00001088 <foo\+0x88>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar4-0x3
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,00001090 <foo\+0x90>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar4-0x3
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	00001098 <foo\+0x98>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar4-0x2
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	000010a0 <foo\+0xa0>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar4-0x2
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,000010a8 <foo\+0xa8>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar4-0x2
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	000010b0 <foo\+0xb0>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar4-0x1
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	000010b8 <foo\+0xb8>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar4-0x1
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,000010c0 <foo\+0xc0>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar4-0x1
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	000010c8 <foo\+0xc8>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	000010d0 <foo\+0xd0>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,000010d8 <foo\+0xd8>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	000010e0 <foo\+0xe0>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar16-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	000010e8 <foo\+0xe8>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar16-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,000010f0 <foo\+0xf0>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar16-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	000010f8 <foo\+0xf8>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar17-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	00001100 <foo\+0x100>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar17-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,00001108 <foo\+0x108>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar17-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	00001110 <foo\+0x110>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar18-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	00001118 <foo\+0x118>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar18-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,00001120 <foo\+0x120>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar18-0x4
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	00001128 <foo\+0x128>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar18-0x3
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	00001130 <foo\+0x130>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar18-0x3
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,00001138 <foo\+0x138>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar18-0x3
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	00001140 <foo\+0x140>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar18-0x2
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	00001148 <foo\+0x148>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar18-0x2
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,00001150 <foo\+0x150>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar18-0x2
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	00001158 <foo\+0x158>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar18-0x1
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	00001160 <foo\+0x160>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar18-0x1
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,00001168 <foo\+0x168>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar18-0x1
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 04110000 	bal	00001170 <foo\+0x170>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar18
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 10000000 	b	00001178 <foo\+0x178>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar18
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000 	bne	v0,v1,00001180 <foo\+0x180>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar18
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+[0-9a-f]+ <[^>]*> 03e00009 	jalr	zero,ra
+[0-9a-f]+ <[^>]*> 00000027 	nor	zero,zero,zero
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/unaligned-branch-micromips-1.l b/gas/testsuite/gas/mips/unaligned-branch-micromips-1.l
new file mode 100644
index 0000000..365a4bc
--- /dev/null
+++ b/gas/testsuite/gas/mips/unaligned-branch-micromips-1.l
@@ -0,0 +1,56 @@
+.*: Assembler messages:
+.*:10: Error: branch to a symbol in another ISA mode
+.*:12: Error: branch to a symbol in another ISA mode
+.*:14: Error: branch to a symbol in another ISA mode
+.*:16: Error: branch to a symbol in another ISA mode
+.*:18: Error: branch to a symbol in another ISA mode
+.*:20: Error: branch to a symbol in another ISA mode
+.*:22: Error: branch to a symbol in another ISA mode
+.*:24: Error: branch to a symbol in another ISA mode
+.*:26: Error: branch to a symbol in another ISA mode
+.*:34: Error: branch to misaligned address \(0x11f5\)
+.*:38: Error: branch to misaligned address \(0x11f7\)
+.*:42: Error: branch to a symbol in another ISA mode
+.*:44: Error: branch to a symbol in another ISA mode
+.*:46: Error: branch to a symbol in another ISA mode
+.*:48: Error: branch to a symbol in another ISA mode
+.*:50: Error: branch to a symbol in another ISA mode
+.*:52: Error: branch to a symbol in another ISA mode
+.*:54: Error: branch to a symbol in another ISA mode
+.*:56: Error: branch to a symbol in another ISA mode
+.*:58: Error: branch to a symbol in another ISA mode
+.*:66: Error: branch to misaligned address \(0x11f5\)
+.*:70: Error: branch to misaligned address \(0x11f7\)
+.*:74: Error: branch to a symbol in another ISA mode
+.*:76: Error: branch to a symbol in another ISA mode
+.*:78: Error: branch to a symbol in another ISA mode
+.*:80: Error: branch to a symbol in another ISA mode
+.*:82: Error: branch to a symbol in another ISA mode
+.*:84: Error: branch to a symbol in another ISA mode
+.*:86: Error: branch to a symbol in another ISA mode
+.*:88: Error: branch to a symbol in another ISA mode
+.*:90: Error: branch to a symbol in another ISA mode
+.*:98: Error: branch to misaligned address \(0x11f5\)
+.*:102: Error: branch to misaligned address \(0x11f7\)
+.*:106: Error: branch to a symbol in another ISA mode
+.*:108: Error: branch to a symbol in another ISA mode
+.*:110: Error: branch to a symbol in another ISA mode
+.*:112: Error: branch to a symbol in another ISA mode
+.*:114: Error: branch to a symbol in another ISA mode
+.*:116: Error: branch to a symbol in another ISA mode
+.*:118: Error: branch to a symbol in another ISA mode
+.*:120: Error: branch to a symbol in another ISA mode
+.*:122: Error: branch to a symbol in another ISA mode
+.*:130: Error: branch to misaligned address \(0x11f5\)
+.*:134: Error: branch to misaligned address \(0x11f7\)
+.*:138: Error: branch to a symbol in another ISA mode
+.*:140: Error: branch to a symbol in another ISA mode
+.*:142: Error: branch to a symbol in another ISA mode
+.*:144: Error: branch to a symbol in another ISA mode
+.*:146: Error: branch to a symbol in another ISA mode
+.*:148: Error: branch to a symbol in another ISA mode
+.*:150: Error: branch to a symbol in another ISA mode
+.*:152: Error: branch to a symbol in another ISA mode
+.*:154: Error: branch to a symbol in another ISA mode
+.*:162: Error: branch to misaligned address \(0x11f5\)
+.*:166: Error: branch to misaligned address \(0x11f7\)
diff --git a/gas/testsuite/gas/mips/unaligned-branch-micromips-1.s b/gas/testsuite/gas/mips/unaligned-branch-micromips-1.s
new file mode 100644
index 0000000..bec74ed
--- /dev/null
+++ b/gas/testsuite/gas/mips/unaligned-branch-micromips-1.s
@@ -0,0 +1,201 @@
+	.text
+	.set	noreorder
+	.space	0x1000
+
+	.align	4
+	.set	micromips
+	.ent	foo
+foo:
+	not	$2, $3
+	bal	bar0
+	 not	$2, $3
+	bal	bar1
+	 not	$2, $3
+	bal	bar2
+	 not	$2, $3
+	bal	bar3
+	 not	$2, $3
+	bal	bar4
+	 not	$2, $3
+	bal	bar4 + 1
+	 not	$2, $3
+	bal	bar4 + 2
+	 not	$2, $3
+	bal	bar4 + 3
+	 not	$2, $3
+	bal	bar4 + 4
+	 not	$2, $3
+	bal	bar16
+	 not	$2, $3
+	bal	bar17
+	 not	$2, $3
+	bal	bar18
+	 not	$2, $3
+	bal	bar18 + 1
+	 not	$2, $3
+	bal	bar18 + 2
+	 not	$2, $3
+	bal	bar18 + 3
+	 not	$2, $3
+	bal	bar18 + 4
+	 not	$2, $3
+	bals	bar0
+	 not	$2, $3
+	bals	bar1
+	 not	$2, $3
+	bals	bar2
+	 not	$2, $3
+	bals	bar3
+	 not	$2, $3
+	bals	bar4
+	 not	$2, $3
+	bals	bar4 + 1
+	 not	$2, $3
+	bals	bar4 + 2
+	 not	$2, $3
+	bals	bar4 + 3
+	 not	$2, $3
+	bals	bar4 + 4
+	 not	$2, $3
+	bals	bar16
+	 not	$2, $3
+	bals	bar17
+	 not	$2, $3
+	bals	bar18
+	 not	$2, $3
+	bals	bar18 + 1
+	 not	$2, $3
+	bals	bar18 + 2
+	 not	$2, $3
+	bals	bar18 + 3
+	 not	$2, $3
+	bals	bar18 + 4
+	 not	$2, $3
+	bne	$2, $3, bar0
+	 not	$2, $3
+	bne	$2, $3, bar1
+	 not	$2, $3
+	bne	$2, $3, bar2
+	 not	$2, $3
+	bne	$2, $3, bar3
+	 not	$2, $3
+	bne	$2, $3, bar4
+	 not	$2, $3
+	bne	$2, $3, bar4 + 1
+	 not	$2, $3
+	bne	$2, $3, bar4 + 2
+	 not	$2, $3
+	bne	$2, $3, bar4 + 3
+	 not	$2, $3
+	bne	$2, $3, bar4 + 4
+	 not	$2, $3
+	bne	$2, $3, bar16
+	 not	$2, $3
+	bne	$2, $3, bar17
+	 not	$2, $3
+	bne	$2, $3, bar18
+	 not	$2, $3
+	bne	$2, $3, bar18 + 1
+	 not	$2, $3
+	bne	$2, $3, bar18 + 2
+	 not	$2, $3
+	bne	$2, $3, bar18 + 3
+	 not	$2, $3
+	bne	$2, $3, bar18 + 4
+	 not	$2, $3
+	b	bar0
+	 not	$2, $3
+	b	bar1
+	 not	$2, $3
+	b	bar2
+	 not	$2, $3
+	b	bar3
+	 not	$2, $3
+	b	bar4
+	 not	$2, $3
+	b	bar4 + 1
+	 not	$2, $3
+	b	bar4 + 2
+	 not	$2, $3
+	b	bar4 + 3
+	 not	$2, $3
+	b	bar4 + 4
+	 not	$2, $3
+	b	bar16
+	 not	$2, $3
+	b	bar17
+	 not	$2, $3
+	b	bar18
+	 not	$2, $3
+	b	bar18 + 1
+	 not	$2, $3
+	b	bar18 + 2
+	 not	$2, $3
+	b	bar18 + 3
+	 not	$2, $3
+	b	bar18 + 4
+	 not	$2, $3
+	bnez	$2, bar0
+	 not	$2, $3
+	bnez	$2, bar1
+	 not	$2, $3
+	bnez	$2, bar2
+	 not	$2, $3
+	bnez	$2, bar3
+	 not	$2, $3
+	bnez	$2, bar4
+	 not	$2, $3
+	bnez	$2, bar4 + 1
+	 not	$2, $3
+	bnez	$2, bar4 + 2
+	 not	$2, $3
+	bnez	$2, bar4 + 3
+	 not	$2, $3
+	bnez	$2, bar4 + 4
+	 not	$2, $3
+	bnez	$2, bar16
+	 not	$2, $3
+	bnez	$2, bar17
+	 not	$2, $3
+	bnez	$2, bar18
+	 not	$2, $3
+	bnez	$2, bar18 + 1
+	 not	$2, $3
+	bnez	$2, bar18 + 2
+	 not	$2, $3
+	bnez	$2, bar18 + 3
+	 not	$2, $3
+	bnez	$2, bar18 + 4
+	 not	$2, $3
+	jalr	$0, $ra
+	 not	$2, $3
+	.end	foo
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	4, 0
+	.space	16
+
+	.macro	obj n:req
+	.type	bar\@, @object
+bar\@ :
+	.byte	0
+	.size	bar\@, . - bar\@
+	.if	\n - 1
+	obj	\n - 1
+	.endif
+	.endm
+
+	.macro	fun n:req
+	.type	bar\@, @function
+bar\@ :
+	.insn
+	.hword	0
+	.size	bar\@, . - bar\@
+	.if	\n - 1
+	fun	\n - 1
+	.endif
+	.endm
+
+	.align	4
+	obj	16
+	fun	8
diff --git a/gas/testsuite/gas/mips/unaligned-branch-micromips-2.l b/gas/testsuite/gas/mips/unaligned-branch-micromips-2.l
new file mode 100644
index 0000000..5ac13134
--- /dev/null
+++ b/gas/testsuite/gas/mips/unaligned-branch-micromips-2.l
@@ -0,0 +1,21 @@
+.*: Assembler messages:
+.*:20: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:24: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
+.*:34: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:38: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
+.*:52: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:56: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
+.*:66: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:70: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
+.*:84: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:88: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
+.*:98: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:102: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
+.*:116: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:120: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
+.*:130: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:134: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
+.*:148: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:152: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
+.*:162: Error: cannot encode misaligned addend in the relocatable field \(0x1\)
+.*:166: Error: cannot encode misaligned addend in the relocatable field \(0x3\)
diff --git a/gas/testsuite/gas/mips/unaligned-branch-micromips-2.s b/gas/testsuite/gas/mips/unaligned-branch-micromips-2.s
new file mode 100644
index 0000000..e65601e
--- /dev/null
+++ b/gas/testsuite/gas/mips/unaligned-branch-micromips-2.s
@@ -0,0 +1,203 @@
+	.text
+	.set	noreorder
+	.space	0x1000
+
+	.align	4
+	.set	micromips
+	.ent	foo
+foo:
+	not	$2, $3
+	bal	bar0
+	 not	$2, $3
+	bal	bar1
+	 not	$2, $3
+	bal	bar2
+	 not	$2, $3
+	bal	bar3
+	 not	$2, $3
+	bal	bar4
+	 not	$2, $3
+	bal	bar4 + 1
+	 not	$2, $3
+	bal	bar4 + 2
+	 not	$2, $3
+	bal	bar4 + 3
+	 not	$2, $3
+	bal	bar4 + 4
+	 not	$2, $3
+	bal	bar16
+	 not	$2, $3
+	bal	bar17
+	 not	$2, $3
+	bal	bar18
+	 not	$2, $3
+	bal	bar18 + 1
+	 not	$2, $3
+	bal	bar18 + 2
+	 not	$2, $3
+	bal	bar18 + 3
+	 not	$2, $3
+	bal	bar18 + 4
+	 not	$2, $3
+	bals	bar0
+	 not	$2, $3
+	bals	bar1
+	 not	$2, $3
+	bals	bar2
+	 not	$2, $3
+	bals	bar3
+	 not	$2, $3
+	bals	bar4
+	 not	$2, $3
+	bals	bar4 + 1
+	 not	$2, $3
+	bals	bar4 + 2
+	 not	$2, $3
+	bals	bar4 + 3
+	 not	$2, $3
+	bals	bar4 + 4
+	 not	$2, $3
+	bals	bar16
+	 not	$2, $3
+	bals	bar17
+	 not	$2, $3
+	bals	bar18
+	 not	$2, $3
+	bals	bar18 + 1
+	 not	$2, $3
+	bals	bar18 + 2
+	 not	$2, $3
+	bals	bar18 + 3
+	 not	$2, $3
+	bals	bar18 + 4
+	 not	$2, $3
+	bne	$2, $3, bar0
+	 not	$2, $3
+	bne	$2, $3, bar1
+	 not	$2, $3
+	bne	$2, $3, bar2
+	 not	$2, $3
+	bne	$2, $3, bar3
+	 not	$2, $3
+	bne	$2, $3, bar4
+	 not	$2, $3
+	bne	$2, $3, bar4 + 1
+	 not	$2, $3
+	bne	$2, $3, bar4 + 2
+	 not	$2, $3
+	bne	$2, $3, bar4 + 3
+	 not	$2, $3
+	bne	$2, $3, bar4 + 4
+	 not	$2, $3
+	bne	$2, $3, bar16
+	 not	$2, $3
+	bne	$2, $3, bar17
+	 not	$2, $3
+	bne	$2, $3, bar18
+	 not	$2, $3
+	bne	$2, $3, bar18 + 1
+	 not	$2, $3
+	bne	$2, $3, bar18 + 2
+	 not	$2, $3
+	bne	$2, $3, bar18 + 3
+	 not	$2, $3
+	bne	$2, $3, bar18 + 4
+	 not	$2, $3
+	b	bar0
+	 not	$2, $3
+	b	bar1
+	 not	$2, $3
+	b	bar2
+	 not	$2, $3
+	b	bar3
+	 not	$2, $3
+	b	bar4
+	 not	$2, $3
+	b	bar4 + 1
+	 not	$2, $3
+	b	bar4 + 2
+	 not	$2, $3
+	b	bar4 + 3
+	 not	$2, $3
+	b	bar4 + 4
+	 not	$2, $3
+	b	bar16
+	 not	$2, $3
+	b	bar17
+	 not	$2, $3
+	b	bar18
+	 not	$2, $3
+	b	bar18 + 1
+	 not	$2, $3
+	b	bar18 + 2
+	 not	$2, $3
+	b	bar18 + 3
+	 not	$2, $3
+	b	bar18 + 4
+	 not	$2, $3
+	bnez	$2, bar0
+	 not	$2, $3
+	bnez	$2, bar1
+	 not	$2, $3
+	bnez	$2, bar2
+	 not	$2, $3
+	bnez	$2, bar3
+	 not	$2, $3
+	bnez	$2, bar4
+	 not	$2, $3
+	bnez	$2, bar4 + 1
+	 not	$2, $3
+	bnez	$2, bar4 + 2
+	 not	$2, $3
+	bnez	$2, bar4 + 3
+	 not	$2, $3
+	bnez	$2, bar4 + 4
+	 not	$2, $3
+	bnez	$2, bar16
+	 not	$2, $3
+	bnez	$2, bar17
+	 not	$2, $3
+	bnez	$2, bar18
+	 not	$2, $3
+	bnez	$2, bar18 + 1
+	 not	$2, $3
+	bnez	$2, bar18 + 2
+	 not	$2, $3
+	bnez	$2, bar18 + 3
+	 not	$2, $3
+	bnez	$2, bar18 + 4
+	 not	$2, $3
+	jalr	$0, $ra
+	 not	$2, $3
+	.end	foo
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	4, 0
+	.space	16
+
+	.macro	obj n:req
+	.globl	bar\@
+	.type	bar\@, @object
+bar\@ :
+	.byte	0
+	.size	bar\@, . - bar\@
+	.if	\n - 1
+	obj	\n - 1
+	.endif
+	.endm
+
+	.macro	fun n:req
+	.globl	bar\@
+	.type	bar\@, @function
+bar\@ :
+	.insn
+	.hword	0
+	.size	bar\@, . - bar\@
+	.if	\n - 1
+	fun	\n - 1
+	.endif
+	.endm
+
+	.align	4
+	obj	16
+	fun	8
diff --git a/gas/testsuite/gas/mips/unaligned-branch-micromips-3.d b/gas/testsuite/gas/mips/unaligned-branch-micromips-3.d
new file mode 100644
index 0000000..56b5f30
--- /dev/null
+++ b/gas/testsuite/gas/mips/unaligned-branch-micromips-3.d
@@ -0,0 +1,277 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: microMIPS branch to unaligned symbol 3
+#as: -n32 -march=from-abi
+#source: unaligned-branch-micromips-2.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+	\.\.\.
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	00001006 <foo\+0x6>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar0-0x4
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	0000100e <foo\+0xe>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar1-0x4
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	00001016 <foo\+0x16>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar2-0x4
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	0000101e <foo\+0x1e>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar3-0x4
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	00001026 <foo\+0x26>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar4-0x4
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	0000102e <foo\+0x2e>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar4-0x3
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	00001036 <foo\+0x36>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar4-0x2
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	0000103e <foo\+0x3e>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar4-0x1
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	00001046 <foo\+0x46>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar4
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	0000104e <foo\+0x4e>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar16-0x4
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	00001056 <foo\+0x56>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar17-0x4
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	0000105e <foo\+0x5e>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar18-0x4
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	00001066 <foo\+0x66>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar18-0x3
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	0000106e <foo\+0x6e>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar18-0x2
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	00001076 <foo\+0x76>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar18-0x1
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4060 0000 	bal	0000107e <foo\+0x7e>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar18
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	00001086 <foo\+0x86>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar0-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	0000108c <foo\+0x8c>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar1-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	00001092 <foo\+0x92>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar2-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	00001098 <foo\+0x98>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar3-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	0000109e <foo\+0x9e>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar4-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	000010a4 <foo\+0xa4>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar4-0x3
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	000010aa <foo\+0xaa>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar4-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	000010b0 <foo\+0xb0>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar4-0x1
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	000010b6 <foo\+0xb6>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	000010bc <foo\+0xbc>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar16-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	000010c2 <foo\+0xc2>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar17-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	000010c8 <foo\+0xc8>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar18-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	000010ce <foo\+0xce>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar18-0x3
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	000010d4 <foo\+0xd4>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar18-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	000010da <foo\+0xda>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar18-0x1
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 4260 0000 	bals	000010e0 <foo\+0xe0>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar18
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,000010e6 <foo\+0xe6>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar0-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,000010ec <foo\+0xec>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar1-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,000010f2 <foo\+0xf2>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar2-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,000010f8 <foo\+0xf8>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar3-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,000010fe <foo\+0xfe>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar4-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,00001104 <foo\+0x104>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar4-0x3
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,0000110a <foo\+0x10a>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar4-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,00001110 <foo\+0x110>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar4-0x1
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,00001116 <foo\+0x116>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,0000111c <foo\+0x11c>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar16-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,00001122 <foo\+0x122>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar17-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,00001128 <foo\+0x128>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar18-0x4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,0000112e <foo\+0x12e>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar18-0x3
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,00001134 <foo\+0x134>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar18-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,0000113a <foo\+0x13a>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar18-0x1
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> b462 0000 	bne	v0,v1,00001140 <foo\+0x140>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar18
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	00001144 <foo\+0x144>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar0-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	00001148 <foo\+0x148>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar1-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	0000114c <foo\+0x14c>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar2-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	00001150 <foo\+0x150>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar3-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	00001154 <foo\+0x154>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar4-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	00001158 <foo\+0x158>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar4-0x1
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	0000115c <foo\+0x15c>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	00001160 <foo\+0x160>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar4\+0x1
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	00001164 <foo\+0x164>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar4\+0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	00001168 <foo\+0x168>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar16-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	0000116c <foo\+0x16c>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar17-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	00001170 <foo\+0x170>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar18-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	00001174 <foo\+0x174>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar18-0x1
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	00001178 <foo\+0x178>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar18
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	0000117c <foo\+0x17c>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar18\+0x1
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> cc00      	b	00001180 <foo\+0x180>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC10_S1	bar18\+0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,00001184 <foo\+0x184>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar0-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,00001188 <foo\+0x188>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar1-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,0000118c <foo\+0x18c>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar2-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,00001190 <foo\+0x190>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar3-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,00001194 <foo\+0x194>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar4-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,00001198 <foo\+0x198>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar4-0x1
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,0000119c <foo\+0x19c>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar4
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,000011a0 <foo\+0x1a0>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar4\+0x1
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,000011a4 <foo\+0x1a4>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar4\+0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,000011a8 <foo\+0x1a8>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar16-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,000011ac <foo\+0x1ac>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar17-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,000011b0 <foo\+0x1b0>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar18-0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,000011b4 <foo\+0x1b4>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar18-0x1
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,000011b8 <foo\+0x1b8>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar18
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,000011bc <foo\+0x1bc>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar18\+0x1
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> ad00      	bnez	v0,000011c0 <foo\+0x1c0>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC7_S1	bar18\+0x2
+[0-9a-f]+ <[^>]*> 4413      	not	v0,v1
+[0-9a-f]+ <[^>]*> 001f 0f3c 	jr	ra
+[0-9a-f]+ <[^>]*> 0003 12d0 	not	v0,v1
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/unaligned-branch-mips16-1.l b/gas/testsuite/gas/mips/unaligned-branch-mips16-1.l
new file mode 100644
index 0000000..a24fdc6
--- /dev/null
+++ b/gas/testsuite/gas/mips/unaligned-branch-mips16-1.l
@@ -0,0 +1,23 @@
+.*: Assembler messages:
+.*:10: Error: branch to a symbol in another ISA mode
+.*:12: Error: branch to a symbol in another ISA mode
+.*:14: Error: branch to a symbol in another ISA mode
+.*:16: Error: branch to a symbol in another ISA mode
+.*:18: Error: branch to a symbol in another ISA mode
+.*:20: Error: branch to a symbol in another ISA mode
+.*:22: Error: branch to a symbol in another ISA mode
+.*:24: Error: branch to a symbol in another ISA mode
+.*:26: Error: branch to a symbol in another ISA mode
+.*:34: Error: branch to misaligned address \(0x10b5\)
+.*:38: Error: branch to misaligned address \(0x10b7\)
+.*:42: Error: branch to a symbol in another ISA mode
+.*:44: Error: branch to a symbol in another ISA mode
+.*:46: Error: branch to a symbol in another ISA mode
+.*:48: Error: branch to a symbol in another ISA mode
+.*:50: Error: branch to a symbol in another ISA mode
+.*:52: Error: branch to a symbol in another ISA mode
+.*:54: Error: branch to a symbol in another ISA mode
+.*:56: Error: branch to a symbol in another ISA mode
+.*:58: Error: branch to a symbol in another ISA mode
+.*:66: Error: branch to misaligned address \(0x10b5\)
+.*:70: Error: branch to misaligned address \(0x10b7\)
diff --git a/gas/testsuite/gas/mips/unaligned-branch-mips16-1.s b/gas/testsuite/gas/mips/unaligned-branch-mips16-1.s
new file mode 100644
index 0000000..d4fad96
--- /dev/null
+++ b/gas/testsuite/gas/mips/unaligned-branch-mips16-1.s
@@ -0,0 +1,105 @@
+	.text
+	.set	noreorder
+	.space	0x1000
+
+	.align	4
+	.set	mips16
+	.ent	foo
+foo:
+	not	$2, $3
+	b	bar0
+	 not	$2, $3
+	b	bar1
+	 not	$2, $3
+	b	bar2
+	 not	$2, $3
+	b	bar3
+	 not	$2, $3
+	b	bar4
+	 not	$2, $3
+	b	bar4 + 1
+	 not	$2, $3
+	b	bar4 + 2
+	 not	$2, $3
+	b	bar4 + 3
+	 not	$2, $3
+	b	bar4 + 4
+	 not	$2, $3
+	b	bar16
+	 not	$2, $3
+	b	bar17
+	 not	$2, $3
+	b	bar18
+	 not	$2, $3
+	b	bar18 + 1
+	 not	$2, $3
+	b	bar18 + 2
+	 not	$2, $3
+	b	bar18 + 3
+	 not	$2, $3
+	b	bar18 + 4
+	 not	$2, $3
+	bnez	$2, bar0
+	 not	$2, $3
+	bnez	$2, bar1
+	 not	$2, $3
+	bnez	$2, bar2
+	 not	$2, $3
+	bnez	$2, bar3
+	 not	$2, $3
+	bnez	$2, bar4
+	 not	$2, $3
+	bnez	$2, bar4 + 1
+	 not	$2, $3
+	bnez	$2, bar4 + 2
+	 not	$2, $3
+	bnez	$2, bar4 + 3
+	 not	$2, $3
+	bnez	$2, bar4 + 4
+	 not	$2, $3
+	bnez	$2, bar16
+	 not	$2, $3
+	bnez	$2, bar17
+	 not	$2, $3
+	bnez	$2, bar18
+	 not	$2, $3
+	bnez	$2, bar18 + 1
+	 not	$2, $3
+	bnez	$2, bar18 + 2
+	 not	$2, $3
+	bnez	$2, bar18 + 3
+	 not	$2, $3
+	bnez	$2, bar18 + 4
+	 not	$2, $3
+	jr	$ra
+	 not	$2, $3
+	.end	foo
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	4, 0
+	.space	16
+
+	.macro	obj n:req
+	.type	bar\@, @object
+bar\@ :
+	.byte	0
+	.size	bar\@, . - bar\@
+	.if	\n - 1
+	obj	\n - 1
+	.endif
+	.endm
+
+	.macro	fun n:req
+	.type	ba[...]

[diff truncated at 100000 bytes]


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]