/* 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:
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;
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'"),
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;
}
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);
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);
char *p;
char *nbuf;
- hash_delete (aarch64_reg_hsh, name, FALSE);
+ str_hash_delete (aarch64_reg_hsh, name);
free ((char *) reg->name);
free (reg);
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);
}
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
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++;
}
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;
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)
{
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;
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;
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
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
*/
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)
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;
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;
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;
{
templates *templ = NULL;
- templ = hash_find_n (aarch64_ops_hsh, start, len);
+ templ = str_hash_find_n (aarch64_ops_hsh, start, len);
return templ;
}
/* 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;
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,
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;
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"));
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;
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;
/* 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;
}
}
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
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;
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));
}
else
{
- if (destelf->size != NULL)
- free (destelf->size);
+ free (destelf->size);
destelf->size = NULL;
}
S_SET_SIZE (dest, S_GET_SIZE (src));