* config/tc-mips.c (is_delay_slot_valid): Simplify expression.
[deliverable/binutils-gdb.git] / gas / config / tc-mips.c
index 35bea8b9fc64fbfeb14d945e603cd97cf8be20ca..024b864fe8cd77ab366eb35e604310770a6acf64 100644 (file)
@@ -1574,6 +1574,11 @@ static bfd_reloc_code_real_type offset_reloc[3]
 
 static unsigned int forced_insn_length;
 
+/* True if we are assembling an instruction.  All dot symbols defined during
+   this time should be treated as code labels.  */
+
+static bfd_boolean mips_assembling_insn;
+
 #ifdef OBJ_ELF
 /* The pdr segment for per procedure frame/regmask info.  Not used for
    ECOFF debugging.  */
@@ -2296,7 +2301,18 @@ is_size_valid (const struct mips_opcode *mo)
 }
 
 /* Return TRUE if the microMIPS opcode MO is valid for the delay slot
-   of the preceding instruction.  Always TRUE in the standard MIPS mode.  */
+   of the preceding instruction.  Always TRUE in the standard MIPS mode.
+
+   We don't accept macros in 16-bit delay slots to avoid a case where
+   a macro expansion fails because it relies on a preceding 32-bit real
+   instruction to have matched and does not handle the operands correctly.
+   The only macros that may expand to 16-bit instructions are JAL that
+   cannot be placed in a delay slot anyway, and corner cases of BALIGN
+   and BGT (that likewise cannot be placed in a delay slot) that decay to
+   a NOP.  In all these cases the macros precede any corresponding real
+   instruction definitions in the opcode table, so they will match in the
+   second pass where the size of the delay slot is ignored and therefore
+   produce correct code.  */
 
 static bfd_boolean
 is_delay_slot_valid (const struct mips_opcode *mo)
@@ -2305,7 +2321,7 @@ is_delay_slot_valid (const struct mips_opcode *mo)
     return TRUE;
 
   if (mo->pinfo == INSN_MACRO)
-    return TRUE;
+    return (history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_16BIT) == 0;
   if ((history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT) != 0
       && micromips_insn_length (mo) != 4)
     return FALSE;
@@ -2592,6 +2608,9 @@ md_assemble (char *str)
   offset_reloc[1] = BFD_RELOC_UNUSED;
   offset_reloc[2] = BFD_RELOC_UNUSED;
 
+  mips_mark_labels ();
+  mips_assembling_insn = TRUE;
+
   if (mips_opts.mips16)
     mips16_ip (str, &insn);
   else
@@ -2602,12 +2621,8 @@ md_assemble (char *str)
     }
 
   if (insn_error)
-    {
-      as_bad ("%s `%s'", insn_error, str);
-      return;
-    }
-
-  if (insn.insn_mo->pinfo == INSN_MACRO)
+    as_bad ("%s `%s'", insn_error, str);
+  else if (insn.insn_mo->pinfo == INSN_MACRO)
     {
       macro_start ();
       if (mips_opts.mips16)
@@ -2625,6 +2640,8 @@ md_assemble (char *str)
       else
        append_insn (&insn, NULL, unused_reloc, FALSE);
     }
+
+  mips_assembling_insn = FALSE;
 }
 
 /* Convenience functions for abstracting away the differences between
@@ -2832,7 +2849,7 @@ s_is_linkonce (symbolS *sym, segT from_seg)
   return linkonce;
 }
 
-/* Mark instruction labels in MIPS16/microMIPS mode.  This permits the
+/* Mark MIPS16 or microMIPS instruction label LABEL.  This permits the
    linker to handle them specially, such as generating jalx instructions
    when needed.  We also make them odd for the duration of the assembly,
    in order to generate the right sort of code.  We will make them even
@@ -2841,36 +2858,39 @@ s_is_linkonce (symbolS *sym, segT from_seg)
    to make them odd again.  */
 
 static void
-mips_compressed_mark_labels (void)
+mips_compressed_mark_label (symbolS *label)
 {
-  segment_info_type *si = seg_info (now_seg);
-  struct insn_label_list *l;
-
   gas_assert (HAVE_CODE_COMPRESSION);
 
-  for (l = si->label_list; l != NULL; l = l->next)
-   {
-      symbolS *label = l->label;
-
 #if defined(OBJ_ELF) || defined(OBJ_MAYBE_ELF)
-      if (IS_ELF)
-       {
-         if (mips_opts.mips16)
-           S_SET_OTHER (label, ELF_ST_SET_MIPS16 (S_GET_OTHER (label)));
-         else
-           S_SET_OTHER (label, ELF_ST_SET_MICROMIPS (S_GET_OTHER (label)));
-       }
-#endif
-      if ((S_GET_VALUE (label) & 1) == 0
-       /* Don't adjust the address if the label is global or weak, or
-          in a link-once section, since we'll be emitting symbol reloc
-          references to it which will be patched up by the linker, and
-          the final value of the symbol may or may not be MIPS16/microMIPS.  */
-         && ! S_IS_WEAK (label)
-         && ! S_IS_EXTERNAL (label)
-         && ! s_is_linkonce (label, now_seg))
-       S_SET_VALUE (label, S_GET_VALUE (label) | 1);
+  if (IS_ELF)
+    {
+      if (mips_opts.mips16)
+       S_SET_OTHER (label, ELF_ST_SET_MIPS16 (S_GET_OTHER (label)));
+      else
+       S_SET_OTHER (label, ELF_ST_SET_MICROMIPS (S_GET_OTHER (label)));
     }
+#endif
+  if ((S_GET_VALUE (label) & 1) == 0
+      /* Don't adjust the address if the label is global or weak, or
+        in a link-once section, since we'll be emitting symbol reloc
+        references to it which will be patched up by the linker, and
+        the final value of the symbol may or may not be MIPS16/microMIPS.  */
+      && !S_IS_WEAK (label)
+      && !S_IS_EXTERNAL (label)
+      && !s_is_linkonce (label, now_seg))
+    S_SET_VALUE (label, S_GET_VALUE (label) | 1);
+}
+
+/* Mark preceding MIPS16 or microMIPS instruction labels.  */
+
+static void
+mips_compressed_mark_labels (void)
+{
+  struct insn_label_list *l;
+
+  for (l = seg_info (now_seg)->label_list; l != NULL; l = l->next)
+    mips_compressed_mark_label (l->label);
 }
 
 /* End the current frag.  Make it a variant frag and record the
@@ -4013,6 +4033,52 @@ micromips_map_reloc (bfd_reloc_code_real_type reloc)
   return reloc;
 }
 
+/* Try to resolve relocation RELOC against constant OPERAND at assembly time.
+   Return true on success, storing the resolved value in RESULT.  */
+
+static bfd_boolean
+calculate_reloc (bfd_reloc_code_real_type reloc, offsetT operand,
+                offsetT *result)
+{
+  switch (reloc)
+    {
+    case BFD_RELOC_MIPS_HIGHEST:
+    case BFD_RELOC_MICROMIPS_HIGHEST:
+      *result = ((operand + 0x800080008000ull) >> 48) & 0xffff;
+      return TRUE;
+
+    case BFD_RELOC_MIPS_HIGHER:
+    case BFD_RELOC_MICROMIPS_HIGHER:
+      *result = ((operand + 0x80008000ull) >> 32) & 0xffff;
+      return TRUE;
+
+    case BFD_RELOC_HI16_S:
+    case BFD_RELOC_MICROMIPS_HI16_S:
+    case BFD_RELOC_MIPS16_HI16_S:
+      *result = ((operand + 0x8000) >> 16) & 0xffff;
+      return TRUE;
+
+    case BFD_RELOC_HI16:
+    case BFD_RELOC_MICROMIPS_HI16:
+    case BFD_RELOC_MIPS16_HI16:
+      *result = (operand >> 16) & 0xffff;
+      return TRUE;
+
+    case BFD_RELOC_LO16:
+    case BFD_RELOC_MICROMIPS_LO16:
+    case BFD_RELOC_MIPS16_LO16:
+      *result = operand & 0xffff;
+      return TRUE;
+
+    case BFD_RELOC_UNUSED:
+      *result = operand;
+      return TRUE;
+
+    default:
+      return FALSE;
+    }
+}
+
 /* Output an instruction.  IP is the instruction information.
    ADDRESS_EXPR is an operand of the instruction to be used with
    RELOC_TYPE.  EXPANSIONP is true if the instruction is part of
@@ -4031,8 +4097,6 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
   if (mips_fix_loongson2f && !HAVE_CODE_COMPRESSION)
     fix_loongson2f (ip);
 
-  mips_mark_labels ();
-
   file_ase_mips16 |= mips_opts.mips16;
   file_ase_micromips |= mips_opts.micromips;
 
@@ -4050,43 +4114,13 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
 
   if (address_expr == NULL)
     ip->complete_p = 1;
-  else if (*reloc_type <= BFD_RELOC_UNUSED
+  else if (reloc_type[0] <= BFD_RELOC_UNUSED
+          && reloc_type[1] == BFD_RELOC_UNUSED
+          && reloc_type[2] == BFD_RELOC_UNUSED
           && address_expr->X_op == O_constant)
     {
-      unsigned int tmp;
-
-      ip->complete_p = 1;
       switch (*reloc_type)
        {
-       case BFD_RELOC_32:
-         ip->insn_opcode |= address_expr->X_add_number;
-         break;
-
-       case BFD_RELOC_MIPS_HIGHEST:
-         tmp = (address_expr->X_add_number + 0x800080008000ull) >> 48;
-         ip->insn_opcode |= tmp & 0xffff;
-         break;
-
-       case BFD_RELOC_MIPS_HIGHER:
-         tmp = (address_expr->X_add_number + 0x80008000ull) >> 32;
-         ip->insn_opcode |= tmp & 0xffff;
-         break;
-
-       case BFD_RELOC_HI16_S:
-         tmp = (address_expr->X_add_number + 0x8000) >> 16;
-         ip->insn_opcode |= tmp & 0xffff;
-         break;
-
-       case BFD_RELOC_HI16:
-         ip->insn_opcode |= (address_expr->X_add_number >> 16) & 0xffff;
-         break;
-
-       case BFD_RELOC_UNUSED:
-       case BFD_RELOC_LO16:
-       case BFD_RELOC_MIPS_GOT_DISP:
-         ip->insn_opcode |= address_expr->X_add_number & 0xffff;
-         break;
-
        case BFD_RELOC_MIPS_JMP:
          {
            int shift;
@@ -4097,7 +4131,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                      (unsigned long) address_expr->X_add_number);
            ip->insn_opcode |= ((address_expr->X_add_number >> shift)
                                & 0x3ffffff);
-           ip->complete_p = 0;
+           ip->complete_p = 1;
          }
          break;
 
@@ -4109,7 +4143,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
            (((address_expr->X_add_number & 0x7c0000) << 3)
               | ((address_expr->X_add_number & 0xf800000) >> 7)
               | ((address_expr->X_add_number & 0x3fffc) >> 2));
-         ip->complete_p = 0;
+         ip->complete_p = 1;
          break;
 
        case BFD_RELOC_16_PCREL_S2:
@@ -4129,13 +4163,22 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                ip->insn_opcode |= ((address_expr->X_add_number >> shift)
                                    & 0xffff);
              }
-           ip->complete_p = 0;
          }
          break;
 
        default:
-         internalError ();
-       }       
+         {
+           offsetT value;
+
+           if (calculate_reloc (*reloc_type, address_expr->X_add_number,
+                                &value))
+             {
+               ip->insn_opcode |= value & 0xffff;
+               ip->complete_p = 1;
+             }
+         }
+         break;
+       }
     }
 
   if (mips_relax.sequence != 2 && !mips_opts.noreorder)
@@ -4420,6 +4463,11 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
              || lo16_reloc_p (reloc_type[0])))
        ip->fixp[0]->fx_no_overflow = 1;
 
+      /* These relocations can have an addend that won't fit in 2 octets.  */
+      if (reloc_type[0] == BFD_RELOC_MICROMIPS_7_PCREL_S1
+         || reloc_type[0] == BFD_RELOC_MICROMIPS_10_PCREL_S1)
+       ip->fixp[0]->fx_no_overflow = 1;
+
       if (mips_relax.sequence)
        {
          if (mips_relax.first_fixup == 0)
@@ -5220,14 +5268,15 @@ mips16_macro_build (expressionS *ep, const char *name, const char *fmt,
        case 'p':
        case 'q':
          {
+           offsetT value;
+
            gas_assert (ep != NULL);
 
            if (ep->X_op != O_constant)
              *r = (int) BFD_RELOC_UNUSED + c;
-           else
+           else if (calculate_reloc (*r, ep->X_add_number, &value))
              {
-               mips16_immed (NULL, 0, c, *r, ep->X_add_number,
-                             0, &insn.insn_opcode);
+               mips16_immed (NULL, 0, c, *r, value, 0, &insn.insn_opcode);
                ep = NULL;
                *r = BFD_RELOC_UNUSED;
              }
@@ -5295,7 +5344,8 @@ macro_build_jalr (expressionS *ep, int cprestore)
   if (mips_opts.micromips)
     {
       jalr = mips_opts.noreorder && !cprestore ? "jalr" : "jalrs";
-      if (MIPS_JALR_HINT_P (ep))
+      if (MIPS_JALR_HINT_P (ep)
+         || (history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT))
        macro_build (NULL, jalr, "t,s", RA, PIC_CALL_REG);
       else
        macro_build (NULL, jalr, "mj", PIC_CALL_REG);
@@ -7735,7 +7785,9 @@ macro (struct mips_cl_insn *ip)
       if (mips_pic == NO_PIC)
        {
          s = jals ? "jalrs" : "jalr";
-         if (mips_opts.micromips && dreg == RA)
+         if (mips_opts.micromips
+             && dreg == RA
+             && !(history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT))
            macro_build (NULL, s, "mj", sreg);
          else
            macro_build (NULL, s, JALR_FMT, dreg, sreg);
@@ -7750,7 +7802,9 @@ macro (struct mips_cl_insn *ip)
 
          s = (mips_opts.micromips && (!mips_opts.noreorder || cprestore)
               ? "jalrs" : "jalr");
-         if (mips_opts.micromips && dreg == RA)
+         if (mips_opts.micromips
+             && dreg == RA
+             && !(history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT))
            macro_build (NULL, s, "mj", sreg);
          else
            macro_build (NULL, s, JALR_FMT, dreg, sreg);
@@ -13369,40 +13423,17 @@ mips16_ip (char *str, struct mips_cl_insn *ip)
            case '\0':
              if (*s == '\0')
                {
+                 offsetT value;
+
                  /* Stuff the immediate value in now, if we can.  */
                  if (imm_expr.X_op == O_constant
                      && *imm_reloc > BFD_RELOC_UNUSED
-                     && *imm_reloc != BFD_RELOC_MIPS16_GOT16
-                     && *imm_reloc != BFD_RELOC_MIPS16_CALL16
-                     && insn->pinfo != INSN_MACRO)
+                     && insn->pinfo != INSN_MACRO
+                     && calculate_reloc (*offset_reloc,
+                                         imm_expr.X_add_number, &value))
                    {
-                     valueT tmp;
-
-                     switch (*offset_reloc)
-                       {
-                         case BFD_RELOC_MIPS16_HI16_S:
-                           tmp = (imm_expr.X_add_number + 0x8000) >> 16;
-                           break;
-
-                         case BFD_RELOC_MIPS16_HI16:
-                           tmp = imm_expr.X_add_number >> 16;
-                           break;
-
-                         case BFD_RELOC_MIPS16_LO16:
-                           tmp = ((imm_expr.X_add_number + 0x8000) & 0xffff)
-                                 - 0x8000;
-                           break;
-
-                         case BFD_RELOC_UNUSED:
-                           tmp = imm_expr.X_add_number;
-                           break;
-
-                         default:
-                           internalError ();
-                       }
-
                      mips16_immed (NULL, 0, *imm_reloc - BFD_RELOC_UNUSED,
-                                   *offset_reloc, tmp, forced_insn_length,
+                                   *offset_reloc, value, forced_insn_length,
                                    &ip->insn_opcode);
                      imm_expr.X_op = O_absent;
                      *imm_reloc = BFD_RELOC_UNUSED;
@@ -13988,6 +14019,31 @@ static const struct mips16_immed_operand mips16_immed_operands[] =
 #define MIPS16_NUM_IMMED \
   (sizeof mips16_immed_operands / sizeof mips16_immed_operands[0])
 
+/* Marshal immediate value VAL for an extended MIPS16 instruction.
+   NBITS is the number of significant bits in VAL.  */
+
+static unsigned long
+mips16_immed_extend (offsetT val, unsigned int nbits)
+{
+  int extval;
+  if (nbits == 16)
+    {
+      extval = ((val >> 11) & 0x1f) | (val & 0x7e0);
+      val &= 0x1f;
+    }
+  else if (nbits == 15)
+    {
+      extval = ((val >> 11) & 0xf) | (val & 0x7f0);
+      val &= 0xf;
+    }
+  else
+    {
+      extval = ((val & 0x1f) << 6) | (val & 0x20);
+      val = 0;
+    }
+  return (extval << 16) | val;
+}
+
 /* Install immediate value VAL into MIPS16 instruction *INSN,
    extending it if necessary.  The instruction in *INSN may
    already be extended.
@@ -14071,7 +14127,6 @@ mips16_immed (char *file, unsigned int line, int type,
   else
     {
       long minext, maxext;
-      int extval;
 
       if (reloc == BFD_RELOC_UNUSED)
        {
@@ -14090,23 +14145,7 @@ mips16_immed (char *file, unsigned int line, int type,
                          _("operand value out of range for instruction"));
        }
 
-      if (op->extbits == 16)
-       {
-         extval = ((val >> 11) & 0x1f) | (val & 0x7e0);
-         val &= 0x1f;
-       }
-      else if (op->extbits == 15)
-       {
-         extval = ((val >> 11) & 0xf) | (val & 0x7f0);
-         val &= 0xf;
-       }
-      else
-       {
-         extval = ((val & 0x1f) << 6) | (val & 0x20);
-         val = 0;
-       }
-
-      *insn |= (extval << 16) | val;
+      *insn |= mips16_immed_extend (val, op->extbits);
     }
 }
 \f
@@ -15350,9 +15389,11 @@ mips_frob_file (void)
       gas_assert (reloc_needs_lo_p (l->fixp->fx_r_type));
 
       /* If a GOT16 relocation turns out to be against a global symbol,
-        there isn't supposed to be a matching LO.  */
+        there isn't supposed to be a matching LO.  Ignore %gots against
+        constants; we'll report an error for those later.  */
       if (got16_reloc_p (l->fixp->fx_r_type)
-         && !pic_need_relax (l->fixp->fx_addsy, l->seg))
+         && !(l->fixp->fx_addsy
+              && pic_need_relax (l->fixp->fx_addsy, l->seg)))
        continue;
 
       /* Check quickly whether the next fixup happens to be a matching %lo.  */
@@ -15410,9 +15451,6 @@ mips_frob_file (void)
     }
 }
 
-/* We may have combined relocations without symbols in the N32/N64 ABI.
-   We have to prevent gas from dropping them.  */
-
 int
 mips_force_relocation (fixS *fixp)
 {
@@ -15426,23 +15464,40 @@ mips_force_relocation (fixS *fixp)
       || fixp->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1)
     return 1;
 
-  if (HAVE_NEWABI
-      && S_GET_SEGMENT (fixp->fx_addsy) == bfd_abs_section_ptr
-      && (fixp->fx_r_type == BFD_RELOC_MIPS_SUB
-         || hi16_reloc_p (fixp->fx_r_type)
-         || lo16_reloc_p (fixp->fx_r_type)))
-    return 1;
-
   return 0;
 }
 
+/* Read the instruction associated with RELOC from BUF.  */
+
+static unsigned int
+read_reloc_insn (char *buf, bfd_reloc_code_real_type reloc)
+{
+  if (mips16_reloc_p (reloc) || micromips_reloc_p (reloc))
+    return read_compressed_insn (buf, 4);
+  else
+    return read_insn (buf);
+}
+
+/* Write instruction INSN to BUF, given that it has been relocated
+   by RELOC.  */
+
+static void
+write_reloc_insn (char *buf, bfd_reloc_code_real_type reloc,
+                 unsigned long insn)
+{
+  if (mips16_reloc_p (reloc) || micromips_reloc_p (reloc))
+    write_compressed_insn (buf, insn, 4);
+  else
+    write_insn (buf, insn);
+}
+
 /* Apply a fixup to the object file.  */
 
 void
 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 {
   char *buf;
-  long insn;
+  unsigned long insn;
   reloc_howto_type *howto;
 
   /* We ignore generic BFD relocations we don't know about.  */
@@ -15508,6 +15563,12 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_MIPS16_TLS_GOTTPREL:
     case BFD_RELOC_MIPS16_TLS_TPREL_HI16:
     case BFD_RELOC_MIPS16_TLS_TPREL_LO16:
+      if (!fixP->fx_addsy)
+       {
+         as_bad_where (fixP->fx_file, fixP->fx_line,
+                       _("TLS relocation against a constant"));
+         break;
+       }
       S_SET_THREAD_LOCAL (fixP->fx_addsy);
       /* fall through */
 
@@ -15529,6 +15590,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_MIPS_JALR:
     case BFD_RELOC_HI16:
     case BFD_RELOC_HI16_S:
+    case BFD_RELOC_LO16:
     case BFD_RELOC_GPREL16:
     case BFD_RELOC_MIPS_LITERAL:
     case BFD_RELOC_MIPS_CALL16:
@@ -15543,6 +15605,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_MIPS16_CALL16:
     case BFD_RELOC_MIPS16_HI16:
     case BFD_RELOC_MIPS16_HI16_S:
+    case BFD_RELOC_MIPS16_LO16:
     case BFD_RELOC_MIPS16_JMP:
     case BFD_RELOC_MICROMIPS_JMP:
     case BFD_RELOC_MICROMIPS_GOT_DISP:
@@ -15555,6 +15618,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_MICROMIPS_JALR:
     case BFD_RELOC_MICROMIPS_HI16:
     case BFD_RELOC_MICROMIPS_HI16_S:
+    case BFD_RELOC_MICROMIPS_LO16:
     case BFD_RELOC_MICROMIPS_GPREL16:
     case BFD_RELOC_MICROMIPS_LITERAL:
     case BFD_RELOC_MICROMIPS_CALL16:
@@ -15563,7 +15627,23 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_MICROMIPS_GOT_LO16:
     case BFD_RELOC_MICROMIPS_CALL_HI16:
     case BFD_RELOC_MICROMIPS_CALL_LO16:
-      /* Nothing needed to do.  The value comes from the reloc entry.  */
+      if (fixP->fx_done)
+       {
+         offsetT value;
+
+         if (calculate_reloc (fixP->fx_r_type, *valP, &value))
+           {
+             insn = read_reloc_insn (buf, fixP->fx_r_type);
+             if (mips16_reloc_p (fixP->fx_r_type))
+               insn |= mips16_immed_extend (value, 16);
+             else
+               insn |= (value & 0xffff);
+             write_reloc_insn (buf, fixP->fx_r_type, insn);
+           }
+         else
+           as_bad_where (fixP->fx_file, fixP->fx_line,
+                         _("Unsupported constant in relocation"));
+       }
       break;
 
     case BFD_RELOC_64:
@@ -15597,27 +15677,6 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
        md_number_to_chars (buf, *valP, fixP->fx_size);
       break;
 
-    case BFD_RELOC_LO16:
-    case BFD_RELOC_MIPS16_LO16:
-    case BFD_RELOC_MICROMIPS_LO16:
-      /* FIXME: Now that embedded-PIC is gone, some of this code/comment
-        may be safe to remove, but if so it's not obvious.  */
-      /* When handling an embedded PIC switch statement, we can wind
-        up deleting a LO16 reloc.  See the 'o' case in mips_ip.  */
-      if (fixP->fx_done)
-       {
-         if (*valP + 0x8000 > 0xffff)
-           as_bad_where (fixP->fx_file, fixP->fx_line,
-                         _("relocation overflow"));
-         /* 32-bit microMIPS instructions are divided into two halfwords.
-            Relocations always refer to the second halfword, regardless
-            of endianness.  */
-         if (target_big_endian || fixP->fx_r_type == BFD_RELOC_MICROMIPS_LO16)
-           buf += 2;
-         md_number_to_chars (buf, *valP, 2);
-       }
-      break;
-
     case BFD_RELOC_16_PCREL_S2:
       if ((*valP & 0x3) != 0)
        as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -18405,7 +18464,7 @@ mips_frob_file_after_relocs (void)
    move it.  This also bumps the value of the symbol by 1 in compressed
    code.  */
 
-void
+static void
 mips_record_label (symbolS *sym)
 {
   segment_info_type *si = seg_info (now_seg);
@@ -18435,6 +18494,17 @@ mips_define_label (symbolS *sym)
   dwarf2_emit_label (sym);
 #endif
 }
+
+/* This function is called by tc_new_dot_label whenever a new dot symbol
+   is defined.  */
+
+void
+mips_add_dot_label (symbolS *sym)
+{
+  mips_record_label (sym);
+  if (mips_assembling_insn && HAVE_CODE_COMPRESSION)
+    mips_compressed_mark_label (sym);
+}
 \f
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
 
This page took 0.037496 seconds and 4 git commands to generate.