/* spu.c -- Assembler for the IBM Synergistic Processing Unit (SPU)
- Copyright (C) 2006-2016 Free Software Foundation, Inc.
+ Copyright (C) 2006-2021 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
const struct spu_opcode spu_opcodes[] = {
#define APUOP(TAG,MACFORMAT,OPCODE,MNEMONIC,ASMFORMAT,DEP,PIPE) \
- { MACFORMAT, (OPCODE) << (32-11), MNEMONIC, ASMFORMAT },
+ { MACFORMAT, (OPCODE ## u) << (32-11), MNEMONIC, ASMFORMAT },
#define APUOPFB(TAG,MACFORMAT,OPCODE,FB,MNEMONIC,ASMFORMAT,DEP,PIPE) \
{ MACFORMAT, ((OPCODE) << (32-11)) | ((FB) << (32-18)), MNEMONIC, ASMFORMAT },
#include "opcode/spu-insns.h"
static void spu_cons (int);
extern char *myname;
-static struct hash_control *op_hash = NULL;
+static htab_t op_hash = NULL;
/* These bits should be turned off in the first address of every segment */
int md_seg_align = 7;
void
md_begin (void)
{
- const char *retval = NULL;
int i;
- /* initialize hash table */
-
- op_hash = hash_new ();
-
- /* loop until you see the end of the list */
+ op_hash = str_htab_create ();
+ /* Hash each mnemonic and record its position. There are
+ duplicates, keep just the first. */
for (i = 0; i < spu_num_opcodes; i++)
- {
- /* hash each mnemonic and record its position */
-
- retval = hash_insert (op_hash, spu_opcodes[i].mnemonic,
- (void *) &spu_opcodes[i]);
-
- if (retval != NULL && strcmp (retval, "exists") != 0)
- as_fatal (_("Can't hash instruction '%s':%s"),
- spu_opcodes[i].mnemonic, retval);
- }
+ str_hash_insert (op_hash, spu_opcodes[i].mnemonic, &spu_opcodes[i], 0);
}
\f
const char *md_shortopts = "";
/* try to find the instruction in the hash table */
- if ((format = (struct spu_opcode *) hash_find (op_hash, op)) == NULL)
+ if ((format = (struct spu_opcode *) str_hash_find (op_hash, op)) == NULL)
{
as_bad (_("Invalid mnemonic '%s'"), op);
return;
do
{
+ char *save = input_line_pointer;
+
+ /* Use deferred_expression here so that an expression involving
+ a symbol that happens to be defined already as an spu symbol,
+ is not resolved. */
deferred_expression (&exp);
if ((exp.X_op == O_symbol
|| exp.X_op == O_constant)
{
expressionS new_exp;
+ save = input_line_pointer;
expression (&new_exp);
if (new_exp.X_op == O_constant)
exp.X_add_number += new_exp.X_add_number;
+ else
+ input_line_pointer = save;
}
reloc = nbytes == 4 ? BFD_RELOC_SPU_PPU32 : BFD_RELOC_SPU_PPU64;
&exp, 0, reloc);
}
else
- emit_expr (&exp, nbytes);
+ {
+ /* Don't use deferred_expression for anything else.
+ deferred_expression won't evaulate dot at the point it is
+ used. */
+ input_line_pointer = save;
+ expression (&exp);
+ emit_expr (&exp, nbytes);
+ }
}
while (*input_line_pointer++ == ',');
tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
{
arelent *reloc;
- reloc = (arelent *) xmalloc (sizeof (arelent));
- reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ reloc = XNEW (arelent);
+ reloc->sym_ptr_ptr = XNEW (asymbol *);
if (fixp->fx_addsy)
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
else if (fixp->fx_subsy)
valueT
md_section_align (segT seg, valueT size)
{
- int align = bfd_get_section_alignment (stdoutput, seg);
+ int align = bfd_section_alignment (seg);
valueT mask = ((valueT) 1 << align) - 1;
return (size + mask) & ~mask;