/* tc-cr16.c -- Assembler code for the CR16 CPU core.
   Copyright (C) 2007-2016 Free Software Foundation, Inc.

   Contributed by M R Swami Reddy <MR.Swami.Reddy@nsc.com>

   This file is part of GAS, the GNU Assembler.

   GAS is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   GAS is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GAS; see the file COPYING.  If not, write to the
   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "as.h"
#include "safe-ctype.h"
#include "dwarf2dbg.h"
#include "opcode/cr16.h"
#include "elf/cr16.h"


/* Word is considered here as a 16-bit unsigned short int.  */
#define WORD_SHIFT  16

/* Register is 2-byte size.  */
#define REG_SIZE   2

/* Maximum size of a single instruction (in words).  */
#define INSN_MAX_SIZE   3

/* Maximum bits which may be set in a `mask16' operand.  */
#define MAX_REGS_IN_MASK16  8

/* Assign a number NUM, shifted by SHIFT bytes, into a location
   pointed by index BYTE of array 'output_opcode'.  */
#define CR16_PRINT(BYTE, NUM, SHIFT)   output_opcode[BYTE] |= (NUM << SHIFT)

/* Operand errors.  */
typedef enum
  {
    OP_LEGAL = 0,       /* Legal operand.  */
    OP_OUT_OF_RANGE,    /* Operand not within permitted range.  */
    OP_NOT_EVEN         /* Operand is Odd number, should be even.  */
  }
op_err;

/* Opcode mnemonics hash table.  */
static struct hash_control *cr16_inst_hash;
/* CR16 registers hash table.  */
static struct hash_control *reg_hash;
/* CR16 register pair hash table.  */
static struct hash_control *regp_hash;
/* CR16 processor registers hash table.  */
static struct hash_control *preg_hash;
/* CR16 processor registers 32 bit hash table.  */
static struct hash_control *pregp_hash;
/* Current instruction we're assembling.  */
const inst *instruction;


static int code_label = 0;

/* Global variables.  */

/* Array to hold an instruction encoding.  */
long output_opcode[2];

/* Nonzero means a relocatable symbol.  */
int relocatable;

/* A copy of the original instruction (used in error messages).  */
char ins_parse[MAX_INST_LEN];

/* The current processed argument number.  */
int cur_arg_num;

/* Generic assembler global variables which must be defined by all targets.  */

/* Characters which always start a comment.  */
const char comment_chars[] = "#";

/* Characters which start a comment at the beginning of a line.  */
const char line_comment_chars[] = "#";

/* This array holds machine specific line separator characters.  */
const char line_separator_chars[] = ";";

/* Chars that can be used to separate mant from exp in floating point nums.  */
const char EXP_CHARS[] = "eE";

/* Chars that mean this number is a floating point constant as in 0f12.456  */
const char FLT_CHARS[] = "f'";

#ifdef OBJ_ELF
/* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
symbolS * GOT_symbol;
#endif

/* Target-specific multicharacter options, not const-declared at usage.  */
const char *md_shortopts = "";
struct option md_longopts[] =
{
  {NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof (md_longopts);

static void
l_cons (int nbytes)
{
  int c;
  expressionS exp;

#ifdef md_flush_pending_output
    md_flush_pending_output ();
#endif

  if (is_it_end_of_statement ())
    {
      demand_empty_rest_of_line ();
      return;
    }

#ifdef TC_ADDRESS_BYTES
  if (nbytes == 0)
    nbytes = TC_ADDRESS_BYTES ();
#endif

#ifdef md_cons_align
  md_cons_align (nbytes);
#endif

  c = 0;
  do
    {
      unsigned int bits_available = BITS_PER_CHAR * nbytes;
      char *hold = input_line_pointer;

      expression (&exp);

      if (*input_line_pointer == ':')
        {
          /* Bitfields.  */
          long value = 0;

          for (;;)
            {
              unsigned long width;

              if (*input_line_pointer != ':')
                {
                  input_line_pointer = hold;
                  break;
                }
              if (exp.X_op == O_absent)
                {
                  as_warn (_("using a bit field width of zero"));
                  exp.X_add_number = 0;
                  exp.X_op = O_constant;
                }

              if (exp.X_op != O_constant)
                {
                  *input_line_pointer = '\0';
                  as_bad (_("field width \"%s\" too complex for a bitfield"), hold);
                  *input_line_pointer = ':';
                  demand_empty_rest_of_line ();
                  return;
                }

              if ((width = exp.X_add_number) >
                  (unsigned int)(BITS_PER_CHAR * nbytes))
                {
                  as_warn (_("field width %lu too big to fit in %d bytes: truncated to %d bits"), width, nbytes, (BITS_PER_CHAR * nbytes));
                  width = BITS_PER_CHAR * nbytes;
                }                   /* Too big.  */


              if (width > bits_available)
                {
                  /* FIXME-SOMEDAY: backing up and reparsing is wasteful.  */
                  input_line_pointer = hold;
                  exp.X_add_number = value;
                  break;
                }

              /* Skip ':'.  */
              hold = ++input_line_pointer;

              expression (&exp);
              if (exp.X_op != O_constant)
                {
                  char cache = *input_line_pointer;

                  *input_line_pointer = '\0';
                  as_bad (_("field value \"%s\" too complex for a bitfield"), hold);
                  *input_line_pointer = cache;
                  demand_empty_rest_of_line ();
                  return;
                }

              value |= ((~(-(1 << width)) & exp.X_add_number)
                        << ((BITS_PER_CHAR * nbytes) - bits_available));

              if ((bits_available -= width) == 0
                  || is_it_end_of_statement ()
                  || *input_line_pointer != ',')
                break;

              hold = ++input_line_pointer;
              expression (&exp);
            }

          exp.X_add_number = value;
          exp.X_op = O_constant;
          exp.X_unsigned = 1;
        }

      if ((*(input_line_pointer) == '@') && (*(input_line_pointer +1) == 'c'))
        code_label = 1;
      emit_expr (&exp, (unsigned int) nbytes);
      ++c;
      if ((*(input_line_pointer) == '@') && (*(input_line_pointer +1) == 'c'))
        {
          input_line_pointer +=3;
          break;
        }
    }
  while ((*input_line_pointer++ == ','));

  /* Put terminator back into stream.  */
  input_line_pointer--;

  demand_empty_rest_of_line ();
}

/* This table describes all the machine specific pseudo-ops
   the assembler has to support.  The fields are:
   *** Pseudo-op name without dot.
   *** Function to call to execute this pseudo-op.
   *** Integer arg to pass to the function.  */

const pseudo_typeS md_pseudo_table[] =
{
  /* In CR16 machine, align is in bytes (not a ptwo boundary).  */
  {"align", s_align_bytes, 0},
  {"long", l_cons,  4 },
  {"4byte", l_cons, 4 },
  {0, 0, 0}
};

/* CR16 relaxation table.  */
const relax_typeS md_relax_table[] =
{
  /* bCC  */
  {0x7f, -0x80, 2, 1},                  /*  8 */
  {0xfffe, -0x10000, 4, 2},             /* 16 */
  {0xfffffe, -0x1000000, 6, 0},         /* 24 */
};

/* Return the bit size for a given operand.  */

static int
get_opbits (operand_type op)
{
  if (op < MAX_OPRD)
    return cr16_optab[op].bit_size;

  return 0;
}

/* Return the argument type of a given operand.  */

static argtype
get_optype (operand_type op)
{
  if (op < MAX_OPRD)
    return cr16_optab[op].arg_type;
  else
    return nullargs;
}

/* Return the flags of a given operand.  */

static int
get_opflags (operand_type op)
{
  if (op < MAX_OPRD)
    return cr16_optab[op].flags;

  return 0;
}

/* Get the cc code.  */

static int
get_cc (char *cc_name)
{
   unsigned int i;

   for (i = 0; i < cr16_num_cc; i++)
     if (strcmp (cc_name, cr16_b_cond_tab[i]) == 0)
       return i;

   return -1;
}

/* Get the core processor register 'reg_name'.  */

static reg
get_register (char *reg_name)
{
  const reg_entry *rreg;

  rreg = (const reg_entry *) hash_find (reg_hash, reg_name);

  if (rreg != NULL)
    return rreg->value.reg_val;

  return nullregister;
}
/* Get the core processor register-pair 'reg_name'.  */

static reg
get_register_pair (char *reg_name)
{
  const reg_entry *rreg;
  char tmp_rp[16]="\0";

  /* Add '(' and ')' to the reg pair, if its not present.  */
  if (reg_name[0] != '(')
    {
      tmp_rp[0] = '(';
      strcat (tmp_rp, reg_name);
      strcat (tmp_rp,")");
      rreg = (const reg_entry *) hash_find (regp_hash, tmp_rp);
    }
  else
    rreg = (const reg_entry *) hash_find (regp_hash, reg_name);

  if (rreg != NULL)
    return rreg->value.reg_val;

  return nullregister;
}

/* Get the index register 'reg_name'.  */

static reg
get_index_register (char *reg_name)
{
  const reg_entry *rreg;

  rreg = (const reg_entry *) hash_find (reg_hash, reg_name);

  if ((rreg != NULL)
      && ((rreg->value.reg_val == 12) || (rreg->value.reg_val == 13)))
    return rreg->value.reg_val;

  return nullregister;
}
/* Get the core processor index register-pair 'reg_name'.  */

static reg
get_index_register_pair (char *reg_name)
{
  const reg_entry *rreg;

  rreg = (const reg_entry *) hash_find (regp_hash, reg_name);

  if (rreg != NULL)
    {
      if ((rreg->value.reg_val != 1) || (rreg->value.reg_val != 7)
          || (rreg->value.reg_val != 9) || (rreg->value.reg_val > 10))
        return rreg->value.reg_val;

      as_bad (_("Unknown register pair - index relative mode: `%d'"), rreg->value.reg_val);
    }

  return nullregister;
}

/* Get the processor register 'preg_name'.  */

static preg
get_pregister (char *preg_name)
{
  const reg_entry *prreg;

  prreg = (const reg_entry *) hash_find (preg_hash, preg_name);

  if (prreg != NULL)
    return prreg->value.preg_val;

  return nullpregister;
}

/* Get the processor register 'preg_name 32 bit'.  */

static preg
get_pregisterp (char *preg_name)
{
  const reg_entry *prreg;

  prreg = (const reg_entry *) hash_find (pregp_hash, preg_name);

  if (prreg != NULL)
    return prreg->value.preg_val;

  return nullpregister;
}


/* Round up a section size to the appropriate boundary.  */

valueT
md_section_align (segT seg, valueT val)
{
  /* Round .text section to a multiple of 2.  */
  if (seg == text_section)
    return (val + 1) & ~1;
  return val;
}

/* Parse an operand that is machine-specific (remove '*').  */

void
md_operand (expressionS * exp)
{
  char c = *input_line_pointer;

  switch (c)
    {
    case '*':
      input_line_pointer++;
      expression (exp);
      break;
    default:
      break;
    }
}

/* Reset global variables before parsing a new instruction.  */

static void
reset_vars (char *op)
{
  cur_arg_num = relocatable = 0;
  memset (& output_opcode, '\0', sizeof (output_opcode));

  /* Save a copy of the original OP (used in error messages).  */
  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
   switch table.  It is used when relaxing, because the linker needs
   to know about all such entries so that it can adjust them if
   necessary.  */

#define SWITCH_TABLE(fix)                                  \
  (   (fix)->fx_addsy != NULL                              \
   && (fix)->fx_subsy != NULL                              \
   && S_GET_SEGMENT ((fix)->fx_addsy) ==                   \
      S_GET_SEGMENT ((fix)->fx_subsy)                      \
   && S_GET_SEGMENT (fix->fx_addsy) != undefined_section   \
   && (   (fix)->fx_r_type == BFD_RELOC_CR16_NUM8          \
       || (fix)->fx_r_type == BFD_RELOC_CR16_NUM16         \
       || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32         \
       || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32a))

/* See whether we need to force a relocation into the output file.
   This is used to force out switch and PC relative relocations when
   relaxing.  */

int
cr16_force_relocation (fixS *fix)
{
  if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
    return 1;

  return 0;
}

/* Record a fixup for a cons expression.  */

void
cr16_cons_fix_new (fragS *frag, int offset, int len, expressionS *exp,
		   bfd_reloc_code_real_type rtype)
{
  switch (len)
    {
    default: rtype = BFD_RELOC_NONE; break;
    case 1: rtype = BFD_RELOC_CR16_NUM8 ; break;
    case 2: rtype = BFD_RELOC_CR16_NUM16; break;
    case 4:
      if (code_label)
        {
          rtype = BFD_RELOC_CR16_NUM32a;
          code_label = 0;
        }
      else
        rtype = BFD_RELOC_CR16_NUM32;
      break;
    }

  fix_new_exp (frag, offset, len, exp, 0, rtype);
}

/* Generate a relocation entry for a fixup.  */

arelent *
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
{
  arelent * reloc;

  /* If symbols are local and resolved, then no relocation needed.  */
  if ( ((fixP->fx_addsy)
        && (S_GET_SEGMENT (fixP->fx_addsy) == absolute_section))
       || ((fixP->fx_subsy)
	   && (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)))
     return NULL;

  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;

  if (fixP->fx_subsy != NULL)
    {
      if (SWITCH_TABLE (fixP))
        {
          /* Keep the current difference in the addend.  */
          reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
                           - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);

          switch (fixP->fx_r_type)
            {
            case BFD_RELOC_CR16_NUM8:
              fixP->fx_r_type = BFD_RELOC_CR16_SWITCH8;
              break;
            case BFD_RELOC_CR16_NUM16:
              fixP->fx_r_type = BFD_RELOC_CR16_SWITCH16;
              break;
            case BFD_RELOC_CR16_NUM32:
              fixP->fx_r_type = BFD_RELOC_CR16_SWITCH32;
              break;
            case BFD_RELOC_CR16_NUM32a:
              fixP->fx_r_type = BFD_RELOC_CR16_NUM32a;
              break;
            default:
              abort ();
              break;
            }
        }
      else
        {
          /* We only resolve difference expressions in the same section.  */
          as_bad_where (fixP->fx_file, fixP->fx_line,
                        _("can't resolve `%s' {%s section} - `%s' {%s section}"),
                        fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
                        segment_name (fixP->fx_addsy
                                      ? S_GET_SEGMENT (fixP->fx_addsy)
                                      : absolute_section),
                        S_GET_NAME (fixP->fx_subsy),
                        segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
        }
    }
#ifdef OBJ_ELF
      if ((fixP->fx_r_type == BFD_RELOC_CR16_GOT_REGREL20)
           && GOT_symbol
	   && fixP->fx_addsy == GOT_symbol)
	{
	    reloc->addend = fixP->fx_offset = reloc->address;
	}
      else if ((fixP->fx_r_type == BFD_RELOC_CR16_GOTC_REGREL20)
           && GOT_symbol
	   && fixP->fx_addsy == GOT_symbol)
	{
	    reloc->addend = fixP->fx_offset = reloc->address;
	}
#endif

  gas_assert ((int) fixP->fx_r_type > 0);
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);

  if (reloc->howto == NULL)
    {
      as_bad_where (fixP->fx_file, fixP->fx_line,
                    _("internal error: reloc %d (`%s') not supported by object file format"),
                    fixP->fx_r_type,
                    bfd_get_reloc_code_name (fixP->fx_r_type));
      return NULL;
    }
  gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);

  return reloc;
}

/* Prepare machine-dependent frags for relaxation.  */

int
md_estimate_size_before_relax (fragS *fragp, asection *seg)
{
  /* If symbol is undefined or located in a different section,
     select the largest supported relocation.  */
  relax_substateT subtype;
  relax_substateT rlx_state[] = {0, 2};

  for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
    {
      if (fragp->fr_subtype == rlx_state[subtype]
          && (!S_IS_DEFINED (fragp->fr_symbol)
              || seg != S_GET_SEGMENT (fragp->fr_symbol)))
        {
          fragp->fr_subtype = rlx_state[subtype + 1];
          break;
        }
    }

  if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
    abort ();

  return md_relax_table[fragp->fr_subtype].rlx_length;
}

void
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;
  bfd_reloc_code_real_type reloc;

  subseg_change (sec, 0);

  switch (fragP->fr_subtype)
    {
    case 0:
      reloc = BFD_RELOC_CR16_DISP8;
      break;
    case 1:
      /* If the subtype is not changed due to :m operand qualifier,
         then no need to update the opcode value.  */
      if ((int)opcode[1] != 0x18)
        {
          opcode[0] = (opcode[0] & 0xf0);
          opcode[1] = 0x18;
        }
      reloc = BFD_RELOC_CR16_DISP16;
      break;
    case 2:
      /* If the subtype is not changed due to :l operand qualifier,
         then no need to update the opcode value.  */
      if ((int)opcode[1] != 0)
        {
          opcode[2] = opcode[0];
          opcode[0] = opcode[1];
          opcode[1] = 0x0;
        }
      reloc = BFD_RELOC_CR16_DISP24;
      break;
    default:
      abort();
    }

  fix_new (fragP, fragP->fr_fix,
           bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
           fragP->fr_symbol, fragP->fr_offset, 1, reloc);
  fragP->fr_var = 0;
  fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
}

symbolS *
md_undefined_symbol (char *name)
{
  if (*name == '_' && *(name + 1) == 'G'
      && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
   {
     if (!GOT_symbol)
       {
         if (symbol_find (name))
             as_bad (_("GOT already in symbol table"));
          GOT_symbol = symbol_new (name, undefined_section,
                                   (valueT) 0, &zero_address_frag);
       }
     return GOT_symbol;
   }
  return 0;
}

/* Process machine-dependent command line options.  Called once for
   each option on the command line that the machine-independent part of
   GAS does not understand.  */

int
md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
{
  return 0;
}

/* Machine-dependent usage-output.  */

void
md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
{
  return;
}

const char *
md_atof (int type, char *litP, int *sizeP)
{
  return ieee_md_atof (type, litP, sizeP, target_big_endian);
}

/* Apply a fixS (fixup of an instruction or data that we didn't have
   enough info to complete immediately) to the data in a frag.
   Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
   relaxation of debug sections, this function is called only when
   fixuping relocations of debug sections.  */

void
md_apply_fix (fixS *fixP, valueT *valP, segT seg)
{
  valueT val = * valP;

  if (fixP->fx_addsy == NULL
      && fixP->fx_pcrel == 0)
    fixP->fx_done = 1;
  else if (fixP->fx_pcrel == 1
      && fixP->fx_addsy != NULL
      && S_GET_SEGMENT (fixP->fx_addsy) == seg)
    fixP->fx_done = 1;
  else
    fixP->fx_done = 0;

  if (fixP->fx_addsy != NULL && !fixP->fx_pcrel)
    {
      val = fixP->fx_offset;
      fixP->fx_done = 1;
    }

  if (fixP->fx_done)
    {
      char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;

      fixP->fx_offset = 0;

      switch (fixP->fx_r_type)
	{
	case BFD_RELOC_CR16_NUM8:
	  bfd_put_8 (stdoutput, (unsigned char) val, buf);
	  break;
	case BFD_RELOC_CR16_NUM16:
	  bfd_put_16 (stdoutput, val, buf);
	  break;
	case BFD_RELOC_CR16_NUM32:
	  bfd_put_32 (stdoutput, val, buf);
	  break;
	case BFD_RELOC_CR16_NUM32a:
	  bfd_put_32 (stdoutput, val, buf);
	  break;
	default:
	  /* We shouldn't ever get here because linkrelax is nonzero.  */
	  abort ();
	  break;
	}
      fixP->fx_done = 0;
    }
  else
    fixP->fx_offset = * valP;
}

/* The location from which a PC relative jump should be calculated,
   given a PC relative reloc.  */

long
md_pcrel_from (fixS *fixp)
{
  return fixp->fx_frag->fr_address + fixp->fx_where;
}

static void
initialise_reg_hash_table (struct hash_control ** hash_table,
                           const reg_entry * register_table,
                           const unsigned int num_entries)
{
  const reg_entry * rreg;
  const char *hashret;

  if ((* hash_table = hash_new ()) == NULL)
    as_fatal (_("Virtual memory exhausted"));

  for (rreg = register_table;
       rreg < (register_table + num_entries);
       rreg++)
    {
      hashret = hash_insert (* hash_table, rreg->name, (char *) rreg);
      if (hashret)
        as_fatal (_("Internal Error:  Can't hash %s: %s"),
                  rreg->name, hashret);
    }
}

/* This function is called once, at assembler startup time.  This should
   set up all the tables, etc that the MD part of the assembler needs.  */

void
md_begin (void)
{
  int i = 0;

  /* Set up a hash table for the instructions.  */
  if ((cr16_inst_hash = hash_new ()) == NULL)
    as_fatal (_("Virtual memory exhausted"));

  while (cr16_instruction[i].mnemonic != NULL)
    {
      const char *hashret;
      const char *mnemonic = cr16_instruction[i].mnemonic;

      hashret = hash_insert (cr16_inst_hash, mnemonic,
                             (char *)(cr16_instruction + i));

      if (hashret != NULL && *hashret != '\0')
        as_fatal (_("Can't hash `%s': %s\n"), cr16_instruction[i].mnemonic,
                  *hashret == 0 ? _("(unknown reason)") : hashret);

      /* Insert unique names into hash table.  The CR16 instruction set
         has many identical opcode names that have different opcodes based
         on the operands.  This hash table then provides a quick index to
         the first opcode with a particular name in the opcode table.  */
      do
        {
          ++i;
        }
      while (cr16_instruction[i].mnemonic != NULL
             && streq (cr16_instruction[i].mnemonic, mnemonic));
    }

  /* Initialize reg_hash hash table.  */
  initialise_reg_hash_table (& reg_hash, cr16_regtab, NUMREGS);
  /* Initialize regp_hash hash table.  */
  initialise_reg_hash_table (& regp_hash, cr16_regptab, NUMREGPS);
  /* Initialize preg_hash hash table.  */
  initialise_reg_hash_table (& preg_hash, cr16_pregtab, NUMPREGS);
  /* Initialize pregp_hash hash table.  */
  initialise_reg_hash_table (& pregp_hash, cr16_pregptab, NUMPREGPS);

  /*  Set linkrelax here to avoid fixups in most sections.  */
  linkrelax = 1;
}

/* Process constants (immediate/absolute)
   and labels (jump targets/Memory locations).  */

static void
process_label_constant (char *str, ins * cr16_ins)
{
  char *saved_input_line_pointer;
  int symbol_with_at = 0;
  int symbol_with_s = 0;
  int symbol_with_m = 0;
  int symbol_with_l = 0;
  int symbol_with_at_got = 0;
  int symbol_with_at_gotc = 0;
  argument *cur_arg = cr16_ins->arg + cur_arg_num;  /* Current argument.  */

  saved_input_line_pointer = input_line_pointer;
  input_line_pointer = str;

  expression (&cr16_ins->exp);

  switch (cr16_ins->exp.X_op)
    {
    case O_big:
    case O_absent:
      /* Missing or bad expr becomes absolute 0.  */
      as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
              str);
      cr16_ins->exp.X_op = O_constant;
      cr16_ins->exp.X_add_number = 0;
      cr16_ins->exp.X_add_symbol = NULL;
      cr16_ins->exp.X_op_symbol = NULL;
      /* Fall through.  */

    case O_constant:
      cur_arg->X_op = O_constant;
      cur_arg->constant = cr16_ins->exp.X_add_number;
      break;

    case O_symbol:
    case O_subtract:
    case O_add:
      cur_arg->X_op = O_symbol;
      cur_arg->constant = cr16_ins->exp.X_add_number;
      cr16_ins->exp.X_add_number = 0;
      cr16_ins->rtype = BFD_RELOC_NONE;
      relocatable = 1;

      if (strneq (input_line_pointer, "@c", 2))
        symbol_with_at = 1;

      if (strneq (input_line_pointer, "@l", 2)
          || strneq (input_line_pointer, ":l", 2))
        symbol_with_l = 1;

      if (strneq (input_line_pointer, "@m", 2)
          || strneq (input_line_pointer, ":m", 2))
        symbol_with_m = 1;

      if (strneq (input_line_pointer, "@s", 2)
          || strneq (input_line_pointer, ":s", 2))
        symbol_with_s = 1;

      if (strneq (input_line_pointer, "@cGOT", 5)
          || strneq (input_line_pointer, "@cgot", 5))
	{
	  if (GOT_symbol == NULL)
           GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);

          symbol_with_at_gotc = 1;
	}
      else if (strneq (input_line_pointer, "@GOT", 4)
          || strneq (input_line_pointer, "@got", 4))
	{
          if ((strneq (input_line_pointer, "+", 1))
	       || (strneq (input_line_pointer, "-", 1)))
           as_warn (_("GOT bad expression with %s."), input_line_pointer);

	  if (GOT_symbol == NULL)
           GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);

          symbol_with_at_got = 1;
	}

      switch (cur_arg->type)
        {
        case arg_cr:
          if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
            {
	      if (symbol_with_at_got)
	          cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
	      else if (symbol_with_at_gotc)
	          cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
	      else if (cur_arg->size == 20)
                cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
              else
                cr16_ins->rtype = BFD_RELOC_CR16_REGREL20a;
            }
          break;

        case arg_crp:
          if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
	   {
	    if (symbol_with_at_got)
	      cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
	    else if (symbol_with_at_gotc)
	      cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
	   } else {
            switch (instruction->size)
              {
              case 1:
                switch (cur_arg->size)
                  {
                  case 0:
                    cr16_ins->rtype = BFD_RELOC_CR16_REGREL0;
                    break;
                  case 4:
                    if (IS_INSN_MNEMONIC ("loadb") || IS_INSN_MNEMONIC ("storb"))
                      cr16_ins->rtype = BFD_RELOC_CR16_REGREL4;
                    else
                      cr16_ins->rtype = BFD_RELOC_CR16_REGREL4a;
                    break;
                  default: break;
                  }
                break;
              case 2:
                cr16_ins->rtype = BFD_RELOC_CR16_REGREL16;
                break;
              case 3:
                if (cur_arg->size == 20)
                  cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
                else
                  cr16_ins->rtype = BFD_RELOC_CR16_REGREL20a;
                break;
              default:
                break;
              }
	    }
          break;

        case arg_idxr:
          if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
	    {
	      if (symbol_with_at_got)
	        cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
	      else if (symbol_with_at_gotc)
	        cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
	      else
                cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
	    }
          break;

        case arg_idxrp:
          if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
	    {
	    if (symbol_with_at_got)
	      cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
	    else if (symbol_with_at_gotc)
	      cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
	    else {
            switch (instruction->size)
              {
              case 1: cr16_ins->rtype = BFD_RELOC_CR16_REGREL0; break;
              case 2: cr16_ins->rtype = BFD_RELOC_CR16_REGREL14; break;
              case 3: cr16_ins->rtype = BFD_RELOC_CR16_REGREL20; break;
              default: break;
              }
	    }
	   }
          break;

        case arg_c:
          if (IS_INSN_MNEMONIC ("bal"))
            cr16_ins->rtype = BFD_RELOC_CR16_DISP24;
          else if (IS_INSN_TYPE (BRANCH_INS))
            {
              if (symbol_with_l)
                cr16_ins->rtype = BFD_RELOC_CR16_DISP24;
              else if (symbol_with_m)
                cr16_ins->rtype = BFD_RELOC_CR16_DISP16;
              else
                cr16_ins->rtype = BFD_RELOC_CR16_DISP8;
            }
          else if (IS_INSN_TYPE (STOR_IMM_INS) || IS_INSN_TYPE (LD_STOR_INS)
                   || IS_INSN_TYPE (CSTBIT_INS))
            {
	      if (symbol_with_s)
                as_bad (_("operand %d: illegal use expression: `%s`"), cur_arg_num + 1, str);
	      if (symbol_with_at_got)
	        cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
	      else if (symbol_with_at_gotc)
	        cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
	      else if (symbol_with_m)
                cr16_ins->rtype = BFD_RELOC_CR16_ABS20;
              else /* Default to (symbol_with_l) */
                cr16_ins->rtype = BFD_RELOC_CR16_ABS24;
            }
          else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
            cr16_ins->rtype = BFD_RELOC_CR16_DISP4;
          break;

        case arg_ic:
          if (IS_INSN_TYPE (ARITH_INS))
            {
	      if (symbol_with_at_got)
	        cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
	      else if (symbol_with_at_gotc)
	        cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
	      else if (symbol_with_s)
                cr16_ins->rtype = BFD_RELOC_CR16_IMM4;
              else if (symbol_with_m)
                cr16_ins->rtype = BFD_RELOC_CR16_IMM20;
              else if (symbol_with_at)
                cr16_ins->rtype = BFD_RELOC_CR16_IMM32a;
              else /* Default to (symbol_with_l) */
                cr16_ins->rtype = BFD_RELOC_CR16_IMM32;
            }
          else if (IS_INSN_TYPE (ARITH_BYTE_INS))
            {
              cr16_ins->rtype = BFD_RELOC_CR16_IMM16;
            }
          break;
        default:
          break;
        }
      break;

    default:
      cur_arg->X_op = cr16_ins->exp.X_op;
      break;
    }

  input_line_pointer = saved_input_line_pointer;
  return;
}

/* Retrieve the opcode image of a given register.
   If the register is illegal for the current instruction,
   issue an error.  */

static int
getreg_image (reg r)
{
  const reg_entry *rreg;
  char *reg_name;
  int is_procreg = 0; /* Nonzero means argument should be processor reg.  */

  /* Check whether the register is in registers table.  */
  if (r < MAX_REG)
    rreg = cr16_regtab + r;
  else /* Register not found.  */
    {
      as_bad (_("Unknown register: `%d'"), r);
      return 0;
    }

  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;

  switch (rreg->type)
    {
    case CR16_R_REGTYPE:
      if (! is_procreg)
        return rreg->image;
      else
        IMAGE_ERR;

    case CR16_P_REGTYPE:
      return rreg->image;
      break;

    default:
      IMAGE_ERR;
    }

  return 0;
}

/* Parsing different types of operands
   -> constants             Immediate/Absolute/Relative numbers
   -> Labels                Relocatable symbols
   -> (reg pair base)       Register pair base
   -> (rbase)               Register base
   -> disp(rbase)           Register relative
   -> [rinx]disp(reg pair)  Register index with reg pair mode
   -> disp(rbase,ridx,scl)  Register index mode.  */

static void
set_operand (char *operand, ins * cr16_ins)
{
  char *operandS; /* Pointer to start of sub-opearand.  */
  char *operandE; /* Pointer to end of sub-opearand.  */

  argument *cur_arg = &cr16_ins->arg[cur_arg_num]; /* Current argument.  */

  /* Initialize pointers.  */
  operandS = operandE = operand;

  switch (cur_arg->type)
    {
    case arg_ic:    /* Case $0x18.  */
      operandS++;
      /* Fall through.  */
    case arg_c:     /* Case 0x18.  */
      /* Set constant.  */
      process_label_constant (operandS, cr16_ins);

      if (cur_arg->type != arg_ic)
        cur_arg->type = arg_c;
      break;

    case arg_icr:   /* Case $0x18(r1).  */
      operandS++;
    case arg_cr:    /* Case 0x18(r1).   */
      /* Set displacement constant.  */
      while (*operandE != '(')
        operandE++;
      *operandE = '\0';
      process_label_constant (operandS, cr16_ins);
      operandS = operandE;
      /* Fall through.  */
    case arg_rbase: /* Case (r1) or (r1,r0).  */
      operandS++;
      /* Set register base.  */
      while (*operandE != ')')
        operandE++;
      *operandE = '\0';
      if ((cur_arg->r = get_register (operandS)) == nullregister)
         as_bad (_("Illegal register `%s' in Instruction `%s'"),
              operandS, ins_parse);

      /* set the arg->rp, if reg is "r12" or "r13" or "14" or "15" */
      if ((cur_arg->type != arg_rbase)
          && ((getreg_image (cur_arg->r) == 12)
              || (getreg_image (cur_arg->r) == 13)
              || (getreg_image (cur_arg->r) == 14)
              || (getreg_image (cur_arg->r) == 15)))
         {
           cur_arg->type = arg_crp;
           cur_arg->rp = cur_arg->r;
         }
      break;

    case arg_crp:    /* Case 0x18(r1,r0).   */
      /* Set displacement constant.  */
      while (*operandE != '(')
        operandE++;
      *operandE = '\0';
      process_label_constant (operandS, cr16_ins);
      operandS = operandE;
      operandS++;
      /* Set register pair base.  */
      while (*operandE != ')')
        operandE++;
      *operandE = '\0';
      if ((cur_arg->rp = get_register_pair (operandS)) == nullregister)
         as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
              operandS, ins_parse);
      break;

    case arg_idxr:
      /* Set register pair base.  */
      if ((strchr (operandS,'(') != NULL))
        {
         while ((*operandE != '(') && (! ISSPACE (*operandE)))
           operandE++;
         if ((cur_arg->rp = get_index_register_pair (operandE)) == nullregister)
              as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
                            operandS, ins_parse);
         *operandE++ = '\0';
         cur_arg->type = arg_idxrp;
        }
      else
        cur_arg->rp = -1;

       operandE = operandS;
      /* Set displacement constant.  */
      while (*operandE != ']')
        operandE++;
      process_label_constant (++operandE, cr16_ins);
      *operandE++ = '\0';
      operandE = operandS;

      /* Set index register .  */
      operandS = strchr (operandE,'[');
      if (operandS != NULL)
        { /* Eliminate '[', detach from rest of operand.  */
          *operandS++ = '\0';

          operandE = strchr (operandS, ']');

          if (operandE == NULL)
            as_bad (_("unmatched '['"));
          else
            { /* Eliminate ']' and make sure it was the last thing
                 in the string.  */
              *operandE = '\0';
              if (*(operandE + 1) != '\0')
                as_bad (_("garbage after index spec ignored"));
            }
        }

      if ((cur_arg->i_r = get_index_register (operandS)) == nullregister)
        as_bad (_("Illegal register `%s' in Instruction `%s'"),
                operandS, ins_parse);
      *operandE = '\0';
      *operandS = '\0';
      break;

    default:
      break;
    }
}

/* Parse a single operand.
   operand - Current operand to parse.
   cr16_ins - Current assembled instruction.  */

static void
parse_operand (char *operand, ins * cr16_ins)
{
  int ret_val;
  argument *cur_arg = cr16_ins->arg + cur_arg_num; /* Current argument.  */

  /* Initialize the type to NULL before parsing.  */
  cur_arg->type = nullargs;

  /* Check whether this is a condition code .  */
  if ((IS_INSN_MNEMONIC ("b")) && ((ret_val = get_cc (operand)) != -1))
    {
      cur_arg->type = arg_cc;
      cur_arg->cc = ret_val;
      cur_arg->X_op = O_register;
      return;
    }

  /* Check whether this is a general processor register.  */
  if ((ret_val = get_register (operand)) != nullregister)
    {
      cur_arg->type = arg_r;
      cur_arg->r = ret_val;
      cur_arg->X_op = 0;
      return;
    }

  /* Check whether this is a general processor register pair.  */
  if ((operand[0] == '(')
      && ((ret_val = get_register_pair (operand)) != nullregister))
    {
      cur_arg->type = arg_rp;
      cur_arg->rp = ret_val;
      cur_arg->X_op = O_register;
      return;
    }

  /* Check whether the operand is a processor register.
     For "lprd" and "sprd" instruction, only 32 bit
     processor registers used.  */
  if (!(IS_INSN_MNEMONIC ("lprd") || (IS_INSN_MNEMONIC ("sprd")))
      && ((ret_val = get_pregister (operand)) != nullpregister))
    {
      cur_arg->type = arg_pr;
      cur_arg->pr = ret_val;
      cur_arg->X_op = O_register;
      return;
    }

  /* Check whether this is a processor register - 32 bit.  */
  if ((ret_val = get_pregisterp (operand)) != nullpregister)
    {
      cur_arg->type = arg_prp;
      cur_arg->prp = ret_val;
      cur_arg->X_op = O_register;
      return;
    }

  /* Deal with special characters.  */
  switch (operand[0])
    {
    case '$':
      if (strchr (operand, '(') != NULL)
        cur_arg->type = arg_icr;
      else
        cur_arg->type = arg_ic;
      goto set_params;
      break;

    case '(':
      cur_arg->type = arg_rbase;
      goto set_params;
      break;

    case '[':
      cur_arg->type = arg_idxr;
      goto set_params;
      break;

    default:
      break;
    }

  if (strchr (operand, '(') != NULL)
    {
      if (strchr (operand, ',') != NULL
          && (strchr (operand, ',') > strchr (operand, '(')))
        cur_arg->type = arg_crp;
      else
        cur_arg->type = arg_cr;
    }
  else
    cur_arg->type = arg_c;

/* Parse an operand according to its type.  */
 set_params:
  cur_arg->constant = 0;
  set_operand (operand, cr16_ins);
}

/* Parse the various operands. Each operand is then analyzed to fillup
   the fields in the cr16_ins data structure.  */

static void
parse_operands (ins * cr16_ins, char *operands)
{
  char *operandS;            /* Operands string.  */
  char *operandH, *operandT; /* Single operand head/tail pointers.  */
  int allocated = 0;         /* Indicates a new operands string was allocated.*/
  char *operand[MAX_OPERANDS];/* Separating the operands.  */
  int op_num = 0;             /* Current operand number we are parsing.  */
  int bracket_flag = 0;       /* Indicates a bracket '(' was found.  */
  int sq_bracket_flag = 0;    /* Indicates a square bracket '[' was found.  */

  /* Preprocess the list of registers, if necessary.  */
  operandS = operandH = operandT = operands;

  while (*operandT != '\0')
    {
      if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
        {
          *operandT++ = '\0';
          operand[op_num++] = strdup (operandH);
          operandH = operandT;
          continue;
        }

      if (*operandT == ' ')
        as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);

      if (*operandT == '(')
        bracket_flag = 1;
      else if (*operandT == '[')
        sq_bracket_flag = 1;

      if (*operandT == ')')
        {
          if (bracket_flag)
            bracket_flag = 0;
          else
            as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
        }
      else if (*operandT == ']')
        {
          if (sq_bracket_flag)
            sq_bracket_flag = 0;
          else
            as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
        }

      if (bracket_flag == 1 && *operandT == ')')
        bracket_flag = 0;
      else if (sq_bracket_flag == 1 && *operandT == ']')
        sq_bracket_flag = 0;

      operandT++;
    }

  /* Adding the last operand.  */
  operand[op_num++] = strdup (operandH);
  cr16_ins->nargs = op_num;

  /* Verifying correct syntax of operands (all brackets should be closed).  */
  if (bracket_flag || sq_bracket_flag)
    as_fatal (_("Missing matching brackets : `%s'"), ins_parse);

  /* Now we parse each operand separately.  */
  for (op_num = 0; op_num < cr16_ins->nargs; op_num++)
    {
      cur_arg_num = op_num;
      parse_operand (operand[op_num], cr16_ins);
      free (operand[op_num]);
    }

  if (allocated)
    free (operandS);
}

/* Get the trap index in dispatch table, given its name.
   This routine is used by assembling the 'excp' instruction.  */

static int
gettrap (char *s)
{
  const trap_entry *trap;

  for (trap = cr16_traps; trap < (cr16_traps + NUMTRAPS); trap++)
    if (strcasecmp (trap->name, s) == 0)
      return trap->entry;

  /* To make compatible with CR16 4.1 tools, the below 3-lines of
   * code added. Refer: Development Tracker item #123 */
  for (trap = cr16_traps; trap < (cr16_traps + NUMTRAPS); trap++)
    if (trap->entry  == (unsigned int) atoi (s))
      return trap->entry;

  as_bad (_("Unknown exception: `%s'"), s);
  return 0;
}

/* Top level module where instruction parsing starts.
   cr16_ins - data structure holds some information.
   operands - holds the operands part of the whole instruction.  */

static void
parse_insn (ins *insn, char *operands)
{
  int i;

  /* Handle instructions with no operands.  */
  for (i = 0; cr16_no_op_insn[i] != NULL; i++)
  {
    if (streq (cr16_no_op_insn[i], instruction->mnemonic))
    {
      insn->nargs = 0;
      return;
    }
  }

  /* Handle 'excp' instructions.  */
  if (IS_INSN_MNEMONIC ("excp"))
    {
      insn->nargs = 1;
      insn->arg[0].type = arg_ic;
      insn->arg[0].constant = gettrap (operands);
      insn->arg[0].X_op = O_constant;
      return;
    }

  if (operands != NULL)
    parse_operands (insn, operands);
}

/* bCC instruction requires special handling.  */
static char *
get_b_cc (char * op)
{
  unsigned int i;
  char op1[5];

  for (i = 1; i < strlen (op); i++)
     op1[i-1] = op[i];

  op1[i-1] = '\0';

  for (i = 0; i < cr16_num_cc ; i++)
    if (streq (op1, cr16_b_cond_tab[i]))
      return (char *) cr16_b_cond_tab[i];

   return NULL;
}

/* bCC instruction requires special handling.  */
static int
is_bcc_insn (char * op)
{
  if (!(streq (op, "bal") || streq (op, "beq0b") || streq (op, "bnq0b")
        || streq (op, "beq0w") || streq (op, "bnq0w")))
    if ((op[0] == 'b') && (get_b_cc (op) != NULL))
      return 1;
  return 0;
}

/* Cinv instruction requires special handling.  */

static void
check_cinv_options (char * operand)
{
  char *p = operand;

  while (*++p != ']')
    {
      switch (*p)
	{
	case ',':
	case ' ':
	case 'i':
	case 'u':
	case 'd':
	  break;
	default:
	  as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
	}
    }
}

/* Retrieve the opcode image of a given register pair.
   If the register is illegal for the current instruction,
   issue an error.  */

static int
getregp_image (reg r)
{
  const reg_entry *rreg;
  char *reg_name;

  /* Check whether the register is in registers table.  */
  if (r < MAX_REG)
    rreg = cr16_regptab + r;
  /* Register not found.  */
  else
    {
      as_bad (_("Unknown register pair: `%d'"), r);
      return 0;
    }

  reg_name = rreg->name;

/* Issue a error message when register  pair is illegal.  */
#define RPAIR_IMAGE_ERR \
  as_bad (_("Illegal register pair (`%s') in Instruction: `%s'"), \
            reg_name, ins_parse);                                 \
  break;

  switch (rreg->type)
    {
    case CR16_RP_REGTYPE:
      return rreg->image;
    default:
      RPAIR_IMAGE_ERR;
    }

  return 0;
}

/* Retrieve the opcode image of a given index register pair.
   If the register is illegal for the current instruction,
   issue an error.  */

static int
getidxregp_image (reg r)
{
  const reg_entry *rreg;
  char *reg_name;

  /* Check whether the register is in registers table.  */
  if (r < MAX_REG)
    rreg = cr16_regptab + r;
  /* Register not found.  */
  else
    {
      as_bad (_("Unknown register pair: `%d'"), r);
      return 0;
    }

  reg_name = rreg->name;

/* Issue a error message when register  pair is illegal.  */
#define IDX_RPAIR_IMAGE_ERR \
  as_bad (_("Illegal index register pair (`%s') in Instruction: `%s'"), \
            reg_name, ins_parse);                                       \

  if (rreg->type == CR16_RP_REGTYPE)
    {
      switch (rreg->image)
        {
        case 0:  return 0; break;
        case 2:  return 1; break;
        case 4:  return 2; break;
        case 6:  return 3; break;
        case 8:  return 4; break;
        case 10: return 5; break;
        case 3:  return 6; break;
        case 5:  return 7; break;
        default:
          break;
        }
    }

  IDX_RPAIR_IMAGE_ERR;
  return 0;
}

/* Retrieve the opcode image of a given processort register.
   If the register is illegal for the current instruction,
   issue an error.  */
static int
getprocreg_image (int r)
{
  const reg_entry *rreg;
  char *reg_name;

  /* Check whether the register is in registers table.  */
  if (r >= MAX_REG && r < MAX_PREG)
    rreg = &cr16_pregtab[r - MAX_REG];
  /* Register not found.  */
  else
    {
      as_bad (_("Unknown processor register : `%d'"), r);
      return 0;
    }

  reg_name = rreg->name;

/* Issue a error message when register  pair is illegal.  */
#define PROCREG_IMAGE_ERR \
  as_bad (_("Illegal processor register (`%s') in Instruction: `%s'"), \
            reg_name, ins_parse);                                      \
  break;

  switch (rreg->type)
    {
    case CR16_P_REGTYPE:
      return rreg->image;
    default:
      PROCREG_IMAGE_ERR;
    }

  return 0;
}

/* Retrieve the opcode image of a given processort register.
   If the register is illegal for the current instruction,
   issue an error.  */
static int
getprocregp_image (int r)
{
  const reg_entry *rreg;
  char *reg_name;
  int pregptab_disp = 0;

  /* Check whether the register is in registers table.  */
  if (r >= MAX_REG && r < MAX_PREG)
    {
      r = r - MAX_REG;
      switch (r)
        {
        case 4: pregptab_disp = 1;  break;
        case 6: pregptab_disp = 2;  break;
        case 8:
        case 9:
        case 10:
          pregptab_disp = 3;  break;
        case 12:
          pregptab_disp = 4;  break;
        case 14:
          pregptab_disp = 5;  break;
        default: break;
        }
      rreg = &cr16_pregptab[r - pregptab_disp];
    }
  /* Register not found.  */
  else
    {
      as_bad (_("Unknown processor register (32 bit) : `%d'"), r);
      return 0;
    }

  reg_name = rreg->name;

/* Issue a error message when register  pair is illegal.  */
#define PROCREGP_IMAGE_ERR \
  as_bad (_("Illegal 32 bit - processor register (`%s') in Instruction: `%s'"),\
            reg_name, ins_parse);                                              \
  break;

  switch (rreg->type)
    {
    case CR16_P_REGTYPE:
      return rreg->image;
    default:
      PROCREGP_IMAGE_ERR;
    }

  return 0;
}

/* Routine used to represent integer X using NBITS bits.  */

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));
}

/* Print a constant value to 'output_opcode':
   ARG holds the operand's type and value.
   SHIFT represents the location of the operand to be print into.
   NBITS determines the size (in bits) of the constant.  */

static void
print_constant (int nbits, int shift, argument *arg)
{
  unsigned long mask = 0;

  long constant = getconstant (arg->constant, nbits);

  switch (nbits)
    {
    case 32:
    case 28:
      /* mask the upper part of the constant, that is, the bits
         going to the lowest byte of output_opcode[0].
         The upper part of output_opcode[1] is always filled,
         therefore it is always masked with 0xFFFF.  */
      mask = (1 << (nbits - 16)) - 1;
      /* Divide the constant between two consecutive words :
         0        1         2         3
         +---------+---------+---------+---------+
         |         | X X X X | x X x X |         |
         +---------+---------+---------+---------+
         output_opcode[0]    output_opcode[1]     */

      CR16_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
      CR16_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
      break;

    case 21:
      if ((nbits == 21) && (IS_INSN_TYPE (LD_STOR_INS)))
	nbits = 20;
      /* Fall through.  */
    case 24:
    case 22:
    case 20:
      /* mask the upper part of the constant, that is, the bits
         going to the lowest byte of output_opcode[0].
         The upper part of output_opcode[1] is always filled,
         therefore it is always masked with 0xFFFF.  */
      mask = (1 << (nbits - 16)) - 1;
      /* Divide the constant between two consecutive words :
         0        1         2          3
         +---------+---------+---------+---------+
         |         | X X X X | - X - X |         |
         +---------+---------+---------+---------+
         output_opcode[0]    output_opcode[1]     */

      if ((instruction->size > 2) && (shift == WORD_SHIFT))
        {
          if (arg->type == arg_idxrp)
            {
              CR16_PRINT (0, ((constant >> WORD_SHIFT) & mask) << 8, 0);
              CR16_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
            }
          else
            {
              CR16_PRINT (0, (((((constant >> WORD_SHIFT) & mask) << 8) & 0x0f00) | ((((constant >> WORD_SHIFT) & mask) >> 4) & 0xf)),0);
              CR16_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
            }
        }
      else
        CR16_PRINT (0, constant, shift);
      break;

    case 14:
      if (arg->type == arg_idxrp)
        {
          if (instruction->size == 2)
            {
              CR16_PRINT (0, ((constant)      & 0xf), shift);        /* 0-3 bits.  */
              CR16_PRINT (0, ((constant >> 4) & 0x3), (shift + 20)); /* 4-5 bits.  */
              CR16_PRINT (0, ((constant >> 6) & 0x3), (shift + 14)); /* 6-7 bits.  */
              CR16_PRINT (0, ((constant >> 8) & 0x3f), (shift + 8)); /* 8-13 bits.  */
            }
          else
            CR16_PRINT (0, constant, shift);
        }
      break;

    case 16:
    case 12:
      /* 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.
         0        1         2         3
         +---------+---------+---------+---------+
         | 'match' |         | X X X X |         |
         +---------+---------+---------+---------+
         output_opcode[0]    output_opcode[1]     */

      if ((instruction->size > 2) && (shift == WORD_SHIFT))
        CR16_PRINT (1, constant, WORD_SHIFT);
      else
        CR16_PRINT (0, constant, shift);
      break;

    case 8:
      CR16_PRINT (0, ((constant / 2) & 0xf), shift);
      CR16_PRINT (0, ((constant / 2) >> 4), (shift + 8));
      break;

    default:
      CR16_PRINT (0, constant,  shift);
      break;
    }
}

/* Print an operand to 'output_opcode', which later on will be
   printed to the object file:
   ARG holds the operand's type, size and value.
   SHIFT represents the printing location of operand.
   NBITS determines the size (in bits) of a constant operand.  */

static void
print_operand (int nbits, int shift, argument *arg)
{
  switch (arg->type)
    {
    case arg_cc:
      CR16_PRINT (0, arg->cc, shift);
      break;

    case arg_r:
      CR16_PRINT (0, getreg_image (arg->r), shift);
      break;

    case arg_rp:
      CR16_PRINT (0, getregp_image (arg->rp), shift);
      break;

    case arg_pr:
      CR16_PRINT (0, getprocreg_image (arg->pr), shift);
      break;

    case arg_prp:
      CR16_PRINT (0, getprocregp_image (arg->prp), shift);
      break;

    case arg_idxrp:
      /*    16      12      8    6      0
            +-----------------------------+
            | r_index | disp  | rp_base   |
            +-----------------------------+          */

      if (instruction->size == 3)
        {
          CR16_PRINT (0, getidxregp_image (arg->rp), 0);
          if (getreg_image (arg->i_r) == 12)
            CR16_PRINT (0, 0, 3);
          else
            CR16_PRINT (0, 1, 3);
        }
      else
        {
          CR16_PRINT (0, getidxregp_image (arg->rp), 16);
          if (getreg_image (arg->i_r) == 12)
            CR16_PRINT (0, 0, 19);
          else
            CR16_PRINT (0, 1, 19);
        }
      print_constant (nbits, shift, arg);
      break;

    case arg_idxr:
      if (getreg_image (arg->i_r) == 12)
        if (IS_INSN_MNEMONIC ("cbitb") || IS_INSN_MNEMONIC ("sbitb")
            || IS_INSN_MNEMONIC ("tbitb"))
          CR16_PRINT (0, 0, 23);
        else CR16_PRINT (0, 0, 24);
      else
        if (IS_INSN_MNEMONIC ("cbitb") || IS_INSN_MNEMONIC ("sbitb")
            || IS_INSN_MNEMONIC ("tbitb"))
          CR16_PRINT (0, 1, 23);
        else CR16_PRINT (0, 1, 24);

      print_constant (nbits, shift, arg);
      break;

    case arg_ic:
    case arg_c:
      print_constant (nbits, shift, arg);
      break;

    case arg_rbase:
      CR16_PRINT (0, getreg_image (arg->r), shift);
      break;

    case arg_cr:
      print_constant (nbits, shift , arg);
      /* Add the register argument to the output_opcode.  */
      CR16_PRINT (0, getreg_image (arg->r), (shift+16));
      break;

    case arg_crp:
      print_constant (nbits, shift , arg);
      if (instruction->size > 1)
        CR16_PRINT (0, getregp_image (arg->rp), (shift + 16));
      else if (IS_INSN_TYPE (LD_STOR_INS) || (IS_INSN_TYPE (CSTBIT_INS)))
        {
          if (instruction->size == 2)
            CR16_PRINT (0, getregp_image (arg->rp), (shift - 8));
          else if (instruction->size == 1)
            CR16_PRINT (0, getregp_image (arg->rp), 16);
        }
      else
        CR16_PRINT (0, getregp_image (arg->rp), shift);
      break;

    default:
      break;
    }
}

/* Retrieve the number of operands for the current assembled instruction.  */

static int
get_number_of_operands (void)
{
  int i;

  for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
    ;
  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.
   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;
  op_err retval = OP_LEGAL;
  long value = *num;

  if (bits == 0 && value > 0) return OP_OUT_OF_RANGE;

  /* For hosts witah longs bigger than 32-bits make sure that the top
     bits of a 32-bit negative value read in by the parser are set,
     so that the correct comparisons are made.  */
  if (value & 0x80000000)
    value |= (-1UL << 31);


  /* Verify operand value is even.  */
  if (flags & OP_EVEN)
    {
      if (value % 2)
        return OP_NOT_EVEN;
    }

  if (flags & OP_DEC)
    {
      value -= 1;
      if (update)
        *num = value;
    }

  if (flags & OP_SHIFT)
    {
      value >>= 1;
      if (update)
        *num = value;
    }
  else if (flags & OP_SHIFT_DEC)
    {
      value = (value >> 1) - 1;
      if (update)
        *num = value;
    }

  if (flags & OP_ABS20)
    {
      if (value > 0xEFFFF)
        return OP_OUT_OF_RANGE;
    }

  if (flags & OP_ESC)
    {
      if (value == 0xB || value == 0x9)
        return OP_OUT_OF_RANGE;
      else if (value == -1)
        {
          if (update)
            *num = 9;
          return retval;
        }
    }

  if (flags & OP_ESC1)
    {
      if (value > 13)
        return OP_OUT_OF_RANGE;
    }

   if (flags & OP_SIGNED)
     {
       max = (1 << (bits - 1)) - 1;
       min = - (1 << (bits - 1));
       if ((value > max) || (value < min))
         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))
         retval = OP_OUT_OF_RANGE;
     }
   else if (flags & OP_NEG)
     {
       max = - 1;
       min = - ((1 << (bits - 1)) - 1);
       if ((value > max) || (value < min))
         retval = OP_OUT_OF_RANGE;
     }
   return retval;
}

/* Bunch of error checkings.
   The checks are made after a matching instruction was found.  */

static 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
     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"), insn->arg[0].r);
    }

  if (IS_INSN_MNEMONIC ("pop")
      || IS_INSN_MNEMONIC ("push")
      || IS_INSN_MNEMONIC ("popret"))
    {
      unsigned int count = insn->arg[0].constant, reg_val;

      /* Check if count operand caused to save/retrive the RA twice
         to generate warning message.  */
     if (insn->nargs > 2)
       {
         reg_val = getreg_image (insn->arg[1].r);

         if (   ((reg_val == 9) &&  (count > 7))
             || ((reg_val == 10) && (count > 6))
             || ((reg_val == 11) && (count > 5))
             || ((reg_val == 12) && (count > 4))
             || ((reg_val == 13) && (count > 2))
             || ((reg_val == 14) && (count > 0)))
           as_warn (_("RA register is saved twice."));

         /* Check if the third operand is "RA" or "ra" */
         if (!(((insn->arg[2].r) == ra) || ((insn->arg[2].r) == RA)))
           as_bad (_("`%s' Illegal use of registers."), ins_parse);
       }

      if (insn->nargs > 1)
       {
         reg_val = getreg_image (insn->arg[1].r);

         /* If register is a register pair ie r12/r13/r14 in operand1, then
            the count constant should be validated.  */
         if (((reg_val == 11) && (count > 7))
             || ((reg_val == 12) && (count > 6))
             || ((reg_val == 13) && (count > 4))
             || ((reg_val == 14) && (count > 2))
             || ((reg_val == 15) && (count > 0)))
           as_bad (_("`%s' Illegal count-register combination."), ins_parse);
       }
     else
       {
         /* Check if the operand is "RA" or "ra" */
         if (!(((insn->arg[0].r) == ra) || ((insn->arg[0].r) == RA)))
           as_bad (_("`%s' Illegal use of register."), ins_parse);
       }
    }

  /* Some instruction assume the stack pointer as rptr operand.
     Issue an error when the register to be loaded is also SP.  */
  if (instruction->flags & NO_SP)
    {
      if (getreg_image (insn->arg[1].r) == getreg_image (sp))
        as_bad (_("`%s' has undefined result"), ins_parse);
    }

  /* 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"),
                  getreg_image (insn->arg[0].r));
    }
}

/* 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.  */

static int
adjust_if_needed (ins *insn ATTRIBUTE_UNUSED)
{
  int ret_value = 0;

  if ((IS_INSN_TYPE (CSTBIT_INS)) || (IS_INSN_TYPE (LD_STOR_INS)))
    {
      if ((instruction->operands[0].op_type == abs24)
           && ((insn->arg[0].constant) > 0xF00000))
        {
          insn->arg[0].constant &= 0xFFFFF;
          instruction--;
          ret_value = 1;
        }
    }

  return ret_value;
}

/* 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
   the instruction table, meeting the following conditions:
    1: Has the same number of operands.
    2: Has the same operand types.
    3: Each operand size is sufficient to represent the instruction's values.
   Returns 1 upon success, 0 upon failure.  */

static int
assemble_insn (const char *mnemonic, ins *insn)
{
  /* Type of each operand in the current template.  */
  argtype cur_type[MAX_OPERANDS];
  /* Size (in bits) of each operand in the current template.  */
  unsigned int cur_size[MAX_OPERANDS];
  /* Flags of each operand in the current template.  */
  unsigned int cur_flags[MAX_OPERANDS];
  /* Instruction type to match.  */
  unsigned int ins_type;
  /* Boolean flag to mark whether a match was found.  */
  int match = 0;
  int i;
  /* Nonzero if an instruction with same number of operands was found.  */
  int found_same_number_of_operands = 0;
  /* Nonzero if an instruction with same argument types was found.  */
  int found_same_argument_types = 0;
  /* Nonzero if a constant was found within the required range.  */
  int found_const_within_range  = 0;
  /* Argument number of an operand with invalid type.  */
  int invalid_optype = -1;
  /* Argument number of an operand with invalid constant value.  */
  int invalid_const  = -1;
  /* 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++)                             \
    ARRAY[i] = FUNC (instruction->operands[i].op_type)

#define GET_CURRENT_TYPE    GET_CURRENT_DATA (get_optype, cur_type)
#define GET_CURRENT_SIZE    GET_CURRENT_DATA (get_opbits, cur_size)
#define GET_CURRENT_FLAGS   GET_CURRENT_DATA (get_opflags, cur_flags)

  /* Instruction has no operands -> only copy the constant opcode.   */
  if (insn->nargs == 0)
    {
      output_opcode[0] = BIN (instruction->match, instruction->match_bits);
      return 1;
    }

  /* 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
     pre-determined. We need to make sure that the type stays the same
     during a search for matching instruction.  */
  ins_type = CR16_INS_TYPE (instruction->flags);

  while (/* Check that match is still not found.  */
         match != 1
         /* Check we didn't get to end of table.  */
         && instruction->mnemonic != NULL
         /* Check that the actual mnemonic is still available.  */
         && IS_INSN_MNEMONIC (mnemonic)
         /* Check that the instruction type wasn't changed.  */
         && IS_INSN_TYPE (ins_type))
    {
      /* Check whether number of arguments is legal.  */
      if (get_number_of_operands () != insn->nargs)
        goto next_insn;
      found_same_number_of_operands = 1;

      /* Initialize arrays with data of each operand in current template.  */
      GET_CURRENT_TYPE;
      GET_CURRENT_SIZE;
      GET_CURRENT_FLAGS;

      /* Check for type compatibility.  */
      for (i = 0; i < insn->nargs; i++)
        {
          if (cur_type[i] != insn->arg[i].type)
            {
              if (invalid_optype == -1)
                invalid_optype = i + 1;
              goto next_insn;
            }
        }
      found_same_argument_types = 1;

      for (i = 0; i < insn->nargs; i++)
        {
          /* If 'bal' instruction size is '2' and reg operand is not 'ra'
             then goto next instruction.  */
          if (IS_INSN_MNEMONIC ("bal") && (i == 0)
              && (instruction->size == 2) && (insn->arg[i].rp != 14))
            goto next_insn;

          /* If 'storb' instruction with 'sp' reg and 16-bit disp of
           * reg-pair, leads to undifined trap, so this should use
           * 20-bit disp of reg-pair.  */
          if (IS_INSN_MNEMONIC ("storb") && (instruction->size == 2)
              && (insn->arg[i].r == 15) && (insn->arg[i + 1].type == arg_crp))
            goto next_insn;

          /* 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[i].X_op == O_constant)
              && (op_error = check_range (&insn->arg[i].constant, cur_size[i],
                                          cur_flags[i], 0)))
            {
              if (invalid_const == -1)
                {
                  invalid_const = i + 1;
                  const_err = op_error;
                }
              goto next_insn;
            }
          /* For symbols, we make sure the relocation size (which was already
             determined) is sufficient.  */
          else if ((insn->arg[i].X_op == O_symbol)
                   && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
                       > cur_size[i]))
                  goto next_insn;
        }
      found_const_within_range = 1;

      /* If we got till here -> Full match is found.  */
      match = 1;
      break;

/* Try again with next instruction.  */
next_insn:
      instruction++;
    }

  if (!match)
    {
      /* We haven't found a match - instruction can't be assembled.  */
      if (!found_same_number_of_operands)
        as_bad (_("Incorrect number of operands"));
      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;
            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).
         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
           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;

          /* 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);
        }

      /* First, copy the instruction's opcode.  */
      output_opcode[0] = BIN (instruction->match, instruction->match_bits);

      for (i = 0; i < insn->nargs; i++)
        {
         /* For BAL (ra),disp17 instruction only. And also set the
            DISP24a relocation type.  */
         if (IS_INSN_MNEMONIC ("bal") && (instruction->size == 2) && i == 0)
           {
             insn->rtype = BFD_RELOC_CR16_DISP24a;
             continue;
           }
          cur_arg_num = i;
          print_operand (cur_size[i], instruction->operands[i].shift,
                         &insn->arg[i]);
        }
    }

  return 1;
}

/* Print the instruction.
   Handle also cases where the instruction is relaxable/relocatable.  */

static void
print_insn (ins *insn)
{
  unsigned int i, j, insn_size;
  char *this_frag;
  unsigned short words[4];
  int addr_mod;

  /* Arrange the insn encodings in a WORD size array.  */
  for (i = 0, j = 0; i < 2; i++)
    {
      words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
      words[j++] = output_opcode[i] & 0xFFFF;
    }

    /* Handle relocation.  */
    if ((instruction->flags & RELAXABLE) && relocatable)
      {
        int relax_subtype;
        /* Write the maximal instruction size supported.  */
        insn_size = INSN_MAX_SIZE;

        if (IS_INSN_TYPE (BRANCH_INS))
          {
            switch (insn->rtype)
              {
              case BFD_RELOC_CR16_DISP24:
                relax_subtype = 2;
                break;
              case BFD_RELOC_CR16_DISP16:
                relax_subtype = 1;
                break;
              default:
                relax_subtype = 0;
                break;
              }
          }
        else
          abort ();

        this_frag = frag_var (rs_machine_dependent, insn_size *2,
                              4, relax_subtype,
                              insn->exp.X_add_symbol,
                              0,
                              0);
      }
    else
      {
        insn_size = instruction->size;
        this_frag = frag_more (insn_size * 2);

        if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
          {
             reloc_howto_type *reloc_howto;
             int size;

             reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);

             if (!reloc_howto)
               abort ();

             size = bfd_get_reloc_size (reloc_howto);

             if (size < 1 || size > 4)
               abort ();

             fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
                          size, &insn->exp, reloc_howto->pc_relative,
                          insn->rtype);
          }
      }

  /* Verify a 2-byte code alignment.  */
  addr_mod = frag_now_fix () & 1;
  if (frag_now->has_code && frag_now->insn_addr != addr_mod)
    as_bad (_("instruction address is not a multiple of 2"));
  frag_now->insn_addr = addr_mod;
  frag_now->has_code = 1;

  /* Write the instruction encoding to frag.  */
  for (i = 0; i < insn_size; i++)
    {
      md_number_to_chars (this_frag, (valueT) words[i], 2);
      this_frag += 2;
    }
}

/* Actually assemble an instruction.  */

static void
cr16_assemble (const char *op, char *param)
{
  ins cr16_ins;

  /* Find the instruction.  */
  instruction = (const inst *) hash_find (cr16_inst_hash, op);
  if (instruction == NULL)
    {
      as_bad (_("Unknown opcode: `%s'"), op);
      return;
    }

  /* Tie dwarf2 debug info to the address at the start of the insn.  */
  dwarf2_emit_insn (0);

  /* Parse the instruction's operands.  */
  parse_insn (&cr16_ins, param);

  /* Assemble the instruction - return upon failure.  */
  if (assemble_insn (op, &cr16_ins) == 0)
    return;

  /* Print the instruction.  */
  print_insn (&cr16_ins);
}

/* This is the guts of the machine-dependent assembler.  OP points to a
   machine dependent instruction.  This function is supposed to emit
   the frags/bytes it assembles to.  */

void
md_assemble (char *op)
{
  ins cr16_ins;
  char *param, param1[32];

  /* Reset global variables for a new instruction.  */
  reset_vars (op);

  /* Strip the mnemonic.  */
  for (param = op; *param != 0 && !ISSPACE (*param); param++)
    ;
  *param++ = '\0';

  /* bCC instuctions and adjust the mnemonic by adding extra white spaces.  */
  if (is_bcc_insn (op))
    {
      strcpy (param1, get_b_cc (op));
      strcat (param1,",");
      strcat (param1, param);
      param = (char *) &param1;
      cr16_assemble ("b", param);
      return;
    }

  /* Checking the cinv options and adjust the mnemonic by removing the
     extra white spaces.  */
  if (streq ("cinv", op))
    {
     /* Validate the cinv options.  */
      check_cinv_options (param);
      strcat (op, param);
    }

  /* MAPPING - SHIFT INSN, if imm4/imm16 positive values
     lsh[b/w] imm4/imm6, reg ==> ashu[b/w] imm4/imm16, reg
     as CR16 core doesn't support lsh[b/w] right shift operaions.  */
  if ((streq ("lshb", op) || streq ("lshw", op) || streq ("lshd", op))
      && (param [0] == '$'))
    {
      strcpy (param1, param);
      /* Find the instruction.  */
      instruction = (const inst *) hash_find (cr16_inst_hash, op);
       parse_operands (&cr16_ins, param1);
      if (((&cr16_ins)->arg[0].type == arg_ic)
          && ((&cr16_ins)->arg[0].constant >= 0))
        {
           if (streq ("lshb", op))
             cr16_assemble ("ashub", param);
           else if (streq ("lshd", op))
             cr16_assemble ("ashud", param);
           else
             cr16_assemble ("ashuw", param);
	   return;
        }
    }

  cr16_assemble (op, param);
}
