Fix overflow detection in the Z80 assembler.
[binutils-gdb.git] / gas / config / tc-ns32k.c
index cab97c17d20bb482e56852c6aefb0cfa768bbe25..98fa520b9ba1f2b6ac3fd392b614484267b1154f 100644 (file)
@@ -1,5 +1,5 @@
 /* ns32k.c  -- Assemble on the National Semiconductor 32k series
-   Copyright (C) 1987-2015 Free Software Foundation, Inc.
+   Copyright (C) 1987-2021 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -84,7 +84,7 @@ struct addr_mode
 typedef struct addr_mode addr_modeS;
 
 char *freeptr, *freeptr_static;        /* Points at some number of free bytes.  */
-struct hash_control *inst_hash_handle;
+htab_t inst_hash_handle;
 
 struct ns32k_opcode *desc;     /* Pointer at description of instruction.  */
 addr_modeS addr_modeP;
@@ -102,7 +102,7 @@ const char FLT_CHARS[] = "fd";      /* We don't want to support lowercase,
 /* Internal structs.  */
 struct ns32k_option
 {
-  char *pattern;
+  const char *pattern;
   unsigned long or;
   unsigned long and;
 };
@@ -132,7 +132,6 @@ struct int_ins_form
 
 struct int_ins_form iif;
 expressionS exprP;
-char *input_line_pointer;
 
 /* Description of the PARTs in IIF
   object[n]:
@@ -149,8 +148,8 @@ char *input_line_pointer;
    10  implied1
    11  implied2
 
-   For every entry there is a datalength in bytes. This is stored in size[n].
-        0,     the objectlength is not explicitly given by the instruction
+   For every entry there is a data length in bytes. This is stored in size[n].
+        0,     the object length is not explicitly given by the instruction
                and the operand is undefined. This is a case for relaxation.
                Reserve 4 bytes for the final object.
 
@@ -174,9 +173,9 @@ char *input_line_pointer;
 
    The low-order-byte corresponds to low physical memory.
    Obviously a FRAGment must be created for each valid disp in PART whose
-   datalength is undefined (to bad) .
+   data length is undefined (to bad) .
    The case where just the expression is undefined is less severe and is
-   handled by fix. Here the number of bytes in the objectfile is known.
+   handled by fix. Here the number of bytes in the object file is known.
    With this representation we simplify the assembly and separates the
    machine dependent/independent parts in a more clean way (said OE).  */
 \f
@@ -334,7 +333,7 @@ const pseudo_typeS md_pseudo_table[] =
    displacement base-adjust as there are other routines that must
    consider this. Also, as we have two various offset-adjusts in the
    ns32k (acb versus br/brs/jsr/bcond), two set of limits would have
-   had to be used.  Now we dont have to think about that.  */
+   had to be used.  Now we don't have to think about that.  */
 
 const relax_typeS md_relax_table[] =
 {
@@ -363,7 +362,7 @@ char disp_test[] =
 char disp_size[] =
 {4, 1, 2, 0, 4};
 \f
-/* Parse a general operand into an addressingmode struct
+/* Parse a general operand into an addressing mode struct
 
    In:  pointer at operand in ascii form
         pointer at addr_mode struct for result
@@ -433,6 +432,7 @@ addr_mode (char *operand,
                  addrmodeP->disp[0] = str + 2;
                  return -1;
                }
+             /* Fall through.  */
            default:
              as_bad (_("Invalid syntax in PC-relative addressing mode"));
              return 0;
@@ -442,7 +442,7 @@ addr_mode (char *operand,
     case 'e':
       if (str[strl - 1] != ']')
        {
-         if ((!strncmp (str, "ext(", 4)) && strl > 7)
+         if ((startswith (str, "ext(")) && strl > 7)
            {                           /* external */
              addrmodeP->disp[0] = str + 4;
              i = 0;
@@ -482,7 +482,7 @@ addr_mode (char *operand,
        {
        case 'f':
          addrmodeP->float_flag = 1;
-         /* Drop through.  */
+         /* Fall through.  */
        case 'r':
          if (str[1] >= '0' && str[1] < '8')
            {
@@ -493,10 +493,10 @@ addr_mode (char *operand,
        default:
          break;
        }
-      /* Drop through.  */
+      /* Fall through.  */
 
     case 3:
-      if (!strncmp (str, "tos", 3))
+      if (startswith (str, "tos"))
        {
          addrmodeP->mode = 23; /* TopOfStack */
          return -1;
@@ -513,11 +513,11 @@ addr_mode (char *operand,
        {
          if (str[strl - 2] == ')')
            {
-             if (!strncmp (&str[strl - 5], "(fp", 3))
+             if (startswith (&str[strl - 5], "(fp"))
                mode = 16;              /* Memory Relative.  */
-             else if (!strncmp (&str[strl - 5], "(sp", 3))
+             else if (startswith (&str[strl - 5], "(sp"))
                mode = 17;
-             else if (!strncmp (&str[strl - 5], "(sb", 3))
+             else if (startswith (&str[strl - 5], "(sb"))
                mode = 18;
 
              if (mode != DEFAULT)
@@ -565,16 +565,16 @@ addr_mode (char *operand,
                  str[strl - 4] = 0;
                  return -1;            /* reg rel */
                }
-             /* Drop through.  */
+             /* Fall through.  */
 
            default:
-             if (!strncmp (&str[strl - 4], "(fp", 3))
+             if (startswith (&str[strl - 4], "(fp"))
                mode = 24;
-             else if (!strncmp (&str[strl - 4], "(sp", 3))
+             else if (startswith (&str[strl - 4], "(sp"))
                mode = 25;
-             else if (!strncmp (&str[strl - 4], "(sb", 3))
+             else if (startswith (&str[strl - 4], "(sb"))
                mode = 26;
-             else if (!strncmp (&str[strl - 4], "(pc", 3))
+             else if (startswith (&str[strl - 4], "(pc"))
                mode = 27;
 
              if (mode != DEFAULT)
@@ -622,7 +622,7 @@ addr_mode (char *operand,
 
          addrmodeP->am_size += 1;      /* scaled index byte.  */
          j = str[strl - 4] - '0';      /* store temporary.  */
-         str[strl - 6] = '\000';       /* nullterminate for recursive call.  */
+         str[strl - 6] = '\000';       /* null terminate for recursive call.  */
          i = addr_mode (str, addrmodeP, 1);
 
          if (!i || addrmodeP->mode == 20)
@@ -704,7 +704,7 @@ get_addr_mode (char *ptr, addr_modeS *addrmodeP)
   if ((tmp = addrmodeP->scaled_reg))
     {                          /* Build indexbyte.  */
       tmp--;                   /* Remember regnumber comes incremented for
-                                  flagpurpose.  */
+                                  flag purpose.  */
       tmp |= addrmodeP->scaled_mode << 3;
       addrmodeP->index_byte = (char) tmp;
       addrmodeP->am_size += 1;
@@ -795,7 +795,7 @@ get_addr_mode (char *ptr, addr_modeS *addrmodeP)
   return addrmodeP->mode;
 }
 
-/* Read an optionlist.  */
+/* Read an option list.  */
 
 static void
 optlist (char *str,                    /* The string to extract options from.  */
@@ -803,7 +803,7 @@ optlist (char *str,                 /* The string to extract options from.  */
         unsigned long *default_map)    /* Default pattern and output.  */
 {
   int i, j, k, strlen1, strlen2;
-  char *patternP, *strP;
+  const char *patternP, *strP;
 
   strlen1 = strlen (str);
 
@@ -878,7 +878,7 @@ bit_fix_new (int size,              /* Length of bitfield.  */
 {
   bit_fixS *bit_fixP;
 
-  bit_fixP = obstack_alloc (&notes, sizeof (bit_fixS));
+  bit_fixP = XOBNEW (&notes, bit_fixS);
 
   bit_fixP->fx_bit_size = size;
   bit_fixP->fx_bit_offset = offset;
@@ -924,8 +924,9 @@ encode_operand (int argc,
       switch ((d = operandsP[(loop << 1) + 1]))
        {
        case 'f':               /* Operand of sfsr turns out to be a nasty
-                                  specialcase.  */
+                                  special-case.  */
          opcode_bit_ptr -= 5;
+         /* Fall through.  */
        case 'Z':               /* Float not immediate.  */
        case 'F':               /* 32 bit float general form.  */
        case 'L':               /* 64 bit float.  */
@@ -984,10 +985,10 @@ encode_operand (int argc,
          argv[i] = freeptr;
          pcrel -= 1;           /* Make pcrel 0 in spite of what case 'p':
                                   wants.  */
-         /* fall thru */
+         /* fallthru */
        case 'p':               /* Displacement - pc relative addressing.  */
          pcrel += 1;
-         /* fall thru */
+         /* fallthru */
        case 'd':               /* Displacement.  */
          iif.instr_size += suffixP[i] ? suffixP[i] : 4;
          IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
@@ -1010,12 +1011,12 @@ encode_operand (int argc,
          opcode_bit_ptr -= 3;
          iif.iifP[1].object |= tmp << opcode_bit_ptr;
          break;
-       case 'O':               /* Setcfg instruction optionslist.  */
+       case 'O':               /* Setcfg instruction options list.  */
          optlist (argv[i], opt3, &tmp);
          opcode_bit_ptr -= 4;
          iif.iifP[1].object |= tmp << 15;
          break;
-       case 'C':               /* Cinv instruction optionslist.  */
+       case 'C':               /* Cinv instruction options list.  */
          optlist (argv[i], opt4, &tmp);
          opcode_bit_ptr -= 4;
          iif.iifP[1].object |= tmp << 15; /* Insert the regtype in opcode.  */
@@ -1102,7 +1103,8 @@ parse (const char *line, int recursive_level)
       c = *lineptr;
       *(char *) lineptr = '\0';
 
-      if (!(desc = (struct ns32k_opcode *) hash_find (inst_hash_handle, line)))
+      desc = (struct ns32k_opcode *) str_hash_find (inst_hash_handle, line);
+      if (!desc)
        as_fatal (_("No such opcode"));
 
       *(char *) lineptr = c;
@@ -1330,7 +1332,7 @@ fix_new_ns32k (fragS *frag,               /* Which frag? */
   fix_bsr (fixP) = bsr;
   fix_bit_fixP (fixP) = bit_fixP;
   /* We have a MD overflow check for displacements.  */
-  fixP->fx_no_overflow = (im_disp != 0);
+  fixP->fx_no_overflow = im_disp != 0 || bit_fixP != NULL;
 }
 
 static void
@@ -1358,7 +1360,7 @@ fix_new_ns32k_exp (fragS *frag,           /* Which frag? */
   fix_bsr (fixP) = bsr;
   fix_bit_fixP (fixP) = bit_fixP;
   /* We have a MD overflow check for displacements.  */
-  fixP->fx_no_overflow = (im_disp != 0);
+  fixP->fx_no_overflow = im_disp != 0 || bit_fixP != NULL;
 }
 
 /* Convert number to chars in correct order.  */
@@ -1369,7 +1371,7 @@ md_number_to_chars (char *buf, valueT value, int nbytes)
   number_to_chars_littleendian (buf, value, nbytes);
 }
 
-/* This is a variant of md_numbers_to_chars. The reason for its'
+/* This is a variant of md_numbers_to_chars. The reason for its
    existence is the fact that ns32k uses Huffman coded
    displacements. This implies that the bit order is reversed in
    displacements and that they are prefixed with a size-tag.
@@ -1434,7 +1436,7 @@ md_number_to_disp (char *buf, long val, int n)
       break;
 
     default:
-      as_fatal (_("Internal logic error.  line %d, file \"%s\""),
+      as_fatal (_("Internal logic error.  Line %d, file: \"%s\""),
                __LINE__, __FILE__);
     }
 }
@@ -1817,7 +1819,7 @@ convert_iif (void)
                  {
                    /* Frag it.  */
                    if (exprP.X_op_symbol)
-                     /* We cant relax this case.  */
+                     /* We can't relax this case.  */
                      as_fatal (_("Can't relax difference"));
                    else
                      {
@@ -1894,21 +1896,17 @@ md_begin (void)
 {
   /* Build a hashtable of the instructions.  */
   const struct ns32k_opcode *ptr;
-  const char *status;
   const struct ns32k_opcode *endop;
 
-  inst_hash_handle = hash_new ();
+  inst_hash_handle = str_htab_create ();
 
   endop = ns32k_opcodes + sizeof (ns32k_opcodes) / sizeof (ns32k_opcodes[0]);
   for (ptr = ns32k_opcodes; ptr < endop; ptr++)
-    {
-      if ((status = hash_insert (inst_hash_handle, ptr->name, (char *) ptr)))
-       /* Fatal.  */
-       as_fatal (_("Can't hash %s: %s"), ptr->name, status);
-    }
+    if (str_hash_insert (inst_hash_handle, ptr->name, ptr, 0) != NULL)
+      as_fatal (_("duplicate %s"), ptr->name);
 
   /* Some private space please!  */
-  freeptr_static = (char *) malloc (PRIVATE_SIZE);
+  freeptr_static = XNEWVEC (char, PRIVATE_SIZE);
 }
 
 /* Turn the string pointed to by litP into a floating point constant
@@ -1916,10 +1914,10 @@ md_begin (void)
    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)
 {
-  return ieee_md_atof (type, litP, sizeP, FALSE);
+  return ieee_md_atof (type, litP, sizeP, false);
 }
 \f
 int
@@ -2123,7 +2121,7 @@ struct option md_longopts[] =
 size_t md_longopts_size = sizeof (md_longopts);
 
 int
-md_parse_option (int c, char *arg)
+md_parse_option (int c, const char *arg)
 {
   switch (c)
     {
@@ -2228,8 +2226,8 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
 
   code = reloc (fixp->fx_size, fixp->fx_pcrel, fix_im_disp (fixp));
 
-  rel = xmalloc (sizeof (arelent));
-  rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+  rel = XNEW (arelent);
+  rel->sym_ptr_ptr = XNEW (asymbol *);
   *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
   if (fixp->fx_pcrel)