/* tc-xgate.c -- Assembler code for Freescale XGATE
   Copyright (C) 2010-2018 Free Software Foundation, Inc.
   Contributed by Sean Keys <skeys@ipdatasys.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 "subsegs.h"
#include "opcode/xgate.h"
#include "dwarf2dbg.h"
#include "elf/xgate.h"

const char comment_chars[] = ";!";
const char line_comment_chars[] = "#*";
const char line_separator_chars[] = "";
const char EXP_CHARS[] = "eE";
const char FLT_CHARS[] = "dD";

/* Max opcodes per opcode handle.  */
#define MAX_OPCODES     0x05

#define SIXTEENTH_BIT		0x8000
#define N_BITS_IN_WORD		16
#define MAX_NUM_OPERANDS	3

/* #define STATE_CONDITIONAL_BRANCH		(1) */
#define STATE_PC_RELATIVE	(2)
#define REGISTER_P(ptr)		(ptr == 'r')
#define INCREMENT		01
#define DECREMENT		02
#define MAXREGISTER		07
#define MINREGISTER		00

#define OPTION_MMCU 'm'

/* This macro has no side-effects.  */
#define ENCODE_RELAX(what,length) (((what) << 2) + (length))

/* Each unique opcode name has a handle.  That handle may
   contain pointers to opcodes with the same name but
   different address modes.  */
struct xgate_opcode_handle
{
  int number_of_modes;
  char *name;
  struct xgate_opcode *opc0[MAX_OPCODES];
};

/* XGATE's registers all are 16-bit general purpose.
   They are numbered according to the specifications.  */
typedef enum register_id
{
  REG_NONE = -1,
  REG_R0 = 0,
  REG_R1 = 1,
  REG_R2 = 2,
  REG_R3 = 3,
  REG_R4 = 4,
  REG_R5 = 5,
  REG_R6 = 6,
  REG_R7 = 7,
  REG_PC = 8,
  REG_CCR = 9
} register_id;

/* Operand Modifiers */
typedef enum op_modifiers
{
  MOD_NONE = -1,
  MOD_POSTINC = 1,
  MOD_PREDEC = 2,
  MOD_CONSTANT = 3,
  MOD_LOAD_HIGH = 4,
  MOD_LOAD_LOW = 5
}op_modifiers;

typedef struct s_operand
{
  expressionS exp;
  register_id reg;
  op_modifiers mod;
} s_operand;


/* Forward declarations.  */
static inline char *skip_whitespace (char *);
static void get_default_target (void);
static char *extract_word (char *, char *, int);
static struct xgate_opcode *xgate_find_match (struct xgate_opcode_handle *,
					      int, s_operand [], unsigned int);
static int cmp_opcode (struct xgate_opcode *, struct xgate_opcode *);
static void xgate_print_table (void);
static unsigned int xgate_get_operands (char *, s_operand []);
static register_id reg_name_search (char *);
static op_modifiers xgate_determine_modifiers (char **);
static void xgate_scan_operands (struct xgate_opcode *opcode, s_operand []);
static unsigned int xgate_parse_operand (struct xgate_opcode *, int *, int,
					 char **, s_operand);

static struct hash_control *xgate_hash;

/* Previous opcode.  */
static unsigned int prev = 0;

static unsigned char fixup_required = 0;

/* Used to enable clipping of 16 bit operands into 8 bit constraints.  */
static unsigned char autoHiLo = 0;

static char oper_check;
static char flag_print_insn_syntax = 0;
static char flag_print_opcodes = 0;

static int current_architecture;
static const char *default_cpu;

/* ELF flags to set in the output file header.  */
static int elf_flags = E_XGATE_F64;

/* This table describes how you change sizes for the various types of variable
   size expressions.  This version only supports two kinds.  */

/* The fields are:
   How far Forward this mode will reach.
   How far Backward this mode will reach.
   How many bytes this mode will add to the size of the frag.
   Which mode to go to if the offset won't fit in this one.  */

relax_typeS md_relax_table[] =
{
  {1, 1, 0, 0},			/* First entries aren't used.  */
  {1, 1, 0, 0},			/* For no good reason except.  */
  {1, 1, 0, 0},			/* that the VAX doesn't either.  */
  {1, 1, 0, 0},
  /* XGATE 9 and 10 bit pc rel todo complete and test */
/*{(511), (-512), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
  {(1023), (-1024), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)}, */
  {0, 0, 0, 0}
};

/* 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[] =
{
  /* The following pseudo-ops are supported for MRI compatibility.  */
  {0, 0, 0}
};

const char *md_shortopts = "m:";

struct option md_longopts[] =
{
#define OPTION_PRINT_INSN_SYNTAX  (OPTION_MD_BASE + 0)
  { "print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX },

#define OPTION_PRINT_OPCODES  (OPTION_MD_BASE + 1)
  { "print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES },

#define OPTION_GENERATE_EXAMPLE  (OPTION_MD_BASE + 2)
  { "generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE },

#define OPTION_MSHORT  (OPTION_MD_BASE + 3)
  { "mshort", no_argument, NULL, OPTION_MSHORT },

#define OPTION_MLONG  (OPTION_MD_BASE + 4)
  { "mlong", no_argument, NULL, OPTION_MLONG },

#define OPTION_MSHORT_DOUBLE  (OPTION_MD_BASE + 5)
  { "mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE },

#define OPTION_MLONG_DOUBLE  (OPTION_MD_BASE + 6)
  { "mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE },

  { NULL, no_argument, NULL, 0 }
};

size_t md_longopts_size = sizeof (md_longopts);

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

int
md_parse_option (int c, const char *arg)
{
  switch (c)
    {
    case OPTION_MMCU:
      if (strcasecmp (arg, "v1") == 0)
	current_architecture = XGATE_V1;
      else if (strcasecmp (arg, "v2") == 0)
	current_architecture = XGATE_V2;
      else if (strcasecmp (arg, "v3") == 0)
	current_architecture = XGATE_V3;
      else
	as_bad (_("architecture variant invalid"));
      break;

    case OPTION_PRINT_INSN_SYNTAX:
      flag_print_insn_syntax = 1;
      break;

    case OPTION_PRINT_OPCODES:
      flag_print_opcodes = 1;
      break;

    case OPTION_GENERATE_EXAMPLE:
      flag_print_opcodes = 2;
      break;

    case OPTION_MSHORT:
      elf_flags &= ~E_XGATE_I32;
      break;

    case OPTION_MLONG:
      elf_flags |= E_XGATE_I32;
      break;

    case OPTION_MSHORT_DOUBLE:
      elf_flags &= ~E_XGATE_F64;
      break;

    case OPTION_MLONG_DOUBLE:
      elf_flags |= E_XGATE_F64;
      break;

    default:
      return 0;
    }
  return 1;
}

const char *
xgate_arch_format (void)
{
  get_default_target ();

  if (current_architecture & cpuxgate)
    return "elf32-xgate";

  return "error";
}

static void
get_default_target (void)
{
  const bfd_target *target;
  bfd abfd;

  if (current_architecture != 0)
    return;

  default_cpu = "unknown";
  target = bfd_find_target (0, &abfd);

  if (target && target->name)
    {
      if (strcmp (target->name, "elf32-xgate") == 0)
	{
	  current_architecture = cpuxgate;
	  default_cpu = "XGATE V1";
	  return;
	}

      as_bad (_("Default target `%s' is not supported."), target->name);
    }
}

void
md_begin (void)
{
  struct xgate_opcode *xgate_opcode_ptr = NULL;
  struct xgate_opcode *xgate_op_table = NULL;
  struct xgate_opcode_handle *op_handles = 0;
  const char *prev_op_name = 0;
  int handle_enum = 0;
  int number_of_op_handles = 0;
  int i, j = 0;

  /* Create a local copy of our opcode table
     including an extra line for NULL termination.  */
  xgate_op_table = XNEWVEC (struct xgate_opcode, xgate_num_opcodes);

  memset (xgate_op_table, 0,
	  sizeof (struct xgate_opcode) * (xgate_num_opcodes));

  for (xgate_opcode_ptr = (struct xgate_opcode*) xgate_opcodes, i = 0;
       i < xgate_num_opcodes; i++)
    xgate_op_table[i] = xgate_opcode_ptr[i];

  qsort (xgate_op_table, xgate_num_opcodes, sizeof (struct xgate_opcode),
	 (int (*)(const void *, const void *)) cmp_opcode);

  /* Calculate number of handles since this will be
     smaller than the raw number of opcodes in the table.  */
  prev_op_name = "";
  for (xgate_opcode_ptr = xgate_op_table, i = 0;  i < xgate_num_opcodes;
       xgate_opcode_ptr++, i++)
    {
      if (strcmp (prev_op_name, xgate_opcode_ptr->name))
	number_of_op_handles++;
      prev_op_name = xgate_opcode_ptr->name;
    }

  op_handles = XNEWVEC (struct xgate_opcode_handle, number_of_op_handles);

  /* Insert unique opcode names into hash table, aliasing duplicates.  */
  xgate_hash = hash_new ();

  prev_op_name = "";
  for (xgate_opcode_ptr = xgate_op_table, i = 0, j = 0; i < xgate_num_opcodes;
       i++, xgate_opcode_ptr++)
    {
      if (!strcmp (prev_op_name, xgate_opcode_ptr->name))
	{
	  handle_enum++;
	  op_handles[j].opc0[handle_enum] = xgate_opcode_ptr;
	}
      else
	{
	  handle_enum = 0;
	  if (i)
	    j++;
	  op_handles[j].name = xgate_opcode_ptr->name;
	  op_handles[j].opc0[0] = xgate_opcode_ptr;
	  hash_insert (xgate_hash, (char *) op_handles[j].name,
		       (char *) &(op_handles[j]));
	}
      op_handles[j].number_of_modes = handle_enum;
      prev_op_name = op_handles[j].name;
    }

  if (flag_print_opcodes)
    {
      xgate_print_table ();
      exit (EXIT_SUCCESS);
    }
}

void
xgate_init_after_args (void)
{
}

void
md_show_usage (FILE * stream)
{
  get_default_target ();

  fprintf (stream,
	   _("\
Freescale XGATE co-processor options:\n\
  -mshort                 use 16-bit int ABI (default)\n\
  -mlong                  use 32-bit int ABI\n\
  -mshort-double          use 32-bit double ABI\n\
  -mlong-double           use 64-bit double ABI (default)\n\
  --mxgate                specify the processor variant [default %s]\n\
  --print-insn-syntax     print the syntax of instruction in case of error\n\
  --print-opcodes         print the list of instructions with syntax\n\
  --generate-example      generate an example of each instruction"),
	   default_cpu);
}

enum bfd_architecture
xgate_arch (void)
{
  get_default_target ();
  return bfd_arch_xgate;
}

int
xgate_mach (void)
{
  return 0;
}

static void
xgate_print_syntax (char *name)
{
  int i;

  for (i = 0; i < xgate_num_opcodes; i++)
    {
      if (!strcmp (xgate_opcodes[i].name, name))
	{
	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IDR))
	    printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n",
		    xgate_opcodes[i].name);
	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_INH))
	    printf ("\tFormat is %s\n", xgate_opcodes[i].name);
	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_TRI))
	    printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes[i].name);
	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_DYA))
	    printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes[i].name);
	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM3))
	    printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes[i].name);
	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM4))
	    printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes[i].name);
	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM8))
	    printf ("\tFormat is %s\tRx, <8-bit value>\n",
		    xgate_opcodes[i].name);
	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16))
	    printf ("\tFormat is %s\tRx, <16-bit value>\n",
		    xgate_opcodes[i].name);
	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_C))
	    printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes[i].name);
	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_C_R))
	    printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes[i].name);
	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_P))
	    printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes[i].name);
	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16mLDW))
	    printf ("\tFormat is %s\tRx, <16-bit value>\n",
		    xgate_opcodes[i].name);
	}
    }
}

static void
xgate_print_table (void)
{
  int i;

  for (i = 0; i < xgate_num_opcodes; i++)
    xgate_print_syntax (xgate_opcodes[i].name);

  return;
}

const char *
xgate_listing_header (void)
{
  if (current_architecture & cpuxgate)
    return "XGATE GAS ";

  return "ERROR MC9S12X GAS ";
}

symbolS *
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
{
  return NULL;
}

/* GAS will call this function for each section at the end of the assembly,
   to permit the CPU backend to adjust the alignment of a section.  */

valueT
md_section_align (asection * seg, valueT addr)
{
  int align = bfd_get_section_alignment (stdoutput, seg);
  return ((addr + (1 << align) - 1) & -(1 << align));
}

void
md_assemble (char *input_line)
{
  struct xgate_opcode *opcode = 0;
  struct xgate_opcode *macro_opcode = 0;
  struct xgate_opcode_handle *opcode_handle = 0;
  /* Caller expects it to be returned as it was passed.  */
  char *saved_input_line = input_line;
  char op_name[9] =  { 0 };
  unsigned int operandCount = 0;
  char *p = 0;

  s_operand new_operands[MAX_NUM_OPERANDS];

  fixup_required = 0;
  oper_check = 0; /* set error flags */
  input_line = extract_word (input_line, op_name, sizeof (op_name));

  /* Check to make sure we are not reading a bogus line.  */
  if (!op_name[0])
    as_bad (_("opcode missing or not found on input line"));

  if (!(opcode_handle = (struct xgate_opcode_handle *) hash_find (xgate_hash,
								  op_name)))
    {
      as_bad (_("opcode %s not found in opcode hash table"), op_name);
    }
  else
    {
      /* Parse operands so we can find the proper opcode bin.  */

      operandCount = xgate_get_operands (input_line, new_operands);

      opcode = xgate_find_match (opcode_handle, opcode_handle->number_of_modes,
				 new_operands, operandCount);

      if (!opcode)
	{
	  as_bad (_("matching operands to opcode"));
	  xgate_print_syntax (opcode_handle->opc0[0]->name);
	}
      else if (opcode->size == 2)
	{
	  /* Size is one word - assemble that native insn.  */
	  xgate_scan_operands (opcode, new_operands);
	}
      else
	{
	  /* Insn is a simplified instruction - expand it out.  */
	  autoHiLo = 1;
	  unsigned int i;

	  /* skip past our ';' separator.  */
	  for (i = strlen (opcode->constraints), p = opcode->constraints; i > 0;
	       i--, p++)
	    {
	      if (*p == ';')
		{
		  p++;
		  break;
		}
	    }
	  input_line = skip_whitespace (input_line);
	  char *macro_inline = input_line;

	  /* Loop though the macro's opcode list and apply operands to
	     each real opcode. */
	  for (i = 0; *p && i < (opcode->size / 2); i++)
	    {
	      /* Loop though macro operand list.  */
	      input_line = macro_inline; /* Rewind.  */
	      p = extract_word (p, op_name, 10);

	      if (!(opcode_handle = (struct xgate_opcode_handle *)
		    hash_find (xgate_hash, op_name)))
		{
		  as_bad (_(": processing macro, real opcode handle"
			    " not found in hash"));
		  break;
		}
	      else
		{
		  operandCount = xgate_get_operands (input_line, new_operands);
		  macro_opcode = xgate_find_match (opcode_handle,
						   opcode_handle->number_of_modes, new_operands,
						   operandCount);
		  xgate_scan_operands (macro_opcode, new_operands);
		}
	    }
	}
    }
  autoHiLo = 0;
  input_line = saved_input_line;
}

/* Force truly undefined symbols to their maximum size, and generally set up
   the frag list to be relaxed.  */

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


/* Relocation, relaxation and frag conversions.  */

/* PC-relative offsets are relative to the start of the
   next instruction.  That is, the address of the offset, plus its
   size, since the offset is always the last part of the insn.  */

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

/* If while processing a fixup, a reloc really needs to be created
   then it is done here.  */

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

  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;

  if (fixp->fx_r_type == 0)
    reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
  else
    reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);

  if (reloc->howto == (reloc_howto_type *) NULL)
    {
      as_bad_where (fixp->fx_file, fixp->fx_line, _
		    ("Relocation %d is not supported by object file format."),
		    (int) fixp->fx_r_type);
      return NULL;
    }

  /* Since we use Rel instead of Rela, encode the vtable entry to be
     used in the relocation's section offset.  */
  if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
    reloc->address = fixp->fx_offset;
  reloc->addend = 0;
  return reloc;
}

/* Patch the instruction with the resolved operand.  Elf relocation
   info will also be generated to take care of linker/loader fixups.
   The XGATE addresses only 16-bit addresses.The BFD_RELOC_32 is necessary
   for the support of --gstabs.  */

void
md_apply_fix (fixS * fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
{
  char *where;
  long value = *valP;
  int opcode = 0;
  ldiv_t result;

  /* If the fixup is done mark it done so no further symbol resolution
     will take place.  */
  if (fixP->fx_addsy == (symbolS *) NULL)
    fixP->fx_done = 1;

  /* We don't actually support subtracting a symbol.  */
  if (fixP->fx_subsy != (symbolS *) NULL)
    as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));

  where = fixP->fx_frag->fr_literal + fixP->fx_where;
  opcode = bfd_getl16 (where);
  int mask = 0;

  switch (fixP->fx_r_type)
    {
    case R_XGATE_PCREL_9:
      if (value < -512 || value > 511)
	as_bad_where (fixP->fx_file, fixP->fx_line,
		      _("Value %ld too large for 9-bit PC-relative branch."),
		      value);
      result = ldiv (value, 2); /* from bytes to words */
      value = result.quot;
      if (result.rem)
	as_bad_where (fixP->fx_file, fixP->fx_line, _
		      ("Value %ld not aligned by 2 for 9-bit"
		       " PC-relative branch."), value);
      /* Clip into 8-bit field.
	 FIXME I'm sure there is a more proper place for this.  */
      mask = 0x1FF;
      value &= mask;
      number_to_chars_bigendian (where, (opcode | value), 2);
      break;
    case R_XGATE_PCREL_10:
      if (value < -1024 || value > 1023)
	as_bad_where (fixP->fx_file, fixP->fx_line,
		      _("Value %ld too large for 10-bit PC-relative branch."),
		      value);
      result = ldiv (value, 2); /* from bytes to words */
      value = result.quot;
      if (result.rem)
	as_bad_where (fixP->fx_file, fixP->fx_line, _
		      ("Value %ld not aligned by 2 for 10-bit"
		       " PC-relative branch."), value);
      /* Clip into 9-bit field.
	 FIXME I'm sure there is a more proper place for this.  */
      mask = 0x3FF;
      value &= mask;
      number_to_chars_bigendian (where, (opcode | value), 2);
      break;
    case BFD_RELOC_XGATE_IMM8_HI:
      if (value < -65537 || value > 65535)
	as_bad_where (fixP->fx_file, fixP->fx_line,
		      _("Value out of 16-bit range."));
      value >>= 8;
      value &= 0x00ff;
      bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
      break;
    case BFD_RELOC_XGATE_24:
    case BFD_RELOC_XGATE_IMM8_LO:
      if (value < -65537 || value > 65535)
	as_bad_where (fixP->fx_file, fixP->fx_line,
		      _("Value out of 16-bit range."));
      value &= 0x00ff;
      bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
      break;
    case BFD_RELOC_XGATE_IMM3:
      if (value < 0 || value > 7)
	as_bad_where (fixP->fx_file, fixP->fx_line,
		      _("Value out of 3-bit range."));
      value <<= 8; /* make big endian */
      number_to_chars_bigendian (where, (opcode | value), 2);
      break;
    case BFD_RELOC_XGATE_IMM4:
      if (value < 0 || value > 15)
	as_bad_where (fixP->fx_file, fixP->fx_line,
		      _("Value out of 4-bit range."));
      value <<= 4; /* align the operand bits */
      number_to_chars_bigendian (where, (opcode | value), 2);
      break;
    case BFD_RELOC_XGATE_IMM5:
      if (value < 0 || value > 31)
	as_bad_where (fixP->fx_file, fixP->fx_line,
		      _("Value out of 5-bit range."));
      value <<= 5; /* align the operand bits */
      number_to_chars_bigendian (where, (opcode | value), 2);
      break;
    case BFD_RELOC_8:
      ((bfd_byte *) where)[0] = (bfd_byte) value;
      break;
    case BFD_RELOC_32:
      bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
      break;
    case BFD_RELOC_16:
      bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
      break;
    default:
      as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP->fx_line,
		fixP->fx_r_type);
      break;
    }
}

/* See whether we need to force a relocation into the output file.  */

int
tc_xgate_force_relocation (fixS * fixP)
{
  if (fixP->fx_r_type == BFD_RELOC_XGATE_RL_GROUP)
    return 1;
  return generic_force_reloc (fixP);
}

/* Here we decide which fixups can be adjusted to make them relative
   to the beginning of the section instead of the symbol.  Basically
   we need to make sure that the linker relaxation is done
   correctly, so in some cases we force the original symbol to be
   used.  */

int
tc_xgate_fix_adjustable (fixS * fixP)
{
  switch (fixP->fx_r_type)
    {
      /* For the linker relaxation to work correctly, these relocs
	 need to be on the symbol itself.  */
    case BFD_RELOC_16:
    case BFD_RELOC_XGATE_RL_JUMP:
    case BFD_RELOC_XGATE_RL_GROUP:
    case BFD_RELOC_VTABLE_INHERIT:
    case BFD_RELOC_VTABLE_ENTRY:
    case BFD_RELOC_32:
      return 0;
    default:
      return 1;
    }
}

void
md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
		 asection * sec ATTRIBUTE_UNUSED,
		 fragS * fragP ATTRIBUTE_UNUSED)
{
  as_bad (("md_convert_frag not implemented yet"));
  abort ();
}

/* Set the ELF specific flags.  */

void
xgate_elf_final_processing (void)
{
  elf_flags |= EF_XGATE_MACH;
  elf_elfheader (stdoutput)->e_flags &= ~EF_XGATE_ABI;
  elf_elfheader (stdoutput)->e_flags |= elf_flags;
}

static inline char *
skip_whitespace (char *s)
{
  while (*s == ' ' || *s == '\t' || *s == '(' || *s == ')')
    s++;

  return s;
}

/* Extract a word (continuous alpha-numeric chars) from the input line.  */

static char *
extract_word (char *from, char *to, int limit)
{
  char *op_end;
  int size = 0;

  /* Drop leading whitespace.  */
  from = skip_whitespace (from);
  *to = 0;
  /* Find the op code end.  */
  for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
    {
      to[size++] = *op_end++;
      if (size + 1 >= limit)
	break;
    }
  to[size] = 0;
  return op_end;
}

static char *
xgate_new_instruction (int size)
{
  char *f = frag_more (size);
  dwarf2_emit_insn (size);
  return f;
}

static unsigned short
xgate_apply_operand (unsigned short new_mask,
		     unsigned short *availiable_mask_bits,
		     unsigned short mask,
		     unsigned char n_bits)
{
  unsigned short n_shifts;
  unsigned int n_drop_bits;

  /* Shift until you find an available operand bit "1" and record
     the number of shifts.  */
  for (n_shifts = 0;
       !(*availiable_mask_bits & SIXTEENTH_BIT) && n_shifts < 16;
       n_shifts++)
    *availiable_mask_bits <<= 1;

  /* Shift for the number of bits your operand requires while bits
     are available.  */
  for (n_drop_bits = n_bits;
       n_drop_bits && (*availiable_mask_bits & SIXTEENTH_BIT);
       --n_drop_bits)
    *availiable_mask_bits <<= 1;

  if (n_drop_bits)
    as_bad (_(":operand has too many bits"));
  *availiable_mask_bits >>= n_shifts + n_bits;
  if ((n_drop_bits == 0) && (*availiable_mask_bits == 0))
    {
      oper_check = 1; /* flag operand check as good */
    }
  new_mask <<= N_BITS_IN_WORD - (n_shifts + n_bits);
  mask |= new_mask;
  return mask;
}

/* Parse ordinary expression.  */

static char *
xgate_parse_exp (char *s, expressionS * op)
{
  input_line_pointer = s;

  expression (op);
  if (op->X_op == O_absent)
    as_bad (_("missing operand"));
  return input_line_pointer;
}

static int
cmp_opcode (struct xgate_opcode *op1, struct xgate_opcode *op2)
{
  return strcmp (op1->name, op2->name);
}

static struct xgate_opcode *
xgate_find_match (struct xgate_opcode_handle *opcode_handle,
		  int numberOfModes, s_operand oprs[], unsigned int operandCount)
{
  int i;

  if (numberOfModes == 0)
    return opcode_handle->opc0[0];

  for (i = 0; i <= numberOfModes; i++)
    {
      switch (operandCount)
        {
      case 0:
        if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_INH))
          return opcode_handle->opc0[i];
        break;
      case 1:
        if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
	  {
	    if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_MON))
	      return opcode_handle->opc0[i];
	    if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_DYA_MON))
	      return opcode_handle->opc0[i];
	  }
        if (oprs[0].reg == REG_NONE)
          if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM3))
            return opcode_handle->opc0[i];
        break;
      case 2:
        if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
          {
            if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7)
	      {
		if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_DYA))
		  return opcode_handle->opc0[i];
	      }
            if (oprs[1].reg == REG_CCR)
              if (!strcmp (opcode_handle->opc0[i]->constraints,
                  XGATE_OP_MON_R_C))
                return opcode_handle->opc0[i];
            if (oprs[1].reg == REG_PC)
              if (!strcmp (opcode_handle->opc0[i]->constraints,
                  XGATE_OP_MON_R_P))
                return opcode_handle->opc0[i];
            if (oprs[1].reg == REG_NONE)
              if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM16)
                  || !strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM8)
                  || !strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM4)
                  || !strcmp (opcode_handle->opc0[i]->constraints,
                      XGATE_OP_IMM16mADD)
                  || !strcmp (opcode_handle->opc0[i]->constraints,
                      XGATE_OP_IMM16mAND)
                  || !strcmp (opcode_handle->opc0[i]->constraints,
                      XGATE_OP_IMM16mCPC)
                  || !strcmp (opcode_handle->opc0[i]->constraints,
                      XGATE_OP_IMM16mSUB)
                  || !strcmp (opcode_handle->opc0[i]->constraints,
                      XGATE_OP_IMM16mLDW))
                return opcode_handle->opc0[i];
          }
        if (oprs[0].reg == REG_CCR)
          if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_MON_C_R))
            return opcode_handle->opc0[i];
        break;
      case 3:
        if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
          {
            if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7)
              {
                if (oprs[2].reg >= REG_R0 && oprs[2].reg <= REG_R7)
                  {
                    if (!strcmp (opcode_handle->opc0[i]->constraints,
                        XGATE_OP_IDR)
                        || !strcmp (opcode_handle->opc0[i]->constraints,
                            XGATE_OP_TRI))
                      return opcode_handle->opc0[i];
                  }

                if (oprs[2].reg == REG_NONE)
                  if (!strcmp (opcode_handle->opc0[i]->constraints,
                      XGATE_OP_IDO5))
                    return opcode_handle->opc0[i];
              }
          }
        break;
      default:
        as_bad (_("unknown operand count"));
        break;
        }
    }
  return NULL ;
}

/* Because we are dealing with two different core that view the system
   memory with different offsets, we must differentiate what core a
   symbol belongs to, in order for the linker to cross-link.  */

int
xgate_frob_symbol (symbolS *sym)
{
  asymbol *bfdsym;
  elf_symbol_type *elfsym;

  bfdsym = symbol_get_bfdsym (sym);
  elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);

  gas_assert (elfsym);

  /* Mark the symbol as being *from XGATE  */
  elfsym->internal_elf_sym.st_target_internal = 1;

  return 0;
}

static unsigned int
xgate_get_operands (char *line, s_operand oprs[])
{
  int num_operands;

  /* If there are no operands, then it must be inherent.  */
  if (*line == 0 || *line == '\n' || *line == '\r')
    return 0;

  for (num_operands = 0; strlen (line) && (num_operands < MAX_NUM_OPERANDS);
       num_operands++)
    {
      line = skip_whitespace (line);
      if (*line == '#')
	line++;

      oprs[num_operands].mod = xgate_determine_modifiers (&line);

      if ((oprs[num_operands].reg = reg_name_search (line)) == REG_NONE)
	line = xgate_parse_exp (line, &oprs[num_operands].exp);

      /* skip to next operand */
      while (*line != 0)
	{
	  if (*line == ',')
	    {
	      line++;
	      break;
	    }
	  line++;
	}
    }
  if (num_operands > MAX_NUM_OPERANDS)
    return 0;
  return num_operands;
}

/* reg_name_search() finds the register number given its name.
   Returns the register number or REG_NONE on failure.  */

static register_id
reg_name_search (char *name)
{
  if (strncasecmp (name, "r0", 2) == 0)
    return REG_R0;
  if (strncasecmp (name, "r1", 2) == 0)
    return REG_R1;
  if (strncasecmp (name, "r2", 2) == 0)
    return REG_R2;
  if (strncasecmp (name, "r3", 2) == 0)
    return REG_R3;
  if (strncasecmp (name, "r4", 2) == 0)
    return REG_R4;
  if (strncasecmp (name, "r5", 2) == 0)
    return REG_R5;
  if (strncasecmp (name, "r6", 2) == 0)
    return REG_R6;
  if (strncasecmp (name, "r7", 2) == 0)
    return REG_R7;
  if (strncasecmp (name, "pc", 2) == 0)
    return REG_PC;
  if (strncasecmp (name, "ccr", 3) == 0)
    return REG_CCR;
  return REG_NONE;
}

/* Parse operand modifiers such as inc/dec/hi/low.  */

static op_modifiers
xgate_determine_modifiers (char **line)
{
  char *local_line = line[0];

  if (strncasecmp (local_line, "%hi", 3) == 0)
    {
      *line += 3;
      return MOD_LOAD_HIGH;
    }
  if (strncasecmp (local_line, "%lo", 3) == 0)
    {
      *line += 3;
      return MOD_LOAD_LOW;
    }
  if (*(local_line + 2) == '+')
    return MOD_POSTINC;
  if (strncasecmp (local_line, "-r", 2) == 0)
    {
      *line += 1;
      return MOD_PREDEC;
    }
  return MOD_NONE;
}

/* Parse instruction operands.  */

static void
xgate_scan_operands (struct xgate_opcode *opcode, s_operand oprs[])
{
  char *frag = xgate_new_instruction (opcode->size);
  int where = frag - frag_now->fr_literal;
  char *op = opcode->constraints;
  unsigned int bin = (int) opcode->bin_opcode;
  unsigned short oper_mask = 0;
  int operand_bit_length = 0;
  unsigned int operand = 0;
  char n_operand_bits = 0;
  char first_operand_equals_second = 0;
  int i = 0;
  char c = 0;

  /* Generate available operand bits mask.  */
  for (i = 0; (c = opcode->format[i]); i++)
    {
      if (ISDIGIT (c) || (c == 's'))
	{
	  oper_mask <<= 1;
	}
      else
	{
	  oper_mask <<= 1;
	  oper_mask += 1;
	  n_operand_bits++;
	}
    }

  /* Parse first operand.  */
  if (*op)
    {
      if (*op == '=')
	{
	  first_operand_equals_second = 1;
	  ++op;
	}
      operand = xgate_parse_operand (opcode, &operand_bit_length, where,
				     &op, oprs[0]);
      ++op;
      bin = xgate_apply_operand (operand, &oper_mask, bin, operand_bit_length);

      if (first_operand_equals_second)
	bin = xgate_apply_operand (operand, &oper_mask, bin,
				   operand_bit_length);
      /* Parse second operand.  */
      if (*op)
	{
	  if (*op == ',')
	    ++op;
	  if (first_operand_equals_second)
	    {
	      bin = xgate_apply_operand (operand, &oper_mask, bin,
					 operand_bit_length);
	      ++op;
	    }
	  else
	    {
	      operand = xgate_parse_operand (opcode, &operand_bit_length, where,
					     &op, oprs[1]);
	      bin = xgate_apply_operand (operand, &oper_mask, bin,
					 operand_bit_length);
	      ++op;
	    }
	}
      /* Parse the third register.  */
      if (*op)
	{
	  if (*op == ',')
	    ++op;
	  operand = xgate_parse_operand (opcode, &operand_bit_length, where,
					 &op, oprs[2]);
	  bin = xgate_apply_operand (operand, &oper_mask, bin,
				     operand_bit_length);
	}
    }
  if (opcode->size == 2 && fixup_required)
    {
      bfd_putl16 (bin, frag);
    }
  else if ( !strcmp (opcode->constraints, XGATE_OP_REL9)
      || !strcmp (opcode->constraints, XGATE_OP_REL10))
    {
      /* Write our data to a frag for further processing.  */
      bfd_putl16 (opcode->bin_opcode, frag);
    }
  else
    {
      /* Apply operand mask(s)to bin opcode and write the output.  */
      /* Since we are done write this frag in xgate BE format.  */
      number_to_chars_bigendian (frag, bin, opcode->size);
    }
  prev = bin;
  return;
}

static unsigned int
xgate_parse_operand (struct xgate_opcode *opcode,
		     int *bit_width,
		     int where,
		     char **op_con,
		     s_operand operand)
{
  char *op_constraint = *op_con;
  unsigned int op_mask = 0;
  unsigned int pp_fix = 0;
  unsigned short max_size = 0;
  int i;

  *bit_width = 0;
  /* Reset.  */

  switch (*op_constraint)
    {
    case '+': /* Indexed register operand +/- or plain r.  */
      /* Default to neither inc or dec.  */
      pp_fix = 0;
      *bit_width = 5;

      if (operand.reg == REG_NONE)
	as_bad (_(": expected register name r0-r7 ") );
      op_mask = operand.reg;
      if (operand.mod == MOD_POSTINC)
	pp_fix = INCREMENT;
      if (operand.mod == MOD_PREDEC)
	pp_fix = DECREMENT;
      op_mask <<= 2;
      op_mask |= pp_fix;
      break;

    case 'r': /* Register operand.  */
      if (operand.reg == REG_NONE)
	as_bad (_(": expected register name r0-r7 "));

      *bit_width = 3;

      op_mask = operand.reg;
      break;

    case 'i': /* Immediate value or expression expected.  */
      /* Advance the original format pointer.  */
      (*op_con)++;
      op_constraint++;
      if (ISDIGIT (*op_constraint))
	*bit_width = (int) *op_constraint - '0';
      else if (*op_constraint == 'a')
	*bit_width = 0x0A;
      else if (*op_constraint == 'f')
	*bit_width = 0x0F;

      /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
      if (operand.exp.X_op == O_constant)
	{
	  op_mask = operand.exp.X_add_number;
	  if (((opcode->name[strlen (opcode->name) - 1] == 'l') && autoHiLo)
	      || operand.mod == MOD_LOAD_LOW)
	    op_mask &= 0x00FF;
	  else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
		    && autoHiLo) || operand.mod == MOD_LOAD_HIGH)
	    op_mask >>= 8;

	  /* Make sure it fits.  */
	  for (i = *bit_width; i; i--)
	    {
	      max_size <<= 1;
	      max_size += 1;
	    }
	  if (op_mask > max_size)
	    as_bad (_(":operand value(%d) too big for constraint"), op_mask);
	}
      else
	{
	  /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24
	     TODO fix.  */
	  fixup_required = 1;
	  if (*op_constraint == '8')
	    {
	      if (((opcode->name[strlen (opcode->name) - 1] == 'l')
		   && autoHiLo) || operand.mod == MOD_LOAD_LOW)
		fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
			     BFD_RELOC_XGATE_24);
	      else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
			&& autoHiLo) || operand.mod == MOD_LOAD_HIGH )
		fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
			     BFD_RELOC_XGATE_IMM8_HI);
	      else
		as_bad (_("you must use a hi/lo directive or 16-bit macro "
			  "to load a 16-bit value."));
	    }
	  else if (*op_constraint == '5')
	    fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
			 BFD_RELOC_XGATE_IMM5);
	  else if (*op_constraint == '4')
	    fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
			 BFD_RELOC_XGATE_IMM4);
	  else if (*op_constraint == '3')
	    fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
			 BFD_RELOC_XGATE_IMM3);
	  else
	    as_bad (_(":unknown relocation constraint size"));
	}
      break;

    case 'c': /* CCR register expected.  */
      *bit_width = 0;
      if (operand.reg != REG_CCR)
	as_bad (_(": expected register name ccr "));
      break;

    case 'p': /* PC register expected.  */
      *bit_width = 0;
      if (operand.reg != REG_PC)
	as_bad (_(": expected register name pc "));
      break;

    case 'b': /* Branch expected.  */
      (*op_con)++;
      op_constraint++;

      if (operand.exp.X_op != O_register)
	{
	  if (*op_constraint == '9')
	    fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
			 R_XGATE_PCREL_9);
	  else if (*op_constraint == 'a')
	    fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
			 R_XGATE_PCREL_10);
	}
      else
	as_fatal (_("Operand `%x' not recognized in fixup8."),
		  operand.exp.X_op);
      break;
    case '?':
      break;

    default:
      as_bad (_("unknown constraint `%c'"), *op_constraint);
      break;
    }
  return op_mask;
}
