/* Altera Nios II assembler.
- Copyright (C) 2012-2017 Free Software Foundation, Inc.
+ Copyright (C) 2012-2020 Free Software Foundation, Inc.
Contributed by Nigel Gray (ngray@altera.com).
Contributed by Mentor Graphics, Inc.
} nios2_ps_insn_infoS;
/* Opcode hash table. */
-static struct hash_control *nios2_opcode_hash = NULL;
+static htab_t nios2_opcode_hash = NULL;
#define nios2_opcode_lookup(NAME) \
- ((struct nios2_opcode *) hash_find (nios2_opcode_hash, (NAME)))
+ ((struct nios2_opcode *) str_hash_find (nios2_opcode_hash, (NAME)))
/* Register hash table. */
-static struct hash_control *nios2_reg_hash = NULL;
+static htab_t nios2_reg_hash = NULL;
#define nios2_reg_lookup(NAME) \
- ((struct nios2_reg *) hash_find (nios2_reg_hash, (NAME)))
+ ((struct nios2_reg *) str_hash_find (nios2_reg_hash, (NAME)))
/* Pseudo-op hash table. */
-static struct hash_control *nios2_ps_hash = NULL;
+static htab_t nios2_ps_hash = NULL;
#define nios2_ps_lookup(NAME) \
- ((nios2_ps_insn_infoS *) hash_find (nios2_ps_hash, (NAME)))
+ ((nios2_ps_insn_infoS *) str_hash_find (nios2_ps_hash, (NAME)))
/* The known current alignment of the current section. */
static int nios2_current_align;
nios2_diagnose_overflow (fixup, howto, fixP, value);
/* Apply the right shift. */
- fixup = ((signed)fixup) >> howto->rightshift;
+ fixup = (offsetT) fixup >> howto->rightshift;
/* Truncate the fixup to right size. */
switch (fixP->fx_r_type)
fixup = fixup & 0xFFFF;
break;
case BFD_RELOC_NIOS2_HIADJ16:
- fixup = ((((fixup >> 16) & 0xFFFF) + ((fixup >> 15) & 0x01))
- & 0xFFFF);
+ fixup = ((fixup + 0x8000) >> 16) & 0xFFFF;
break;
default:
{
- int n = sizeof (fixup) * 8 - howto->bitsize;
- fixup = (fixup << n) >> n;
+ fixup &= ((valueT) 1 << howto->bitsize) - 1;
break;
}
}
mask = (reglist & 0x00ffc000) >> 14;
if (reglist & (1 << 28))
mask |= 1 << 10;
- if (reglist & (1 << 31))
+ if (reglist & (1u << 31))
mask |= 1 << 11;
}
insn->insn_code |= SET_IW_F1X4L17_REGMASK (mask);
static void
nios2_free_arg (char **parsed_args, int num ATTRIBUTE_UNUSED, int start)
{
- if (parsed_args[start])
- {
- free (parsed_args[start]);
- parsed_args[start] = NULL;
- }
+ free (parsed_args[start]);
+ parsed_args[start] = NULL;
}
/* This function swaps the pseudo-op for a real op. */
md_begin (void)
{
int i;
- const char *inserted;
switch (nios2_architecture)
{
/* Create and fill a hashtable for the Nios II opcodes, registers and
arguments. */
- nios2_opcode_hash = hash_new ();
- nios2_reg_hash = hash_new ();
- nios2_ps_hash = hash_new ();
+ nios2_opcode_hash = str_htab_create ();
+ nios2_reg_hash = str_htab_create ();
+ nios2_ps_hash = str_htab_create ();
for (i = 0; i < nios2_num_opcodes; ++i)
- {
- inserted
- = hash_insert (nios2_opcode_hash, nios2_opcodes[i].name,
- (PTR) & nios2_opcodes[i]);
- if (inserted != NULL)
- {
- fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
- nios2_opcodes[i].name, inserted);
- /* Probably a memory allocation problem? Give up now. */
- as_fatal (_("Broken assembler. No assembly attempted."));
- }
- }
+ str_hash_insert (nios2_opcode_hash, nios2_opcodes[i].name,
+ (PTR) & nios2_opcodes[i]);
for (i = 0; i < nios2_num_regs; ++i)
- {
- inserted
- = hash_insert (nios2_reg_hash, nios2_regs[i].name,
- (PTR) & nios2_regs[i]);
- if (inserted != NULL)
- {
- fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
- nios2_regs[i].name, inserted);
- /* Probably a memory allocation problem? Give up now. */
- as_fatal (_("Broken assembler. No assembly attempted."));
- }
-
- }
+ str_hash_insert (nios2_reg_hash, nios2_regs[i].name,
+ (PTR) & nios2_regs[i]);
for (i = 0; i < nios2_num_ps_insn_info_structs; ++i)
- {
- inserted
- = hash_insert (nios2_ps_hash, nios2_ps_insn_info_structs[i].pseudo_insn,
- (PTR) & nios2_ps_insn_info_structs[i]);
- if (inserted != NULL)
- {
- fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
- nios2_ps_insn_info_structs[i].pseudo_insn, inserted);
- /* Probably a memory allocation problem? Give up now. */
- as_fatal (_("Broken assembler. No assembly attempted."));
- }
- }
+ str_hash_insert (nios2_ps_hash, nios2_ps_insn_info_structs[i].pseudo_insn,
+ (PTR) & nios2_ps_insn_info_structs[i]);
/* Assembler option defaults. */
nios2_as_options.noat = FALSE;
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;
return flags;
}
-/* Implement TC_PARSE_CONS_EXPRESSION to handle %tls_ldo(...) */
+/* Implement TC_PARSE_CONS_EXPRESSION to handle %tls_ldo(...) and
+ %gotoff(...). */
bfd_reloc_code_real_type
nios2_cons (expressionS *exp, int size)
{
- bfd_reloc_code_real_type nios2_tls_ldo_reloc = BFD_RELOC_NONE;
+ bfd_reloc_code_real_type explicit_reloc = BFD_RELOC_NONE;
+ const char *reloc_name = NULL;
SKIP_WHITESPACE ();
if (input_line_pointer[0] == '%')
{
if (strprefix (input_line_pointer + 1, "tls_ldo"))
{
+ reloc_name = "%tls_ldo";
if (size != 4)
as_bad (_("Illegal operands: %%tls_ldo in %d-byte data field"),
size);
else
{
input_line_pointer += 8;
- nios2_tls_ldo_reloc = BFD_RELOC_NIOS2_TLS_DTPREL;
+ explicit_reloc = BFD_RELOC_NIOS2_TLS_DTPREL;
}
}
- if (nios2_tls_ldo_reloc != BFD_RELOC_NONE)
+ else if (strprefix (input_line_pointer + 1, "gotoff"))
+ {
+ reloc_name = "%gotoff";
+ if (size != 4)
+ as_bad (_("Illegal operands: %%gotoff in %d-byte data field"),
+ size);
+ else
+ {
+ input_line_pointer += 7;
+ explicit_reloc = BFD_RELOC_NIOS2_GOTOFF;
+ }
+ }
+
+ if (explicit_reloc != BFD_RELOC_NONE)
{
SKIP_WHITESPACE ();
if (input_line_pointer[0] != '(')
- as_bad (_("Illegal operands: %%tls_ldo requires arguments in ()"));
+ as_bad (_("Illegal operands: %s requires arguments in ()"),
+ reloc_name);
else
{
int c;
}
if (c != ')')
- as_bad (_("Illegal operands: %%tls_ldo requires arguments in ()"));
+ as_bad (_("Illegal operands: %s requires arguments in ()"),
+ reloc_name);
else
{
*end = '\0';
expression (exp);
*end = c;
if (input_line_pointer != end)
- as_bad (_("Illegal operands: %%tls_ldo requires arguments in ()"));
+ as_bad (_("Illegal operands: %s requires arguments in ()"),
+ reloc_name);
else
{
input_line_pointer++;
SKIP_WHITESPACE ();
c = *input_line_pointer;
if (! is_end_of_line[c] && c != ',')
- as_bad (_("Illegal operands: garbage after %%tls_ldo()"));
+ as_bad (_("Illegal operands: garbage after %s()"),
+ reloc_name);
}
}
}
}
}
- if (nios2_tls_ldo_reloc == BFD_RELOC_NONE)
+ if (explicit_reloc == BFD_RELOC_NONE)
expression (exp);
- return nios2_tls_ldo_reloc;
+ return explicit_reloc;
}
/* Implement HANDLE_ALIGN. */