Fix overflow detection in the Z80 assembler.
[binutils-gdb.git] / gas / config / tc-crx.c
index a2314b713b38a93755f780b13f55219963a39719..d33a0bf076657de368b766dfb93e557175238ad5 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-crx.c -- Assembler code for the CRX CPU core.
-   Copyright (C) 2004-2015 Free Software Foundation, Inc.
+   Copyright (C) 2004-2021 Free Software Foundation, Inc.
 
    Contributed by Tomer Levi, NSC, Israel.
    Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
@@ -23,7 +23,7 @@
    MA 02110-1301, USA.  */
 
 #include "as.h"
-#include "bfd_stdint.h"
+#include <stdint.h>
 #include "safe-ctype.h"
 #include "dwarf2dbg.h"
 #include "opcode/crx.h"
 
 /* Utility macros for string comparison.  */
 #define streq(a, b)           (strcmp (a, b) == 0)
-#define strneq(a, b, c)       (strncmp (a, b, c) == 0)
 
 /* Assign a number NUM, shifted by SHIFT bytes, into a location
    pointed by index BYTE of array 'output_opcode'.  */
-#define CRX_PRINT(BYTE, NUM, SHIFT)   output_opcode[BYTE] |= (NUM << SHIFT)
+#define CRX_PRINT(BYTE, NUM, SHIFT)   output_opcode[BYTE] |= (NUM) << (SHIFT)
 
 /* Operand errors.  */
 typedef enum
@@ -57,33 +56,33 @@ typedef enum
     OP_NOT_EVEN,       /* Operand is Odd number, should be even.  */
     OP_ILLEGAL_DISPU4, /* Operand is not within DISPU4 range.  */
     OP_ILLEGAL_CST4,   /* Operand is not within CST4 range.  */
-    OP_NOT_UPPER_64KB  /* Operand is not within the upper 64KB 
+    OP_NOT_UPPER_64KB  /* Operand is not within the upper 64KB
                           (0xFFFF0000-0xFFFFFFFF).  */
   }
 op_err;
 
 /* Opcode mnemonics hash table.  */
-static struct hash_control *crx_inst_hash;
+static htab_t crx_inst_hash;
 /* CRX registers hash table.  */
-static struct hash_control *reg_hash;
+static htab_t reg_hash;
 /* CRX coprocessor registers hash table.  */
-static struct hash_control *copreg_hash;
+static htab_t copreg_hash;
 /* Current instruction we're assembling.  */
-const inst *instruction;
+static const inst *instruction;
 
 /* Global variables.  */
 
 /* Array to hold an instruction encoding.  */
-long output_opcode[2];
+static long output_opcode[2];
 
 /* Nonzero means a relocatable symbol.  */
-int relocatable;
+static int relocatable;
 
 /* A copy of the original instruction (used in error messages).  */
-char ins_parse[MAX_INST_LEN];
+static char ins_parse[MAX_INST_LEN];
 
 /* The current processed argument number.  */
-int cur_arg_num;
+static int cur_arg_num;
 
 /* Generic assembler global variables which must be defined by all targets.  */
 
@@ -140,31 +139,8 @@ const relax_typeS md_relax_table[] =
   {0xfffffe, -0x1000000, 6, 0}         /* 24 */
 };
 
-static void    reset_vars              (char *);
-static reg     get_register            (char *);
-static copreg  get_copregister         (char *);
-static argtype get_optype              (operand_type);
-static int     get_opbits              (operand_type);
-static int     get_opflags             (operand_type);
-static int     get_number_of_operands   (void);
-static void    parse_operand           (char *, ins *);
-static int     gettrap                 (const char *);
-static void    handle_LoadStor         (const char *);
-static int     get_cinv_parameters      (const char *);
-static long    getconstant             (long, int);
-static op_err  check_range             (long *, int, unsigned int, int);
-static int     getreg_image            (reg);
-static void    parse_operands          (ins *, char *);
-static void    parse_insn              (ins *, char *);
-static void    print_operand           (int, int, argument *);
-static void    print_constant          (int, int, argument *);
-static int     exponent2scale          (int);
-static void    mask_reg                        (int, unsigned short *);
-static void    process_label_constant   (char *, ins *);
-static void    set_operand             (char *, ins *);
-static char *  preprocess_reglist       (char *, int *);
-static int     assemble_insn           (char *, ins *);
-static void    print_insn              (ins *);
+static int     get_cinv_parameters     (const char *);
+static char *  preprocess_reglist      (char *, int *);
 static void    warn_if_needed          (ins *);
 static int     adjust_if_needed                (ins *);
 
@@ -208,7 +184,7 @@ get_register (char *reg_name)
 {
   const reg_entry *rreg;
 
-  rreg = (const reg_entry *) hash_find (reg_hash, reg_name);
+  rreg = (const reg_entry *) str_hash_find (reg_hash, reg_name);
 
   if (rreg != NULL)
     return rreg->value.reg_val;
@@ -223,7 +199,7 @@ get_copregister (char *copreg_name)
 {
   const reg_entry *coreg;
 
-  coreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
+  coreg = (const reg_entry *) str_hash_find (copreg_hash, copreg_name);
 
   if (coreg != NULL)
     return coreg->value.copreg_val;
@@ -308,8 +284,8 @@ tc_gen_reloc (asection *section 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->addend = fixP->fx_offset;
@@ -402,7 +378,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
 {
   /* 'opcode' points to the start of the instruction, whether
      we need to change the instruction's fixed encoding.  */
-  char *opcode = fragP->fr_literal + fragP->fr_fix;
+  char *opcode = &fragP->fr_literal[0] + fragP->fr_fix;
   bfd_reloc_code_real_type reloc;
 
   subseg_change (sec, 0);
@@ -451,7 +427,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
    GAS does not understand.  */
 
 int
-md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
+md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
 {
   return 0;
 }
@@ -464,7 +440,7 @@ md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
   return;
 }
 
-char *
+const char *
 md_atof (int type, char *litP, int *sizeP)
 {
   return ieee_md_atof (type, litP, sizeP, target_big_endian);
@@ -527,23 +503,17 @@ md_pcrel_from (fixS *fixp)
 void
 md_begin (void)
 {
-  const char *hashret = NULL;
   int i = 0;
 
   /* Set up a hash table for the instructions.  */
-  if ((crx_inst_hash = hash_new ()) == NULL)
-    as_fatal (_("Virtual memory exhausted"));
-  
+  crx_inst_hash = str_htab_create ();
+
   while (crx_instruction[i].mnemonic != NULL)
     {
       const char *mnemonic = crx_instruction[i].mnemonic;
 
-      hashret = hash_insert (crx_inst_hash, mnemonic,
-                            (void *) &crx_instruction[i]);
-
-      if (hashret != NULL && *hashret != '\0')
-       as_fatal (_("Can't hash `%s': %s\n"), crx_instruction[i].mnemonic,
-                 *hashret == 0 ? _("(unknown reason)") : hashret);
+      if (str_hash_insert (crx_inst_hash, mnemonic, &crx_instruction[i], 0))
+       as_fatal (_("duplicate %s"), mnemonic);
 
       /* Insert unique names into hash table.  The CRX instruction set
         has many identical opcode names that have different opcodes based
@@ -558,46 +528,31 @@ md_begin (void)
     }
 
   /* Initialize reg_hash hash table.  */
-  if ((reg_hash = hash_new ()) == NULL)
-    as_fatal (_("Virtual memory exhausted"));
-
+  reg_hash = str_htab_create ();
   {
     const reg_entry *regtab;
 
     for (regtab = crx_regtab;
         regtab < (crx_regtab + NUMREGS); regtab++)
-      {
-       hashret = hash_insert (reg_hash, regtab->name, (void *) regtab);
-       if (hashret)
-         as_fatal (_("Internal Error:  Can't hash %s: %s"),
-                   regtab->name,
-                   hashret);
-      }
+      if (str_hash_insert (reg_hash, regtab->name, regtab, 0) != NULL)
+       as_fatal (_("duplicate %s"), regtab->name);
   }
 
   /* Initialize copreg_hash hash table.  */
-  if ((copreg_hash = hash_new ()) == NULL)
-    as_fatal (_("Virtual memory exhausted"));
-
+  copreg_hash = str_htab_create ();
   {
     const reg_entry *copregtab;
 
     for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
         copregtab++)
-      {
-       hashret = hash_insert (copreg_hash, copregtab->name,
-                              (void *) copregtab);
-       if (hashret)
-         as_fatal (_("Internal Error:  Can't hash %s: %s"),
-                   copregtab->name,
-                   hashret);
-      }
+      if (str_hash_insert (copreg_hash, copregtab->name, copregtab, 0) != NULL)
+       as_fatal (_("duplicate %s"), copregtab->name);
   }
   /*  Set linkrelax here to avoid fixups in most sections.  */
   linkrelax = 1;
 }
 
-/* Process constants (immediate/absolute) 
+/* Process constants (immediate/absolute)
    and labels (jump targets/Memory locations).  */
 
 static void
@@ -610,7 +565,7 @@ process_label_constant (char *str, ins * crx_ins)
   input_line_pointer = str;
 
   expression (&crx_ins->exp);
-  
+
   switch (crx_ins->exp.X_op)
     {
     case O_big:
@@ -639,42 +594,42 @@ process_label_constant (char *str, ins * crx_ins)
       switch (cur_arg->type)
        {
        case arg_cr:
-          if (IS_INSN_TYPE (LD_STOR_INS_INC))
+         if (IS_INSN_TYPE (LD_STOR_INS_INC))
            crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
-          else if (IS_INSN_TYPE (CSTBIT_INS)
+         else if (IS_INSN_TYPE (CSTBIT_INS)
                   || IS_INSN_TYPE (STOR_IMM_INS))
            crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
-          else
+         else
            crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
          break;
 
        case arg_idxr:
-           crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
+         crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
          break;
-       
+
        case arg_c:
-          if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
+         if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
            crx_ins->rtype = BFD_RELOC_CRX_REL16;
          else if (IS_INSN_TYPE (BRANCH_INS))
            crx_ins->rtype = BFD_RELOC_CRX_REL8;
-          else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
+         else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
                   || IS_INSN_TYPE (CSTBIT_INS))
            crx_ins->rtype = BFD_RELOC_CRX_ABS32;
          else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
            crx_ins->rtype = BFD_RELOC_CRX_REL4;
-          else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
+         else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
            crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
          break;
-       
+
        case arg_ic:
-          if (IS_INSN_TYPE (ARITH_INS))
+         if (IS_INSN_TYPE (ARITH_INS))
            crx_ins->rtype = BFD_RELOC_CRX_IMM32;
          else if (IS_INSN_TYPE (ARITH_BYTE_INS))
            crx_ins->rtype = BFD_RELOC_CRX_IMM16;
          break;
        default:
          break;
-      }
+       }
       break;
 
     default:
@@ -715,8 +670,8 @@ exponent2scale (int val)
 static void
 set_operand (char *operand, ins * crx_ins)
 {
-  char *operandS; /* Pointer to start of sub-opearand.  */
-  char *operandE; /* Pointer to end of sub-opearand.  */
+  char *operandS; /* Pointer to start of sub-operand.  */
+  char *operandE; /* Pointer to end of sub-operand.  */
   expressionS scale;
   int scale_val;
   char *input_save, c;
@@ -730,10 +685,11 @@ set_operand (char *operand, ins * crx_ins)
     case arg_sc:    /* Case *+0x18.  */
     case arg_ic:    /* Case $0x18.  */
       operandS++;
+      /* Fall through.  */
     case arg_c:            /* Case 0x18.  */
       /* Set constant.  */
       process_label_constant (operandS, crx_ins);
-      
+
       if (cur_arg->type != arg_ic)
        cur_arg->type = arg_c;
       break;
@@ -746,7 +702,8 @@ set_operand (char *operand, ins * crx_ins)
        operandE++;
       *operandE = '\0';
       process_label_constant (operandS, crx_ins);
-      operandS = operandE;    
+      operandS = operandE;
+      /* Fall through.  */
     case arg_rbase: /* Case (r1).  */
       operandS++;
       /* Set register base.  */
@@ -754,7 +711,7 @@ set_operand (char *operand, ins * crx_ins)
        operandE++;
       *operandE = '\0';
       if ((cur_arg->r = get_register (operandS)) == nullregister)
-       as_bad (_("Illegal register `%s' in Instruction `%s'"),
+       as_bad (_("Illegal register `%s' in instruction `%s'"),
                operandS, ins_parse);
 
       if (cur_arg->type != arg_rbase)
@@ -768,13 +725,13 @@ set_operand (char *operand, ins * crx_ins)
       *operandE = '\0';
       process_label_constant (operandS, crx_ins);
       operandS = ++operandE;
-      
+
       /* Set register base.  */
       while ((*operandE != ',') && (! ISSPACE (*operandE)))
        operandE++;
       *operandE++ = '\0';
       if ((cur_arg->r = get_register (operandS)) == nullregister)
-       as_bad (_("Illegal register `%s' in Instruction `%s'"),
+       as_bad (_("Illegal register `%s' in instruction `%s'"),
                operandS, ins_parse);
 
       /* Skip leading white space.  */
@@ -789,7 +746,7 @@ set_operand (char *operand, ins * crx_ins)
       *operandE++ = '\0';
 
       if ((cur_arg->i_r = get_register (operandS)) == nullregister)
-       as_bad (_("Illegal register `%s' in Instruction `%s'"),
+       as_bad (_("Illegal register `%s' in instruction `%s'"),
                operandS, ins_parse);
 
       /* Skip leading white space.  */
@@ -801,7 +758,7 @@ set_operand (char *operand, ins * crx_ins)
       if (c == ')')
        cur_arg->scale = 0;
       else
-        {
+       {
          while (*operandE != ')')
            operandE++;
          *operandE = '\0';
@@ -815,12 +772,12 @@ set_operand (char *operand, ins * crx_ins)
          scale_val = scale.X_add_number;
 
          /* Check if the scale value is legal.  */
-          if (scale_val != 1 && scale_val != 2
-              && scale_val != 4 && scale_val != 8)
+         if (scale_val != 1 && scale_val != 2
+             && scale_val != 4 && scale_val != 8)
            as_bad (_("Illegal Scale - `%d'"), scale_val);
 
          cur_arg->scale = exponent2scale (scale_val);
-        }
+       }
       break;
 
     default:
@@ -868,7 +825,7 @@ parse_operand (char *operand, ins * crx_ins)
       if (strchr (operand, '(') != NULL)
        cur_arg->type = arg_icr;
       else
-        cur_arg->type = arg_ic;
+       cur_arg->type = arg_ic;
       goto set_params;
       break;
 
@@ -883,14 +840,14 @@ parse_operand (char *operand, ins * crx_ins)
       break;
 
     default:
-       break;
+      break;
     }
-      
+
   if (strchr (operand, '(') != NULL)
     {
       if (strchr (operand, ',') != NULL
-          && (strchr (operand, ',') > strchr (operand, '(')))
-           cur_arg->type = arg_idxr;
+         && (strchr (operand, ',') > strchr (operand, '(')))
+       cur_arg->type = arg_idxr;
       else
        cur_arg->type = arg_cr;
     }
@@ -898,13 +855,13 @@ parse_operand (char *operand, ins * crx_ins)
     cur_arg->type = arg_c;
   goto set_params;
 
-/* Parse an operand according to its type.  */
-set_params:
+  /* Parse an operand according to its type.  */
+ set_params:
   cur_arg->constant = 0;
   set_operand (operand, crx_ins);
 }
 
-/* Parse the various operands. Each operand is then analyzed to fillup 
+/* Parse the various operands. Each operand is then analyzed to fillup
    the fields in the crx_ins data structure.  */
 
 static void
@@ -925,12 +882,12 @@ parse_operands (ins * crx_ins, char *operands)
   while (*operandT != '\0')
     {
       if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
-        {
+       {
          *operandT++ = '\0';
          operand[op_num++] = strdup (operandH);
-          operandH = operandT;
-          continue;
-        }
+         operandH = operandT;
+         continue;
+       }
 
       if (*operandT == ' ')
        as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
@@ -999,18 +956,18 @@ gettrap (const char *s)
   return 0;
 }
 
-/* Post-Increment instructions, as well as Store-Immediate instructions, are a 
-   sub-group within load/stor instruction groups. 
-   Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to 
-   advance the instruction pointer to the start of that sub-group (that is, up 
+/* Post-Increment instructions, as well as Store-Immediate instructions, are a
+   sub-group within load/stor instruction groups.
+   Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
+   advance the instruction pointer to the start of that sub-group (that is, up
    to the first instruction of that type).
    Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS.  */
 
 static void
 handle_LoadStor (const char *operands)
 {
-  /* Post-Increment instructions precede Store-Immediate instructions in 
-     CRX instruction table, hence they are handled before. 
+  /* Post-Increment instructions precede Store-Immediate instructions in
+     CRX instruction table, hence they are handled before.
      This synchronization should be kept.  */
 
   /* Assuming Post-Increment insn has the following format :
@@ -1041,9 +998,9 @@ parse_insn (ins *insn, char *operands)
   int i;
 
   /* Handle instructions with no operands.  */
-  for (i = 0; no_op_insn[i] != NULL; i++)
+  for (i = 0; crx_no_op_insn[i] != NULL; i++)
   {
-    if (streq (no_op_insn[i], instruction->mnemonic))
+    if (streq (crx_no_op_insn[i], instruction->mnemonic))
     {
       insn->nargs = 0;
       return;
@@ -1105,7 +1062,7 @@ get_cinv_parameters (const char *operand)
    issue an error.  */
 
 static int
-getreg_image (reg r)
+getreg_image (int r)
 {
   const reg_entry *rreg;
   char *reg_name;
@@ -1132,9 +1089,8 @@ getreg_image (reg r)
 
 /* Issue a error message when register is illegal.  */
 #define IMAGE_ERR \
-  as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
-           reg_name, ins_parse);                            \
-  break;
+  as_bad (_("Illegal register (`%s') in instruction: `%s'"), \
+         reg_name, ins_parse);
 
   switch (rreg->type)
   {
@@ -1143,18 +1099,21 @@ getreg_image (reg r)
        return rreg->image;
       else
        IMAGE_ERR;
+      break;
 
     case CRX_CFG_REGTYPE:
       if (is_procreg)
        return rreg->image;
       else
        IMAGE_ERR;
+      break;
 
     case CRX_R_REGTYPE:
       if (! is_procreg)
        return rreg->image;
       else
        IMAGE_ERR;
+      break;
 
     case CRX_C_REGTYPE:
     case CRX_CS_REGTYPE:
@@ -1163,6 +1122,7 @@ getreg_image (reg r)
 
     default:
       IMAGE_ERR;
+      break;
   }
 
   return 0;
@@ -1185,8 +1145,7 @@ static void
 print_constant (int nbits, int shift, argument *arg)
 {
   unsigned long mask = 0;
-
-  long constant = getconstant (arg->constant, nbits);
+  unsigned long constant = getconstant (arg->constant, nbits);
 
   switch (nbits)
   {
@@ -1207,7 +1166,7 @@ print_constant (int nbits, int shift, argument *arg)
              output_opcode[0]    output_opcode[1]     */
 
       CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
-      CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
+      CRX_PRINT (1, constant & 0xFFFF, WORD_SHIFT);
       break;
 
     case 16:
@@ -1220,8 +1179,8 @@ print_constant (int nbits, int shift, argument *arg)
          break;
        }
 
-      /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is 
-        always filling the upper part of output_opcode[1]. If we mistakenly 
+      /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
+        always filling the upper part of output_opcode[1]. If we mistakenly
         write it to output_opcode[0], the constant prefix (that is, 'match')
         will be overridden.
                 0         1         2         3
@@ -1259,14 +1218,14 @@ print_operand (int nbits, int shift, argument *arg)
 
     case arg_copr:
       if (arg->cr < c0 || arg->cr > c15)
-       as_bad (_("Illegal Co-processor register in Instruction `%s' "),
+       as_bad (_("Illegal co-processor register in instruction `%s'"),
                ins_parse);
       CRX_PRINT (0, getreg_image (arg->cr), shift);
       break;
 
     case arg_copsr:
       if (arg->cr < cs0 || arg->cr > cs15)
-       as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
+       as_bad (_("Illegal co-processor special register in instruction `%s'"),
                ins_parse);
       CRX_PRINT (0, getreg_image (arg->cr), shift);
       break;
@@ -1279,6 +1238,7 @@ print_operand (int nbits, int shift, argument *arg)
       CRX_PRINT (0, getreg_image (arg->r), 12);
       CRX_PRINT (0, getreg_image (arg->i_r), 8);
       CRX_PRINT (0, arg->scale, 6);
+      /* Fall through.  */
     case arg_ic:
     case arg_c:
       print_constant (nbits, shift, arg);
@@ -1316,8 +1276,8 @@ get_number_of_operands (void)
   return i;
 }
 
-/* Verify that the number NUM can be represented in BITS bits (that is, 
-   within its permitted range), based on the instruction's FLAGS.  
+/* Verify that the number NUM can be represented in BITS bits (that is,
+   within its permitted range), based on the instruction's FLAGS.
    If UPDATE is nonzero, update the value of NUM if necessary.
    Return OP_LEGAL upon success, actual error type upon failure.  */
 
@@ -1325,7 +1285,7 @@ static op_err
 check_range (long *num, int bits, int unsigned flags, int update)
 {
   uint32_t max;
-  int retval = OP_LEGAL;
+  op_err retval = OP_LEGAL;
   int bin;
   uint32_t upper_64kb = 0xffff0000;
   uint32_t value = *num;
@@ -1379,12 +1339,12 @@ check_range (long *num, int bits, int unsigned flags, int update)
     {
       int is_dispu4 = 0;
 
-      uint32_t mul = (instruction->flags & DISPUB4 ? 1 
+      uint32_t mul = (instruction->flags & DISPUB4 ? 1
                      : instruction->flags & DISPUW4 ? 2
                      : instruction->flags & DISPUD4 ? 4
                      : 0);
-      
-      for (bin = 0; bin < cst4_maps; bin++)
+
+      for (bin = 0; bin < crx_cst4_maps; bin++)
        {
          if (value == mul * bin)
            {
@@ -1401,9 +1361,9 @@ check_range (long *num, int bits, int unsigned flags, int update)
     {
       int is_cst4 = 0;
 
-      for (bin = 0; bin < cst4_maps; bin++)
+      for (bin = 0; bin < crx_cst4_maps; bin++)
        {
-         if (value == (uint32_t) cst4_map[bin])
+         if (value == (uint32_t) crx_cst4_map[bin])
            {
              is_cst4 = 1;
              if (update)
@@ -1436,7 +1396,7 @@ check_range (long *num, int bits, int unsigned flags, int update)
 
 /* Assemble a single instruction:
    INSN is already parsed (that is, all operand values and types are set).
-   For instruction to be assembled, we need to find an appropriate template in 
+   For instruction to be assembled, we need to find an appropriate template in
    the instruction table, meeting the following conditions:
     1: Has the same number of operands.
     2: Has the same operand types.
@@ -1470,9 +1430,9 @@ assemble_insn (char *mnemonic, ins *insn)
   /* Operand error (used for issuing various constant error messages).  */
   op_err op_error, const_err = OP_LEGAL;
 
-/* Retrieve data (based on FUNC) for each operand of a given instruction.  */
-#define GET_CURRENT_DATA(FUNC, ARRAY)                            \
-  for (i = 0; i < insn->nargs; i++)                              \
+  /* Retrieve data (based on FUNC) for each operand of a given instruction.  */
+#define GET_CURRENT_DATA(FUNC, ARRAY)                  \
+  for (i = 0; i < insn->nargs; i++)                    \
     ARRAY[i] = FUNC (instruction->operands[i].op_type)
 
 #define GET_CURRENT_TYPE    GET_CURRENT_DATA(get_optype, cur_type)
@@ -1489,7 +1449,7 @@ assemble_insn (char *mnemonic, ins *insn)
   /* In some case, same mnemonic can appear with different instruction types.
      For example, 'storb' is supported with 3 different types :
      LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
-     We assume that when reaching this point, the instruction type was 
+     We assume that when reaching this point, the instruction type was
      pre-determined. We need to make sure that the type stays the same
      during a search for matching instruction.  */
   ins_type = CRX_INS_TYPE(instruction->flags);
@@ -1515,7 +1475,7 @@ assemble_insn (char *mnemonic, ins *insn)
 
       /* Check for type compatibility.  */
       for (i = 0; i < insn->nargs; i++)
-        {
+       {
          if (cur_type[i] != insn->arg[i].type)
            {
              if (invalid_optype == -1)
@@ -1529,34 +1489,31 @@ assemble_insn (char *mnemonic, ins *insn)
        {
          /* Reverse the operand indices for certain opcodes:
             Index 0      -->> 1
-            Index 1      -->> 0        
+            Index 1      -->> 0
             Other index  -->> stays the same.  */
-         int j = instruction->flags & REVERSE_MATCH ? 
-                 i == 0 ? 1 : 
-                 i == 1 ? 0 : i : 
-                 i;
-
-         /* Only check range - don't update the constant's value, since the 
-            current instruction may not be the last we try to match.  
-            The constant's value will be updated later, right before printing 
+         int j = (instruction->flags & REVERSE_MATCH) && i <= 1 ? 1 - i : i;
+
+         /* Only check range - don't update the constant's value, since the
+            current instruction may not be the last we try to match.
+            The constant's value will be updated later, right before printing
             it to the object file.  */
-         if ((insn->arg[j].X_op == O_constant) 
-              && (op_error = check_range (&insn->arg[j].constant, cur_size[j], 
-                                          cur_flags[j], 0)))
-           {
+         if ((insn->arg[j].X_op == O_constant)
+             && (op_error = check_range (&insn->arg[j].constant, cur_size[j],
+                                         cur_flags[j], 0)))
+           {
              if (invalid_const == -1)
-             {
-               invalid_const = j + 1;
-               const_err = op_error;
-             }
+               {
+                 invalid_const = j + 1;
+                 const_err = op_error;
+               }
              goto next_insn;
            }
-         /* For symbols, we make sure the relocation size (which was already 
+         /* For symbols, we make sure the relocation size (which was already
             determined) is sufficient.  */
          else if ((insn->arg[j].X_op == O_symbol)
-                   && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize 
-                        > cur_size[j]))
-                 goto next_insn;
+                  && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
+                      > cur_size[j]))
+           goto next_insn;
        }
       found_const_within_range = 1;
 
@@ -1564,8 +1521,8 @@ assemble_insn (char *mnemonic, ins *insn)
       match = 1;
       break;
 
-/* Try again with next instruction.  */
-next_insn:
+      /* Try again with next instruction.  */
+    next_insn:
       instruction++;
     }
 
@@ -1577,89 +1534,88 @@ next_insn:
       else if (!found_same_argument_types)
        as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
       else if (!found_const_within_range)
-      {
-       switch (const_err)
        {
-       case OP_OUT_OF_RANGE:
-         as_bad (_("Operand out of range (arg %d)"), invalid_const);
-         break;
-       case OP_NOT_EVEN:
-         as_bad (_("Operand has odd displacement (arg %d)"), invalid_const);
-         break;
-       case OP_ILLEGAL_DISPU4:
-         as_bad (_("Invalid DISPU4 operand value (arg %d)"), invalid_const);
-         break;
-       case OP_ILLEGAL_CST4:
-         as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const);
-         break;
-       case OP_NOT_UPPER_64KB:
-         as_bad (_("Operand value is not within upper 64 KB (arg %d)"), 
-                   invalid_const);
-         break;
-       default:
-         as_bad (_("Illegal operand (arg %d)"), invalid_const);
-         break;
+         switch (const_err)
+           {
+           case OP_OUT_OF_RANGE:
+             as_bad (_("Operand out of range (arg %d)"), invalid_const);
+             break;
+           case OP_NOT_EVEN:
+             as_bad (_("Operand has odd displacement (arg %d)"),
+                     invalid_const);
+             break;
+           case OP_ILLEGAL_DISPU4:
+             as_bad (_("Invalid DISPU4 operand value (arg %d)"),
+                     invalid_const);
+             break;
+           case OP_ILLEGAL_CST4:
+             as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const);
+             break;
+           case OP_NOT_UPPER_64KB:
+             as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
+                     invalid_const);
+             break;
+           default:
+             as_bad (_("Illegal operand (arg %d)"), invalid_const);
+             break;
+           }
        }
-      }
-      
+
       return 0;
     }
   else
     /* Full match - print the encoding to output file.  */
     {
-      /* Make further checkings (such that couldn't be made earlier).
+      /* Make further checking (such that couldn't be made earlier).
         Warn the user if necessary.  */
       warn_if_needed (insn);
-      
+
       /* Check whether we need to adjust the instruction pointer.  */
       if (adjust_if_needed (insn))
-       /* If instruction pointer was adjusted, we need to update 
+       /* If instruction pointer was adjusted, we need to update
           the size of the current template operands.  */
        GET_CURRENT_SIZE;
 
       for (i = 0; i < insn->nargs; i++)
-        {
-         int j = instruction->flags & REVERSE_MATCH ? 
-                 i == 0 ? 1 : 
-                 i == 1 ? 0 : i : 
-                 i;
+       {
+         int j = (instruction->flags & REVERSE_MATCH) && i <= 1 ? 1 - i : i;
 
          /* This time, update constant value before printing it.  */
-         if ((insn->arg[j].X_op == O_constant) 
-              && (check_range (&insn->arg[j].constant, cur_size[j], 
-                               cur_flags[j], 1) != OP_LEGAL))
-             as_fatal (_("Illegal operand (arg %d)"), j+1);
+         if ((insn->arg[j].X_op == O_constant)
+             && (check_range (&insn->arg[j].constant, cur_size[j],
+                              cur_flags[j], 1) != OP_LEGAL))
+           as_fatal (_("Illegal operand (arg %d)"), j+1);
        }
 
       /* First, copy the instruction's opcode.  */
       output_opcode[0] = BIN (instruction->match, instruction->match_bits);
 
       for (i = 0; i < insn->nargs; i++)
-        {
+       {
          cur_arg_num = i;
-          print_operand (cur_size[i], instruction->operands[i].shift, 
+         print_operand (cur_size[i], instruction->operands[i].shift,
                         &insn->arg[i]);
-        }
+       }
     }
 
   return 1;
 }
 
-/* Bunch of error checkings.
+/* Bunch of error checking.
    The checks are made after a matching instruction was found.  */
 
 void
 warn_if_needed (ins *insn)
 {
-  /* If the post-increment address mode is used and the load/store 
-     source register is the same as rbase, the result of the 
+  /* If the post-increment address mode is used and the load/store
+     source register is the same as rbase, the result of the
      instruction is undefined.  */
   if (IS_INSN_TYPE (LD_STOR_INS_INC))
     {
       /* Enough to verify that one of the arguments is a simple reg.  */
       if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
        if (insn->arg[0].r == insn->arg[1].r)
-         as_bad (_("Same src/dest register is used (`r%d'), result is undefined"), 
+         as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
                   insn->arg[0].r);
     }
 
@@ -1671,17 +1627,17 @@ warn_if_needed (ins *insn)
        as_bad (_("`%s' has undefined result"), ins_parse);
     }
 
-  /* If the rptr register is specified as one of the registers to be loaded, 
+  /* If the rptr register is specified as one of the registers to be loaded,
      the final contents of rptr are undefined. Thus, we issue an error.  */
   if (instruction->flags & NO_RPTR)
     {
       if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
-       as_bad (_("Same src/dest register is used (`r%d'), result is undefined"), 
+       as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
         getreg_image (insn->arg[0].r));
     }
 }
 
-/* In some cases, we need to adjust the instruction pointer although a 
+/* In some cases, we need to adjust the instruction pointer although a
    match was already found. Here, we gather all these cases.
    Returns 1 if instruction pointer was adjusted, otherwise 0.  */
 
@@ -1696,26 +1652,26 @@ adjust_if_needed (ins *insn)
     {
       if ((instruction->operands[0].op_type == cst4)
          && instruction->operands[1].op_type == regr)
-        {
-          if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
+       {
+         if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
            {
              instruction++;
              ret_value = 1;
            }
-        }
+       }
     }
 
-  /* Optimization: Omit a zero displacement in bit operations, 
+  /* Optimization: Omit a zero displacement in bit operations,
      saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)').  */
   if (IS_INSN_TYPE (CSTBIT_INS))
     {
       if ((instruction->operands[1].op_type == rbase_disps12)
-          && (insn->arg[1].X_op == O_constant)
-          && (insn->arg[1].constant == 0))
-            {
-              instruction--;
-             ret_value = 1;
-            }
+         && (insn->arg[1].X_op == O_constant)
+         && (insn->arg[1].constant == 0))
+       {
+         instruction--;
+         ret_value = 1;
+       }
     }
 
   return ret_value;
@@ -1730,7 +1686,7 @@ mask_reg (int r, unsigned short int *mask)
 {
   if ((reg)r > (reg)sp)
     {
-      as_bad (_("Invalid Register in Register List"));
+      as_bad (_("Invalid register in register list"));
       return;
     }
 
@@ -1749,7 +1705,7 @@ preprocess_reglist (char *param, int *allocated)
   int reg_counter = 0;           /* Count number of parsed registers.  */
   unsigned short int mask = 0;   /* Mask for 16 general purpose registers.  */
   char *new_param;               /* New created operands string.  */
-  char *paramP = param;                  /* Pointer to original opearands string.  */
+  char *paramP = param;                  /* Pointer to original operands string.  */
   char maskstring[10];           /* Array to print the mask as a string.  */
   int hi_found = 0, lo_found = 0; /* Boolean flags for hi/lo registers.  */
   reg r;
@@ -1765,7 +1721,7 @@ preprocess_reglist (char *param, int *allocated)
 
   while (*paramP++ != '{');
 
-  new_param = (char *)xcalloc (MAX_INST_LEN, sizeof (char));
+  new_param = XCNEWVEC (char, MAX_INST_LEN);
   *allocated = 1;
   strncpy (new_param, param, paramP - param - 1);
 
@@ -1781,21 +1737,21 @@ preprocess_reglist (char *param, int *allocated)
 
       /* Coprocessor register c<N>.  */
       if (IS_INSN_TYPE (COP_REG_INS))
-        {
-          if (((cr = get_copregister (reg_name)) == nullcopregister)
+       {
+         if (((cr = get_copregister (reg_name)) == nullcopregister)
              || (crx_copregtab[cr-MAX_REG].type != CRX_C_REGTYPE))
            as_fatal (_("Illegal register `%s' in cop-register list"), reg_name);
          mask_reg (getreg_image (cr - c0), &mask);
-        }
+       }
       /* Coprocessor Special register cs<N>.  */
       else if (IS_INSN_TYPE (COPS_REG_INS))
-        {
-          if (((cr = get_copregister (reg_name)) == nullcopregister)
+       {
+         if (((cr = get_copregister (reg_name)) == nullcopregister)
              || (crx_copregtab[cr-MAX_REG].type != CRX_CS_REGTYPE))
-           as_fatal (_("Illegal register `%s' in cop-special-register list"), 
+           as_fatal (_("Illegal register `%s' in cop-special-register list"),
                      reg_name);
          mask_reg (getreg_image (cr - cs0), &mask);
-        }
+       }
       /* User register u<N>.  */
       else if (instruction->flags & USER_REG)
        {
@@ -1809,15 +1765,15 @@ preprocess_reglist (char *param, int *allocated)
              lo_found = 1;
              goto next_inst;
            }
-          else if (((r = get_register (reg_name)) == nullregister)
-             || (crx_regtab[r].type != CRX_U_REGTYPE))
+         else if (((r = get_register (reg_name)) == nullregister)
+                  || (crx_regtab[r].type != CRX_U_REGTYPE))
            as_fatal (_("Illegal register `%s' in user register list"), reg_name);
-         
-         mask_reg (getreg_image (r - u0), &mask);        
+
+         mask_reg (getreg_image (r - u0), &mask);
        }
       /* General purpose register r<N>.  */
       else
-        {
+       {
          if (streq(reg_name, "hi"))
            {
              hi_found = 1;
@@ -1828,20 +1784,20 @@ preprocess_reglist (char *param, int *allocated)
              lo_found = 1;
              goto next_inst;
            }
-          else if (((r = get_register (reg_name)) == nullregister)
-             || (crx_regtab[r].type != CRX_R_REGTYPE))
+         else if (((r = get_register (reg_name)) == nullregister)
+                  || (crx_regtab[r].type != CRX_R_REGTYPE))
            as_fatal (_("Illegal register `%s' in register list"), reg_name);
 
          mask_reg (getreg_image (r - r0), &mask);
-        }
+       }
 
       if (++reg_counter > MAX_REGS_IN_MASK16)
        as_bad (_("Maximum %d bits may be set in `mask16' operand"),
                MAX_REGS_IN_MASK16);
 
-next_inst:
+    next_inst:
       while (!ISALNUM (*paramP) && *paramP != '}')
-         paramP++;
+       paramP++;
     }
 
   if (*++paramP != '\0')
@@ -1879,7 +1835,7 @@ next_inst:
 /* Print the instruction.
    Handle also cases where the instruction is relaxable/relocatable.  */
 
-void
+static void
 print_insn (ins *insn)
 {
   unsigned int i, j, insn_size;
@@ -1894,7 +1850,7 @@ print_insn (ins *insn)
       words[j++] = output_opcode[i] & 0xFFFF;
     }
 
-  /* Handle relaxtion.  */
+  /* Handle relaxation.  */
   if ((instruction->flags & RELAXABLE) && relocatable)
     {
       int relax_subtype;
@@ -1983,7 +1939,7 @@ md_assemble (char *op)
   *param++ = '\0';
 
   /* Find the instruction.  */
-  instruction = (const inst *) hash_find (crx_inst_hash, op);
+  instruction = (const inst *) str_hash_find (crx_inst_hash, op);
   if (instruction == NULL)
     {
       as_bad (_("Unknown opcode: `%s'"), op);