Rearrange symbol_create parameters
[deliverable/binutils-gdb.git] / gas / config / tc-aarch64.c
index 69ccc59e8744e0ba1b4bac75d78161684352d033..c7cae1abfec7ca86ddc3f196721b29ffea429777 100644 (file)
@@ -451,21 +451,21 @@ get_reg_expected_msg (aarch64_reg_type reg_type)
 /* Instructions take 4 bytes in the object file.  */
 #define INSN_SIZE      4
 
-static struct hash_control *aarch64_ops_hsh;
-static struct hash_control *aarch64_cond_hsh;
-static struct hash_control *aarch64_shift_hsh;
-static struct hash_control *aarch64_sys_regs_hsh;
-static struct hash_control *aarch64_pstatefield_hsh;
-static struct hash_control *aarch64_sys_regs_ic_hsh;
-static struct hash_control *aarch64_sys_regs_dc_hsh;
-static struct hash_control *aarch64_sys_regs_at_hsh;
-static struct hash_control *aarch64_sys_regs_tlbi_hsh;
-static struct hash_control *aarch64_sys_regs_sr_hsh;
-static struct hash_control *aarch64_reg_hsh;
-static struct hash_control *aarch64_barrier_opt_hsh;
-static struct hash_control *aarch64_nzcv_hsh;
-static struct hash_control *aarch64_pldop_hsh;
-static struct hash_control *aarch64_hint_opt_hsh;
+static htab_t aarch64_ops_hsh;
+static htab_t aarch64_cond_hsh;
+static htab_t aarch64_shift_hsh;
+static htab_t aarch64_sys_regs_hsh;
+static htab_t aarch64_pstatefield_hsh;
+static htab_t aarch64_sys_regs_ic_hsh;
+static htab_t aarch64_sys_regs_dc_hsh;
+static htab_t aarch64_sys_regs_at_hsh;
+static htab_t aarch64_sys_regs_tlbi_hsh;
+static htab_t aarch64_sys_regs_sr_hsh;
+static htab_t aarch64_reg_hsh;
+static htab_t aarch64_barrier_opt_hsh;
+static htab_t aarch64_nzcv_hsh;
+static htab_t aarch64_pldop_hsh;
+static htab_t aarch64_hint_opt_hsh;
 
 /* Stuff needed to resolve the label ambiguity
    As:
@@ -764,7 +764,7 @@ parse_reg (char **ccp)
     p++;
   while (ISALPHA (*p) || ISDIGIT (*p) || *p == '_');
 
-  reg = (reg_entry *) hash_find_n (aarch64_reg_hsh, start, p - start);
+  reg = (reg_entry *) str_hash_find_n (aarch64_reg_hsh, start, p - start);
 
   if (!reg)
     return NULL;
@@ -1315,7 +1315,7 @@ insert_reg_alias (char *str, int number, aarch64_reg_type type)
   reg_entry *new;
   const char *name;
 
-  if ((new = hash_find (aarch64_reg_hsh, str)) != 0)
+  if ((new = str_hash_find (aarch64_reg_hsh, str)) != 0)
     {
       if (new->builtin)
        as_warn (_("ignoring attempt to redefine built-in register '%s'"),
@@ -1337,8 +1337,7 @@ insert_reg_alias (char *str, int number, aarch64_reg_type type)
   new->type = type;
   new->builtin = FALSE;
 
-  if (hash_insert (aarch64_reg_hsh, name, (void *) new))
-    abort ();
+  str_hash_insert (aarch64_reg_hsh, name, (void *) new);
 
   return new;
 }
@@ -1367,7 +1366,7 @@ create_register_alias (char *newname, char *p)
   if (*oldname == '\0')
     return FALSE;
 
-  old = hash_find (aarch64_reg_hsh, oldname);
+  old = str_hash_find (aarch64_reg_hsh, oldname);
   if (!old)
     {
       as_warn (_("unknown register '%s' -- .req ignored"), oldname);
@@ -1456,7 +1455,7 @@ s_unreq (int a ATTRIBUTE_UNUSED)
     as_bad (_("invalid syntax for .unreq directive"));
   else
     {
-      reg_entry *reg = hash_find (aarch64_reg_hsh, name);
+      reg_entry *reg = str_hash_find (aarch64_reg_hsh, name);
 
       if (!reg)
        as_bad (_("unknown register alias '%s'"), name);
@@ -1468,7 +1467,7 @@ s_unreq (int a ATTRIBUTE_UNUSED)
          char *p;
          char *nbuf;
 
-         hash_delete (aarch64_reg_hsh, name, FALSE);
+         str_hash_delete (aarch64_reg_hsh, name);
          free ((char *) reg->name);
          free (reg);
 
@@ -1479,20 +1478,20 @@ s_unreq (int a ATTRIBUTE_UNUSED)
          nbuf = strdup (name);
          for (p = nbuf; *p; p++)
            *p = TOUPPER (*p);
-         reg = hash_find (aarch64_reg_hsh, nbuf);
+         reg = str_hash_find (aarch64_reg_hsh, nbuf);
          if (reg)
            {
-             hash_delete (aarch64_reg_hsh, nbuf, FALSE);
+             str_hash_delete (aarch64_reg_hsh, nbuf);
              free ((char *) reg->name);
              free (reg);
            }
 
          for (p = nbuf; *p; p++)
            *p = TOLOWER (*p);
-         reg = hash_find (aarch64_reg_hsh, nbuf);
+         reg = str_hash_find (aarch64_reg_hsh, nbuf);
          if (reg)
            {
-             hash_delete (aarch64_reg_hsh, nbuf, FALSE);
+             str_hash_delete (aarch64_reg_hsh, nbuf);
              free ((char *) reg->name);
              free (reg);
            }
@@ -1536,7 +1535,7 @@ make_mapping_symbol (enum mstate state, valueT value, fragS * frag)
       abort ();
     }
 
-  symbolP = symbol_new (symname, now_seg, value, frag);
+  symbolP = symbol_new (symname, now_seg, frag, value);
   symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
 
   /* Save the mapping symbols for future reference.  Also check that
@@ -1743,7 +1742,7 @@ find_or_make_literal_pool (int size)
   if (pool->symbol == NULL)
     {
       pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
-                                   (valueT) 0, &zero_address_frag);
+                                   &zero_address_frag, 0);
       pool->id = latest_pool_num++;
     }
 
@@ -2190,7 +2189,7 @@ reg_name_p (char *str, aarch64_reg_type reg_type)
     return FALSE;
 
   skip_whitespace (str);
-  if (*str == ',' || is_end_of_line[(unsigned int) *str])
+  if (*str == ',' || is_end_of_line[(unsigned char) *str])
     return TRUE;
 
   return FALSE;
@@ -3122,7 +3121,7 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode)
       return FALSE;
     }
 
-  shift_op = hash_find_n (aarch64_shift_hsh, *str, p - *str);
+  shift_op = str_hash_find_n (aarch64_shift_hsh, *str, p - *str);
 
   if (shift_op == NULL)
     {
@@ -3979,7 +3978,7 @@ parse_pldop (char **str)
   while (ISALNUM (*q))
     q++;
 
-  o = hash_find_n (aarch64_pldop_hsh, p, q - p);
+  o = str_hash_find_n (aarch64_pldop_hsh, p, q - p);
   if (!o)
     return PARSE_FAIL;
 
@@ -4000,7 +3999,7 @@ parse_barrier (char **str)
   while (ISALPHA (*q))
     q++;
 
-  o = hash_find_n (aarch64_barrier_opt_hsh, p, q - p);
+  o = str_hash_find_n (aarch64_barrier_opt_hsh, p, q - p);
   if (!o)
     return PARSE_FAIL;
 
@@ -4022,7 +4021,7 @@ parse_barrier_psb (char **str,
   while (ISALPHA (*q))
     q++;
 
-  o = hash_find_n (aarch64_hint_opt_hsh, p, q - p);
+  o = str_hash_find_n (aarch64_hint_opt_hsh, p, q - p);
   if (!o)
     {
       set_fatal_syntax_error
@@ -4057,7 +4056,7 @@ parse_bti_operand (char **str,
   while (ISALPHA (*q))
     q++;
 
-  o = hash_find_n (aarch64_hint_opt_hsh, p, q - p);
+  o = str_hash_find_n (aarch64_hint_opt_hsh, p, q - p);
   if (!o)
     {
       set_fatal_syntax_error
@@ -4095,24 +4094,28 @@ parse_bti_operand (char **str,
 */
 
 static int
-parse_sys_reg (char **str, struct hash_control *sys_regs,
+parse_sys_reg (char **str, htab_t sys_regs,
               int imple_defined_p, int pstatefield_p,
               uint32_t* flags)
 {
   char *p, *q;
-  char buf[32];
+  char buf[AARCH64_MAX_SYSREG_NAME_LEN];
   const aarch64_sys_reg *o;
   int value;
 
   p = buf;
   for (q = *str; ISALNUM (*q) || *q == '_'; q++)
-    if (p < buf + 31)
+    if (p < buf + (sizeof (buf) - 1))
       *p++ = TOLOWER (*q);
   *p = '\0';
-  /* Assert that BUF be large enough.  */
-  gas_assert (p - buf == q - *str);
 
-  o = hash_find (sys_regs, buf);
+  /* If the name is longer than AARCH64_MAX_SYSREG_NAME_LEN then it cannot be a
+     valid system register.  This is enforced by construction of the hash
+     table.  */
+  if (p - buf != q - *str)
+    return PARSE_FAIL;
+
+  o = str_hash_find (sys_regs, buf);
   if (!o)
     {
       if (!imple_defined_p)
@@ -4137,10 +4140,12 @@ parse_sys_reg (char **str, struct hash_control *sys_regs,
       if (pstatefield_p && !aarch64_pstatefield_supported_p (cpu_variant, o))
        as_bad (_("selected processor does not support PSTATE field "
                  "name '%s'"), buf);
-      if (!pstatefield_p && !aarch64_sys_reg_supported_p (cpu_variant, o))
+      if (!pstatefield_p
+         && !aarch64_sys_ins_reg_supported_p (cpu_variant, o->value,
+                                              o->flags, o->features))
        as_bad (_("selected processor does not support system register "
                  "name '%s'"), buf);
-      if (aarch64_sys_reg_deprecated_p (o))
+      if (aarch64_sys_reg_deprecated_p (o->flags))
        as_warn (_("system register name '%s' is deprecated and may be "
                   "removed in a future release"), buf);
       value = o->value;
@@ -4156,25 +4161,34 @@ parse_sys_reg (char **str, struct hash_control *sys_regs,
    for the option, or NULL.  */
 
 static const aarch64_sys_ins_reg *
-parse_sys_ins_reg (char **str, struct hash_control *sys_ins_regs)
+parse_sys_ins_reg (char **str, htab_t sys_ins_regs)
 {
   char *p, *q;
-  char buf[32];
+  char buf[AARCH64_MAX_SYSREG_NAME_LEN];
   const aarch64_sys_ins_reg *o;
 
   p = buf;
   for (q = *str; ISALNUM (*q) || *q == '_'; q++)
-    if (p < buf + 31)
+    if (p < buf + (sizeof (buf) - 1))
       *p++ = TOLOWER (*q);
   *p = '\0';
 
-  o = hash_find (sys_ins_regs, buf);
+  /* If the name is longer than AARCH64_MAX_SYSREG_NAME_LEN then it cannot be a
+     valid system register.  This is enforced by construction of the hash
+     table.  */
+  if (p - buf != q - *str)
+    return NULL;
+
+  o = str_hash_find (sys_ins_regs, buf);
   if (!o)
     return NULL;
 
-  if (!aarch64_sys_ins_reg_supported_p (cpu_variant, o))
+  if (!aarch64_sys_ins_reg_supported_p (cpu_variant, o->value, o->flags, 0))
     as_bad (_("selected processor does not support system register "
              "name '%s'"), buf);
+  if (aarch64_sys_reg_deprecated_p (o->flags))
+    as_warn (_("system register name '%s' is deprecated and may be "
+          "removed in a future release"), buf);
 
   *str = q;
   return o;
@@ -4328,7 +4342,10 @@ reencode_movzn_to_movn (uint32_t opcode)
 static fixS *
 fix_new_aarch64 (fragS * frag,
                 int where,
-                short int size, expressionS * exp, int pc_rel, int reloc)
+                short int size,
+                expressionS * exp,
+                int pc_rel,
+                int reloc)
 {
   fixS *new_fix;
 
@@ -5078,7 +5095,7 @@ lookup_mnemonic (const char *start, int len)
 {
   templates *templ = NULL;
 
-  templ = hash_find_n (aarch64_ops_hsh, start, len);
+  templ = str_hash_find_n (aarch64_ops_hsh, start, len);
   return templ;
 }
 
@@ -5109,7 +5126,7 @@ opcode_lookup (char **str)
   /* Handle a possible condition.  */
   if (dot)
     {
-      cond = hash_find_n (aarch64_cond_hsh, dot + 1, end - dot - 1);
+      cond = str_hash_find_n (aarch64_cond_hsh, dot + 1, end - dot - 1);
       if (cond)
        {
          inst.cond = cond->value;
@@ -6149,6 +6166,7 @@ parse_operands (char *str, const aarch64_opcode *opcode)
          break;
 
        case AARCH64_OPND_EXCEPTION:
+       case AARCH64_OPND_UNDEFINED:
          po_misc_or_fail (parse_immediate_expression (&str, &inst.reloc.exp,
                                                       imm_reg_type));
          assign_imm_if_const_or_fixup_later (&inst.reloc, info,
@@ -6159,7 +6177,7 @@ parse_operands (char *str, const aarch64_opcode *opcode)
 
        case AARCH64_OPND_NZCV:
          {
-           const asm_nzcv *nzcv = hash_find_n (aarch64_nzcv_hsh, str, 4);
+           const asm_nzcv *nzcv = str_hash_find_n (aarch64_nzcv_hsh, str, 4);
            if (nzcv != NULL)
              {
                str += 4;
@@ -6178,7 +6196,7 @@ parse_operands (char *str, const aarch64_opcode *opcode)
            do
              str++;
            while (ISALPHA (*str));
-           info->cond = hash_find_n (aarch64_cond_hsh, start, str - start);
+           info->cond = str_hash_find_n (aarch64_cond_hsh, start, str - start);
            if (info->cond == NULL)
              {
                set_syntax_error (_("invalid condition"));
@@ -7544,7 +7562,7 @@ md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
            as_bad (_("GOT already in the symbol table"));
 
          GOT_symbol = symbol_new (name, undefined_section,
-                                  (valueT) 0, &zero_address_frag);
+                                  &zero_address_frag, 0);
        }
 
       return GOT_symbol;
@@ -7745,11 +7763,12 @@ fix_insn (fixS *fixP, uint32_t flags, offsetT value)
   switch (opnd)
     {
     case AARCH64_OPND_EXCEPTION:
+    case AARCH64_OPND_UNDEFINED:
       if (unsigned_overflow (value, 16))
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("immediate out of range"));
       insn = get_aarch64_insn (buf);
-      insn |= encode_svc_imm (value);
+      insn |= (opnd == AARCH64_OPND_EXCEPTION) ? encode_svc_imm (value) : value;
       put_aarch64_insn (buf, insn);
       break;
 
@@ -8267,8 +8286,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
   /* Free the allocated the struct aarch64_inst.
      N.B. currently there are very limited number of fix-up types actually use
      this field, so the impact on the performance should be minimal .  */
-  if (fixP->tc_fix_data.inst != NULL)
-    free (fixP->tc_fix_data.inst);
+  free (fixP->tc_fix_data.inst);
 
   return;
 }
@@ -8602,13 +8620,16 @@ aarch64_adjust_symtab (void)
 }
 
 static void
-checked_hash_insert (struct hash_control *table, const char *key, void *value)
+checked_hash_insert (htab_t table, const char *key, void *value)
 {
-  const char *hash_err;
+  str_hash_insert (table, key, value);
+}
 
-  hash_err = hash_insert (table, key, value);
-  if (hash_err)
-    printf ("Internal Error:  Can't hash %s\n", key);
+static void
+sysreg_hash_insert (htab_t table, const char *key, void *value)
+{
+  gas_assert (strlen (key) < AARCH64_MAX_SYSREG_NAME_LEN);
+  checked_hash_insert (table, key, value);
 }
 
 static void
@@ -8619,7 +8640,7 @@ fill_instruction_hash_table (void)
   while (opcode->name != NULL)
     {
       templates *templ, *new_templ;
-      templ = hash_find (aarch64_ops_hsh, opcode->name);
+      templ = str_hash_find (aarch64_ops_hsh, opcode->name);
 
       new_templ = XNEW (templates);
       new_templ->opcode = opcode;
@@ -8665,56 +8686,56 @@ md_begin (void)
   unsigned mach;
   unsigned int i;
 
-  if ((aarch64_ops_hsh = hash_new ()) == NULL
-      || (aarch64_cond_hsh = hash_new ()) == NULL
-      || (aarch64_shift_hsh = hash_new ()) == NULL
-      || (aarch64_sys_regs_hsh = hash_new ()) == NULL
-      || (aarch64_pstatefield_hsh = hash_new ()) == NULL
-      || (aarch64_sys_regs_ic_hsh = hash_new ()) == NULL
-      || (aarch64_sys_regs_dc_hsh = hash_new ()) == NULL
-      || (aarch64_sys_regs_at_hsh = hash_new ()) == NULL
-      || (aarch64_sys_regs_tlbi_hsh = hash_new ()) == NULL
-      || (aarch64_sys_regs_sr_hsh = hash_new ()) == NULL
-      || (aarch64_reg_hsh = hash_new ()) == NULL
-      || (aarch64_barrier_opt_hsh = hash_new ()) == NULL
-      || (aarch64_nzcv_hsh = hash_new ()) == NULL
-      || (aarch64_pldop_hsh = hash_new ()) == NULL
-      || (aarch64_hint_opt_hsh = hash_new ()) == NULL)
+  if ((aarch64_ops_hsh = str_htab_create ()) == NULL
+      || (aarch64_cond_hsh = str_htab_create ()) == NULL
+      || (aarch64_shift_hsh = str_htab_create ()) == NULL
+      || (aarch64_sys_regs_hsh = str_htab_create ()) == NULL
+      || (aarch64_pstatefield_hsh = str_htab_create ()) == NULL
+      || (aarch64_sys_regs_ic_hsh = str_htab_create ()) == NULL
+      || (aarch64_sys_regs_dc_hsh = str_htab_create ()) == NULL
+      || (aarch64_sys_regs_at_hsh = str_htab_create ()) == NULL
+      || (aarch64_sys_regs_tlbi_hsh = str_htab_create ()) == NULL
+      || (aarch64_sys_regs_sr_hsh = str_htab_create ()) == NULL
+      || (aarch64_reg_hsh = str_htab_create ()) == NULL
+      || (aarch64_barrier_opt_hsh = str_htab_create ()) == NULL
+      || (aarch64_nzcv_hsh = str_htab_create ()) == NULL
+      || (aarch64_pldop_hsh = str_htab_create ()) == NULL
+      || (aarch64_hint_opt_hsh = str_htab_create ()) == NULL)
     as_fatal (_("virtual memory exhausted"));
 
   fill_instruction_hash_table ();
 
   for (i = 0; aarch64_sys_regs[i].name != NULL; ++i)
-    checked_hash_insert (aarch64_sys_regs_hsh, aarch64_sys_regs[i].name,
+    sysreg_hash_insert (aarch64_sys_regs_hsh, aarch64_sys_regs[i].name,
                         (void *) (aarch64_sys_regs + i));
 
   for (i = 0; aarch64_pstatefields[i].name != NULL; ++i)
-    checked_hash_insert (aarch64_pstatefield_hsh,
+    sysreg_hash_insert (aarch64_pstatefield_hsh,
                         aarch64_pstatefields[i].name,
                         (void *) (aarch64_pstatefields + i));
 
   for (i = 0; aarch64_sys_regs_ic[i].name != NULL; i++)
-    checked_hash_insert (aarch64_sys_regs_ic_hsh,
+    sysreg_hash_insert (aarch64_sys_regs_ic_hsh,
                         aarch64_sys_regs_ic[i].name,
                         (void *) (aarch64_sys_regs_ic + i));
 
   for (i = 0; aarch64_sys_regs_dc[i].name != NULL; i++)
-    checked_hash_insert (aarch64_sys_regs_dc_hsh,
+    sysreg_hash_insert (aarch64_sys_regs_dc_hsh,
                         aarch64_sys_regs_dc[i].name,
                         (void *) (aarch64_sys_regs_dc + i));
 
   for (i = 0; aarch64_sys_regs_at[i].name != NULL; i++)
-    checked_hash_insert (aarch64_sys_regs_at_hsh,
+    sysreg_hash_insert (aarch64_sys_regs_at_hsh,
                         aarch64_sys_regs_at[i].name,
                         (void *) (aarch64_sys_regs_at + i));
 
   for (i = 0; aarch64_sys_regs_tlbi[i].name != NULL; i++)
-    checked_hash_insert (aarch64_sys_regs_tlbi_hsh,
+    sysreg_hash_insert (aarch64_sys_regs_tlbi_hsh,
                         aarch64_sys_regs_tlbi[i].name,
                         (void *) (aarch64_sys_regs_tlbi + i));
 
   for (i = 0; aarch64_sys_regs_sr[i].name != NULL; i++)
-    checked_hash_insert (aarch64_sys_regs_sr_hsh,
+    sysreg_hash_insert (aarch64_sys_regs_sr_hsh,
                         aarch64_sys_regs_sr[i].name,
                         (void *) (aarch64_sys_regs_sr + i));
 
@@ -9555,8 +9576,7 @@ aarch64_elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
     }
   else
     {
-      if (destelf->size != NULL)
-       free (destelf->size);
+      free (destelf->size);
       destelf->size = NULL;
     }
   S_SET_SIZE (dest, S_GET_SIZE (src));
This page took 0.031773 seconds and 4 git commands to generate.