Rearrange symbol_create parameters
[deliverable/binutils-gdb.git] / gas / config / tc-mips.c
index 6244d8ac091c562ddb5fdcf8611095d2790a343b..ebcc633dd81aaf0cc573570c8d252718e0b0f6d5 100644 (file)
@@ -675,13 +675,13 @@ static int g_switch_seen = 0;
 static int nopic_need_relax (symbolS *, int);
 
 /* Handle of the OPCODE hash table.  */
-static struct hash_control *op_hash = NULL;
+static htab_t op_hash = NULL;
 
 /* The opcode hash table we use for the mips16.  */
-static struct hash_control *mips16_op_hash = NULL;
+static htab_t mips16_op_hash = NULL;
 
 /* The opcode hash table we use for the microMIPS ASE.  */
-static struct hash_control *micromips_op_hash = NULL;
+static htab_t micromips_op_hash = NULL;
 
 /* This array holds the chars that always start a comment.  If the
     pre-processor is disabled, these aren't very useful.  */
@@ -812,6 +812,9 @@ static int mips_debug = 0;
    fill a branch delay slot.  */
 static struct mips_cl_insn history[1 + MAX_NOPS + MAX_LLSC_RANGE];
 
+/* The maximum number of LABELS detect for the same address.  */
+#define MAX_LABELS_SAME 10
+
 /* Arrays of operands for each instruction.  */
 #define MAX_OPERANDS 6
 struct mips_operand_array
@@ -886,11 +889,6 @@ struct mips_hi_fixup
 
 static struct mips_hi_fixup *mips_hi_fixup_list;
 
-/* The frag containing the last explicit relocation operator.
-   Null if explicit relocations have not been used.  */
-
-static fragS *prev_reloc_op_frag;
-
 /* Map mips16 register numbers to normal MIPS register numbers.  */
 
 static const unsigned int mips16_to_32_reg_map[] =
@@ -3670,7 +3668,6 @@ validate_micromips_insn (const struct mips_opcode *opc,
 void
 md_begin (void)
 {
-  const char *retval = NULL;
   int i = 0;
   int broken = 0;
 
@@ -3690,21 +3687,14 @@ md_begin (void)
   if (! bfd_set_arch_mach (stdoutput, bfd_arch_mips, file_mips_opts.arch))
     as_warn (_("could not set architecture and machine"));
 
-  op_hash = hash_new ();
+  op_hash = str_htab_create ();
 
   mips_operands = XCNEWVEC (struct mips_operand_array, NUMOPCODES);
   for (i = 0; i < NUMOPCODES;)
     {
       const char *name = mips_opcodes[i].name;
 
-      retval = hash_insert (op_hash, name, (void *) &mips_opcodes[i]);
-      if (retval != NULL)
-       {
-         fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
-                  mips_opcodes[i].name, retval);
-         /* Probably a memory allocation problem?  Give up now.  */
-         as_fatal (_("broken assembler, no assembly attempted"));
-       }
+      str_hash_insert (op_hash, name, (void *) &mips_opcodes[i]);
       do
        {
          if (!validate_mips_insn (&mips_opcodes[i], 0xffffffff,
@@ -3727,7 +3717,7 @@ md_begin (void)
       while ((i < NUMOPCODES) && !strcmp (mips_opcodes[i].name, name));
     }
 
-  mips16_op_hash = hash_new ();
+  mips16_op_hash = str_htab_create ();
   mips16_operands = XCNEWVEC (struct mips_operand_array,
                              bfd_mips16_num_opcodes);
 
@@ -3736,10 +3726,7 @@ md_begin (void)
     {
       const char *name = mips16_opcodes[i].name;
 
-      retval = hash_insert (mips16_op_hash, name, (void *) &mips16_opcodes[i]);
-      if (retval != NULL)
-       as_fatal (_("internal: can't hash `%s': %s"),
-                 mips16_opcodes[i].name, retval);
+      str_hash_insert (mips16_op_hash, name, (void *) &mips16_opcodes[i]);
       do
        {
          if (!validate_mips16_insn (&mips16_opcodes[i], &mips16_operands[i]))
@@ -3755,7 +3742,7 @@ md_begin (void)
             && strcmp (mips16_opcodes[i].name, name) == 0);
     }
 
-  micromips_op_hash = hash_new ();
+  micromips_op_hash = str_htab_create ();
   micromips_operands = XCNEWVEC (struct mips_operand_array,
                                 bfd_micromips_num_opcodes);
 
@@ -3764,11 +3751,8 @@ md_begin (void)
     {
       const char *name = micromips_opcodes[i].name;
 
-      retval = hash_insert (micromips_op_hash, name,
+      str_hash_insert (micromips_op_hash, name,
                            (void *) &micromips_opcodes[i]);
-      if (retval != NULL)
-       as_fatal (_("internal: can't hash `%s': %s"),
-                 micromips_opcodes[i].name, retval);
       do
        {
          struct mips_cl_insn *micromips_nop_insn;
@@ -3805,18 +3789,18 @@ md_begin (void)
      helps us detect invalid uses of them.  */
   for (i = 0; reg_names[i].name; i++)
     symbol_table_insert (symbol_new (reg_names[i].name, reg_section,
-                                    reg_names[i].num, /* & RNUM_MASK, */
-                                    &zero_address_frag));
+                                    &zero_address_frag,
+                                    reg_names[i].num));
   if (HAVE_NEWABI)
     for (i = 0; reg_names_n32n64[i].name; i++)
       symbol_table_insert (symbol_new (reg_names_n32n64[i].name, reg_section,
-                                      reg_names_n32n64[i].num, /* & RNUM_MASK, */
-                                      &zero_address_frag));
+                                      &zero_address_frag,
+                                      reg_names_n32n64[i].num));
   else
     for (i = 0; reg_names_o32[i].name; i++)
       symbol_table_insert (symbol_new (reg_names_o32[i].name, reg_section,
-                                      reg_names_o32[i].num, /* & RNUM_MASK, */
-                                      &zero_address_frag));
+                                      &zero_address_frag,
+                                      reg_names_o32[i].num));
 
   for (i = 0; i < 32; i++)
     {
@@ -3825,17 +3809,17 @@ md_begin (void)
       /* R5900 VU0 floating-point register.  */
       sprintf (regname, "$vf%d", i);
       symbol_table_insert (symbol_new (regname, reg_section,
-                                      RTYPE_VF | i, &zero_address_frag));
+                                      &zero_address_frag, RTYPE_VF | i));
 
       /* R5900 VU0 integer register.  */
       sprintf (regname, "$vi%d", i);
       symbol_table_insert (symbol_new (regname, reg_section,
-                                      RTYPE_VI | i, &zero_address_frag));
+                                      &zero_address_frag, RTYPE_VI | i));
 
       /* MSA register.  */
       sprintf (regname, "$w%d", i);
       symbol_table_insert (symbol_new (regname, reg_section,
-                                      RTYPE_MSA | i, &zero_address_frag));
+                                      &zero_address_frag, RTYPE_MSA | i));
     }
 
   obstack_init (&mips_operand_tokens);
@@ -4775,7 +4759,7 @@ gpr_read_mask (const struct mips_cl_insn *ip)
   if (pinfo2 & INSN2_READ_SP)
     mask |= 1 << SP;
   if (pinfo2 & INSN2_READ_GPR_31)
-    mask |= 1 << 31;
+    mask |= 1u << 31;
   /* Don't include register 0.  */
   return mask & ~1;
 }
@@ -4794,7 +4778,7 @@ gpr_write_mask (const struct mips_cl_insn *ip)
   if (pinfo & INSN_WRITE_GPR_24)
     mask |= 1 << 24;
   if (pinfo & INSN_WRITE_GPR_31)
-    mask |= 1 << 31;
+    mask |= 1u << 31;
   if (pinfo & INSN_UDI)
     /* UDI instructions have traditionally been assumed to write to RD.  */
     mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RD, *ip);
@@ -6901,7 +6885,21 @@ fix_loongson2f (struct mips_cl_insn * ip)
     fix_loongson2f_jump (ip);
 }
 
-/* Fix loongson3 llsc errata: Insert sync before ll/lld. */
+static bfd_boolean
+has_label_name (const char *arr[], size_t len ,const char *s)
+{
+  unsigned long i;
+  for (i = 0; i < len; i++)
+    {
+      if (!arr[i])
+       return FALSE;
+      if (streq (arr[i], s))
+       return TRUE;
+    }
+  return FALSE;
+}
+
+/* Fix loongson3 llsc errata: Insert sync before ll/lld.  */
 
 static void
 fix_loongson3_llsc (struct mips_cl_insn * ip)
@@ -6915,10 +6913,30 @@ fix_loongson3_llsc (struct mips_cl_insn * ip)
       && S_IS_LOCAL (seg_info (now_seg)->label_list->label)
       && (strcmp (ip->insn_mo->name, "sync") != 0))
     {
-      const char *label_name = S_GET_NAME (seg_info (now_seg)->label_list->label);
-      unsigned long lookback = ARRAY_SIZE (history);
       unsigned long i;
+      valueT label_value;
+      const char *label_names[MAX_LABELS_SAME];
+      const char *label_name;
+
+      label_name = S_GET_NAME (seg_info (now_seg)->label_list->label);
+      label_names[0] = label_name;
+      struct insn_label_list *llist = seg_info (now_seg)->label_list;
+      label_value = S_GET_VALUE (llist->label);
+
+      for (i = 1; i < MAX_LABELS_SAME; i++)
+       {
+         llist = llist->next;
+         if (!llist)
+           break;
+         if (S_GET_VALUE (llist->label) == label_value)
+           label_names[i] = S_GET_NAME (llist->label);
+         else
+           break;
+       }
+      for (; i < MAX_LABELS_SAME; i++)
+       label_names[i] = NULL;
 
+      unsigned long lookback = ARRAY_SIZE (history);
       for (i = 0; i < lookback; i++)
        {
          if (streq (history[i].insn_mo->name, "ll")
@@ -6938,7 +6956,9 @@ fix_loongson3_llsc (struct mips_cl_insn * ip)
 
                  if (delayed_branch_p (&history[j]))
                    {
-                     if (streq (history[j].target, label_name))
+                     if (has_label_name (label_names,
+                                         MAX_LABELS_SAME,
+                                         history[j].target))
                        {
                          add_fixed_insn (&sync_insn);
                          insert_into_history (0, 1, &sync_insn);
@@ -6952,7 +6972,7 @@ fix_loongson3_llsc (struct mips_cl_insn * ip)
     }
   /* If we find a sc, we look forward to look for an branch insn,
      and see whether it jump back and out of ll/sc.  */
-  else if (streq(ip->insn_mo->name, "sc") || streq(ip->insn_mo->name, "scd"))
+  else if (streq (ip->insn_mo->name, "sc") || streq (ip->insn_mo->name, "scd"))
     {
       unsigned long lookback = ARRAY_SIZE (history) - 1;
       unsigned long i;
@@ -8988,7 +9008,7 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
   bfd_reloc_code_real_type r[3];
   const struct mips_opcode *amo;
   const struct mips_operand *operand;
-  struct hash_control *hash;
+  htab_t hash;
   struct mips_cl_insn insn;
   va_list args;
   unsigned int uval;
@@ -9006,7 +9026,7 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
   r[1] = BFD_RELOC_UNUSED;
   r[2] = BFD_RELOC_UNUSED;
   hash = mips_opts.micromips ? micromips_op_hash : op_hash;
-  amo = (struct mips_opcode *) hash_find (hash, name);
+  amo = (struct mips_opcode *) str_hash_find (hash, name);
   gas_assert (amo);
   gas_assert (strcmp (name, amo->name) == 0);
 
@@ -9164,7 +9184,7 @@ mips16_macro_build (expressionS *ep, const char *name, const char *fmt,
   bfd_reloc_code_real_type r[3]
     = {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
 
-  mo = (struct mips_opcode *) hash_find (mips16_op_hash, name);
+  mo = (struct mips_opcode *) str_hash_find (mips16_op_hash, name);
   gas_assert (mo);
   gas_assert (strcmp (name, mo->name) == 0);
 
@@ -14224,7 +14244,7 @@ mips16_macro (struct mips_cl_insn *ip)
    opcode bits in *OPCODE_EXTRA.  */
 
 static struct mips_opcode *
-mips_lookup_insn (struct hash_control *hash, const char *start,
+mips_lookup_insn (htab_t hash, const char *start,
                  ssize_t length, unsigned int *opcode_extra)
 {
   char *name, *dot, *p;
@@ -14236,7 +14256,7 @@ mips_lookup_insn (struct hash_control *hash, const char *start,
   name = xstrndup (start, length);
 
   /* Look up the instruction as-is.  */
-  insn = (struct mips_opcode *) hash_find (hash, name);
+  insn = (struct mips_opcode *) str_hash_find (hash, name);
   if (insn)
     goto end;
 
@@ -14248,7 +14268,7 @@ mips_lookup_insn (struct hash_control *hash, const char *start,
       if (*p == 0 && mask != 0)
        {
          *dot = 0;
-         insn = (struct mips_opcode *) hash_find (hash, name);
+         insn = (struct mips_opcode *) str_hash_find (hash, name);
          *dot = '.';
          if (insn && (insn->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX) != 0)
            {
@@ -14274,7 +14294,7 @@ mips_lookup_insn (struct hash_control *hash, const char *start,
       if (suffix)
        {
          memmove (name + opend - 2, name + opend, length - opend + 1);
-         insn = (struct mips_opcode *) hash_find (hash, name);
+         insn = (struct mips_opcode *) str_hash_find (hash, name);
          if (insn)
            {
              forced_insn_length = suffix;
@@ -14299,7 +14319,7 @@ static void
 mips_ip (char *str, struct mips_cl_insn *insn)
 {
   const struct mips_opcode *first, *past;
-  struct hash_control *hash;
+  htab_t hash;
   char format;
   size_t end;
   struct mips_operand_token *tokens;
@@ -14395,7 +14415,7 @@ mips16_ip (char *str, struct mips_cl_insn *insn)
   forced_insn_length = l;
 
   *end = 0;
-  first = (struct mips_opcode *) hash_find (mips16_op_hash, str);
+  first = (struct mips_opcode *) str_hash_find (mips16_op_hash, str);
   *end = c;
 
   if (!first)
@@ -14681,12 +14701,8 @@ my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
 
   expr_end = str;
 
-  if (reloc_index != 0)
-    {
-      prev_reloc_op_frag = frag_now;
-      for (i = 0; i < reloc_index; i++)
-       reloc[i] = reversed_reloc[reloc_index - 1 - i];
-    }
+  for (i = 0; i < reloc_index; i++)
+    reloc[i] = reversed_reloc[reloc_index - 1 - i];
 
   return reloc_index;
 }
@@ -16326,8 +16342,8 @@ s_change_sec (int sec)
 
     case 's':
       seg = subseg_new (".sdata", (subsegT) get_absolute_expression ());
-      bfd_set_section_flags (seg,
-                            SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA);
+      bfd_set_section_flags (seg, (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+                                  | SEC_DATA | SEC_SMALL_DATA));
       if (strncmp (TARGET_OS, "elf", 3) != 0)
        record_alignment (seg, 4);
       demand_empty_rest_of_line ();
@@ -16335,7 +16351,7 @@ s_change_sec (int sec)
 
     case 'B':
       seg = subseg_new (".sbss", (subsegT) get_absolute_expression ());
-      bfd_set_section_flags (seg, SEC_ALLOC);
+      bfd_set_section_flags (seg, SEC_ALLOC | SEC_SMALL_DATA);
       if (strncmp (TARGET_OS, "elf", 3) != 0)
        record_alignment (seg, 4);
       demand_empty_rest_of_line ();
@@ -18860,7 +18876,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
            }
 
          /* Make a label at the end for use with the branch.  */
-         l = symbol_new (micromips_label_name (), asec, fragp->fr_fix, fragp);
+         l = symbol_new (micromips_label_name (), asec, fragp, fragp->fr_fix);
          micromips_label_inc ();
          S_SET_OTHER (l, ELF_ST_SET_MICROMIPS (S_GET_OTHER (l)));
 
This page took 0.032496 seconds and 4 git commands to generate.