aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog20
-rw-r--r--bfd/bfd-in2.h3
-rw-r--r--bfd/elf32-mips.c18
-rw-r--r--bfd/elf64-mips.c33
-rw-r--r--bfd/elfn32-mips.c33
-rw-r--r--bfd/elfxx-mips.c35
-rw-r--r--bfd/libbfd.h1
-rw-r--r--bfd/reloc.c5
-rw-r--r--gas/ChangeLog33
-rw-r--r--gas/config/tc-mips.c54
-rw-r--r--gas/testsuite/gas/mips/branch-weak-6.d14
-rw-r--r--gas/testsuite/gas/mips/branch-weak-7.d14
-rw-r--r--gas/testsuite/gas/mips/branch-weak.s6
-rw-r--r--gas/testsuite/gas/mips/mips.exp2
-rw-r--r--gas/testsuite/gas/mips/mips16-branch-absolute.d19
-rw-r--r--gas/testsuite/gas/mips/mips16-branch-absolute.l6
-rw-r--r--gas/testsuite/gas/mips/mips16-branch-addend-2.d21
-rw-r--r--gas/testsuite/gas/mips/mips16-branch-addend-2.l6
-rw-r--r--gas/testsuite/gas/mips/mips16-branch-addend-2.s2
-rw-r--r--gas/testsuite/gas/mips/mips16-branch-addend-3.d19
-rw-r--r--gas/testsuite/gas/mips/mips16-branch-addend-3.l6
-rw-r--r--gas/testsuite/gas/mips/mips16-branch-reloc-2.d21
-rw-r--r--gas/testsuite/gas/mips/mips16-branch-reloc-2.l6
-rw-r--r--gas/testsuite/gas/mips/mips16-branch-reloc-3.d19
-rw-r--r--gas/testsuite/gas/mips/mips16-branch-reloc-3.l6
-rw-r--r--include/ChangeLog4
-rw-r--r--include/elf/mips.h3
-rw-r--r--ld/ChangeLog9
-rw-r--r--ld/testsuite/ld-mips-elf/mips-elf.exp5
-rw-r--r--ld/testsuite/ld-mips-elf/mips16-branch-2.d19
-rw-r--r--ld/testsuite/ld-mips-elf/mips16-branch-3.d20
-rw-r--r--ld/testsuite/ld-mips-elf/mips16-branch-addend-2.d19
-rw-r--r--ld/testsuite/ld-mips-elf/mips16-branch-addend-3.d20
-rw-r--r--ld/testsuite/ld-mips-elf/mips16-branch.s15
34 files changed, 464 insertions, 52 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index bf95751..e6ed960 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 ebed966..30513c4 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 5654fb6..029de27 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 34144f0..f04c4b5 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 c955877..734ebf6 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 3b7723e..e47276b 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
@@ -2232,6 +2238,13 @@ aligned_pcrel_reloc_p (int r_type)
}
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)
{
return (r_type == R_MICROMIPS_26_S1
@@ -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 bf17f43..2b1777e 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 443ad6f..e962e71 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -2305,6 +2305,11 @@ 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
BFD_RELOC_MIPS_26_PCREL_S2
diff --git a/gas/ChangeLog b/gas/ChangeLog
index d6afee2..ba19df2 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 ab2ea0c..092e7b4 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 0000000..e16b1b8
--- /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 0000000..b291289
--- /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 eedef7a..a2dc734 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 d268dc0..4f5651b 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 90a9ea7..3e1ec8e 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 c72b8d0..0000000
--- 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 ae98546..3e61c24 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 d30fd62..0000000
--- 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 fe9e5b8..6035db8 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 165e8f1..f3ecb75 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 c72b8d0..0000000
--- 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 1e6ecb4..4f920d2 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 d30fd62..0000000
--- 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 d25d42e..c8e75fb 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 c72b8d0..0000000
--- 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 ecfac71..ad63599 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 d6fd808..7e813de 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 c1b7f45..be31872 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 8fb55e4..0d5842f 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 0000000..9528733
--- /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 0000000..88918c1
--- /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 0000000..c724bdd
--- /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 0000000..84bccc7
--- /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 0000000..0024cdd
--- /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