/* tc-d30v.c -- Assembler code for the Mitsubishi D30V
- Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
#include "safe-ctype.h"
#include "subsegs.h"
#include "opcode/d30v.h"
+#include "dwarf2dbg.h"
const char comment_chars[] = ";";
const char line_comment_chars[] = "#";
static struct hash_control *d30v_hash;
/* Do a binary search of the pre_defined_registers array to see if
- NAME is a valid regiter name. Return the register number from the
+ NAME is a valid register name. Return the register number from the
array on success, or -1 on failure. */
static int
fprintf (stream, _("\nD30V options:\n\
-O Make adjacent short instructions parallel if possible.\n\
-n Warn about all NOPs inserted by the assembler.\n\
--N Warn about NOPs inserted after word multiplies.\n\
--c Warn about symbols whoes names match register names.\n\
+-N Warn about NOPs inserted after word multiplies.\n\
+-c Warn about symbols whose names match register names.\n\
-C Opposite of -C. -c is the default.\n"));
}
int
-md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
+md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
{
switch (c)
{
return 0;
}
-char *
+const char *
md_atof (int type, char *litP, int *sizeP)
{
return ieee_md_atof (type, litP, sizeP, TRUE);
valueT
md_section_align (asection *seg, valueT addr)
{
- int align = bfd_get_section_alignment (stdoutput, seg);
- return ((addr + (1 << align) - 1) & (-1 << align));
+ int align = bfd_section_alignment (seg);
+ return ((addr + (1 << align) - 1) & -(1 << align));
}
void
static long long
build_insn (struct d30v_insn *opcode, expressionS *opers)
{
- int i, length, bits, shift, flags;
+ int i, bits, shift, flags;
unsigned long number, id = 0;
long long insn;
struct d30v_opcode *op = opcode->op;
if (flags & OPERAND_SHIFT)
bits += 3;
- length = d30v_operand_table[form->operands[i]].length;
shift = 12 - d30v_operand_table[form->operands[i]].position;
if (opers[i].X_op != O_symbol)
number = opers[i].X_add_number;
int i, where;
char *f = frag_more (8);
+ dwarf2_emit_insn (8);
insn |= FM11;
d30v_number_to_chars (f, insn, 8);
char *f = frag_more (8);
int i, where;
+ dwarf2_emit_insn (8);
if (warn_nops == NOP_ALL)
as_warn (_("%s NOP inserted"), use_sequential ?
_("sequential") : _("parallel"));
}
else if (prev_left_kills_right_p)
{
- /* The left instruction kils the right slot, so we
+ /* The left instruction kills the right slot, so we
must leave it empty. */
write_1_short (opcode1, insn1, fx->next, FALSE);
return 1;
}
f = frag_more (8);
+ dwarf2_emit_insn (8);
d30v_number_to_chars (f, insn, 8);
/* If the previous instruction was a 32-bit multiply but it is put into a
int fsize,
int cmp_hack)
{
- int numops, match, index, i = 0, j, k;
+ int match, opcode_index, i = 0, j, k;
struct d30v_format *fm;
if (opcode == NULL)
return NULL;
/* Get all the operands and save them as expressions. */
- numops = get_operands (myops, cmp_hack);
+ get_operands (myops, cmp_hack);
- while ((index = opcode->format[i++]) != 0)
+ while ((opcode_index = opcode->format[i++]) != 0)
{
- if (fsize == FORCE_SHORT && index >= LONG)
+ if (fsize == FORCE_SHORT && opcode_index >= LONG)
continue;
- if (fsize == FORCE_LONG && index < LONG)
+ if (fsize == FORCE_LONG && opcode_index < LONG)
continue;
- fm = (struct d30v_format *) &d30v_format_table[index];
- k = index;
- while (fm->form == index)
+ fm = (struct d30v_format *) &d30v_format_table[opcode_index];
+ k = opcode_index;
+ while (fm->form == opcode_index)
{
match = 1;
/* Now check the operands for compatibility. */
{
int flags = d30v_operand_table[fm->operands[j]].flags;
int bits = d30v_operand_table[fm->operands[j]].bits;
- int X_op = myops[j].X_op;
+ operatorT X_op = myops[j].X_op;
int num = myops[j].X_add_number;
if (flags & OPERAND_SPECIAL)
/* Calculate the current address by running through the
previous frags and adding our current offset. */
- value = 0;
+ value = frag_now_fix_octets ();
for (f = frchain_now->frch_root; f; f = f->fr_next)
value += f->fr_fix + f->fr_offset;
- value = (S_GET_VALUE (myops[j].X_add_symbol) - value
- - (obstack_next_free (&frchain_now->frch_obstack)
- - frag_now->fr_literal));
+ value = S_GET_VALUE (myops[j].X_add_symbol) - value;
if (check_range (value, bits, flags))
match = 0;
}
if (!strncmp (name, "cmp", 3))
{
int p, i;
- char **str = (char **) d30v_cc_names;
+ char **d30v_str = (char **) d30v_cc_names;
+
if (name[3] == 'u')
p = 4;
else
p = 3;
- for (i = 1; *str && strncmp (*str, &name[p], 2); i++, str++)
+ for (i = 1; *d30v_str && strncmp (*d30v_str, &name[p], 2); i++, d30v_str++)
;
/* cmpu only supports some condition codes. */
}
}
- if (!*str)
+ if (!*d30v_str)
{
name[p + 2] = 0;
as_bad (_("unknown condition code: %s"), &name[p]);
if (pfill == NULL)
{
if (n > 2
- && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
+ && (bfd_section_flags (now_seg) & SEC_CODE) != 0)
{
static char const nop[4] = { 0x00, 0xf0, 0x00, 0x00 };
else
{
f = frag_more (8);
+ dwarf2_emit_insn (8);
d30v_number_to_chars (f, NOP2, 8);
if (warn_nops == NOP_ALL || warn_nops == NOP_MULTIPLY)
tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
{
arelent *reloc;
- reloc = xmalloc (sizeof (arelent));
- reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+ reloc = XNEW (arelent);
+ reloc->sym_ptr_ptr = XNEW (asymbol *);
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
}
static void
-check_size (long value, int bits, char *file, int line)
+check_size (long value, int bits, const char *file, int line)
{
int tmp, max;
/* Record this label for future adjustment after we find out what
kind of data it references, and the required alignment therewith. */
d30v_last_label = lab;
+
+ dwarf2_emit_label (lab);
}
/* Hook into cons for capturing alignment changes. */
{
int log_size;
+ /* Don't specially align anything in debug sections. */
+ if ((now_seg->flags & SEC_ALLOC) == 0
+ || strcmp (now_seg->name, ".eh_frame") == 0)
+ return;
+
log_size = 0;
while ((size >>= 1) != 0)
++log_size;
switch (fixP->fx_r_type)
{
- case BFD_RELOC_8: /* Check for a bad .byte directive. */
- if (fixP->fx_addsy != NULL)
- as_bad (_("line %d: unable to place address of symbol '%s' into a byte"),
- fixP->fx_line, S_GET_NAME (fixP->fx_addsy));
- else if (((unsigned)value) > 0xff)
- as_bad (_("line %d: unable to place value %lx into a byte"),
- fixP->fx_line, value);
- else
- *(unsigned char *) where = value;
+ case BFD_RELOC_8:
+ *(unsigned char *) where = value;
break;
- case BFD_RELOC_16: /* Check for a bad .short directive. */
- if (fixP->fx_addsy != NULL)
- as_bad (_("line %d: unable to place address of symbol '%s' into a short"),
- fixP->fx_line, S_GET_NAME (fixP->fx_addsy));
- else if (((unsigned)value) > 0xffff)
- as_bad (_("line %d: unable to place value %lx into a short"),
- fixP->fx_line, value);
- else
- bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
+ case BFD_RELOC_16:
+ bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
break;
- case BFD_RELOC_64: /* Check for a bad .quad directive. */
- if (fixP->fx_addsy != NULL)
- as_bad (_("line %d: unable to place address of symbol '%s' into a quad"),
- fixP->fx_line, S_GET_NAME (fixP->fx_addsy));
- else
- {
- bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
- bfd_putb32 (0, ((unsigned char *) where) + 4);
- }
+ case BFD_RELOC_64:
+ bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
+ bfd_putb32 (0, ((unsigned char *) where) + 4);
break;
case BFD_RELOC_D30V_6: