as_bad_subtract
[binutils-gdb.git] / gas / config / tc-cris.c
index aba4ef7dffce373d8db5acbe9820ea0b79ae88c7..02ce2acfe006d1191eec9caad4143093a535f58c 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-cris.c -- Assembler code for the CRIS CPU core.
-   Copyright (C) 2000-2014 Free Software Foundation, Inc.
+   Copyright (C) 2000-2021 Free Software Foundation, Inc.
 
    Contributed by Axis Communications AB, Lund, Sweden.
    Originally written for GAS 1.38.1 by Mikael Asker.
@@ -81,7 +81,7 @@ struct cris_prefix
   expressionS expr;
 
   /* If there's an expression, we might need a relocation.  Here's the
-     type of what relocation to start relaxaton with.
+     type of what relocation to start relaxation with.
      The relocation is assumed to start immediately after the prefix insn,
      so we don't provide an offset.  */
   enum bfd_reloc_code_real reloc;
@@ -119,7 +119,7 @@ enum cris_archs
   arch_cris_any_v0_v10, arch_crisv32, arch_cris_common_v10_v32
 };
 
-static enum cris_archs cris_arch_from_string (char **);
+static enum cris_archs cris_arch_from_string (const char **);
 static int cris_insn_ver_valid_for_arch (enum cris_insn_version_usage,
                                         enum cris_archs);
 
@@ -160,29 +160,29 @@ static void cris_sym_no_leading_underscore (void);
 static char *cris_insn_first_word_frag (void);
 
 /* Handle to the opcode hash table.  */
-static struct hash_control *op_hash = NULL;
+static htab_t op_hash = NULL;
 
 /* If we target cris-axis-linux-gnu (as opposed to generic cris-axis-elf),
    we default to no underscore and required register-prefixes.  The
    difference is in the default values.  */
 #ifdef TE_LINUX
-#define DEFAULT_CRIS_AXIS_LINUX_GNU TRUE
+#define DEFAULT_CRIS_AXIS_LINUX_GNU true
 #else
-#define DEFAULT_CRIS_AXIS_LINUX_GNU FALSE
+#define DEFAULT_CRIS_AXIS_LINUX_GNU false
 #endif
 
 /* Whether we demand that registers have a `$' prefix.  Default here.  */
-static bfd_boolean demand_register_prefix = DEFAULT_CRIS_AXIS_LINUX_GNU;
+static bool demand_register_prefix = DEFAULT_CRIS_AXIS_LINUX_GNU;
 
 /* Whether global user symbols have a leading underscore.  Default here.  */
-static bfd_boolean symbols_have_leading_underscore
+static bool symbols_have_leading_underscore
   = !DEFAULT_CRIS_AXIS_LINUX_GNU;
 
 /* Whether or not we allow PIC, and expand to PIC-friendly constructs.  */
-static bfd_boolean pic = FALSE;
+static bool pic = false;
 
 /* Whether or not we allow TLS suffixes.  For the moment, we always do.  */
-static const bfd_boolean tls = TRUE;
+static const bool tls = true;
 
 /* If we're configured for "cris", default to allow all v0..v10
    instructions and register names.  */
@@ -1186,30 +1186,27 @@ cris_insn_first_word_frag (void)
 void
 md_begin (void)
 {
-  const char *hashret = NULL;
   int i = 0;
 
   /* Set up a hash table for the instructions.  */
-  op_hash = hash_new ();
-  if (op_hash == NULL)
-    as_fatal (_("Virtual memory exhausted"));
+  op_hash = str_htab_create ();
 
   /* Enable use of ".if ..asm.arch.cris.v32"
      and ".if ..asm.arch.cris.common_v10_v32" and a few others.  */
   symbol_table_insert (symbol_new ("..asm.arch.cris.v32", absolute_section,
-                                  (cris_arch == arch_crisv32),
-                                  &zero_address_frag));
+                                  &zero_address_frag,
+                                  cris_arch == arch_crisv32));
   symbol_table_insert (symbol_new ("..asm.arch.cris.v10", absolute_section,
-                                  (cris_arch == arch_crisv10),
-                                  &zero_address_frag));
+                                  &zero_address_frag,
+                                  cris_arch == arch_crisv10));
   symbol_table_insert (symbol_new ("..asm.arch.cris.common_v10_v32",
                                   absolute_section,
-                                  (cris_arch == arch_cris_common_v10_v32),
-                                  &zero_address_frag));
+                                  &zero_address_frag,
+                                  cris_arch == arch_cris_common_v10_v32));
   symbol_table_insert (symbol_new ("..asm.arch.cris.any_v0_v10",
                                   absolute_section,
-                                  (cris_arch == arch_cris_any_v0_v10),
-                                  &zero_address_frag));
+                                  &zero_address_frag,
+                                  cris_arch == arch_cris_any_v0_v10));
 
   while (cris_opcodes[i].name != NULL)
     {
@@ -1222,12 +1219,9 @@ md_begin (void)
          continue;
        }
 
-      /* Need to cast to get rid of "const".  FIXME: Fix hash_insert instead.  */
-      hashret = hash_insert (op_hash, name, (void *) &cris_opcodes[i]);
+      if (str_hash_insert (op_hash, name, &cris_opcodes[i], 0) != NULL)
+       as_fatal (_("duplicate %s"), name);
 
-      if (hashret != NULL && *hashret != '\0')
-       as_fatal (_("Can't hash `%s': %s\n"), cris_opcodes[i].name,
-                 *hashret == 0 ? _("(unknown reason)") : hashret);
       do
        {
          if (cris_opcodes[i].match & cris_opcodes[i].lose)
@@ -1492,6 +1486,19 @@ md_assemble (char *str)
     }
 }
 
+/* Helper error-reporting function: calls as_bad for a format string
+   for a single value and zeroes the offending value (zero assumed
+   being a valid value) to avoid repeated error reports in later value
+   checking.  */
+
+static void
+cris_bad (const char *format, offsetT *valp)
+{
+  /* We cast to long so the format string can assume that format.  */
+  as_bad (format, (long) *valp);
+  *valp = 0;
+}
+
 /* Low level text-to-bits assembly.  */
 
 static void
@@ -1545,7 +1552,7 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
     }
 
   /* Find the instruction.  */
-  instruction = (struct cris_opcode *) hash_find (op_hash, insn_text);
+  instruction = (struct cris_opcode *) str_hash_find (op_hash, insn_text);
   if (instruction == NULL)
     {
       as_bad (_("Unknown opcode: `%s'"), insn_text);
@@ -1646,8 +1653,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                  if (out_insnp->expr.X_op == O_constant
                      && (out_insnp->expr.X_add_number < 0
                          || out_insnp->expr.X_add_number > 31))
-                   as_bad (_("Immediate value not in 5 bit unsigned range: %ld"),
-                           out_insnp->expr.X_add_number);
+                   cris_bad (_("Immediate value not in 5 bit unsigned range: %ld"),
+                             &out_insnp->expr.X_add_number);
 
                  out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_5;
                  continue;
@@ -1662,8 +1669,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                  if (out_insnp->expr.X_op == O_constant
                      && (out_insnp->expr.X_add_number < 0
                          || out_insnp->expr.X_add_number > 15))
-                   as_bad (_("Immediate value not in 4 bit unsigned range: %ld"),
-                           out_insnp->expr.X_add_number);
+                   cris_bad (_("Immediate value not in 4 bit unsigned range: %ld"),
+                             &out_insnp->expr.X_add_number);
 
                  out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_4;
                  continue;
@@ -1714,8 +1721,9 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                  if (out_insnp->expr.X_op == O_constant
                      && (out_insnp->expr.X_add_number < -32
                          || out_insnp->expr.X_add_number > 31))
-                   as_bad (_("Immediate value not in 6 bit range: %ld"),
-                           out_insnp->expr.X_add_number);
+                   cris_bad (_("Immediate value not in 6 bit range: %ld"),
+                             &out_insnp->expr.X_add_number);
+
                  out_insnp->reloc = BFD_RELOC_CRIS_SIGNED_6;
                  continue;
                }
@@ -1729,8 +1737,9 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                  if (out_insnp->expr.X_op == O_constant
                      && (out_insnp->expr.X_add_number < 0
                          || out_insnp->expr.X_add_number > 63))
-                   as_bad (_("Immediate value not in 6 bit unsigned range: %ld"),
-                           out_insnp->expr.X_add_number);
+                   cris_bad (_("Immediate value not in 6 bit unsigned range: %ld"),
+                             &out_insnp->expr.X_add_number);
+
                  out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_6;
                  continue;
                }
@@ -1797,7 +1806,7 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
              out_insnp->opcode |= regno << 12;
              out_insnp->reloc = BFD_RELOC_CRIS_SIGNED_8;
              continue;
-             
+
            case 'O':
              /* A BDAP expression for any size, "expr,R".  */
              if (! cris_get_expression (&s, &prefixp->expr))
@@ -2122,8 +2131,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                        if (out_insnp->expr.X_op == O_constant
                            && (out_insnp->expr.X_add_number < -128
                                || out_insnp->expr.X_add_number > 255))
-                         as_bad (_("Immediate value not in 8 bit range: %ld"),
-                                 out_insnp->expr.X_add_number);
+                         cris_bad (_("Immediate value not in 8 bit range: %ld"),
+                                   &out_insnp->expr.X_add_number);
                        /* Fall through.  */
                      case 2:
                        /* FIXME:  We need an indicator in the instruction
@@ -2132,8 +2141,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                        if (out_insnp->expr.X_op == O_constant
                            && (out_insnp->expr.X_add_number < -32768
                                || out_insnp->expr.X_add_number > 65535))
-                         as_bad (_("Immediate value not in 16 bit range: %ld"),
-                                 out_insnp->expr.X_add_number);
+                         cris_bad (_("Immediate value not in 16 bit range: %ld"),
+                                   &out_insnp->expr.X_add_number);
                        out_insnp->imm_oprnd_size = 2;
                        break;
 
@@ -2162,18 +2171,18 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                          if (instruction->imm_oprnd_size == SIZE_FIELD
                              && (out_insnp->expr.X_add_number < -128
                                  || out_insnp->expr.X_add_number > 255))
-                           as_bad (_("Immediate value not in 8 bit range: %ld"),
-                                   out_insnp->expr.X_add_number);
+                           cris_bad (_("Immediate value not in 8 bit range: %ld"),
+                                     &out_insnp->expr.X_add_number);
                          else if (instruction->imm_oprnd_size == SIZE_FIELD_SIGNED
                              && (out_insnp->expr.X_add_number < -128
                                  || out_insnp->expr.X_add_number > 127))
-                           as_bad (_("Immediate value not in 8 bit signed range: %ld"),
-                                   out_insnp->expr.X_add_number);
+                           cris_bad (_("Immediate value not in 8 bit signed range: %ld"),
+                                     &out_insnp->expr.X_add_number);
                          else if (instruction->imm_oprnd_size == SIZE_FIELD_UNSIGNED
                                   && (out_insnp->expr.X_add_number < 0
                                       || out_insnp->expr.X_add_number > 255))
-                           as_bad (_("Immediate value not in 8 bit unsigned range: %ld"),
-                                   out_insnp->expr.X_add_number);
+                           cris_bad (_("Immediate value not in 8 bit unsigned range: %ld"),
+                                     &out_insnp->expr.X_add_number);
                        }
 
                      /* Fall through.  */
@@ -2183,18 +2192,18 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                          if (instruction->imm_oprnd_size == SIZE_FIELD
                              && (out_insnp->expr.X_add_number < -32768
                                  || out_insnp->expr.X_add_number > 65535))
-                           as_bad (_("Immediate value not in 16 bit range: %ld"),
-                                   out_insnp->expr.X_add_number);
+                           cris_bad (_("Immediate value not in 16 bit range: %ld"),
+                                     &out_insnp->expr.X_add_number);
                          else if (instruction->imm_oprnd_size == SIZE_FIELD_SIGNED
                              && (out_insnp->expr.X_add_number < -32768
                                  || out_insnp->expr.X_add_number > 32767))
-                           as_bad (_("Immediate value not in 16 bit signed range: %ld"),
-                                   out_insnp->expr.X_add_number);
+                           cris_bad (_("Immediate value not in 16 bit signed range: %ld"),
+                                     &out_insnp->expr.X_add_number);
                          else if (instruction->imm_oprnd_size == SIZE_FIELD_UNSIGNED
                              && (out_insnp->expr.X_add_number < 0
                                  || out_insnp->expr.X_add_number > 65535))
-                           as_bad (_("Immediate value not in 16 bit unsigned range: %ld"),
-                                   out_insnp->expr.X_add_number);
+                           cris_bad (_("Immediate value not in 16 bit unsigned range: %ld"),
+                                     &out_insnp->expr.X_add_number);
                        }
                      out_insnp->imm_oprnd_size = 2;
                      break;
@@ -3482,14 +3491,14 @@ cris_get_reloc_suffix (char **cPP, bfd_reloc_code_real_type *relocp,
     const char *const suffix;
     unsigned int len;
     bfd_reloc_code_real_type reloc;
-    bfd_boolean pic_p;
-    bfd_boolean tls_p;
+    bool pic_p;
+    bool tls_p;
   } pic_suffixes[] =
     {
 #undef PICMAP
-#define PICMAP(s, r) {s, sizeof (s) - 1, r, TRUE, FALSE}
-#define PICTLSMAP(s, r) {s, sizeof (s) - 1, r, TRUE, TRUE}
-#define TLSMAP(s, r) {s, sizeof (s) - 1, r, FALSE, TRUE}
+#define PICMAP(s, r) {s, sizeof (s) - 1, r, true, false}
+#define PICTLSMAP(s, r) {s, sizeof (s) - 1, r, true, true}
+#define TLSMAP(s, r) {s, sizeof (s) - 1, r, false, true}
       /* Keep this in order with longest unambiguous prefix first.  */
       PICMAP ("GOTPLT16", BFD_RELOC_CRIS_16_GOTPLT),
       PICMAP ("GOTPLT", BFD_RELOC_CRIS_32_GOTPLT),
@@ -3576,7 +3585,7 @@ cris_get_reloc_suffix (char **cPP, bfd_reloc_code_real_type *relocp,
    code as assembly code, but if they do, they should be able enough to
    find out the correct bit patterns and use them.  */
 
-char *
+const char *
 md_atof (int type ATTRIBUTE_UNUSED, char *litp ATTRIBUTE_UNUSED,
         int *sizep ATTRIBUTE_UNUSED)
 {
@@ -3787,7 +3796,7 @@ cris_number_to_imm (char *bufp, long val, int n, fixS *fixP, segT seg)
    GAS does not understand.  */
 
 int
-md_parse_option (int arg, char *argp ATTRIBUTE_UNUSED)
+md_parse_option (int arg, const char *argp ATTRIBUTE_UNUSED)
 {
   switch (arg)
     {
@@ -3802,23 +3811,23 @@ md_parse_option (int arg, char *argp ATTRIBUTE_UNUSED)
       break;
 
     case OPTION_NO_US:
-      demand_register_prefix = TRUE;
+      demand_register_prefix = true;
 
       if (OUTPUT_FLAVOR == bfd_target_aout_flavour)
        as_bad (_("--no-underscore is invalid with a.out format"));
       else
-       symbols_have_leading_underscore = FALSE;
+       symbols_have_leading_underscore = false;
       break;
 
     case OPTION_US:
-      demand_register_prefix = FALSE;
-      symbols_have_leading_underscore = TRUE;
+      demand_register_prefix = false;
+      symbols_have_leading_underscore = true;
       break;
 
     case OPTION_PIC:
       if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
        as_bad (_("--pic is invalid for this object format"));
-      pic = TRUE;
+      pic = true;
       if (cris_arch != arch_crisv32)
        md_long_jump_size = cris_any_v0_v10_long_jump_size_pic;
       else
@@ -3827,7 +3836,7 @@ md_parse_option (int arg, char *argp ATTRIBUTE_UNUSED)
 
     case OPTION_ARCH:
       {
-       char *str = argp;
+       const char *str = argp;
        enum cris_archs argarch = cris_arch_from_string (&str);
 
        if (argarch == arch_cris_unknown)
@@ -3944,9 +3953,9 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
       return 0;
     }
 
-  relP = (arelent *) xmalloc (sizeof (arelent));
+  relP = XNEW (arelent);
   gas_assert (relP != 0);
-  relP->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+  relP->sym_ptr_ptr = XNEW (asymbol *);
   *relP->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
   relP->address = fixP->fx_frag->fr_address + fixP->fx_where;
 
@@ -4039,23 +4048,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
     fixP->fx_done = 1;
 
-  if (fixP->fx_bit_fixP || fixP->fx_im_disp != 0)
-    {
-      as_bad_where (fixP->fx_file, fixP->fx_line, _("Invalid relocation"));
-      fixP->fx_done = 1;
-    }
-  else
-    {
-      /* We can't actually support subtracting a symbol.  */
-      if (fixP->fx_subsy != (symbolS *) NULL)
-       as_bad_where (fixP->fx_file, fixP->fx_line,
-                     _("expression too complex"));
+  /* We can't actually support subtracting a symbol.  */
+  if (fixP->fx_subsy != (symbolS *) NULL)
+    as_bad_subtract (fixP);
 
-      /* This operand-type is scaled.  */
-      if (fixP->fx_r_type == BFD_RELOC_CRIS_LAPCQ_OFFSET)
-       val /= 2;
-      cris_number_to_imm (buf, val, fixP->fx_size, fixP, seg);
-    }
+  /* This operand-type is scaled.  */
+  if (fixP->fx_r_type == BFD_RELOC_CRIS_LAPCQ_OFFSET)
+    val /= 2;
+  cris_number_to_imm (buf, val, fixP->fx_size, fixP, seg);
 }
 
 /* All relocations are relative to the location just after the fixup;
@@ -4132,7 +4132,7 @@ tc_cris_check_adjusted_broken_word (offsetT new_offset, struct broken_word *brok
 static void
 cris_force_reg_prefix (void)
 {
-  demand_register_prefix = TRUE;
+  demand_register_prefix = true;
 }
 
 /* Do not demand a leading REGISTER_PREFIX_CHAR for all registers.  */
@@ -4140,7 +4140,7 @@ cris_force_reg_prefix (void)
 static void
 cris_relax_reg_prefix (void)
 {
-  demand_register_prefix = FALSE;
+  demand_register_prefix = false;
 }
 
 /* Adjust for having a leading '_' on all user symbols.  */
@@ -4243,7 +4243,7 @@ s_cris_dtpoff (int bytes)
 
   p = frag_more (bytes);
   md_number_to_chars (p, 0, bytes);
-  fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE,
+  fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, false,
               BFD_RELOC_CRIS_32_DTPREL);
 
   demand_empty_rest_of_line ();
@@ -4256,7 +4256,7 @@ s_cris_dtpoff (int bytes)
    arch_cris_unknown is returned.  */
 
 static enum cris_archs
-cris_arch_from_string (char **str)
+cris_arch_from_string (const char **str)
 {
   static const struct cris_arch_struct
   {
@@ -4312,7 +4312,7 @@ cris_insn_ver_valid_for_arch (enum cris_insn_version_usage iver,
         || iver == cris_ver_v8_10
         || iver == cris_ver_v10
         || iver == cris_ver_v10p);
-      
+
     case arch_crisv32:
       return
        (iver == cris_ver_version_all
@@ -4383,7 +4383,7 @@ s_cris_arch (int dummy ATTRIBUTE_UNUSED)
      would be more useful than confusing, implementation-wise and
      user-wise.  */
 
-  char *str = input_line_pointer;
+  const char *str = input_line_pointer;
   enum cris_archs arch = cris_arch_from_string (&str);
 
   if (arch == arch_cris_unknown)
@@ -4399,7 +4399,7 @@ s_cris_arch (int dummy ATTRIBUTE_UNUSED)
   else if (arch != cris_arch)
     as_bad (_(".arch <arch> requires a matching --march=... option"));
 
-  input_line_pointer = str;
+  input_line_pointer = (char *) str;
   demand_empty_rest_of_line ();
   return;
 }