diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index bf95751371881469a84c38085801f5c967b3ecb8..e6ed9609fccaa66709cd7bc67e94108c7f3e31b5 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,23 @@
+2016-06-28  Maciej W. Rozycki  <macro@imgtec.com>
+
+	* elf32-mips.c (elf_mips16_howto_table_rel): Add
+	R_MIPS16_PC16_S1.
+	(mips16_reloc_map): Likewise.
+	* elf64-mips.c (mips16_elf64_howto_table_rel): Likewise.
+	(mips16_elf64_howto_table_rela): Likewise.
+	(mips16_reloc_map): Likewise.
+	* elfn32-mips.c (elf_mips16_howto_table_rel): Likewise.
+	(elf_mips16_howto_table_rela): Likewise.
+	(mips16_reloc_map): Likewise.
+	* elfxx-mips.c (mips16_branch_reloc_p): New function.
+	(mips16_reloc_p): Handle R_MIPS16_PC16_S1.
+	(b_reloc_p): Likewise.
+	(mips_elf_calculate_relocation): Likewise.
+	(_bfd_mips_elf_check_relocs): Likewise.
+	* reloc.c (BFD_RELOC_MIPS16_16_PCREL_S1): New relocation.
+	* bfd-in2.h: Regenerate.
+	* libbfd.h: Regenerate.
+
 2016-06-27  Alan Modra  <amodra@gmail.com>
 
 	PR ld/19264
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index ebed9664bb28f553d5cc0f719819d00ea53dabd9..30513c4c3f39f7829ad0ea0e87f21b374994ddb0 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2998,6 +2998,9 @@ to compensate for the borrow when the low bits are added.  */
   BFD_RELOC_MICROMIPS_10_PCREL_S1,
   BFD_RELOC_MICROMIPS_16_PCREL_S1,
 
+/* MIPS16 PC-relative relocation.  */
+  BFD_RELOC_MIPS16_16_PCREL_S1,
+
 /* MIPS PC-relative relocations.  */
   BFD_RELOC_MIPS_21_PCREL_S2,
   BFD_RELOC_MIPS_26_PCREL_S2,
diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
index 5654fb664e9862bc6224e0e424e72e6e33f7618a..029de279fe8b88c1e91302cf9bfb4ac390112baa 100644
--- a/bfd/elf32-mips.c
+++ b/bfd/elf32-mips.c
@@ -1027,6 +1027,21 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 	 0x0000ffff,		/* src_mask */
 	 0x0000ffff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
+
+  /* MIPS16 16-bit PC-relative branch offset.  */
+  HOWTO (R_MIPS16_PC16_S1,	/* type */
+	 1,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 "R_MIPS16_PC16_S1",	/* name */
+	 TRUE,			/* partial_inplace */
+	 0x0000ffff,		/* src_mask */
+	 0x0000ffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
 };
 
 static reloc_howto_type elf_micromips_howto_table_rel[] =
@@ -2023,7 +2038,8 @@ static const struct elf_reloc_map mips16_reloc_map[] =
     R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
   { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
   { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
-  { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
+  { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min },
+  { BFD_RELOC_MIPS16_16_PCREL_S1, R_MIPS16_PC16_S1 - R_MIPS16_min }
 };
 
 static const struct elf_reloc_map micromips_reloc_map[] =
diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c
index 34144f038b6bb0804b9452cb0d52652e1f8bc90d..f04c4b5a80269cc78d6ba3d172033b42f5faf6d6 100644
--- a/bfd/elf64-mips.c
+++ b/bfd/elf64-mips.c
@@ -1881,6 +1881,21 @@ static reloc_howto_type mips16_elf64_howto_table_rel[] =
 	 0x0000ffff,		/* src_mask */
 	 0x0000ffff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
+
+  /* MIPS16 16-bit PC-relative branch offset.  */
+  HOWTO (R_MIPS16_PC16_S1,	/* type */
+	 1,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 "R_MIPS16_PC16_S1",	/* name */
+	 TRUE,			/* partial_inplace */
+	 0x0000ffff,		/* src_mask */
+	 0x0000ffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
 };
 
 static reloc_howto_type mips16_elf64_howto_table_rela[] =
@@ -2082,6 +2097,21 @@ static reloc_howto_type mips16_elf64_howto_table_rela[] =
 	 0,			/* src_mask */
 	 0x0000ffff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
+
+  /* MIPS16 16-bit PC-relative branch offset.  */
+  HOWTO (R_MIPS16_PC16_S1,	/* type */
+	 1,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 "R_MIPS16_PC16_S1",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0x0000ffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
 };
 
 static reloc_howto_type micromips_elf64_howto_table_rel[] =
@@ -3415,7 +3445,8 @@ static const struct elf_reloc_map mips16_reloc_map[] =
     R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
   { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
   { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
-  { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
+  { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min },
+  { BFD_RELOC_MIPS16_16_PCREL_S1, R_MIPS16_PC16_S1 - R_MIPS16_min }
 };
 
 static const struct elf_reloc_map micromips_reloc_map[] =
diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c
index c955877afe5e9d382484bea0e2c87fc8d73dde84..734ebf63f21e194f5c97a87a764b354c1e66d90a 100644
--- a/bfd/elfn32-mips.c
+++ b/bfd/elfn32-mips.c
@@ -1847,6 +1847,21 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 	 0x0000ffff,		/* src_mask */
 	 0x0000ffff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
+
+  /* MIPS16 16-bit PC-relative branch offset.  */
+  HOWTO (R_MIPS16_PC16_S1,	/* type */
+	 1,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 "R_MIPS16_PC16_S1",	/* name */
+	 TRUE,			/* partial_inplace */
+	 0x0000ffff,		/* src_mask */
+	 0x0000ffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
 };
 
 static reloc_howto_type elf_mips16_howto_table_rela[] =
@@ -2048,6 +2063,21 @@ static reloc_howto_type elf_mips16_howto_table_rela[] =
 	 0,			/* src_mask */
 	 0x0000ffff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
+
+  /* MIPS16 16-bit PC-relative branch offset.  */
+  HOWTO (R_MIPS16_PC16_S1,	/* type */
+	 1,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 "R_MIPS16_PC16_S1",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0x0000ffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
 };
 
 static reloc_howto_type elf_micromips_howto_table_rel[] =
@@ -3231,7 +3261,8 @@ static const struct elf_reloc_map mips16_reloc_map[] =
     R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
   { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
   { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
-  { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
+  { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min },
+  { BFD_RELOC_MIPS16_16_PCREL_S1, R_MIPS16_PC16_S1 - R_MIPS16_min }
 };
 
 static const struct elf_reloc_map micromips_reloc_map[] =
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 3b7723e3d0ef0e877eea5acb8f3de36e8c834a05..e47276bc61cca2f5bd9d2ad9531439400a62a087 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -2090,7 +2090,11 @@ mips_elf_check_symbols (struct mips_elf_link_hash_entry *h, void *data)
 
    All we need to do here is shuffle the bits appropriately.
    As above, the two 16-bit halves must be swapped on a
-   little-endian system.  */
+   little-endian system.
+
+   Finally R_MIPS16_PC16_S1 corresponds to R_MIPS_PC16, however the
+   relocatable field is shifted by 1 rather than 2 and the same bit
+   shuffling is done as with the relocations above.  */
 
 static inline bfd_boolean
 mips16_reloc_p (int r_type)
@@ -2110,6 +2114,7 @@ mips16_reloc_p (int r_type)
     case R_MIPS16_TLS_GOTTPREL:
     case R_MIPS16_TLS_TPREL_HI16:
     case R_MIPS16_TLS_TPREL_LO16:
+    case R_MIPS16_PC16_S1:
       return TRUE;
 
     default:
@@ -2221,7 +2226,8 @@ b_reloc_p (int r_type)
   return (r_type == R_MIPS_PC26_S2
 	  || r_type == R_MIPS_PC21_S2
 	  || r_type == R_MIPS_PC16
-	  || r_type == R_MIPS_GNU_REL16_S2);
+	  || r_type == R_MIPS_GNU_REL16_S2
+	  || r_type == R_MIPS16_PC16_S1);
 }
 
 static inline bfd_boolean
@@ -2231,6 +2237,13 @@ aligned_pcrel_reloc_p (int r_type)
 	  || r_type == R_MIPS_PC19_S2);
 }
 
+static inline bfd_boolean
+mips16_branch_reloc_p (int r_type)
+{
+  return (r_type == R_MIPS16_26
+	  || r_type == R_MIPS16_PC16_S1);
+}
+
 static inline bfd_boolean
 micromips_branch_reloc_p (int r_type)
 {
@@ -5562,7 +5575,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
     }
 
   /* Make sure MIPS16 and microMIPS are not used together.  */
-  if ((r_type == R_MIPS16_26 && target_is_micromips_code_p)
+  if ((mips16_branch_reloc_p (r_type) && target_is_micromips_code_p)
       || (micromips_branch_reloc_p (r_type) && target_is_16_bit_code_p))
    {
       (*_bfd_error_handler)
@@ -5994,6 +6007,21 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
       value &= howto->dst_mask;
       break;
 
+    case R_MIPS16_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)
+	  && ((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);
+      value >>= howto->rightshift;
+      value &= howto->dst_mask;
+      break;
+
     case R_MIPS_PC21_S2:
       if (howto->partial_inplace)
 	addend = _bfd_mips_elf_sign_extend (addend, 23);
@@ -8346,6 +8374,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	case R_MIPS_PC21_S2:
 	case R_MIPS_PC26_S2:
 	case R_MIPS16_26:
+	case R_MIPS16_PC16_S1:
 	case R_MICROMIPS_26_S1:
 	case R_MICROMIPS_PC7_S1:
 	case R_MICROMIPS_PC10_S1:
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index bf17f4353411fc398f357ec39423859c63009198..2b1777ef21f2a921c029068a706c1f5326989b11 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1156,6 +1156,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_MICROMIPS_7_PCREL_S1",
   "BFD_RELOC_MICROMIPS_10_PCREL_S1",
   "BFD_RELOC_MICROMIPS_16_PCREL_S1",
+  "BFD_RELOC_MIPS16_16_PCREL_S1",
   "BFD_RELOC_MIPS_21_PCREL_S2",
   "BFD_RELOC_MIPS_26_PCREL_S2",
   "BFD_RELOC_MIPS_18_PCREL_S3",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 443ad6f7553d6bd26d180288f5c1cb4c183ceec2..e962e71868ee51922fa292fdb5d9b8010141e927 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -2304,6 +2304,11 @@ ENUMX
 ENUMDOC
   microMIPS PC-relative relocations.
 
+ENUM
+  BFD_RELOC_MIPS16_16_PCREL_S1
+ENUMDOC
+  MIPS16 PC-relative relocation.
+
 ENUM
   BFD_RELOC_MIPS_21_PCREL_S2
 ENUMX
diff --git a/gas/ChangeLog b/gas/ChangeLog
index d6afee21d4532d6e022d88727ea7772fcaf7d103..ba19df2eae6e86858e3fd77ad57e299b8cad1c22 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,36 @@
+2016-06-28  Maciej W. Rozycki  <macro@imgtec.com>
+
+	* config/tc-mips.c (mips16_reloc_p): Handle
+	BFD_RELOC_MIPS16_16_PCREL_S1.
+	(b_reloc_p): Likewise.
+	(limited_pcrel_reloc_p): Likewise.
+	(md_pcrel_from): Likewise.
+	(md_apply_fix): Likewise.
+	(tc_gen_reloc): Likewise.
+	(md_convert_frag): Likewise.
+	(mips_fix_adjustable): Update comment.
+	* testsuite/gas/mips/mips16-branch-reloc-2.d: Remove error
+	output, add dump patterns.
+	* testsuite/gas/mips/mips16-branch-reloc-3.d: Remove error
+	output, add dump patterns.
+	* testsuite/gas/mips/mips16-branch-addend-2.d: Remove error
+	output, add dump patterns.
+	* testsuite/gas/mips/mips16-branch-addend-3.d: Remove error
+	output, add dump patterns.
+	* testsuite/gas/mips/mips16-branch-absolute.d: Remove error
+	output, add dump patterns.
+	* testsuite/gas/mips/mips16-branch-reloc-2.l: Remove file.
+	* testsuite/gas/mips/mips16-branch-reloc-3.l: Remove file.
+	* testsuite/gas/mips/mips16-branch-addend-2.l: Remove file.
+	* testsuite/gas/mips/mips16-branch-addend-3.l: Remove file.
+	* testsuite/gas/mips/mips16-branch-absolute.l: Remove file.
+	* testsuite/gas/mips/mips16-branch-addend-2.s: Add padding.
+	* testsuite/gas/mips/branch-weak.s: Adjust alignment, avoid
+	implicit instruction padding, avoid MIPS16 JR->JRC conversion.
+	* testsuite/gas/mips/branch-weak-6.d: New test.
+	* testsuite/gas/mips/branch-weak-7.d: New test.
+	* testsuite/gas/mips/mips.exp: Run the new tests.
+
 2016-06-27  Vineet Gupta  <vgupta@synopsys.com>
 
 	* config//tc-arc.c (tc_arc_frame_initial_instructions): Use
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index ab2ea0c8c7cdf3268e5d6634607ee98921755cd3..092e7b430d2f0a28e1d9df42a233bf9ab657aff0 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -4060,6 +4060,7 @@ mips16_reloc_p (bfd_reloc_code_real_type reloc)
     case BFD_RELOC_MIPS16_HI16_S:
     case BFD_RELOC_MIPS16_HI16:
     case BFD_RELOC_MIPS16_LO16:
+    case BFD_RELOC_MIPS16_16_PCREL_S1:
       return TRUE;
 
     default:
@@ -4114,6 +4115,7 @@ b_reloc_p (bfd_reloc_code_real_type reloc)
   return (reloc == BFD_RELOC_MIPS_26_PCREL_S2
 	  || reloc == BFD_RELOC_MIPS_21_PCREL_S2
 	  || reloc == BFD_RELOC_16_PCREL_S2
+	  || reloc == BFD_RELOC_MIPS16_16_PCREL_S1
 	  || reloc == BFD_RELOC_MICROMIPS_16_PCREL_S1
 	  || reloc == BFD_RELOC_MICROMIPS_10_PCREL_S1
 	  || reloc == BFD_RELOC_MICROMIPS_7_PCREL_S1);
@@ -4162,6 +4164,7 @@ limited_pcrel_reloc_p (bfd_reloc_code_real_type reloc)
   switch (reloc)
     {
     case BFD_RELOC_16_PCREL_S2:
+    case BFD_RELOC_MIPS16_16_PCREL_S1:
     case BFD_RELOC_MICROMIPS_7_PCREL_S1:
     case BFD_RELOC_MICROMIPS_10_PCREL_S1:
     case BFD_RELOC_MICROMIPS_16_PCREL_S1:
@@ -14628,6 +14631,7 @@ md_pcrel_from (fixS *fixP)
 
     case BFD_RELOC_MICROMIPS_16_PCREL_S1:
     case BFD_RELOC_MICROMIPS_JMP:
+    case BFD_RELOC_MIPS16_16_PCREL_S1:
     case BFD_RELOC_16_PCREL_S2:
     case BFD_RELOC_MIPS_21_PCREL_S2:
     case BFD_RELOC_MIPS_26_PCREL_S2:
@@ -14852,6 +14856,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     switch (fixP->fx_r_type)
       {
       case BFD_RELOC_16_PCREL_S2:
+      case BFD_RELOC_MIPS16_16_PCREL_S1:
       case BFD_RELOC_MICROMIPS_7_PCREL_S1:
       case BFD_RELOC_MICROMIPS_10_PCREL_S1:
       case BFD_RELOC_MICROMIPS_16_PCREL_S1:
@@ -15184,6 +15189,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	}
       break;
 
+    case BFD_RELOC_MIPS16_16_PCREL_S1:
     case BFD_RELOC_MICROMIPS_7_PCREL_S1:
     case BFD_RELOC_MICROMIPS_10_PCREL_S1:
     case BFD_RELOC_MICROMIPS_16_PCREL_S1:
@@ -17216,11 +17222,11 @@ mips_fix_adjustable (fixS *fixp)
 
        5. We cannot reduce jump relocations (R_MIPS_26, R_MIPS16_26 or
 	  R_MICROMIPS_26_S1) or branch relocations (R_MIPS_PC26_S2,
-	  R_MIPS_PC21_S2, R_MIPS_PC16, R_MICROMIPS_PC16_S1,
-	  R_MICROMIPS_PC10_S1 or R_MICROMIPS_PC7_S1) against MIPS16 or
-	  microMIPS symbols because we need to keep the MIPS16 or
-	  microMIPS symbol for the purpose of mode mismatch detection
-	  and JAL to JALX instruction conversion in the linker.
+	  R_MIPS_PC21_S2, R_MIPS_PC16, R_MIPS16_PC16_S1,
+	  R_MICROMIPS_PC16_S1, R_MICROMIPS_PC10_S1 or R_MICROMIPS_PC7_S1)
+	  against MIPS16 or microMIPS symbols because we need to keep the
+	  MIPS16 or microMIPS symbol for the purpose of mode mismatch
+	  detection and JAL to JALX instruction conversion in the linker.
 
      For simplicity, we deal with (3)-(4) by not reducing _any_ relocation
      against a MIPS16 symbol.  We deal with (5) by additionally leaving
@@ -17263,6 +17269,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
   if (fixp->fx_pcrel)
     {
       gas_assert (fixp->fx_r_type == BFD_RELOC_16_PCREL_S2
+		  || fixp->fx_r_type == BFD_RELOC_MIPS16_16_PCREL_S1
 		  || fixp->fx_r_type == BFD_RELOC_MICROMIPS_7_PCREL_S1
 		  || fixp->fx_r_type == BFD_RELOC_MICROMIPS_10_PCREL_S1
 		  || fixp->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1
@@ -17870,8 +17877,41 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
 	  || (operand->root.type == OP_PCREL
 	      ? asec != symsec
 	      : !bfd_is_abs_section (symsec)))
-	as_bad_where (fragp->fr_file, fragp->fr_line,
-		      _("unsupported relocation"));
+	{
+	  bfd_reloc_code_real_type reloc = BFD_RELOC_NONE;
+	  expressionS exp;
+	  fixS *fixp;
+
+	  switch (type)
+	    {
+	    case 'p':
+	    case 'q':
+	      reloc = BFD_RELOC_MIPS16_16_PCREL_S1;
+	      break;
+	    default:
+	      as_bad_where (fragp->fr_file, fragp->fr_line,
+			    _("unsupported relocation"));
+	      break;
+	    }
+	  if (reloc != BFD_RELOC_NONE)
+	    {
+	      gas_assert (ext);
+
+	      exp.X_op = O_symbol;
+	      exp.X_add_symbol = fragp->fr_symbol;
+	      exp.X_add_number = fragp->fr_offset;
+
+	      fixp = fix_new_exp (fragp, buf - fragp->fr_literal, 2, &exp,
+				  TRUE, reloc);
+
+	      fixp->fx_file = fragp->fr_file;
+	      fixp->fx_line = fragp->fr_line;
+
+	      /* These relocations can have an addend that won't fit
+		 in 2 octets.  */
+	      fixp->fx_no_overflow = 1;
+	    }
+	}
       else
 	mips16_immed (fragp->fr_file, fragp->fr_line, type,
 		      BFD_RELOC_UNUSED, val, user_length, &insn);
diff --git a/gas/testsuite/gas/mips/branch-weak-6.d b/gas/testsuite/gas/mips/branch-weak-6.d
new file mode 100644
index 0000000000000000000000000000000000000000..e16b1b89c16f667066a8d46d9a0d4ef3c8ac9dbf
--- /dev/null
+++ b/gas/testsuite/gas/mips/branch-weak-6.d
@@ -0,0 +1,14 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS16 branch to a weak symbol
+#as: -32 -mips16 --defsym align=12
+#source: branch-weak.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> f7ff 101e 	b	00000000 <foo>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+	\.\.\.
+[0-9a-f]+ <[^>]*> e820      	jr	ra
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/branch-weak-7.d b/gas/testsuite/gas/mips/branch-weak-7.d
new file mode 100644
index 0000000000000000000000000000000000000000..b291289fbfbddca01224dfb920687cfa8304a6da
--- /dev/null
+++ b/gas/testsuite/gas/mips/branch-weak-7.d
@@ -0,0 +1,14 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS16 short branch to a weak symbol
+#as: -32 -mips16 --defsym align=4
+#source: branch-weak.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> f7ff 101e 	b	00000000 <foo>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+	\.\.\.
+[0-9a-f]+ <[^>]*> e820      	jr	ra
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/branch-weak.s b/gas/testsuite/gas/mips/branch-weak.s
index eedef7a5477ca917d75de3404534d4fc1c0fe502..a2dc7344a128cddba22df6a0d2acd9adb7cbafe5 100644
--- a/gas/testsuite/gas/mips/branch-weak.s
+++ b/gas/testsuite/gas/mips/branch-weak.s
@@ -1,5 +1,5 @@
 	.text
-	.align	4, 0
+	.align	align, 0
 	.globl	foo
 	.ent	foo
 foo:
@@ -11,9 +11,9 @@ foo:
 	.weak	bar
 	.ent	bar
 bar:
+	nop
 	jr	$ra
 	.end	bar
 
 # Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
-	.align  4, 0
-	.space  16
+	.align  align, 0
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index d268dc00ce5be3294e79722856082630b414d915..4f5651b4a4694736a43a75dcb973dfdf6acdb182 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -588,6 +588,8 @@ if { [istarget mips*-*-vxworks*] } {
     run_dump_test "branch-weak-3"
     run_dump_test "branch-weak-4"
     run_dump_test "branch-weak-5"
+    run_dump_test "branch-weak-6"
+    run_dump_test "branch-weak-7"
     run_dump_test "branch-local-1"
     if $has_newabi {
 	run_dump_test "branch-local-n32-1"
diff --git a/gas/testsuite/gas/mips/mips16-branch-absolute.d b/gas/testsuite/gas/mips/mips16-branch-absolute.d
index 90a9ea7cc7b3895e01836097812dbddbec579efb..3e1ec8e3d3ed42501a803e759f4e6c20dcb7a0a9 100644
--- a/gas/testsuite/gas/mips/mips16-branch-absolute.d
+++ b/gas/testsuite/gas/mips/mips16-branch-absolute.d
@@ -1,3 +1,20 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
 #name: MIPS16 branch to absolute expression
 #as: -32
-#error-output: mips16-branch-absolute.l
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+	\.\.\.
+[0-9a-f]+ <[^>]*> f000 1000 	b	00001004 <foo\+0x4>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	\*ABS\*
+[0-9a-f]+ <[^>]*> f000 6000 	bteqz	00001008 <foo\+0x8>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	\*ABS\*
+[0-9a-f]+ <[^>]*> f000 6100 	btnez	0000100c <foo\+0xc>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	\*ABS\*
+[0-9a-f]+ <[^>]*> f000 2200 	beqz	v0,00001010 <foo\+0x10>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	\*ABS\*
+[0-9a-f]+ <[^>]*> f000 2a00 	bnez	v0,00001014 <foo\+0x14>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	\*ABS\*
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/mips16-branch-absolute.l b/gas/testsuite/gas/mips/mips16-branch-absolute.l
deleted file mode 100644
index c72b8d03b07501bb8019808690b50147d761dc28..0000000000000000000000000000000000000000
--- a/gas/testsuite/gas/mips/mips16-branch-absolute.l
+++ /dev/null
@@ -1,6 +0,0 @@
-.*: Assembler messages:
-.*:8: Error: unsupported relocation
-.*:9: Error: unsupported relocation
-.*:10: Error: unsupported relocation
-.*:11: Error: unsupported relocation
-.*:12: Error: unsupported relocation
diff --git a/gas/testsuite/gas/mips/mips16-branch-addend-2.d b/gas/testsuite/gas/mips/mips16-branch-addend-2.d
index ae9854666d0e12800b4470fb9ca0783aba72ce64..3e61c24e5ea6b57702267d627d490d362c432dbb 100644
--- a/gas/testsuite/gas/mips/mips16-branch-addend-2.d
+++ b/gas/testsuite/gas/mips/mips16-branch-addend-2.d
@@ -1,3 +1,22 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
 #name: MIPS16 branch relocation with addend 2
 #as: -32
-#error-output: mips16-branch-addend-2.l
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+	\.\.\.
+[0-9a-f]+ <[^>]*> f101 1018 	b	00002234 <bar\+0x1204>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f101 6018 	bteqz	00002238 <bar\+0x1208>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f101 6118 	btnez	0000223c <bar\+0x120c>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f101 2218 	beqz	v0,00002240 <bar\+0x1210>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f101 2a18 	bnez	v0,00002244 <bar\+0x1214>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/mips16-branch-addend-2.l b/gas/testsuite/gas/mips/mips16-branch-addend-2.l
deleted file mode 100644
index d30fd62237f6654b133152aee1768ac670482e6c..0000000000000000000000000000000000000000
--- a/gas/testsuite/gas/mips/mips16-branch-addend-2.l
+++ /dev/null
@@ -1,6 +0,0 @@
-.*: Assembler messages:
-.*:9: Error: unsupported relocation
-.*:10: Error: unsupported relocation
-.*:11: Error: unsupported relocation
-.*:12: Error: unsupported relocation
-.*:13: Error: unsupported relocation
diff --git a/gas/testsuite/gas/mips/mips16-branch-addend-2.s b/gas/testsuite/gas/mips/mips16-branch-addend-2.s
index fe9e5b8aa537688319fdedb989f90a5503aab800..6035db89bea04ccea0cfe0b44770473349e03c67 100644
--- a/gas/testsuite/gas/mips/mips16-branch-addend-2.s
+++ b/gas/testsuite/gas/mips/mips16-branch-addend-2.s
@@ -26,6 +26,8 @@ bar:
 	.set	nomips16
 	.end	bar
 
+	.space	0x1000
+
 # Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
 	.align	4, 0
 	.space	16
diff --git a/gas/testsuite/gas/mips/mips16-branch-addend-3.d b/gas/testsuite/gas/mips/mips16-branch-addend-3.d
index 165e8f1e7e57faaae125131b9049ffc219bb8f18..f3ecb7516d6f1a3e53ee64a534281c457b014fbc 100644
--- a/gas/testsuite/gas/mips/mips16-branch-addend-3.d
+++ b/gas/testsuite/gas/mips/mips16-branch-addend-3.d
@@ -1,3 +1,20 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
 #name: MIPS16 branch relocation with addend 3
 #as: -32
-#error-output: mips16-branch-reloc-3.l
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+	\.\.\.
+[0-9a-f]+ <[^>]*> f101 1018 	b	00002234 <foo\+0x1234>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f101 6018 	bteqz	00002238 <foo\+0x1238>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f101 6118 	btnez	0000223c <foo\+0x123c>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f101 2218 	beqz	v0,00002240 <foo\+0x1240>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f101 2a18 	bnez	v0,00002244 <foo\+0x1244>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/mips16-branch-addend-3.l b/gas/testsuite/gas/mips/mips16-branch-addend-3.l
deleted file mode 100644
index c72b8d03b07501bb8019808690b50147d761dc28..0000000000000000000000000000000000000000
--- a/gas/testsuite/gas/mips/mips16-branch-addend-3.l
+++ /dev/null
@@ -1,6 +0,0 @@
-.*: Assembler messages:
-.*:8: Error: unsupported relocation
-.*:9: Error: unsupported relocation
-.*:10: Error: unsupported relocation
-.*:11: Error: unsupported relocation
-.*:12: Error: unsupported relocation
diff --git a/gas/testsuite/gas/mips/mips16-branch-reloc-2.d b/gas/testsuite/gas/mips/mips16-branch-reloc-2.d
index 1e6ecb4b20235c7d36e7e0f8ce350f6721c77144..4f920d203c4cecea3787b0ddba918562d9fa97ef 100644
--- a/gas/testsuite/gas/mips/mips16-branch-reloc-2.d
+++ b/gas/testsuite/gas/mips/mips16-branch-reloc-2.d
@@ -1,3 +1,22 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
 #name: MIPS16 branch relocation 2
 #as: -32
-#error-output: mips16-branch-reloc-2.l
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+	\.\.\.
+[0-9a-f]+ <[^>]*> f7ff 101e 	b	00001000 <foo>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f7ff 601e 	bteqz	00001004 <foo\+0x4>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f7ff 611e 	btnez	00001008 <foo\+0x8>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f7ff 221e 	beqz	v0,0000100c <foo\+0xc>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f7ff 2a1e 	bnez	v0,00001010 <foo\+0x10>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/mips16-branch-reloc-2.l b/gas/testsuite/gas/mips/mips16-branch-reloc-2.l
deleted file mode 100644
index d30fd62237f6654b133152aee1768ac670482e6c..0000000000000000000000000000000000000000
--- a/gas/testsuite/gas/mips/mips16-branch-reloc-2.l
+++ /dev/null
@@ -1,6 +0,0 @@
-.*: Assembler messages:
-.*:9: Error: unsupported relocation
-.*:10: Error: unsupported relocation
-.*:11: Error: unsupported relocation
-.*:12: Error: unsupported relocation
-.*:13: Error: unsupported relocation
diff --git a/gas/testsuite/gas/mips/mips16-branch-reloc-3.d b/gas/testsuite/gas/mips/mips16-branch-reloc-3.d
index d25d42e3623f9e8dc1ae3a065f12fee358c8ab9e..c8e75fba2233ab3d451304cb896565f6541b7149 100644
--- a/gas/testsuite/gas/mips/mips16-branch-reloc-3.d
+++ b/gas/testsuite/gas/mips/mips16-branch-reloc-3.d
@@ -1,3 +1,20 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
 #name: MIPS16 branch relocation 3
 #as: -32
-#error-output: mips16-branch-reloc-3.l
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+	\.\.\.
+[0-9a-f]+ <[^>]*> f7ff 101e 	b	00001000 <foo>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f7ff 601e 	bteqz	00001004 <foo\+0x4>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f7ff 611e 	btnez	00001008 <foo\+0x8>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f7ff 221e 	beqz	v0,0000100c <foo\+0xc>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> f7ff 2a1e 	bnez	v0,00001010 <foo\+0x10>
+[ 	]*[0-9a-f]+: R_MIPS16_PC16_S1	bar
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
diff --git a/gas/testsuite/gas/mips/mips16-branch-reloc-3.l b/gas/testsuite/gas/mips/mips16-branch-reloc-3.l
deleted file mode 100644
index c72b8d03b07501bb8019808690b50147d761dc28..0000000000000000000000000000000000000000
--- a/gas/testsuite/gas/mips/mips16-branch-reloc-3.l
+++ /dev/null
@@ -1,6 +0,0 @@
-.*: Assembler messages:
-.*:8: Error: unsupported relocation
-.*:9: Error: unsupported relocation
-.*:10: Error: unsupported relocation
-.*:11: Error: unsupported relocation
-.*:12: Error: unsupported relocation
diff --git a/include/ChangeLog b/include/ChangeLog
index ecfac716419685634e66eb38e265d5c8832f09dd..ad63599b0b6e678031794d4d6a4ebe17dc5868f0 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@
+2016-06-28  Maciej W. Rozycki  <macro@imgtec.com>
+
+	* elf/mips.h (R_MIPS16_PC16_S1): New relocation.
+
 2016-06-25  Trevor Saunders  <tbsaunde+binutils@tbsaunde.org>
 
 	* elf/xtensa.h (xtensa_make_property_section): New prototype.
diff --git a/include/elf/mips.h b/include/elf/mips.h
index d6fd808cbef56461f91c1a7993789e0dfd83bd59..7e813de82801b92e04bf9912671840bc7c1abbb6 100644
--- a/include/elf/mips.h
+++ b/include/elf/mips.h
@@ -114,7 +114,8 @@ START_RELOC_NUMBERS (elf_mips_reloc_type)
   RELOC_NUMBER (R_MIPS16_TLS_GOTTPREL, 110)
   RELOC_NUMBER (R_MIPS16_TLS_TPREL_HI16, 111)
   RELOC_NUMBER (R_MIPS16_TLS_TPREL_LO16, 112)
-  FAKE_RELOC (R_MIPS16_max, 113)
+  RELOC_NUMBER (R_MIPS16_PC16_S1, 113)
+  FAKE_RELOC (R_MIPS16_max, 114)
   /* These relocations are specific to VxWorks.  */
   RELOC_NUMBER (R_MIPS_COPY, 126)
   RELOC_NUMBER (R_MIPS_JUMP_SLOT, 127)
diff --git a/ld/ChangeLog b/ld/ChangeLog
index c1b7f45c03d798059edaeebed1663f917dcd7406..be31872c0441d74d9477560044f8946a82c718f0 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,12 @@
+2016-06-28  Maciej W. Rozycki  <macro@imgtec.com>
+
+	* testsuite/ld-mips-elf/mips16-branch-2.d: New test.
+	* testsuite/ld-mips-elf/mips16-branch-3.d: New test.
+	* testsuite/ld-mips-elf/mips16-branch-addend-2.d: New test.
+	* testsuite/ld-mips-elf/mips16-branch-addend-3.d: New test.
+	* testsuite/ld-mips-elf/mips16-branch.s: New test source.
+	* testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.
+
 2016-06-27  Nick Clifton  <nickc@redhat.com>
 
 	PR ld/20302
diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp
index 8fb55e48bab84a8c3aa3f7c15ee7d2539185c32a..0d5842ffcf1aac9039df7b977a54f887e2d6a4f5 100644
--- a/ld/testsuite/ld-mips-elf/mips-elf.exp
+++ b/ld/testsuite/ld-mips-elf/mips-elf.exp
@@ -143,6 +143,11 @@ run_dump_test "mips16-1"
 # MIPS branch offset final link checking.
 run_dump_test "branch-misc-1"
 
+run_dump_test "mips16-branch-2" [list [list ld $abi_ldflags(o32)]]
+run_dump_test "mips16-branch-3" [list [list ld $abi_ldflags(o32)]]
+run_dump_test "mips16-branch-addend-2" [list [list ld $abi_ldflags(o32)]]
+run_dump_test "mips16-branch-addend-3" [list [list ld $abi_ldflags(o32)]]
+
 # Jalx test
 run_dump_test "jalx-1"
 
diff --git a/ld/testsuite/ld-mips-elf/mips16-branch-2.d b/ld/testsuite/ld-mips-elf/mips16-branch-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..95287334a2295af92daf925219620d96ca5ecf63
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/mips16-branch-2.d
@@ -0,0 +1,19 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS16 link branch 2
+#source: ../../../gas/testsuite/gas/mips/mips16-branch-reloc-2.s
+#as: -EB -32
+#ld: -EB -Ttext 0x1c000000 -e bar
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+	\.\.\.
+[0-9a-f]+ <[^>]*> f000 1016 	b	1c001030 <bar>
+[0-9a-f]+ <[^>]*> f000 6014 	bteqz	1c001030 <bar>
+[0-9a-f]+ <[^>]*> f000 6112 	btnez	1c001030 <bar>
+[0-9a-f]+ <[^>]*> f000 2210 	beqz	v0,1c001030 <bar>
+[0-9a-f]+ <[^>]*> f000 2a0e 	bnez	v0,1c001030 <bar>
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
diff --git a/ld/testsuite/ld-mips-elf/mips16-branch-3.d b/ld/testsuite/ld-mips-elf/mips16-branch-3.d
new file mode 100644
index 0000000000000000000000000000000000000000..88918c1a93d87a17c3197df317e11b7161ec6a46
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/mips16-branch-3.d
@@ -0,0 +1,20 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS16 link branch 3
+#source: mips16-branch.s
+#source: ../../../gas/testsuite/gas/mips/mips16-branch-reloc-3.s
+#as: -EB -32
+#ld: -EB -Ttext 0x1c000000 -e bar
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+	\.\.\.
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
+[0-9a-f]+ <[^>]*> f7fe 100e 	b	1c001000 <bar>
+[0-9a-f]+ <[^>]*> f7fe 600c 	bteqz	1c001000 <bar>
+[0-9a-f]+ <[^>]*> f7fe 610a 	btnez	1c001000 <bar>
+[0-9a-f]+ <[^>]*> f7fe 2208 	beqz	v0,1c001000 <bar>
+[0-9a-f]+ <[^>]*> f7fe 2a06 	bnez	v0,1c001000 <bar>
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
diff --git a/ld/testsuite/ld-mips-elf/mips16-branch-addend-2.d b/ld/testsuite/ld-mips-elf/mips16-branch-addend-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..c724bddbe2411eb1a8c3547674f2687e6d755b8b
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/mips16-branch-addend-2.d
@@ -0,0 +1,19 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS16 link branch addend 2
+#source: ../../../gas/testsuite/gas/mips/mips16-branch-addend-2.s
+#as: -EB -32
+#ld: -EB -Ttext 0x1c000000 -e bar
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+	\.\.\.
+[0-9a-f]+ <[^>]*> f121 1010 	b	1c002264 <bar\+0x1234>
+[0-9a-f]+ <[^>]*> f121 600e 	bteqz	1c002264 <bar\+0x1234>
+[0-9a-f]+ <[^>]*> f121 610c 	btnez	1c002264 <bar\+0x1234>
+[0-9a-f]+ <[^>]*> f121 220a 	beqz	v0,1c002264 <bar\+0x1234>
+[0-9a-f]+ <[^>]*> f121 2a08 	bnez	v0,1c002264 <bar\+0x1234>
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
diff --git a/ld/testsuite/ld-mips-elf/mips16-branch-addend-3.d b/ld/testsuite/ld-mips-elf/mips16-branch-addend-3.d
new file mode 100644
index 0000000000000000000000000000000000000000..84bccc781743959babe020e088baa65eec87ae91
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/mips16-branch-addend-3.d
@@ -0,0 +1,20 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS16 link branch addend 3
+#source: mips16-branch.s
+#source: ../../../gas/testsuite/gas/mips/mips16-branch-addend-3.s
+#as: -EB -32
+#ld: -EB -Ttext 0x1c000000 -e bar
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+	\.\.\.
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
+[0-9a-f]+ <[^>]*> f100 1008 	b	1c002234 <foo\+0x214>
+[0-9a-f]+ <[^>]*> f100 6006 	bteqz	1c002234 <foo\+0x214>
+[0-9a-f]+ <[^>]*> f100 6104 	btnez	1c002234 <foo\+0x214>
+[0-9a-f]+ <[^>]*> f100 2202 	beqz	v0,1c002234 <foo\+0x214>
+[0-9a-f]+ <[^>]*> f100 2a00 	bnez	v0,1c002234 <foo\+0x214>
+[0-9a-f]+ <[^>]*> 6500      	nop
+	\.\.\.
diff --git a/ld/testsuite/ld-mips-elf/mips16-branch.s b/ld/testsuite/ld-mips-elf/mips16-branch.s
new file mode 100644
index 0000000000000000000000000000000000000000..0024cdd5fc27d1c5708ceaf40d9e1d84362024eb
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/mips16-branch.s
@@ -0,0 +1,15 @@
+	.text
+	.globl	bar
+
+	.space	0x1000
+
+	.ent	bar
+	.set	mips16
+bar:
+	nop
+	.set	nomips16
+	.end	bar
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	4, 0
+	.space	16