Fix overflow detection in the Z80 assembler.
[binutils-gdb.git] / gas / config / tc-ip2k.c
index 4f5fbc2eb0a852d401bf46615482aa8c32517d53..0adc672a12044fbd3af7d7b0a5089726836ec806 100644 (file)
@@ -1,11 +1,11 @@
 /* tc-ip2k.c -- Assembler for the Scenix IP2xxx.
-   Copyright (C) 2000, 2002, 2003, 2005 Free Software Foundation.
+   Copyright (C) 2000-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,
    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
    Boston, MA 02110-1301, USA.  */
 
-#include <stdio.h>
 #include "as.h"
-#include "subsegs.h"     
+#include "subsegs.h"
 #include "symcat.h"
 #include "opcodes/ip2k-desc.h"
 #include "opcodes/ip2k-opc.h"
 #include "cgen.h"
 #include "elf/common.h"
 #include "elf/ip2k.h"
-#include "libbfd.h"
 
 /* Structure to hold all of the different components describing
    an individual instruction.  */
@@ -53,7 +51,7 @@ ip2k_insn;
 
 const char comment_chars[]        = ";";
 const char line_comment_chars[]   = "#";
-const char line_separator_chars[] = ""; 
+const char line_separator_chars[] = "";
 const char EXP_CHARS[]            = "eE";
 const char FLT_CHARS[]            = "dD";
 
@@ -73,35 +71,18 @@ ip2k_elf_section_rtn (int i)
 
   if (force_code_align)
     {
-      /* The s_align_ptwo function expects that we are just after a .align
-        directive and it will either try and read the align value or stop
-        if end of line so we must fake it out so it thinks we are at the
-        end of the line.  */
-      char *old_input_line_pointer = input_line_pointer;
-      input_line_pointer = "\n";
-      s_align_ptwo (1);
+      do_align (1, NULL, 0, 0);
       force_code_align = 0;
-      /* Restore.  */
-      input_line_pointer = old_input_line_pointer;
     }
 }
 
 static void
 ip2k_elf_section_text (int i)
 {
-  char *old_input_line_pointer;
   obj_elf_text(i);
 
-  /* the s_align_ptwo function expects that we are just after a .align
-     directive and it will either try and read the align value or stop if
-     end of line so we must fake it out so it thinks we are at the end of
-     the line.  */
-  old_input_line_pointer = input_line_pointer;
-  input_line_pointer = "\n";
-  s_align_ptwo (1);
+  do_align (1, NULL, 0, 0);
   force_code_align = 0;
-  /* Restore.  */
-  input_line_pointer = old_input_line_pointer;
 }
 
 /* The target specific pseudo-ops which we support.  */
@@ -120,7 +101,7 @@ enum options
   OPTION_CPU_IP2022EXT
 };
 
-struct option md_longopts[] = 
+struct option md_longopts[] =
 {
   { "mip2022",     no_argument, NULL, OPTION_CPU_IP2022 },
   { "mip2022ext",  no_argument, NULL, OPTION_CPU_IP2022EXT },
@@ -131,7 +112,7 @@ size_t md_longopts_size = sizeof (md_longopts);
 const char * md_shortopts = "";
 
 int
-md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED)
+md_parse_option (int c ATTRIBUTE_UNUSED, const char * arg ATTRIBUTE_UNUSED)
 {
   switch (c)
     {
@@ -165,7 +146,7 @@ void
 md_begin (void)
 {
   /* Initialize the `cgen' interface.  */
-  
+
   /* Set the machine number and endian.  */
   gas_cgen_cpu_desc = ip2k_cgen_cpu_open (CGEN_CPU_OPEN_MACHS,
                                          ip2k_mach_bitmask,
@@ -179,6 +160,8 @@ md_begin (void)
 
   /* Set the machine type.  */
   bfd_default_set_arch_mach (stdoutput, bfd_arch_ip2k, ip2k_mach);
+
+  literal_prefix_dollar_hex = true;
 }
 
 
@@ -230,9 +213,9 @@ md_assemble (char * str)
 valueT
 md_section_align (segT segment, valueT size)
 {
-  int align = bfd_get_section_alignment (stdoutput, segment);
+  int align = bfd_section_alignment (segment);
 
-  return ((size + (1 << align) - 1) & (-1 << align));
+  return ((size + (1 << align) - 1) & -(1 << align));
 }
 
 
@@ -246,9 +229,9 @@ int
 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
                               segT    segment ATTRIBUTE_UNUSED)
 {
-  as_fatal (_("md_estimate_size_before_relax\n"));
+  as_fatal (_("relaxation not supported\n"));
   return 1;
-} 
+}
 
 
 /* *fragP has been relaxed to its final size, and now needs to have
@@ -269,12 +252,9 @@ md_convert_frag (bfd   * abfd  ATTRIBUTE_UNUSED,
 /* Functions concerning relocs.  */
 
 long
-md_pcrel_from (fixS *fixP)
+md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
 {
-  as_fatal (_("md_pcrel_from\n"));
-
-  /* Return the address of the delay slot. */
-  return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
+  abort ();
 }
 
 
@@ -332,59 +312,10 @@ md_number_to_chars (char * buf, valueT val, int n)
   number_to_chars_bigendian (buf, val, n);
 }
 
-/* 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.  */
-
-/* Equal to MAX_PRECISION in atof-ieee.c  */
-#define MAX_LITTLENUMS 6
-
-char *
+const char *
 md_atof (int type, char * litP, int *  sizeP)
 {
-  int              prec;
-  LITTLENUM_TYPE   words [MAX_LITTLENUMS];
-  LITTLENUM_TYPE  *wordP;
-  char *           t;
-
-  switch (type)
-    {
-    case 'f':
-    case 'F':
-    case 's':
-    case 'S':
-      prec = 2;
-      break;
-
-    case 'd':
-    case 'D':
-    case 'r':
-    case 'R':
-      prec = 4;
-      break;
-
-   /* FIXME: Some targets allow other format chars for bigger sizes here.  */
-
-    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 * sizeof (LITTLENUM_TYPE);
-
-  /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
-     the ip2k endianness.  */
-  for (wordP = words; prec--;)
-    {
-      md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
-      litP += sizeof (LITTLENUM_TYPE);
-    }
-     
-  return 0;
+  return ieee_md_atof (type, litP, sizeP, true);
 }
 
 
@@ -431,7 +362,7 @@ ip2k_force_relocation (fixS * fix)
 }
 
 void
-ip2k_apply_fix3 (fixS *fixP, valueT *valueP, segT seg)
+ip2k_apply_fix (fixS *fixP, valueT *valueP, segT seg)
 {
   if (fixP->fx_r_type == BFD_RELOC_IP2K_TEXT
       && ! fixP->fx_addsy
@@ -445,7 +376,7 @@ ip2k_apply_fix3 (fixS *fixP, valueT *valueP, segT seg)
       /* Must be careful when we are fixing up an FR.  We could be
         fixing up an offset to (SP) or (DP) in which case we don't
         want to step on the top 2 bits of the FR operand.  The
-        gas_cgen_md_apply_fix3 doesn't know any better and overwrites
+        gas_cgen_md_apply_fix doesn't know any better and overwrites
         the entire operand.  We counter this by adding the bits
         to the new value.  */
       char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
@@ -454,17 +385,18 @@ ip2k_apply_fix3 (fixS *fixP, valueT *valueP, segT seg)
       CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
       CGEN_INSN_INT insn_value
        = cgen_get_insn_value (cd, (unsigned char *) where,
-                              CGEN_INSN_BITSIZE (fixP->fx_cgen.insn));
+                              CGEN_INSN_BITSIZE (fixP->fx_cgen.insn),
+                              gas_cgen_cpu_desc->insn_endian);
       /* Preserve (DP) or (SP) specification.  */
       *valueP += (insn_value & 0x180);
     }
 
-  gas_cgen_md_apply_fix3 (fixP, valueP, seg);
+  gas_cgen_md_apply_fix (fixP, valueP, seg);
 }
 
 int
-ip2k_elf_section_flags (int flags,
-                       int attr ATTRIBUTE_UNUSED,
+ip2k_elf_section_flags (flagword flags,
+                       bfd_vma attr ATTRIBUTE_UNUSED,
                        int type ATTRIBUTE_UNUSED)
 {
   /* This is used to detect when the section changes to an executable section.
@@ -473,7 +405,7 @@ ip2k_elf_section_flags (int flags,
      word alignment should be forced.  */
   if (flags & SEC_CODE)
     force_code_align = 1;
+
   return flags;
 }