MIPS16: Add R_MIPS16_PC16_S1 branch relocation support
authorMaciej W. Rozycki <macro@imgtec.com>
Tue, 28 Jun 2016 00:23:36 +0000 (01:23 +0100)
committerMaciej W. Rozycki <macro@imgtec.com>
Tue, 28 Jun 2016 00:29:56 +0000 (01:29 +0100)
For R_MIPS16_PC16_S1 the calculation is `(sign_extend(A) + S - P) >> 1'
and the usual MIPS16 bit shuffling applies to relocated field handling,
as per the encoding of the branch target in the extended form of the
MIPS16 B, BEQZ, BNEZ, BTEQZ and BTNEZ instructions.

include/
* elf/mips.h (R_MIPS16_PC16_S1): New relocation.

bfd/
* 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.

gas/
* 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.

ld/
* 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.

34 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf32-mips.c
bfd/elf64-mips.c
bfd/elfn32-mips.c
bfd/elfxx-mips.c
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-mips.c
gas/testsuite/gas/mips/branch-weak-6.d [new file with mode: 0644]
gas/testsuite/gas/mips/branch-weak-7.d [new file with mode: 0644]
gas/testsuite/gas/mips/branch-weak.s
gas/testsuite/gas/mips/mips.exp
gas/testsuite/gas/mips/mips16-branch-absolute.d
gas/testsuite/gas/mips/mips16-branch-absolute.l [deleted file]
gas/testsuite/gas/mips/mips16-branch-addend-2.d
gas/testsuite/gas/mips/mips16-branch-addend-2.l [deleted file]
gas/testsuite/gas/mips/mips16-branch-addend-2.s
gas/testsuite/gas/mips/mips16-branch-addend-3.d
gas/testsuite/gas/mips/mips16-branch-addend-3.l [deleted file]
gas/testsuite/gas/mips/mips16-branch-reloc-2.d
gas/testsuite/gas/mips/mips16-branch-reloc-2.l [deleted file]
gas/testsuite/gas/mips/mips16-branch-reloc-3.d
gas/testsuite/gas/mips/mips16-branch-reloc-3.l [deleted file]
include/ChangeLog
include/elf/mips.h
ld/ChangeLog
ld/testsuite/ld-mips-elf/mips-elf.exp
ld/testsuite/ld-mips-elf/mips16-branch-2.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-branch-3.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-branch-addend-2.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-branch-addend-3.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips16-branch.s [new file with mode: 0644]

index bf95751371881469a84c38085801f5c967b3ecb8..e6ed9609fccaa66709cd7bc67e94108c7f3e31b5 100644 (file)
@@ -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
index ebed9664bb28f553d5cc0f719819d00ea53dabd9..30513c4c3f39f7829ad0ea0e87f21b374994ddb0 100644 (file)
@@ -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,
index 5654fb664e9862bc6224e0e424e72e6e33f7618a..029de279fe8b88c1e91302cf9bfb4ac390112baa 100644 (file)
@@ -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[] =
index 34144f038b6bb0804b9452cb0d52652e1f8bc90d..f04c4b5a80269cc78d6ba3d172033b42f5faf6d6 100644 (file)
@@ -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[] =
index c955877afe5e9d382484bea0e2c87fc8d73dde84..734ebf63f21e194f5c97a87a764b354c1e66d90a 100644 (file)
@@ -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[] =
index 3b7723e3d0ef0e877eea5acb8f3de36e8c834a05..e47276bc61cca2f5bd9d2ad9531439400a62a087 100644 (file)
@@ -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:
index bf17f4353411fc398f357ec39423859c63009198..2b1777ef21f2a921c029068a706c1f5326989b11 100644 (file)
@@ -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",
index 443ad6f7553d6bd26d180288f5c1cb4c183ceec2..e962e71868ee51922fa292fdb5d9b8010141e927 100644 (file)
@@ -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
index d6afee21d4532d6e022d88727ea7772fcaf7d103..ba19df2eae6e86858e3fd77ad57e299b8cad1c22 100644 (file)
@@ -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
index ab2ea0c8c7cdf3268e5d6634607ee98921755cd3..092e7b430d2f0a28e1d9df42a233bf9ab657aff0 100644 (file)
@@ -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 (file)
index 0000000..e16b1b8
--- /dev/null
@@ -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 (file)
index 0000000..b291289
--- /dev/null
@@ -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
+       \.\.\.
index eedef7a5477ca917d75de3404534d4fc1c0fe502..a2dc7344a128cddba22df6a0d2acd9adb7cbafe5 100644 (file)
@@ -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
index d268dc00ce5be3294e79722856082630b414d915..4f5651b4a4694736a43a75dcb973dfdf6acdb182 100644 (file)
@@ -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"
index 90a9ea7cc7b3895e01836097812dbddbec579efb..3e1ec8e3d3ed42501a803e759f4e6c20dcb7a0a9 100644 (file)
@@ -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 (file)
index c72b8d0..0000000
+++ /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
index ae9854666d0e12800b4470fb9ca0783aba72ce64..3e61c24e5ea6b57702267d627d490d362c432dbb 100644 (file)
@@ -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 (file)
index d30fd62..0000000
+++ /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
index fe9e5b8aa537688319fdedb989f90a5503aab800..6035db89bea04ccea0cfe0b44770473349e03c67 100644 (file)
@@ -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
index 165e8f1e7e57faaae125131b9049ffc219bb8f18..f3ecb7516d6f1a3e53ee64a534281c457b014fbc 100644 (file)
@@ -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 (file)
index c72b8d0..0000000
+++ /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
index 1e6ecb4b20235c7d36e7e0f8ce350f6721c77144..4f920d203c4cecea3787b0ddba918562d9fa97ef 100644 (file)
@@ -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 (file)
index d30fd62..0000000
+++ /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
index d25d42e3623f9e8dc1ae3a065f12fee358c8ab9e..c8e75fba2233ab3d451304cb896565f6541b7149 100644 (file)
@@ -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 (file)
index c72b8d0..0000000
+++ /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
index ecfac716419685634e66eb38e265d5c8832f09dd..ad63599b0b6e678031794d4d6a4ebe17dc5868f0 100644 (file)
@@ -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.
index d6fd808cbef56461f91c1a7993789e0dfd83bd59..7e813de82801b92e04bf9912671840bc7c1abbb6 100644 (file)
@@ -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)
index c1b7f45c03d798059edaeebed1663f917dcd7406..be31872c0441d74d9477560044f8946a82c718f0 100644 (file)
@@ -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
index 8fb55e48bab84a8c3aa3f7c15ee7d2539185c32a..0d5842ffcf1aac9039df7b977a54f887e2d6a4f5 100644 (file)
@@ -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 (file)
index 0000000..9528733
--- /dev/null
@@ -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 (file)
index 0000000..88918c1
--- /dev/null
@@ -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 (file)
index 0000000..c724bdd
--- /dev/null
@@ -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 (file)
index 0000000..84bccc7
--- /dev/null
@@ -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 (file)
index 0000000..0024cdd
--- /dev/null
@@ -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