tc-cr16.c: Use memmove to concatenate 2 overlapping strings
[deliverable/binutils-gdb.git] / gas / config / tc-crx.c
index 988610b882e274ae6d5631bc50df218b0b19457c..09efa095fdf1d4ebb57fcafb967e4bf4707c0ef7 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-crx.c -- Assembler code for the CRX CPU core.
-   Copyright 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004-2020 Free Software Foundation, Inc.
 
    Contributed by Tomer Levi, NSC, Israel.
    Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
@@ -9,7 +9,7 @@
 
    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,
@@ -23,6 +23,7 @@
    MA 02110-1301, USA.  */
 
 #include "as.h"
+#include "bfd_stdint.h"
 #include "safe-ctype.h"
 #include "dwarf2dbg.h"
 #include "opcode/crx.h"
@@ -56,7 +57,7 @@ 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;
@@ -68,21 +69,21 @@ static struct hash_control *reg_hash;
 /* CRX coprocessor registers hash table.  */
 static struct hash_control *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.  */
 
@@ -147,9 +148,9 @@ 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                 (char *);
-static void    handle_LoadStor         (char *);
-static int     get_cinv_parameters      (char *);
+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);
@@ -205,12 +206,12 @@ get_opflags (operand_type op)
 static reg
 get_register (char *reg_name)
 {
-  const reg_entry *reg;
+  const reg_entry *rreg;
 
-  reg = (const reg_entry *) hash_find (reg_hash, reg_name);
+  rreg = (const reg_entry *) hash_find (reg_hash, reg_name);
 
-  if (reg != NULL)
-    return reg->value.reg_val;
+  if (rreg != NULL)
+    return rreg->value.reg_val;
   else
     return nullregister;
 }
@@ -220,12 +221,12 @@ get_register (char *reg_name)
 static copreg
 get_copregister (char *copreg_name)
 {
-  const reg_entry *copreg;
+  const reg_entry *coreg;
 
-  copreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
+  coreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
 
-  if (copreg != NULL)
-    return copreg->value.copreg_val;
+  if (coreg != NULL)
+    return coreg->value.copreg_val;
   else
     return nullcopregister;
 }
@@ -268,7 +269,8 @@ reset_vars (char *op)
   memset (& output_opcode, '\0', sizeof (output_opcode));
 
   /* Save a copy of the original OP (used in error messages).  */
-  strcpy (ins_parse, op);
+  strncpy (ins_parse, op, sizeof ins_parse - 1);
+  ins_parse [sizeof ins_parse - 1] = 0;
 }
 
 /* This macro decides whether a particular reloc is an entry in a
@@ -306,8 +308,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;
@@ -350,7 +352,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
        }
     }
 
-  assert ((int) fixP->fx_r_type > 0);
+  gas_assert ((int) fixP->fx_r_type > 0);
   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
 
   if (reloc->howto == (reloc_howto_type *) NULL)
@@ -361,7 +363,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
                    bfd_get_reloc_code_name (fixP->fx_r_type));
       return NULL;
     }
-  assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
+  gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
 
   return reloc;
 }
@@ -449,7 +451,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;
 }
@@ -462,58 +464,10 @@ md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
   return;
 }
 
-/* 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;
-
-  if (! target_big_endian)
-    {
-      for (i = prec - 1; i >= 0; i--)
-       {
-         md_number_to_chars (litP, (valueT) words[i], 2);
-         litP += 2;
-       }
-    }
-  else
-    {
-      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, target_big_endian);
 }
 
 /* Apply a fixS (fixup of an instruction or data that we didn't have
@@ -523,7 +477,7 @@ md_atof (int type, char *litP, int *sizeP)
    fixuping relocations of debug sections.  */
 
 void
-md_apply_fix3 (fixS *fixP, valueT *valP, segT seg)
+md_apply_fix (fixS *fixP, valueT *valP, segT seg)
 {
   valueT val = * valP;
   char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
@@ -579,13 +533,13 @@ md_begin (void)
   /* Set up a hash table for the instructions.  */
   if ((crx_inst_hash = hash_new ()) == NULL)
     as_fatal (_("Virtual memory exhausted"));
-  
+
   while (crx_instruction[i].mnemonic != NULL)
     {
       const char *mnemonic = crx_instruction[i].mnemonic;
 
       hashret = hash_insert (crx_inst_hash, mnemonic,
-       (PTR) &crx_instruction[i]);
+                            (void *) &crx_instruction[i]);
 
       if (hashret != NULL && *hashret != '\0')
        as_fatal (_("Can't hash `%s': %s\n"), crx_instruction[i].mnemonic,
@@ -613,9 +567,9 @@ md_begin (void)
     for (regtab = crx_regtab;
         regtab < (crx_regtab + NUMREGS); regtab++)
       {
-       hashret = hash_insert (reg_hash, regtab->name, (PTR) regtab);
+       hashret = hash_insert (reg_hash, regtab->name, (void *) regtab);
        if (hashret)
-         as_fatal (_("Internal Error:  Can't hash %s: %s"),
+         as_fatal (_("Internal error: Can't hash %s: %s"),
                    regtab->name,
                    hashret);
       }
@@ -631,9 +585,10 @@ md_begin (void)
     for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
         copregtab++)
       {
-       hashret = hash_insert (copreg_hash, copregtab->name, (PTR) copregtab);
+       hashret = hash_insert (copreg_hash, copregtab->name,
+                              (void *) copregtab);
        if (hashret)
-         as_fatal (_("Internal Error:  Can't hash %s: %s"),
+         as_fatal (_("Internal error: Can't hash %s: %s"),
                    copregtab->name,
                    hashret);
       }
@@ -642,7 +597,7 @@ md_begin (void)
   linkrelax = 1;
 }
 
-/* Process constants (immediate/absolute) 
+/* Process constants (immediate/absolute)
    and labels (jump targets/Memory locations).  */
 
 static void
@@ -655,7 +610,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:
@@ -696,7 +651,7 @@ process_label_constant (char *str, ins * crx_ins)
        case arg_idxr:
            crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
          break;
-       
+
        case arg_c:
           if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
            crx_ins->rtype = BFD_RELOC_CRX_REL16;
@@ -710,7 +665,7 @@ process_label_constant (char *str, ins * crx_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))
            crx_ins->rtype = BFD_RELOC_CRX_IMM32;
@@ -760,8 +715,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;
@@ -775,10 +730,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;
@@ -791,7 +747,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.  */
@@ -799,7 +756,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)
@@ -813,13 +770,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.  */
@@ -834,7 +791,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.  */
@@ -930,7 +887,7 @@ parse_operand (char *operand, ins * crx_ins)
     default:
        break;
     }
-      
+
   if (strchr (operand, '(') != NULL)
     {
       if (strchr (operand, ',') != NULL
@@ -943,13 +900,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
@@ -1032,7 +989,7 @@ parse_operands (ins * crx_ins, char *operands)
    This routine is used by assembling the 'excp' instruction.  */
 
 static int
-gettrap (char *s)
+gettrap (const char *s)
 {
   const trap_entry *trap;
 
@@ -1044,18 +1001,18 @@ gettrap (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 (char *operands)
+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 :
@@ -1086,9 +1043,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;
@@ -1117,9 +1074,9 @@ parse_insn (ins *insn, char *operands)
 /* Cinv instruction requires special handling.  */
 
 static int
-get_cinv_parameters (char * operand)
+get_cinv_parameters (const char *operand)
 {
-  char *p = operand;
+  const char *p = operand;
   int d_used = 0, i_used = 0, u_used = 0, b_used = 0;
 
   while (*++p != ']')
@@ -1152,7 +1109,7 @@ get_cinv_parameters (char * operand)
 static int
 getreg_image (reg r)
 {
-  const reg_entry *reg;
+  const reg_entry *rreg;
   char *reg_name;
   int is_procreg = 0; /* Nonzero means argument should be processor reg.  */
 
@@ -1162,10 +1119,10 @@ getreg_image (reg r)
 
   /* Check whether the register is in registers table.  */
   if (r < MAX_REG)
-    reg = &crx_regtab[r];
+    rreg = &crx_regtab[r];
   /* Check whether the register is in coprocessor registers table.  */
-  else if (r < MAX_COPREG)
-    reg = &crx_copregtab[r-MAX_REG];
+  else if (r < (int) MAX_COPREG)
+    rreg = &crx_copregtab[r-MAX_REG];
   /* Register not found.  */
   else
     {
@@ -1173,41 +1130,44 @@ getreg_image (reg r)
       return 0;
     }
 
-  reg_name = reg->name;
+  reg_name = rreg->name;
 
 /* 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 (reg->type)
+  switch (rreg->type)
   {
     case CRX_U_REGTYPE:
       if (is_procreg || (instruction->flags & USER_REG))
-       return reg->image;
+       return rreg->image;
       else
        IMAGE_ERR;
+      break;
 
     case CRX_CFG_REGTYPE:
       if (is_procreg)
-       return reg->image;
+       return rreg->image;
       else
        IMAGE_ERR;
+      break;
 
     case CRX_R_REGTYPE:
       if (! is_procreg)
-       return reg->image;
+       return rreg->image;
       else
        IMAGE_ERR;
+      break;
 
     case CRX_C_REGTYPE:
     case CRX_CS_REGTYPE:
-      return reg->image;
+      return rreg->image;
       break;
 
     default:
       IMAGE_ERR;
+      break;
   }
 
   return 0;
@@ -1218,9 +1178,7 @@ getreg_image (reg r)
 static long
 getconstant (long x, int nbits)
 {
-  /* The following expression avoids overflow if
-     'nbits' is the number of bits in 'bfd_vma'.  */
-  return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
+  return x & ((((1U << (nbits - 1)) - 1) << 1) | 1);
 }
 
 /* Print a constant value to 'output_opcode':
@@ -1267,10 +1225,10 @@ 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 overriden.
+        will be overridden.
                 0         1         2         3
            +---------+---------+---------+---------+
            | 'match' |         | X X X X |         |
@@ -1306,14 +1264,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;
@@ -1326,6 +1284,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);
@@ -1363,19 +1322,19 @@ 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.  */
 
 static op_err
 check_range (long *num, int bits, int unsigned flags, int update)
 {
-  long min, max;
-  int retval = OP_LEGAL;
+  uint32_t max;
+  op_err retval = OP_LEGAL;
   int bin;
-  long upper_64kb = 0xFFFF0000;
-  long value = *num;
+  uint32_t upper_64kb = 0xffff0000;
+  uint32_t value = *num;
 
   /* Verify operand value is even.  */
   if (flags & OP_EVEN)
@@ -1399,7 +1358,12 @@ check_range (long *num, int bits, int unsigned flags, int update)
 
   if (flags & OP_SHIFT)
     {
+      /* All OP_SHIFT args are also OP_SIGNED, so we want to keep the
+        sign.  However, right shift of a signed type with a negative
+        value is implementation defined.  See ISO C 6.5.7.  So we use
+        an unsigned type and sign extend afterwards.  */
       value >>= 1;
+      value = (value ^ 0x40000000) - 0x40000000;
       if (update)
        *num = value;
     }
@@ -1421,13 +1385,14 @@ check_range (long *num, int bits, int unsigned flags, int update)
     {
       int is_dispu4 = 0;
 
-      int mul = (instruction->flags & DISPUB4) ? 1 
-               : (instruction->flags & DISPUW4) ? 2
-               : (instruction->flags & DISPUD4) ? 4 : 0;
-      
-      for (bin = 0; bin < cst4_maps; bin++)
+      uint32_t mul = (instruction->flags & DISPUB4 ? 1
+                     : instruction->flags & DISPUW4 ? 2
+                     : instruction->flags & DISPUD4 ? 4
+                     : 0);
+
+      for (bin = 0; bin < crx_cst4_maps; bin++)
        {
-         if (value == (mul * bin))
+         if (value == mul * bin)
            {
              is_dispu4 = 1;
              if (update)
@@ -1442,9 +1407,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 == cst4_map[bin])
+         if (value == (uint32_t) crx_cst4_map[bin])
            {
              is_cst4 = 1;
              if (update)
@@ -1457,17 +1422,19 @@ check_range (long *num, int bits, int unsigned flags, int update)
     }
   else if (flags & OP_SIGNED)
     {
-      max = (1 << (bits - 1)) - 1;
-      min = - (1 << (bits - 1));
-      if ((value > max) || (value < min))
+      max = 1;
+      max = max << (bits - 1);
+      value += max;
+      max = ((max - 1) << 1) | 1;
+      if (value > max)
        retval = OP_OUT_OF_RANGE;
     }
   else if (flags & OP_UNSIGNED)
     {
-      max = ((((1 << (bits - 1)) - 1) << 1) | 1);
-      min = 0;
-      if (((unsigned long) value > (unsigned long) max) 
-           || ((unsigned long) value < (unsigned long) min))
+      max = 1;
+      max = max << (bits - 1);
+      max = ((max - 1) << 1) | 1;
+      if (value > max)
        retval = OP_OUT_OF_RANGE;
     }
   return retval;
@@ -1475,7 +1442,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.
@@ -1528,7 +1495,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);
@@ -1568,19 +1535,19 @@ 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 : 
+         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 
+         /* 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], 
+         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)
@@ -1590,10 +1557,10 @@ assemble_insn (char *mnemonic, ins *insn)
              }
              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 
+                   && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
                         > cur_size[j]))
                  goto next_insn;
        }
@@ -1603,8 +1570,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++;
     }
 
@@ -1632,7 +1599,7 @@ next_insn:
          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)"), 
+         as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
                    invalid_const);
          break;
        default:
@@ -1640,32 +1607,32 @@ next_insn:
          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 : 
+         int j = instruction->flags & REVERSE_MATCH ?
+                 i == 0 ? 1 :
+                 i == 1 ? 0 : 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], 
+         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);
        }
@@ -1676,7 +1643,7 @@ next_insn:
       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]);
         }
     }
@@ -1684,21 +1651,21 @@ next_insn:
   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);
     }
 
@@ -1710,17 +1677,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.  */
 
@@ -1744,7 +1711,7 @@ adjust_if_needed (ins *insn)
         }
     }
 
-  /* 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))
     {
@@ -1769,7 +1736,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;
     }
 
@@ -1788,7 +1755,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;
@@ -1804,7 +1771,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);
 
@@ -1831,7 +1798,7 @@ preprocess_reglist (char *param, int *allocated)
         {
           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);
         }
@@ -1851,8 +1818,8 @@ preprocess_reglist (char *param, int *allocated)
           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
@@ -1878,7 +1845,7 @@ preprocess_reglist (char *param, int *allocated)
        as_bad (_("Maximum %d bits may be set in `mask16' operand"),
                MAX_REGS_IN_MASK16);
 
-next_inst:
+    next_inst:
       while (!ISALNUM (*paramP) && *paramP != '}')
          paramP++;
     }
@@ -1933,7 +1900,7 @@ print_insn (ins *insn)
       words[j++] = output_opcode[i] & 0xFFFF;
     }
 
-  /* Handle relaxtion.  */
+  /* Handle relaxation.  */
   if ((instruction->flags & RELAXABLE) && relocatable)
     {
       int relax_subtype;
@@ -2026,6 +1993,7 @@ md_assemble (char *op)
   if (instruction == NULL)
     {
       as_bad (_("Unknown opcode: `%s'"), op);
+      param[-1] = c;
       return;
     }
 
@@ -2037,8 +2005,12 @@ md_assemble (char *op)
 
   /* Assemble the instruction - return upon failure.  */
   if (assemble_insn (op, &crx_ins) == 0)
-    return;
+    {
+      param[-1] = c;
+      return;
+    }
 
   /* Print the instruction.  */
+  param[-1] = c;
   print_insn (&crx_ins);
 }
This page took 0.041013 seconds and 4 git commands to generate.