]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gas/config/tc-d10v.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gas / config / tc-d10v.c
index c12eb640294837341af606ca98a6304ce460fd14..d126927b6f15521b5fb1f59df8784c566dbc44a1 100644 (file)
@@ -1,12 +1,11 @@
 /* tc-d10v.c -- Assembler code for the Mitsubishi D10V
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006
-   Free Software Foundation, Inc.
+   Copyright (C) 1996-2021 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
    GAS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
+   the Free Software Foundation; either version 3, or (at your option)
    any later version.
 
    GAS is distributed in the hope that it will be useful,
@@ -24,6 +23,7 @@
 #include "subsegs.h"
 #include "opcode/d10v.h"
 #include "elf/ppc.h"
+#include "dwarf2dbg.h"
 
 const char comment_chars[]        = ";";
 const char line_comment_chars[]   = "#";
@@ -101,10 +101,10 @@ struct option md_longopts[] =
 size_t md_longopts_size = sizeof (md_longopts);
 
 /* Opcode hash table.  */
-static struct hash_control *d10v_hash;
+static htab_t d10v_hash;
 
 /* Do a binary search of the d10v_predefined_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
@@ -222,7 +222,7 @@ md_show_usage (FILE *stream)
 }
 
 int
-md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
+md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
 {
   switch (c)
     {
@@ -251,44 +251,10 @@ md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   return 0;
 }
 
-/* Turn a string in input_line_pointer into a floating point constant
-   of type TYPE, and store the appropriate bytes in *LITP.  The number
-   of LITTLENUMS emitted is stored in *SIZEP.  An error message is
-   returned, or NULL on OK.  */
-
-char *
+const char *
 md_atof (int type, char *litP, int *sizeP)
 {
-  int prec;
-  LITTLENUM_TYPE words[4];
-  char *t;
-  int i;
-
-  switch (type)
-    {
-    case 'f':
-      prec = 2;
-      break;
-    case 'd':
-      prec = 4;
-      break;
-    default:
-      *sizeP = 0;
-      return _("bad call to md_atof");
-    }
-
-  t = atof_ieee (input_line_pointer, type, words);
-  if (t)
-    input_line_pointer = t;
-
-  *sizeP = prec * 2;
-
-  for (i = 0; i < prec; i++)
-    {
-      md_number_to_chars (litP, (valueT) words[i], 2);
-      litP += 2;
-    }
-  return NULL;
+  return ieee_md_atof (type, litP, sizeP, TRUE);
 }
 
 void
@@ -302,16 +268,16 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
 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
 md_begin (void)
 {
-  char *prev_name = "";
+  const char *prev_name = "";
   struct d10v_opcode *opcode;
-  d10v_hash = hash_new ();
+  d10v_hash = str_htab_create ();
 
   /* Insert unique names into hash table.  The D10v instruction set
      has many identical opcode names that have different opcodes based
@@ -323,7 +289,7 @@ md_begin (void)
       if (strcmp (prev_name, opcode->name))
        {
          prev_name = (char *) opcode->name;
-         hash_insert (d10v_hash, opcode->name, (char *) opcode);
+         str_hash_insert (d10v_hash, opcode->name, opcode, 0);
        }
     }
 
@@ -644,6 +610,7 @@ write_long (unsigned long insn, Fixups *fx)
   int i, where;
   char *f = frag_more (4);
 
+  dwarf2_emit_insn (4);
   insn |= FM11;
   number_to_chars_bigendian (f, insn, 4);
 
@@ -679,6 +646,7 @@ write_1_short (struct d10v_opcode *opcode,
   char *f = frag_more (4);
   int i, where;
 
+  dwarf2_emit_insn (4);
   if (opcode->exec_type & PARONLY)
     as_fatal (_("Instruction must be executed in parallel with another instruction."));
 
@@ -1093,6 +1061,7 @@ write_2_short (struct d10v_opcode *opcode1,
     }
 
   f = frag_more (4);
+  dwarf2_emit_insn (4);
   number_to_chars_bigendian (f, insn, 4);
 
   /* Process fixup chains.  fx refers to insn2 when j == 0, and to
@@ -1148,7 +1117,7 @@ write_2_short (struct d10v_opcode *opcode1,
 static unsigned long prev_insn;
 static struct d10v_opcode *prev_opcode = 0;
 static subsegT prev_subseg;
-static segT prev_seg = 0;;
+static segT prev_seg = 0;
 
 /* Find the symbol which has the same name as the register in exp.  */
 
@@ -1230,7 +1199,9 @@ find_opcode (struct d10v_opcode *opcode, expressionS myops[])
          for (i = 0; opcode->operands[i + 1]; i++)
            {
              int bits = d10v_operands[next_opcode->operands[opnum]].bits;
-             int flags = d10v_operands[next_opcode->operands[opnum]].flags;
+
+             flags = d10v_operands[next_opcode->operands[opnum]].flags;
+
              if (flags & OPERAND_ADDR)
                bits += 2;
 
@@ -1255,9 +1226,7 @@ find_opcode (struct d10v_opcode *opcode, expressionS myops[])
                  sym_frag = symbol_get_frag (myops[opnum].X_add_symbol);
                  found_symbol = FALSE;
 
-                 current_position =
-                   obstack_next_free (&frchain_now->frch_obstack)
-                   - frag_now->fr_literal;
+                 current_position = frag_now_fix_octets ();
                  symbol_position = S_GET_VALUE (myops[opnum].X_add_symbol);
 
                  for (f = frchain_now->frch_root; f; f = f->fr_next)
@@ -1440,7 +1409,6 @@ do_assemble (char *str, struct d10v_opcode **opcode)
   char name[20];
   int nlen = 0;
   expressionS myops[6];
-  unsigned long insn;
 
   /* Drop leading whitespace.  */
   while (*str == ' ')
@@ -1448,11 +1416,13 @@ do_assemble (char *str, struct d10v_opcode **opcode)
 
   /* Find the opcode end.  */
   for (op_start = op_end = (unsigned char *) str;
-       *op_end && nlen < 20 && !is_end_of_line[*op_end] && *op_end != ' ';
+       *op_end && !is_end_of_line[*op_end] && *op_end != ' ';
        op_end++)
     {
       name[nlen] = TOLOWER (op_start[nlen]);
       nlen++;
+      if (nlen == sizeof (name) - 1)
+       break;
     }
   name[nlen] = 0;
 
@@ -1460,9 +1430,9 @@ do_assemble (char *str, struct d10v_opcode **opcode)
     return -1;
 
   /* Find the first opcode with the proper name.  */
-  *opcode = (struct d10v_opcode *) hash_find (d10v_hash, name);
+  *opcode = (struct d10v_opcode *) str_hash_find (d10v_hash, name);
   if (*opcode == NULL)
-    as_fatal (_("unknown opcode: %s"), name);
+    return -1;
 
   save = input_line_pointer;
   input_line_pointer = (char *) op_end;
@@ -1471,8 +1441,7 @@ do_assemble (char *str, struct d10v_opcode **opcode)
     return -1;
   input_line_pointer = save;
 
-  insn = build_insn ((*opcode), myops, 0);
-  return insn;
+  return build_insn ((*opcode), myops, 0);
 }
 
 /* If while processing a fixup, a reloc really needs to be created.
@@ -1482,8 +1451,8 @@ arelent *
 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);
@@ -1579,7 +1548,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
          if ( segf && segf->sym != fixP->fx_addsy)
            value = 0;
         }
-      /* Drop through.  */
+      /* Fall through.  */
     case BFD_RELOC_D10V_18:
       /* Instruction addresses are always right-shifted by 2.  */
       value >>= AT_WORD_RIGHT_SHIFT;
@@ -1589,8 +1558,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
        {
          struct d10v_opcode *rep, *repi;
 
-         rep = (struct d10v_opcode *) hash_find (d10v_hash, "rep");
-         repi = (struct d10v_opcode *) hash_find (d10v_hash, "repi");
+         rep = (struct d10v_opcode *) str_hash_find (d10v_hash, "rep");
+         repi = (struct d10v_opcode *) str_hash_find (d10v_hash, "repi");
          if ((insn & FM11) == FM11
              && ((repi != NULL
                   && (insn & repi->mask) == (unsigned) repi->opcode)
@@ -1611,6 +1580,9 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_16:
       bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
       break;
+    case BFD_RELOC_8:
+      *where = value;
+      break;
 
     case BFD_RELOC_VTABLE_INHERIT:
     case BFD_RELOC_VTABLE_ENTRY:
@@ -1662,6 +1634,15 @@ d10v_cleanup (void)
   return 1;
 }
 
+void
+d10v_frob_label (symbolS *lab)
+{
+  d10v_cleanup ();
+  symbol_set_frag (lab, frag_now);
+  S_SET_VALUE (lab, (valueT) frag_now_fix ());
+  dwarf2_emit_label (lab);
+}
+
 /* Like normal .word, except support @word.
    Clobbers input_line_pointer, checks end-of-line.  */
 
@@ -1778,7 +1759,7 @@ md_assemble (char *str)
          prev_seg = now_seg;
          prev_subseg = now_subseg;
          if (prev_insn == (unsigned long) -1)
-           as_fatal (_("can't find opcode "));
+           as_fatal (_("can't find previous opcode "));
          fixups = fixups->next;
          str = str2 + 2;
        }
@@ -1788,11 +1769,10 @@ md_assemble (char *str)
   if (insn == (unsigned long) -1)
     {
       if (extype != PACK_UNSPEC)
-       {
-         etype = extype;
-         return;
-       }
-      as_fatal (_("can't find opcode "));
+       etype = extype;
+      else
+       as_bad (_("could not assemble: %s"), str);
+      return;
     }
 
   if (etype != PACK_UNSPEC)