OSDN Git Service

bfd/
authormacro <macro>
Fri, 29 Jul 2011 22:46:26 +0000 (22:46 +0000)
committermacro <macro>
Fri, 29 Jul 2011 22:46:26 +0000 (22:46 +0000)
* elfxx-mips.c: Adjust comments throughout.
(mips_elf_relax_delete_bytes): Reshape code.
(_bfd_mips_elf_relax_section): Remove check for
R_MICROMIPS_GPREL16 relocations.  Reshape code.

gas/
* config/tc-mips.c: Adjust comments throughout.
(reglist_lookup): Reshape code.
(jmp_reloc_p, jalr_reloc_p): Reformat.
(got16_reloc_p, hi16_reloc_p, lo16_reloc_p): Handle microMIPS
relocations.
(gpr_mod_mask): Remove unused variable.
(gpr_read_mask, gpr_write_mask): Reshape code.
(fpr_read_mask, fpr_write_mask): Likewise.
(nops_for_vr4130): Ensure non-microMIPS mode.
(can_swap_branch_p): Correct pinfo2 reference.  Reshape code.
(append_insn): Skip Loongson 2F workaround in MIPS16 mode.  Use
the outermost operator of a compound relocation to determines
the relocated field.  Fix formatting.
(md_convert_frag): Reshape code.

include/opcode/
* mips.h: Clarify the description of microMIPS instruction
manipulation macros.
(MICROMIPSOP_MASK_MAJOR, MICROMIPSOP_SH_MAJOR): Remove macros.

bfd/ChangeLog
bfd/elfxx-mips.c
gas/ChangeLog
gas/config/tc-mips.c
include/opcode/ChangeLog
include/opcode/mips.h

index c3fac58..54d926f 100644 (file)
@@ -1,3 +1,10 @@
+2011-07-29  Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * elfxx-mips.c: Adjust comments throughout.
+       (mips_elf_relax_delete_bytes): Reshape code.
+       (_bfd_mips_elf_relax_section): Remove check for
+       R_MICROMIPS_GPREL16 relocations.  Reshape code.
+
 2011-07-28  Roland McGrath  <mcgrathr@google.com>
 
        * elf32-i386.c (NACL_PLT_ENTRY_SIZE, NACLMASK): New macros.
index 53a9477..36b881e 100644 (file)
@@ -11910,8 +11910,7 @@ mips_elf_relax_delete_bytes (bfd *abfd,
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
   for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
-    if (isym->st_shndx == sec_shndx
-       && isym->st_value > addr)
+    if (isym->st_shndx == sec_shndx && isym->st_value > addr)
       isym->st_value -= count;
 
   /* Now adjust the global symbols defined in this section.  */
@@ -11928,9 +11927,8 @@ mips_elf_relax_delete_bytes (bfd *abfd,
           || sym_hash->root.type == bfd_link_hash_defweak)
          && sym_hash->root.u.def.section == sec)
        {
-         bfd_vma value;
+         bfd_vma value = sym_hash->root.u.def.value;
 
-         value = sym_hash->root.u.def.value;
          if (ELF_ST_IS_MICROMIPS (sym_hash->other))
            value &= MINUS_TWO;
          if (value > addr)
@@ -12336,6 +12334,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
       unsigned long opcode;
       bfd_vma symval;
       bfd_vma pcrval;
+      bfd_byte *ptr;
       int fndopc;
 
       /* The number of bytes to delete for relaxation and from where
@@ -12347,8 +12346,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
          this reloc.  */
       if (r_type != R_MICROMIPS_HI16
          && r_type != R_MICROMIPS_PC16_S1
-         && r_type != R_MICROMIPS_26_S1
-         && r_type != R_MICROMIPS_GPREL16)
+         && r_type != R_MICROMIPS_26_S1)
        continue;
 
       /* Get the section contents if we haven't done so already.  */
@@ -12361,6 +12359,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
          else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
            goto error_return;
        }
+      ptr = contents + irel->r_offset;
 
       /* Read this BFD's local symbols if we haven't done so already.  */
       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
@@ -12432,8 +12431,8 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
       if (irel->r_offset + 4 > sec->size)
        continue;
 
-      opcode  = bfd_get_16 (abfd, contents + irel->r_offset    ) << 16;
-      opcode |= bfd_get_16 (abfd, contents + irel->r_offset + 2);
+      opcode  = bfd_get_16 (abfd, ptr    ) << 16;
+      opcode |= bfd_get_16 (abfd, ptr + 2);
 
       /* This is the pc-relative distance from the instruction the
          relocation is applied to, to the symbol referred.  */
@@ -12477,7 +12476,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
 
          /* See if the LUI instruction *might* be in a branch delay slot.  */
          if (irel->r_offset >= 2
-             && check_br16_dslot (abfd, contents + irel->r_offset - 2) > 0
+             && check_br16_dslot (abfd, ptr - 2)
              && !(irel->r_offset >= 4
                   /* If the instruction is actually a 4-byte branch,
                      the value of check_br16_dslot doesn't matter.
@@ -12487,7 +12486,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
                                          irel->r_offset - 4)))
            continue;
          if (irel->r_offset >= 4
-             && check_br32_dslot (abfd, contents + irel->r_offset - 4) > 0)
+             && check_br32_dslot (abfd, ptr - 4))
            continue;
 
          reg = OP32_SREG (opcode);
@@ -12502,11 +12501,11 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
            case 0:
              break;
            case 2:
-             if (check_br16 (abfd, contents + irel->r_offset + 4, reg))
+             if (check_br16 (abfd, ptr + 4, reg))
                break;
              continue;
            case 4:
-             if (check_br32 (abfd, contents + irel->r_offset + 4, reg))
+             if (check_br32 (abfd, ptr + 4, reg))
                break;
              continue;
            default:
@@ -12581,8 +12580,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
               && irel->r_offset + 5 < sec->size
               && ((fndopc = find_match (opcode, bz_rs_insns_32)) >= 0
                   || (fndopc = find_match (opcode, bz_rt_insns_32)) >= 0)
-              && MATCH (bfd_get_16 (abfd, contents + irel->r_offset + 4),
-                        nop_insn_16))
+              && MATCH (bfd_get_16 (abfd, ptr + 4), nop_insn_16))
        {
          unsigned long reg;
 
@@ -12593,10 +12591,8 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
                    | BZC32_REG_FIELD (reg)
                    | (opcode & 0xffff));               /* Addend value.  */
 
-         bfd_put_16 (abfd, (opcode >> 16) & 0xffff,
-                     contents + irel->r_offset);
-         bfd_put_16 (abfd,  opcode        & 0xffff,
-                     contents + irel->r_offset + 2);
+         bfd_put_16 (abfd, (opcode >> 16) & 0xffff, ptr);
+         bfd_put_16 (abfd,  opcode        & 0xffff, ptr + 2);
 
          /* Delete the 16-bit delay slot NOP: two bytes from
             irel->offset + 4.  */
@@ -12617,7 +12613,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
          bfd_put_16 (abfd,
                      (b_insn_16.match
                       | (opcode & 0x3ff)),             /* Addend value.  */
-                     contents + irel->r_offset);
+                     ptr);
 
          /* Delete 2 bytes from irel->r_offset + 2.  */
          delcnt = 2;
@@ -12645,7 +12641,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
                      (bz_insns_16[fndopc].match
                       | BZ16_REG_FIELD (reg)
                       | (opcode & 0x7f)),              /* Addend value.  */
-                     contents + irel->r_offset);
+                     ptr);
 
          /* Delete 2 bytes from irel->r_offset + 2.  */
          delcnt = 2;
@@ -12661,14 +12657,13 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
          unsigned long n32opc;
          bfd_boolean relaxed = FALSE;
 
-         n32opc  = bfd_get_16 (abfd, contents + irel->r_offset + 4) << 16;
-         n32opc |= bfd_get_16 (abfd, contents + irel->r_offset + 6);
+         n32opc  = bfd_get_16 (abfd, ptr + 4) << 16;
+         n32opc |= bfd_get_16 (abfd, ptr + 6);
 
          if (MATCH (n32opc, nop_insn_32))
            {
              /* Replace delay slot 32-bit NOP with a 16-bit NOP.  */
-             bfd_put_16 (abfd, nop_insn_16.match,
-                         contents + irel->r_offset + 4);
+             bfd_put_16 (abfd, nop_insn_16.match, ptr + 4);
 
              relaxed = TRUE;
            }
@@ -12679,7 +12674,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
                          (move_insn_16.match
                           | MOVE16_RD_FIELD (MOVE32_RD (n32opc))
                           | MOVE16_RS_FIELD (MOVE32_RS (n32opc))),
-                         contents + irel->r_offset + 4);
+                         ptr + 4);
 
              relaxed = TRUE;
            }
@@ -12691,9 +12686,9 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
              /* JAL with 32-bit delay slot that is changed to a JALS
                 with 16-bit delay slot.  */
              bfd_put_16 (abfd, (jal_insn_32_bd16.match >> 16) & 0xffff,
-                         contents + irel->r_offset);
+                         ptr);
              bfd_put_16 (abfd,  jal_insn_32_bd16.match        & 0xffff,
-                         contents + irel->r_offset + 2);
+                         ptr + 2);
 
              /* Delete 2 bytes from irel->r_offset + 6.  */
              delcnt = 2;
index e91a35a..25e0b62 100644 (file)
@@ -1,3 +1,20 @@
+2011-07-29  Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * config/tc-mips.c: Adjust comments throughout.
+       (reglist_lookup): Reshape code.
+       (jmp_reloc_p, jalr_reloc_p): Reformat.
+       (got16_reloc_p, hi16_reloc_p, lo16_reloc_p): Handle microMIPS
+       relocations.
+       (gpr_mod_mask): Remove unused variable.
+       (gpr_read_mask, gpr_write_mask): Reshape code.
+       (fpr_read_mask, fpr_write_mask): Likewise.
+       (nops_for_vr4130): Ensure non-microMIPS mode.
+       (can_swap_branch_p): Correct pinfo2 reference.  Reshape code.
+       (append_insn): Skip Loongson 2F workaround in MIPS16 mode.  Use
+       the outermost operator of a compound relocation to determines
+       the relocated field.  Fix formatting.
+       (md_convert_frag): Reshape code.
+
 2011-07-29  Tristan Gingold  <gingold@adacore.com>
 
        * frags.c (frag_var_init): New function.
index af78329..8f57985 100644 (file)
@@ -483,7 +483,7 @@ static int mips_32bitmode = 0;
    (strncmp (TARGET_CPU, "mips16", sizeof ("mips16") - 1) == 0         \
     || strncmp (TARGET_CANONICAL, "mips-lsi-elf", sizeof ("mips-lsi-elf") - 1) == 0)
 
-/* Return true if the given CPU supports microMIPS.  */
+/* Return true if the given CPU supports the microMIPS ASE.  */
 #define CPU_HAS_MICROMIPS(cpu) 0
 
 /* True if CPU has a dror instruction.  */
@@ -2141,7 +2141,7 @@ reg_lookup (char **s, unsigned int types, unsigned int *regnop)
    As a special exception if one of s0-s7 registers is specified as
    the range's lower delimiter and s8 (fp) is its upper one, then no
    registers whose numbers place them between s7 and s8 (i.e. $24-$29)
-   are selected; they have to be named separately if needed.  */
+   are selected; they have to be listed separately if needed.  */
 
 static int
 reglist_lookup (char **s, unsigned int types, unsigned int *reglistp)
@@ -2150,9 +2150,9 @@ reglist_lookup (char **s, unsigned int types, unsigned int *reglistp)
   unsigned int lastregno;
   bfd_boolean ok = TRUE;
   unsigned int regmask;
-  unsigned int regno;
+  char *s_endlist = *s;
   char *s_reset = *s;
-  char *s_end_of_list = *s;
+  unsigned int regno;
 
   while (reg_lookup (s, types, &regno))
     {
@@ -2177,14 +2177,14 @@ reglist_lookup (char **s, unsigned int types, unsigned int *reglistp)
       regmask ^= (1 << regno) - 1;
       reglist |= regmask;
 
-      s_end_of_list = *s;
+      s_endlist = *s;
       if (**s != ',')
        break;
       (*s)++;
     }
 
   if (ok)
-    *s = s_end_of_list;
+    *s = s_endlist;
   else
     *s = s_reset;
   if (reglistp)
@@ -2663,41 +2663,36 @@ micromips_reloc_p (bfd_reloc_code_real_type reloc)
 }
 
 static inline bfd_boolean
+jmp_reloc_p (bfd_reloc_code_real_type reloc)
+{
+  return reloc == BFD_RELOC_MIPS_JMP || reloc == BFD_RELOC_MICROMIPS_JMP;
+}
+
+static inline bfd_boolean
 got16_reloc_p (bfd_reloc_code_real_type reloc)
 {
-  return (reloc == BFD_RELOC_MIPS_GOT16
-         || reloc == BFD_RELOC_MIPS16_GOT16
+  return (reloc == BFD_RELOC_MIPS_GOT16 || reloc == BFD_RELOC_MIPS16_GOT16
          || reloc == BFD_RELOC_MICROMIPS_GOT16);
 }
 
 static inline bfd_boolean
 hi16_reloc_p (bfd_reloc_code_real_type reloc)
 {
-  return (reloc == BFD_RELOC_HI16_S
-         || reloc == BFD_RELOC_MIPS16_HI16_S
+  return (reloc == BFD_RELOC_HI16_S || reloc == BFD_RELOC_MIPS16_HI16_S
          || reloc == BFD_RELOC_MICROMIPS_HI16_S);
 }
 
 static inline bfd_boolean
 lo16_reloc_p (bfd_reloc_code_real_type reloc)
 {
-  return (reloc == BFD_RELOC_LO16
-         || reloc == BFD_RELOC_MIPS16_LO16
+  return (reloc == BFD_RELOC_LO16 || reloc == BFD_RELOC_MIPS16_LO16
          || reloc == BFD_RELOC_MICROMIPS_LO16);
 }
 
 static inline bfd_boolean
-jmp_reloc_p (bfd_reloc_code_real_type reloc)
-{
-  return (reloc == BFD_RELOC_MIPS_JMP
-         || reloc == BFD_RELOC_MICROMIPS_JMP);
-}
-
-static inline bfd_boolean
 jalr_reloc_p (bfd_reloc_code_real_type reloc)
 {
-  return (reloc == BFD_RELOC_MIPS_JALR
-         || reloc == BFD_RELOC_MICROMIPS_JALR);
+  return reloc == BFD_RELOC_MIPS_JALR || reloc == BFD_RELOC_MICROMIPS_JALR;
 }
 
 /* Return true if the given relocation might need a matching %lo().
@@ -2893,17 +2888,15 @@ relax_end (void)
   mips_relax.sequence = 0;
 }
 
-/* Return the mask of core registers that instruction IP may
-   read or write.  */
+/* Return the mask of core registers that IP reads or writes.  */
 
 static unsigned int
 gpr_mod_mask (const struct mips_cl_insn *ip)
 {
-  unsigned long pinfo, pinfo2;
+  unsigned long pinfo2;
   unsigned int mask;
 
   mask = 0;
-  pinfo = ip->insn_mo->pinfo;
   pinfo2 = ip->insn_mo->pinfo2;
   if (mips_opts.micromips)
     {
@@ -2969,27 +2962,20 @@ gpr_read_mask (const struct mips_cl_insn *ip)
       if (pinfo & MIPS16_INSN_READ_GPR_X)
        mask |= 1 << MIPS16_EXTRACT_OPERAND (REGR32, *ip);
     }
-  else if (mips_opts.micromips)
-    {
-      if (pinfo & INSN_READ_GPR_T)
-       mask |= 1 << EXTRACT_OPERAND (1, RT, *ip);
-      if (pinfo & INSN_READ_GPR_S)
-       mask |= 1 << EXTRACT_OPERAND (1, RS, *ip);
-      if (pinfo2 & INSN2_READ_GPR_31)
-       mask |= 1 << RA;
-      if (pinfo2 & INSN2_READ_GP)
-       mask |= 1 << GP;
-    }
   else
     {
       if (pinfo2 & INSN2_READ_GPR_D)
-       mask |= 1 << EXTRACT_OPERAND (0, RD, *ip);
+       mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RD, *ip);
       if (pinfo & INSN_READ_GPR_T)
-       mask |= 1 << EXTRACT_OPERAND (0, RT, *ip);
+       mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RT, *ip);
       if (pinfo & INSN_READ_GPR_S)
-       mask |= 1 << EXTRACT_OPERAND (0, RS, *ip);
+       mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RS, *ip);
+      if (pinfo2 & INSN2_READ_GP)
+       mask |= 1 << GP;
+      if (pinfo2 & INSN2_READ_GPR_31)
+       mask |= 1 << RA;
       if (pinfo2 & INSN2_READ_GPR_Z)
-       mask |= 1 << EXTRACT_OPERAND (0, RZ, *ip);
+       mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RZ, *ip);
     }
   /* Don't include register 0.  */
   return mask & ~1;
@@ -3023,23 +3009,14 @@ gpr_write_mask (const struct mips_cl_insn *ip)
       if (pinfo & MIPS16_INSN_WRITE_GPR_Y)
        mask |= 1 << MIPS16OP_EXTRACT_REG32R (ip->insn_opcode);
     }
-  else if (mips_opts.micromips)
-    {
-      if (pinfo & INSN_WRITE_GPR_D)
-       mask |= 1 << EXTRACT_OPERAND (1, RD, *ip);
-      if (pinfo & INSN_WRITE_GPR_T)
-       mask |= 1 << EXTRACT_OPERAND (1, RT, *ip);
-      if (pinfo2 & INSN2_WRITE_GPR_S)
-       mask |= 1 << EXTRACT_OPERAND (1, RS, *ip);
-      if (pinfo & INSN_WRITE_GPR_31)
-       mask |= 1 << RA;
-    }
   else
     {
       if (pinfo & INSN_WRITE_GPR_D)
        mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RD, *ip);
       if (pinfo & INSN_WRITE_GPR_T)
        mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RT, *ip);
+      if (pinfo2 & INSN2_WRITE_GPR_S)
+       mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RS, *ip);
       if (pinfo & INSN_WRITE_GPR_31)
        mask |= 1 << RA;
       if (pinfo2 & INSN2_WRITE_GPR_Z)
@@ -3060,19 +3037,10 @@ fpr_read_mask (const struct mips_cl_insn *ip)
   mask = 0;
   pinfo = ip->insn_mo->pinfo;
   pinfo2 = ip->insn_mo->pinfo2;
-  if (mips_opts.micromips)
+  if (!mips_opts.mips16)
     {
       if (pinfo2 & INSN2_READ_FPR_D)
-       mask |= 1 << EXTRACT_OPERAND (1, FD, *ip);
-      if (pinfo & INSN_READ_FPR_S)
-       mask |= 1 << EXTRACT_OPERAND (1, FS, *ip);
-      if (pinfo & INSN_READ_FPR_T)
-       mask |= 1 << EXTRACT_OPERAND (1, FT, *ip);
-      if (pinfo & INSN_READ_FPR_R)
-       mask |= 1 << EXTRACT_OPERAND (1, FR, *ip);
-    }
-  else if (!mips_opts.mips16)
-    {
+       mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, FD, *ip);
       if (pinfo & INSN_READ_FPR_S)
        mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, FS, *ip);
       if (pinfo & INSN_READ_FPR_T)
@@ -3100,16 +3068,7 @@ fpr_write_mask (const struct mips_cl_insn *ip)
   mask = 0;
   pinfo = ip->insn_mo->pinfo;
   pinfo2 = ip->insn_mo->pinfo2;
-  if (mips_opts.micromips)
-    {
-      if (pinfo2 & INSN_WRITE_FPR_D)
-       mask |= 1 << EXTRACT_OPERAND (1, FD, *ip);
-      if (pinfo & INSN_WRITE_FPR_S)
-       mask |= 1 << EXTRACT_OPERAND (1, FS, *ip);
-      if (pinfo & INSN_WRITE_FPR_T)
-       mask |= 1 << EXTRACT_OPERAND (1, FT, *ip);
-    }
-  else if (!mips_opts.mips16)
+  if (!mips_opts.mips16)
     {
       if (pinfo & INSN_WRITE_FPR_D)
        mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, FD, *ip);
@@ -3316,6 +3275,7 @@ nops_for_vr4130 (int ignore, const struct mips_cl_insn *hist,
     if (MF_HILO_INSN (hist[i].insn_mo->pinfo))
       {
        /* Extract the destination register.  */
+       gas_assert (!mips_opts.micromips);
        mask = gpr_write_mask (&hist[i]);
 
        /* No nops are needed if INSN reads that register.  */
@@ -3720,8 +3680,9 @@ can_swap_branch_p (struct mips_cl_insn *ip)
     return FALSE;
 
   /* If the previous instruction is in a variant frag other than this
-     branch's one, we cannot do the swap.  This does not apply to the
-     mips16, which uses variant frags for different purposes.  */
+     branch's one, we cannot do the swap.  This does not apply to
+     MIPS16/microMIPS code, which uses variant frags for different
+     purposes.  */
   if (!HAVE_CODE_COMPRESSION
       && history[0].frag
       && history[0].frag->fr_type == rs_machine_dependent)
@@ -3781,17 +3742,16 @@ can_swap_branch_p (struct mips_cl_insn *ip)
 
   /* If the previous instruction has an incorrect size for a fixed
      branch delay slot in microMIPS mode, we cannot swap.  */
-  if (mips_opts.micromips)
-    {
-      pinfo2 = ip->insn_mo->pinfo;
-      if ((pinfo2 & INSN2_BRANCH_DELAY_16BIT)
-         && insn_length (history) != 2)
-       return FALSE;
-
-      if ((pinfo2 & INSN2_BRANCH_DELAY_32BIT)
-         && insn_length (history) != 4)
-       return FALSE;
-    }
+  pinfo2 = ip->insn_mo->pinfo2;
+  if (mips_opts.micromips
+      && (pinfo2 & INSN2_BRANCH_DELAY_16BIT)
+      && insn_length (history) != 2)
+    return FALSE;
+  if (mips_opts.micromips
+      && (pinfo2 & INSN2_BRANCH_DELAY_32BIT)
+      && insn_length (history) != 4)
+    return FALSE;
+
   return TRUE;
 }
 
@@ -3984,10 +3944,10 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
 {
   unsigned long prev_pinfo, prev_pinfo2, pinfo, pinfo2;
   bfd_boolean relaxed_branch = FALSE;
-  bfd_boolean relax32;
   enum append_method method;
+  bfd_boolean relax32;
 
-  if (mips_fix_loongson2f && !mips_opts.micromips)
+  if (mips_fix_loongson2f && !HAVE_CODE_COMPRESSION)
     fix_loongson2f (ip);
 
   mips_mark_labels ();
@@ -4192,9 +4152,9 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
      If the instruction produced is a branch that we will swap with
      the preceding instruction, then we add the displacement by which
      the branch will be moved backwards.  This is more appropriate
-     and for MIPS16/microMIPS code also prevents a debugger from placing
-     a breakpoint in the middle of the branch (and corrupting code if
-     software breakpoints are used).  */
+     and for MIPS16/microMIPS code also prevents a debugger from
+     placing a breakpoint in the middle of the branch (and corrupting
+     code if software breakpoints are used).  */
   dwarf2_emit_insn ((HAVE_CODE_COMPRESSION ? -1 : 0)
                    + (method == APPEND_SWAP ? insn_length (history) : 0));
 #endif
@@ -4330,6 +4290,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
   if (!ip->complete_p && *reloc_type < BFD_RELOC_UNUSED)
     {
       bfd_reloc_code_real_type final_type[3];
+      reloc_howto_type *howto0;
       reloc_howto_type *howto;
       int i;
 
@@ -4340,7 +4301,8 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
 
       /* In a compound relocation, it is the final (outermost)
         operator that determines the relocated field.  */
-      howto = bfd_reloc_type_lookup (stdoutput, final_type[i - 1]);
+      howto = howto0 = bfd_reloc_type_lookup (stdoutput, final_type[i - 1]);
+
       if (howto == NULL)
        {
          /* To reproduce this failure try assembling gas/testsuites/
@@ -4350,16 +4312,17 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                  final_type[i - 1]);
          howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
        }
-         
-      howto = bfd_reloc_type_lookup (stdoutput, final_type[0]);
+
+      if (i > 1)
+       howto0 = bfd_reloc_type_lookup (stdoutput, final_type[0]);
       ip->fixp[0] = fix_new_exp (ip->frag, ip->where,
                                 bfd_get_reloc_size (howto),
                                 address_expr,
-                                howto->pc_relative, final_type[0]);
+                                howto0 && howto0->pc_relative,
+                                final_type[0]);
 
       /* Tag symbols that have a R_MIPS16_26 relocation against them.  */
-      if (reloc_type[0] == BFD_RELOC_MIPS16_JMP
-         && ip->fixp[0]->fx_addsy)
+      if (final_type[0] == BFD_RELOC_MIPS16_JMP && ip->fixp[0]->fx_addsy)
        *symbol_get_tc (ip->fixp[0]->fx_addsy) = 1;
 
       /* These relocations can have an addend that won't fit in
@@ -17800,8 +17763,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
       bfd_boolean compact = RELAX_MICROMIPS_COMPACT (fragp->fr_subtype);
       bfd_boolean al = RELAX_MICROMIPS_LINK (fragp->fr_subtype);
       int type = RELAX_MICROMIPS_TYPE (fragp->fr_subtype);
-      unsigned long jal, jalr, jr;
-
+      bfd_boolean short_ds;
       unsigned long insn;
       expressionS exp;
       fixS *fixp;
@@ -17841,7 +17803,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
          return;
        }
 
-      /* Handle 32-bit branches that fit or forced to fit.  */
+      /* Handle 32-bit branches that fit or are forced to fit.  */
       if (!RELAX_MICROMIPS_RELAX32 (fragp->fr_subtype)
          || !RELAX_MICROMIPS_TOOFAR32 (fragp->fr_subtype))
        {
@@ -17914,18 +17876,8 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
       as_warn_where (fragp->fr_file, fragp->fr_line,
                     _("Relaxed out-of-range branch into a jump"));
 
-      /* Check the short-delay-slot bit.  */
-      if (al && (insn & 0x02000000) != 0)
-       {
-         jal = 0x74000000;                             /* jals  */
-         jalr = 0x45e0;                                /* jalrs  */
-       }
-      else
-       {
-         jal = 0xf4000000;                             /* jal  */
-         jalr = 0x45c0;                                /* jalr  */
-       }
-      jr = compact ? 0x45a0 : 0x4580;                  /* jr/c  */
+      /* Set the short-delay-slot bit.  */
+      short_ds = al && (insn & 0x02000000) != 0;
 
       if (!RELAX_MICROMIPS_UNCOND (fragp->fr_subtype))
        {
@@ -17995,6 +17947,8 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
 
       if (mips_pic == NO_PIC)
        {
+         unsigned long jal = short_ds ? 0x74000000 : 0xf4000000; /* jal/s  */
+
          /* j/jal/jals <sym>  R_MICROMIPS_26_S1  */
          insn = al ? jal : 0xd4000000;
 
@@ -18019,6 +17973,8 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
       else
        {
          unsigned long at = RELAX_MICROMIPS_AT (fragp->fr_subtype);
+         unsigned long jalr = short_ds ? 0x45e0 : 0x45c0;      /* jalr/s  */
+         unsigned long jr = compact ? 0x45a0 : 0x4580;         /* jr/c  */
 
          /* lw/ld $at, <sym>($gp)  R_MICROMIPS_GOT16  */
          insn = HAVE_64BIT_ADDRESSES ? 0xdc1c0000 : 0xfc1c0000;
index 3c69275..e7bfecd 100644 (file)
@@ -1,3 +1,9 @@
+2011-07-29  Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * mips.h: Clarify the description of microMIPS instruction
+       manipulation macros.
+       (MICROMIPSOP_MASK_MAJOR, MICROMIPSOP_SH_MAJOR): Remove macros.
+
 2011-07-24  Chao-ying Fu  <fu@mips.com>
             Maciej W. Rozycki  <macro@codesourcery.com>
 
index ba68331..609a4af 100644 (file)
@@ -1329,13 +1329,10 @@ extern int bfd_mips_num_opcodes;
 extern const struct mips_opcode mips16_opcodes[];
 extern const int bfd_mips16_num_opcodes;
 
-/* These are the bitmasks and shift counts used for the different
-   fields in the instruction formats.  Other than MAJOR, no masks are
-   provided for the fixed portions of an instruction, since they are
-   not needed.  */
+/* These are the bit masks and shift counts used for the different fields
+   in the microMIPS instruction formats.  No masks are provided for the
+   fixed portions of an instruction, since they are not needed.  */
 
-#define MICROMIPSOP_MASK_MAJOR         0x3f
-#define MICROMIPSOP_SH_MAJOR           26
 #define MICROMIPSOP_MASK_IMMEDIATE     0xffff
 #define MICROMIPSOP_SH_IMMEDIATE       0
 #define MICROMIPSOP_MASK_DELTA         0xffff