/* tc-d10v.c -- Assembler code for the Mitsubishi D10V
   Copyright (C) 1996-2019 Free Software Foundation, Inc.

   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/d10v.h"
#include "elf/ppc.h"
#include "dwarf2dbg.h"

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

int Optimizing = 0;

#define AT_WORD_P(X) ((X)->X_op == O_right_shift \
		      && (X)->X_op_symbol != NULL \
		      && symbol_constant_p ((X)->X_op_symbol) \
		      && S_GET_VALUE ((X)->X_op_symbol) == AT_WORD_RIGHT_SHIFT)
#define AT_WORD_RIGHT_SHIFT 2

/* Fixups.  */
#define MAX_INSN_FIXUPS  5

struct d10v_fixup
{
  expressionS exp;
  int operand;
  int pcrel;
  int size;
  bfd_reloc_code_real_type reloc;
};

typedef struct _fixups
{
  int fc;
  struct d10v_fixup fix[MAX_INSN_FIXUPS];
  struct _fixups *next;
} Fixups;

static Fixups FixUps[2];
static Fixups *fixups;

static int do_not_ignore_hash = 0;

typedef int packing_type;
#define PACK_UNSPEC 	(0)	/* Packing order not specified.  */
#define PACK_PARALLEL	(1)	/* "||"  */
#define PACK_LEFT_RIGHT (2)	/* "->"  */
#define PACK_RIGHT_LEFT (3)	/* "<-"  */
static packing_type etype = PACK_UNSPEC; /* Used by d10v_cleanup.  */

/* TRUE if instruction swapping warnings should be inhibited.
   --nowarnswap.  */
static bfd_boolean flag_warn_suppress_instructionswap;

/* TRUE if instruction packing should be performed when --gstabs is specified.
   --gstabs-packing, --no-gstabs-packing.  */
static bfd_boolean flag_allow_gstabs_packing = 1;

/* Local functions.  */

enum options
{
  OPTION_NOWARNSWAP = OPTION_MD_BASE,
  OPTION_GSTABSPACKING,
  OPTION_NOGSTABSPACKING
};

struct option md_longopts[] =
{
  {"nowarnswap", no_argument, NULL, OPTION_NOWARNSWAP},
  {"gstabspacking",  no_argument, NULL, OPTION_GSTABSPACKING},
  {"gstabs-packing", no_argument, NULL, OPTION_GSTABSPACKING},
  {"nogstabspacking",   no_argument, NULL, OPTION_NOGSTABSPACKING},
  {"no-gstabs-packing", no_argument, NULL, OPTION_NOGSTABSPACKING},
  {NULL, no_argument, NULL, 0}
};

size_t md_longopts_size = sizeof (md_longopts);

/* Opcode hash table.  */
static struct hash_control *d10v_hash;

/* Do a binary search of the d10v_predefined_registers array to see if
   NAME is a valid register name.  Return the register number from the
   array on success, or -1 on failure.  */

static int
reg_name_search (char *name)
{
  int middle, low, high;
  int cmp;

  low = 0;
  high = d10v_reg_name_cnt () - 1;

  do
    {
      middle = (low + high) / 2;
      cmp = strcasecmp (name, d10v_predefined_registers[middle].name);
      if (cmp < 0)
	high = middle - 1;
      else if (cmp > 0)
	low = middle + 1;
      else
	return d10v_predefined_registers[middle].value;
    }
  while (low <= high);
  return -1;
}

/* Check the string at input_line_pointer
   to see if it is a valid register name.  */

static int
register_name (expressionS *expressionP)
{
  int reg_number;
  char c, *p = input_line_pointer;

  while (*p
	 && *p != '\n' && *p != '\r' && *p != ',' && *p != ' ' && *p != ')')
    p++;

  c = *p;
  if (c)
    *p++ = 0;

  /* Look to see if it's in the register table.  */
  reg_number = reg_name_search (input_line_pointer);
  if (reg_number >= 0)
    {
      expressionP->X_op = O_register;
      /* Temporarily store a pointer to the string here.  */
      expressionP->X_op_symbol = (symbolS *) input_line_pointer;
      expressionP->X_add_number = reg_number;
      input_line_pointer = p;
      return 1;
    }
  if (c)
    *(p - 1) = c;
  return 0;
}

static int
check_range (unsigned long num, int bits, int flags)
{
  long min, max;
  int retval = 0;

  /* Don't bother checking 16-bit values.  */
  if (bits == 16)
    return 0;

  if (flags & OPERAND_SHIFT)
    {
      /* All special shift operands are unsigned and <= 16.
	 We allow 0 for now.  */
      if (num > 16)
	return 1;
      else
	return 0;
    }

  if (flags & OPERAND_SIGNED)
    {
      /* Signed 3-bit integers are restricted to the (-2, 3) range.  */
      if (flags & RESTRICTED_NUM3)
	{
	  if ((long) num < -2 || (long) num > 3)
	    retval = 1;
	}
      else
	{
	  max = (1 << (bits - 1)) - 1;
	  min = - (1 << (bits - 1));
	  if (((long) num > max) || ((long) num < min))
	    retval = 1;
	}
    }
  else
    {
      max = (1 << bits) - 1;
      min = 0;
      if (((long) num > max) || ((long) num < min))
	retval = 1;
    }
  return retval;
}

void
md_show_usage (FILE *stream)
{
  fprintf (stream, _("D10V options:\n\
-O                      Optimize.  Will do some operations in parallel.\n\
--gstabs-packing        Pack adjacent short instructions together even\n\
                        when --gstabs is specified.  On by default.\n\
--no-gstabs-packing     If --gstabs is specified, do not pack adjacent\n\
                        instructions together.\n"));
}

int
md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
{
  switch (c)
    {
    case 'O':
      /* Optimize. Will attempt to parallelize operations.  */
      Optimizing = 1;
      break;
    case OPTION_NOWARNSWAP:
      flag_warn_suppress_instructionswap = 1;
      break;
    case OPTION_GSTABSPACKING:
      flag_allow_gstabs_packing = 1;
      break;
    case OPTION_NOGSTABSPACKING:
      flag_allow_gstabs_packing = 0;
      break;
    default:
      return 0;
    }
  return 1;
}

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

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

void
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
		 asection *sec ATTRIBUTE_UNUSED,
		 fragS *fragP ATTRIBUTE_UNUSED)
{
  abort ();
}

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

void
md_begin (void)
{
  const char *prev_name = "";
  struct d10v_opcode *opcode;
  d10v_hash = hash_new ();

  /* Insert unique names into hash table.  The D10v 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.  */

  for (opcode = (struct d10v_opcode *) d10v_opcodes; opcode->name; opcode++)
    {
      if (strcmp (prev_name, opcode->name))
	{
	  prev_name = (char *) opcode->name;
	  hash_insert (d10v_hash, opcode->name, (char *) opcode);
	}
    }

  fixups = &FixUps[0];
  FixUps[0].next = &FixUps[1];
  FixUps[1].next = &FixUps[0];
}

/* Remove the postincrement or postdecrement operator ( '+' or '-' )
   from an expression.  */

static int
postfix (char *p)
{
  while (*p != '-' && *p != '+')
    {
      if (*p == 0 || *p == '\n' || *p == '\r')
	break;
      p++;
    }

  if (*p == '-')
    {
      *p = ' ';
      return -1;
    }
  if (*p == '+')
    {
      *p = ' ';
      return 1;
    }

  return 0;
}

static bfd_reloc_code_real_type
get_reloc (struct d10v_operand *op)
{
  int bits = op->bits;

  if (bits <= 4)
    return 0;

  if (op->flags & OPERAND_ADDR)
    {
      if (bits == 8)
	return BFD_RELOC_D10V_10_PCREL_R;
      else
	return BFD_RELOC_D10V_18_PCREL;
    }

  return BFD_RELOC_16;
}

/* Parse a string of operands.  Return an array of expressions.  */

static int
get_operands (expressionS exp[])
{
  char *p = input_line_pointer;
  int numops = 0;
  int post = 0;
  int uses_at = 0;

  while (*p)
    {
      while (*p == ' ' || *p == '\t' || *p == ',')
	p++;
      if (*p == 0 || *p == '\n' || *p == '\r')
	break;

      if (*p == '@')
	{
	  uses_at = 1;

	  p++;
	  exp[numops].X_op = O_absent;
	  if (*p == '(')
	    {
	      p++;
	      exp[numops].X_add_number = OPERAND_ATPAR;
	    }
	  else if (*p == '-')
	    {
	      p++;
	      exp[numops].X_add_number = OPERAND_ATMINUS;
	    }
	  else
	    {
	      exp[numops].X_add_number = OPERAND_ATSIGN;
	      if (*p == '+')
		{
		  numops++;
		  exp[numops].X_op = O_absent;
		  exp[numops].X_add_number = OPERAND_PLUS;
		  p++;
		}
	      post = postfix (p);
	    }
	  numops++;
	  continue;
	}

      if (*p == ')')
	{
	  /* Just skip the trailing paren.  */
	  p++;
	  continue;
	}

      input_line_pointer = p;

      /* Check to see if it might be a register name.  */
      if (!register_name (&exp[numops]))
	{
	  /* Parse as an expression.  */
	  if (uses_at)
	    {
	      /* Any expression that involves the indirect addressing
		 cannot also involve immediate addressing.  Therefore
		 the use of the hash character is illegal.  */
	      int save = do_not_ignore_hash;
	      do_not_ignore_hash = 1;

	      expression (&exp[numops]);

	      do_not_ignore_hash = save;
	    }
	  else
	    expression (&exp[numops]);
	}

      if (strncasecmp (input_line_pointer, "@word", 5) == 0)
	{
	  input_line_pointer += 5;
	  if (exp[numops].X_op == O_register)
	    {
	      /* If it looked like a register name but was followed by
                 "@word" then it was really a symbol, so change it to
                 one.  */
	      exp[numops].X_op = O_symbol;
	      exp[numops].X_add_symbol =
		symbol_find_or_make ((char *) exp[numops].X_op_symbol);
	    }

	  /* Check for identifier@word+constant.  */
	  if (*input_line_pointer == '-' || *input_line_pointer == '+')
	    {
	      expressionS new_exp;
	      expression (&new_exp);
	      exp[numops].X_add_number = new_exp.X_add_number;
	    }

	  /* Convert expr into a right shift by AT_WORD_RIGHT_SHIFT.  */
	  {
	    expressionS new_exp;
	    memset (&new_exp, 0, sizeof new_exp);
	    new_exp.X_add_number = AT_WORD_RIGHT_SHIFT;
	    new_exp.X_op = O_constant;
	    new_exp.X_unsigned = 1;
	    exp[numops].X_op_symbol = make_expr_symbol (&new_exp);
	    exp[numops].X_op = O_right_shift;
	  }

	  know (AT_WORD_P (&exp[numops]));
	}

      if (exp[numops].X_op == O_illegal)
	as_bad (_("illegal operand"));
      else if (exp[numops].X_op == O_absent)
	as_bad (_("missing operand"));

      numops++;
      p = input_line_pointer;
    }

  switch (post)
    {
    case -1:	/* Postdecrement mode.  */
      exp[numops].X_op = O_absent;
      exp[numops++].X_add_number = OPERAND_MINUS;
      break;
    case 1:	/* Postincrement mode.  */
      exp[numops].X_op = O_absent;
      exp[numops++].X_add_number = OPERAND_PLUS;
      break;
    }

  exp[numops].X_op = 0;
  return numops;
}

static unsigned long
d10v_insert_operand (unsigned long insn,
		     int op_type,
		     offsetT value,
		     int left,
		     fixS *fix)
{
  int shift, bits;

  shift = d10v_operands[op_type].shift;
  if (left)
    shift += 15;

  bits = d10v_operands[op_type].bits;

  /* Truncate to the proper number of bits.  */
  if (check_range (value, bits, d10v_operands[op_type].flags))
    as_bad_where (fix->fx_file, fix->fx_line,
		  _("operand out of range: %ld"), (long) value);

  value &= 0x7FFFFFFF >> (31 - bits);
  insn |= (value << shift);

  return insn;
}

/* Take a pointer to the opcode entry in the opcode table and the
   array of operand expressions.  Return the instruction.  */

static unsigned long
build_insn (struct d10v_opcode *opcode,
	    expressionS *opers,
	    unsigned long insn)
{
  int i, bits, shift, flags, format;
  unsigned long number;

  /* The insn argument is only used for the DIVS kludge.  */
  if (insn)
    format = LONG_R;
  else
    {
      insn = opcode->opcode;
      format = opcode->format;
    }

  for (i = 0; opcode->operands[i]; i++)
    {
      flags = d10v_operands[opcode->operands[i]].flags;
      bits = d10v_operands[opcode->operands[i]].bits;
      shift = d10v_operands[opcode->operands[i]].shift;
      number = opers[i].X_add_number;

      if (flags & OPERAND_REG)
	{
	  number &= REGISTER_MASK;
	  if (format == LONG_L)
	    shift += 15;
	}

      if (opers[i].X_op != O_register && opers[i].X_op != O_constant)
	{
	  /* Now create a fixup.  */

	  if (fixups->fc >= MAX_INSN_FIXUPS)
	    as_fatal (_("too many fixups"));

	  if (AT_WORD_P (&opers[i]))
	    {
	      /* Recognize XXX>>1+N aka XXX@word+N as special (AT_WORD).  */
	      fixups->fix[fixups->fc].reloc = BFD_RELOC_D10V_18;
	      opers[i].X_op = O_symbol;
	      opers[i].X_op_symbol = NULL; /* Should free it.  */
	      /* number is left shifted by AT_WORD_RIGHT_SHIFT so
                 that, it is aligned with the symbol's value.  Later,
                 BFD_RELOC_D10V_18 will right shift (symbol_value +
                 X_add_number).  */
	      number <<= AT_WORD_RIGHT_SHIFT;
	      opers[i].X_add_number = number;
	    }
	  else
	    {
	      fixups->fix[fixups->fc].reloc =
		get_reloc ((struct d10v_operand *) &d10v_operands[opcode->operands[i]]);

	      /* Check that an immediate was passed to ops that expect one.  */
	      if ((flags & OPERAND_NUM)
		  && (fixups->fix[fixups->fc].reloc == 0))
		as_bad (_("operand is not an immediate"));
	    }

	  if (fixups->fix[fixups->fc].reloc == BFD_RELOC_16 ||
	      fixups->fix[fixups->fc].reloc == BFD_RELOC_D10V_18)
	    fixups->fix[fixups->fc].size = 2;
	  else
	    fixups->fix[fixups->fc].size = 4;

	  fixups->fix[fixups->fc].exp = opers[i];
	  fixups->fix[fixups->fc].operand = opcode->operands[i];
	  fixups->fix[fixups->fc].pcrel =
	    (flags & OPERAND_ADDR) ? TRUE : FALSE;
	  (fixups->fc)++;
	}

      /* Truncate to the proper number of bits.  */
      if ((opers[i].X_op == O_constant) && check_range (number, bits, flags))
	as_bad (_("operand out of range: %lu"), number);
      number &= 0x7FFFFFFF >> (31 - bits);
      insn = insn | (number << shift);
    }

  /* kludge: for DIVS, we need to put the operands in twice on the second
     pass, format is changed to LONG_R to force the second set of operands
     to not be shifted over 15.  */
  if ((opcode->opcode == OPCODE_DIVS) && (format == LONG_L))
    insn = build_insn (opcode, opers, insn);

  return insn;
}

/* Write out a long form instruction.  */

static void
write_long (unsigned long insn, Fixups *fx)
{
  int i, where;
  char *f = frag_more (4);

  dwarf2_emit_insn (4);
  insn |= FM11;
  number_to_chars_bigendian (f, insn, 4);

  for (i = 0; i < fx->fc; i++)
    {
      if (fx->fix[i].reloc)
	{
	  where = f - frag_now->fr_literal;
	  if (fx->fix[i].size == 2)
	    where += 2;

	  if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
	    fx->fix[i].operand |= 4096;

	  fix_new_exp (frag_now,
		       where,
		       fx->fix[i].size,
		       &(fx->fix[i].exp),
		       fx->fix[i].pcrel,
		       fx->fix[i].operand|2048);
	}
    }
  fx->fc = 0;
}

/* Write out a short form instruction by itself.  */

static void
write_1_short (struct d10v_opcode *opcode,
	       unsigned long insn,
	       Fixups *fx)
{
  char *f = frag_more (4);
  int i, where;

  dwarf2_emit_insn (4);
  if (opcode->exec_type & PARONLY)
    as_fatal (_("Instruction must be executed in parallel with another instruction."));

  /* The other container needs to be NOP.
     According to 4.3.1: for FM=00, sub-instructions performed only by IU
     cannot be encoded in L-container.  */
  if (opcode->unit == IU)
    insn |= FM00 | (NOP << 15);		/* Right container.  */
  else
    insn = FM00 | (insn << 15) | NOP;	/* Left container.  */

  number_to_chars_bigendian (f, insn, 4);
  for (i = 0; i < fx->fc; i++)
    {
      if (fx->fix[i].reloc)
	{
	  where = f - frag_now->fr_literal;
	  if (fx->fix[i].size == 2)
	    where += 2;

	  if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
	    fx->fix[i].operand |= 4096;

	  /* If it's an R reloc, we may have to switch it to L.  */
	  if ((fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R)
	      && (opcode->unit != IU))
	    fx->fix[i].operand |= 1024;

	  fix_new_exp (frag_now,
		       where,
		       fx->fix[i].size,
		       &(fx->fix[i].exp),
		       fx->fix[i].pcrel,
		       fx->fix[i].operand|2048);
	}
    }
  fx->fc = 0;
}

/* Determine if there are any resource conflicts among two manually
   parallelized instructions.  Some of this was lifted from parallel_ok.  */

static void
check_resource_conflict (struct d10v_opcode *op1,
			 unsigned long insn1,
			 struct d10v_opcode *op2,
			 unsigned long insn2)
{
  int i, j, flags, mask, shift, regno;
  unsigned long ins, mod[2];
  struct d10v_opcode *op;

  if ((op1->exec_type & SEQ)
      || ! ((op1->exec_type & PAR) || (op1->exec_type & PARONLY)))
    {
      as_warn (_("packing conflict: %s must dispatch sequentially"),
	      op1->name);
      return;
    }

  if ((op2->exec_type & SEQ)
      || ! ((op2->exec_type & PAR) || (op2->exec_type & PARONLY)))
    {
      as_warn (_("packing conflict: %s must dispatch sequentially"),
	      op2->name);
      return;
    }

   /* See if both instructions write to the same resource.

      The idea here is to create two sets of bitmasks (mod and used) which
      indicate which registers are modified or used by each instruction.
      The operation can only be done in parallel if neither instruction
      modifies the same register. Accesses to control registers and memory
      are treated as accesses to a single register. So if both instructions
      write memory or if the first instruction writes memory and the second
      reads, then they cannot be done in parallel. We treat reads to the PSW
      (which includes C, F0, and F1) in isolation. So simultaneously writing
      C and F0 in two different sub-instructions is permitted.  */

  /* The bitmasks (mod and used) look like this (bit 31 = MSB).
     r0-r15	  0-15
     a0-a1	  16-17
     cr (not psw) 18
     psw(other)   19
     mem	  20
     psw(C flag)  21
     psw(F0 flag) 22  */

  for (j = 0; j < 2; j++)
    {
      if (j == 0)
	{
	  op = op1;
	  ins = insn1;
	}
      else
	{
	  op = op2;
	  ins = insn2;
	}
      mod[j] = 0;
      if (op->exec_type & BRANCH_LINK)
	mod[j] |= 1 << 13;

      for (i = 0; op->operands[i]; i++)
	{
	  flags = d10v_operands[op->operands[i]].flags;
	  shift = d10v_operands[op->operands[i]].shift;
	  mask = 0x7FFFFFFF >> (31 - d10v_operands[op->operands[i]].bits);
	  if (flags & OPERAND_REG)
	    {
	      regno = (ins >> shift) & mask;
	      if (flags & (OPERAND_ACC0 | OPERAND_ACC1))
		regno += 16;
	      else if (flags & OPERAND_CONTROL)	/* mvtc or mvfc */
		{
		  if (regno == 0)
		    regno = 19;
		  else
		    regno = 18;
		}
	      else if (flags & OPERAND_FFLAG)
		regno = 22;
	      else if (flags & OPERAND_CFLAG)
		regno = 21;

	      if (flags & OPERAND_DEST
		  /* Auto inc/dec also modifies the register.  */
		  || (op->operands[i + 1] != 0
		      && (d10v_operands[op->operands[i + 1]].flags
			  & (OPERAND_PLUS | OPERAND_MINUS)) != 0))
		{
		  mod[j] |= 1 << regno;
		  if (flags & OPERAND_EVEN)
		    mod[j] |= 1 << (regno + 1);
		}
	    }
	  else if (flags & OPERAND_ATMINUS)
	    {
	      /* SP implicitly used/modified.  */
	      mod[j] |= 1 << 15;
	    }
	}

      if (op->exec_type & WMEM)
	mod[j] |= 1 << 20;
      else if (op->exec_type & WF0)
	mod[j] |= 1 << 22;
      else if (op->exec_type & WCAR)
	mod[j] |= 1 << 21;
    }

  if ((mod[0] & mod[1]) == 0)
    return;
  else
    {
      unsigned long x;
      x = mod[0] & mod[1];

      for (j = 0; j <= 15; j++)
	if (x & (1 << j))
	  as_warn (_("resource conflict (R%d)"), j);
      for (j = 16; j <= 17; j++)
	if (x & (1 << j))
	  as_warn (_("resource conflict (A%d)"), j - 16);
      if (x & (1 << 19))
	as_warn (_("resource conflict (PSW)"));
      if (x & (1 << 21))
	as_warn (_("resource conflict (C flag)"));
      if (x & (1 << 22))
	as_warn (_("resource conflict (F flag)"));
    }
}

/* Check 2 instructions and determine if they can be safely
   executed in parallel.  Return 1 if they can be.  */

static int
parallel_ok (struct d10v_opcode *op1,
	     unsigned long insn1,
	     struct d10v_opcode *op2,
	     unsigned long insn2,
	     packing_type exec_type)
{
  int i, j, flags, mask, shift, regno;
  unsigned long ins, mod[2], used[2];
  struct d10v_opcode *op;

  if ((op1->exec_type & SEQ) != 0 || (op2->exec_type & SEQ) != 0
      || (op1->exec_type & PAR) == 0 || (op2->exec_type & PAR) == 0
      || (op1->unit == BOTH) || (op2->unit == BOTH)
      || (op1->unit == IU && op2->unit == IU)
      || (op1->unit == MU && op2->unit == MU))
    return 0;

  /* If this is auto parallelization, and the first instruction is a
     branch or should not be packed, then don't parallelize.  */
  if (exec_type == PACK_UNSPEC
      && (op1->exec_type & (ALONE | BRANCH)))
    return 0;

  /* The idea here is to create two sets of bitmasks (mod and used)
     which indicate which registers are modified or used by each
     instruction.  The operation can only be done in parallel if
     instruction 1 and instruction 2 modify different registers, and
     the first instruction does not modify registers that the second
     is using (The second instruction can modify registers that the
     first is using as they are only written back after the first
     instruction has completed).  Accesses to control registers, PSW,
     and memory are treated as accesses to a single register.  So if
     both instructions write memory or if the first instruction writes
     memory and the second reads, then they cannot be done in
     parallel.  Likewise, if the first instruction mucks with the psw
     and the second reads the PSW (which includes C, F0, and F1), then
     they cannot operate safely in parallel.  */

  /* The bitmasks (mod and used) look like this (bit 31 = MSB).
     r0-r15	  0-15
     a0-a1	  16-17
     cr (not psw) 18
     psw	  19
     mem	  20  */

  for (j = 0; j < 2; j++)
    {
      if (j == 0)
	{
	  op = op1;
	  ins = insn1;
	}
      else
	{
	  op = op2;
	  ins = insn2;
	}
      mod[j] = used[j] = 0;
      if (op->exec_type & BRANCH_LINK)
	mod[j] |= 1 << 13;

      for (i = 0; op->operands[i]; i++)
	{
	  flags = d10v_operands[op->operands[i]].flags;
	  shift = d10v_operands[op->operands[i]].shift;
	  mask = 0x7FFFFFFF >> (31 - d10v_operands[op->operands[i]].bits);
	  if (flags & OPERAND_REG)
	    {
	      regno = (ins >> shift) & mask;
	      if (flags & (OPERAND_ACC0 | OPERAND_ACC1))
		regno += 16;
	      else if (flags & OPERAND_CONTROL)	/* mvtc or mvfc.  */
		{
		  if (regno == 0)
		    regno = 19;
		  else
		    regno = 18;
		}
	      else if (flags & (OPERAND_FFLAG | OPERAND_CFLAG))
		regno = 19;

	      if (flags & OPERAND_DEST)
		{
		  mod[j] |= 1 << regno;
		  if (flags & OPERAND_EVEN)
		    mod[j] |= 1 << (regno + 1);
		}
	      else
		{
		  used[j] |= 1 << regno;
		  if (flags & OPERAND_EVEN)
		    used[j] |= 1 << (regno + 1);

		  /* Auto inc/dec also modifies the register.  */
		  if (op->operands[i + 1] != 0
		      && (d10v_operands[op->operands[i + 1]].flags
			  & (OPERAND_PLUS | OPERAND_MINUS)) != 0)
		    mod[j] |= 1 << regno;
		}
	    }
	  else if (flags & OPERAND_ATMINUS)
	    {
	      /* SP implicitly used/modified.  */
	      mod[j] |= 1 << 15;
	      used[j] |= 1 << 15;
	    }
	}
      if (op->exec_type & RMEM)
	used[j] |= 1 << 20;
      else if (op->exec_type & WMEM)
	mod[j] |= 1 << 20;
      else if (op->exec_type & RF0)
	used[j] |= 1 << 19;
      else if (op->exec_type & WF0)
	mod[j] |= 1 << 19;
      else if (op->exec_type & WCAR)
	mod[j] |= 1 << 19;
    }
  if ((mod[0] & mod[1]) == 0 && (mod[0] & used[1]) == 0)
    return 1;
  return 0;
}

/* Expects two short instructions.
   If possible, writes out both as a single packed instruction.
   Otherwise, writes out the first one, packed with a NOP.
   Returns number of instructions not written out.  */

static int
write_2_short (struct d10v_opcode *opcode1,
	       unsigned long insn1,
	       struct d10v_opcode *opcode2,
	       unsigned long insn2,
	       packing_type exec_type,
	       Fixups *fx)
{
  unsigned long insn;
  char *f;
  int i, j, where;

  if ((exec_type != PACK_PARALLEL)
      && ((opcode1->exec_type & PARONLY) || (opcode2->exec_type & PARONLY)))
    as_fatal (_("Instruction must be executed in parallel"));

  if ((opcode1->format & LONG_OPCODE) || (opcode2->format & LONG_OPCODE))
    as_fatal (_("Long instructions may not be combined."));

  switch (exec_type)
    {
    case PACK_UNSPEC:	/* Order not specified.  */
      if (opcode1->exec_type & ALONE)
	{
	  /* Case of a short branch on a separate GAS line.  Pack with NOP.  */
	  write_1_short (opcode1, insn1, fx->next);
	  return 1;
	}
      if (Optimizing
	  && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
	{
	  /* Parallel.  */
	  if (opcode1->unit == IU)
	    insn = FM00 | (insn2 << 15) | insn1;
	  else if (opcode2->unit == MU)
	    insn = FM00 | (insn2 << 15) | insn1;
	  else
	    insn = FM00 | (insn1 << 15) | insn2;
	}
      else if (opcode1->unit == IU)
	/* Reverse sequential with IU opcode1 on right and done first.  */
	insn = FM10 | (insn2 << 15) | insn1;
      else
	/* Sequential with non-IU opcode1 on left and done first.  */
	insn = FM01 | (insn1 << 15) | insn2;
      break;

    case PACK_PARALLEL:
      if (opcode1->exec_type & SEQ || opcode2->exec_type & SEQ)
	as_fatal
	  (_("One of these instructions may not be executed in parallel."));
      if (opcode1->unit == IU)
	{
	  if (opcode2->unit == IU)
	    as_fatal (_("Two IU instructions may not be executed in parallel"));
	  if (!flag_warn_suppress_instructionswap)
	    as_warn (_("Swapping instruction order"));
	  insn = FM00 | (insn2 << 15) | insn1;
	}
      else if (opcode2->unit == MU)
	{
	  if (opcode1->unit == MU)
	    as_fatal (_("Two MU instructions may not be executed in parallel"));
	  if (!flag_warn_suppress_instructionswap)
	    as_warn (_("Swapping instruction order"));
	  insn = FM00 | (insn2 << 15) | insn1;
	}
      else
	insn = FM00 | (insn1 << 15) | insn2;
      check_resource_conflict (opcode1, insn1, opcode2, insn2);
      break;

    case PACK_LEFT_RIGHT:
      if (opcode1->unit != IU)
	insn = FM01 | (insn1 << 15) | insn2;
      else if (opcode2->unit == MU || opcode2->unit == EITHER)
	{
	  if (!flag_warn_suppress_instructionswap)
	    as_warn (_("Swapping instruction order"));
	  insn = FM10 | (insn2 << 15) | insn1;
	}
      else
	as_fatal (_("IU instruction may not be in the left container"));
      if (opcode1->exec_type & ALONE)
	as_warn (_("Instruction in R container is squashed by flow control instruction in L container."));
      break;

    case PACK_RIGHT_LEFT:
      if (opcode2->unit != MU)
	insn = FM10 | (insn1 << 15) | insn2;
      else if (opcode1->unit == IU || opcode1->unit == EITHER)
	{
	  if (!flag_warn_suppress_instructionswap)
	    as_warn (_("Swapping instruction order"));
	  insn = FM01 | (insn2 << 15) | insn1;
	}
      else
	as_fatal (_("MU instruction may not be in the right container"));
      if (opcode2->exec_type & ALONE)
	as_warn (_("Instruction in R container is squashed by flow control instruction in L container."));
      break;

    default:
      as_fatal (_("unknown execution type passed to write_2_short()"));
    }

  f = frag_more (4);
  dwarf2_emit_insn (4);
  number_to_chars_bigendian (f, insn, 4);

  /* Process fixup chains.  fx refers to insn2 when j == 0, and to
     insn1 when j == 1.  Yes, it's reversed.  */

  for (j = 0; j < 2; j++)
    {
      for (i = 0; i < fx->fc; i++)
	{
	  if (fx->fix[i].reloc)
	    {
	      where = f - frag_now->fr_literal;
	      if (fx->fix[i].size == 2)
		where += 2;

	      if (fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R
		  /* A BFD_RELOC_D10V_10_PCREL_R relocation applied to
		     the instruction in the L container has to be
		     adjusted to BDF_RELOC_D10V_10_PCREL_L.  When
		     j==0, we're processing insn2's operands, so we
		     want to mark the operand if insn2 is *not* in the
		     R container.  When j==1, we're processing insn1's
		     operands, so we want to mark the operand if insn2
		     *is* in the R container.  Note that, if two
		     instructions are identical, we're never going to
		     swap them, so the test is safe.  */
		  && j == ((insn & 0x7fff) == insn2))
		fx->fix[i].operand |= 1024;

	      if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
		fx->fix[i].operand |= 4096;

	      fix_new_exp (frag_now,
			   where,
			   fx->fix[i].size,
			   &(fx->fix[i].exp),
			   fx->fix[i].pcrel,
			   fx->fix[i].operand|2048);
	    }
	}
      fx->fc = 0;
      fx = fx->next;
    }
  return 0;
}

/* This is the main entry point for the machine-dependent assembler.
   str points to a machine-dependent instruction.  This function is
   supposed to emit the frags/bytes it assembles to.  For the D10V, it
   mostly handles the special VLIW parsing and packing and leaves the
   difficult stuff to do_assemble().  */

static unsigned long prev_insn;
static struct d10v_opcode *prev_opcode = 0;
static subsegT prev_subseg;
static segT prev_seg = 0;

/* Find the symbol which has the same name as the register in exp.  */

static symbolS *
find_symbol_matching_register (expressionS *exp)
{
  int i;

  if (exp->X_op != O_register)
    return NULL;

  /* Find the name of the register.  */
  for (i = d10v_reg_name_cnt (); i--;)
    if (d10v_predefined_registers[i].value == exp->X_add_number)
      break;

  if (i < 0)
    abort ();

  /* Now see if a symbol has been defined with the same name.  */
  return symbol_find (d10v_predefined_registers[i].name);
}

/* Get a pointer to an entry in the opcode table.
   The function must look at all opcodes with the same name and use
   the operands to choose the correct opcode.  */

static struct d10v_opcode *
find_opcode (struct d10v_opcode *opcode, expressionS myops[])
{
  int i, match;
  struct d10v_opcode *next_opcode;

  /* Get all the operands and save them as expressions.  */
  get_operands (myops);

  /* Now see if the operand is a fake.  If so, find the correct size
     instruction, if possible.  */
  if (opcode->format == OPCODE_FAKE)
    {
      int opnum = opcode->operands[0];
      int flags;

      if (myops[opnum].X_op == O_register)
	{
	  myops[opnum].X_op = O_symbol;
	  myops[opnum].X_add_symbol =
	    symbol_find_or_make ((char *) myops[opnum].X_op_symbol);
	  myops[opnum].X_add_number = 0;
	  myops[opnum].X_op_symbol = NULL;
	}

      next_opcode = opcode + 1;

      /* If the first operand is supposed to be a register, make sure
	 we got a valid one.  */
      flags = d10v_operands[next_opcode->operands[0]].flags;
      if (flags & OPERAND_REG)
	{
	  int X_op = myops[0].X_op;
	  int num = myops[0].X_add_number;

	  if (X_op != O_register
	      || (num & ~flags
		  & (OPERAND_GPR | OPERAND_ACC0 | OPERAND_ACC1
		     | OPERAND_FFLAG | OPERAND_CFLAG | OPERAND_CONTROL))
	      || ((flags & OPERAND_SP) && ! (num & OPERAND_SP)))
	    {
	      as_bad (_("bad opcode or operands"));
	      return 0;
	    }
	}

      if (myops[opnum].X_op == O_constant
	  || (myops[opnum].X_op == O_symbol
	      && S_IS_DEFINED (myops[opnum].X_add_symbol)
	      && (S_GET_SEGMENT (myops[opnum].X_add_symbol) == now_seg)))
	{
	  for (i = 0; opcode->operands[i + 1]; i++)
	    {
	      int bits = d10v_operands[next_opcode->operands[opnum]].bits;

	      flags = d10v_operands[next_opcode->operands[opnum]].flags;

	      if (flags & OPERAND_ADDR)
		bits += 2;

	      if (myops[opnum].X_op == O_constant)
		{
		  if (!check_range (myops[opnum].X_add_number, bits, flags))
		    break;
		}
	      else
		{
		  fragS *sym_frag;
		  fragS *f;
		  unsigned long current_position;
		  unsigned long symbol_position;
		  unsigned long value;
		  bfd_boolean found_symbol;

		  /* Calculate the address of the current instruction
		     and the address of the symbol.  Do this by summing
		     the offsets of previous frags until we reach the
		     frag containing the symbol, and the current frag.  */
		  sym_frag = symbol_get_frag (myops[opnum].X_add_symbol);
		  found_symbol = FALSE;

		  current_position = frag_now_fix_octets ();
		  symbol_position = S_GET_VALUE (myops[opnum].X_add_symbol);

		  for (f = frchain_now->frch_root; f; f = f->fr_next)
		    {
		      current_position += f->fr_fix + f->fr_offset;

		      if (f == sym_frag)
			found_symbol = TRUE;

		      if (! found_symbol)
			symbol_position += f->fr_fix + f->fr_offset;
		    }

		  value = symbol_position;

		  if (flags & OPERAND_ADDR)
		    value -= current_position;

		  if (AT_WORD_P (&myops[opnum]))
		    {
		      if (bits > 4)
			{
			  bits += 2;
			  if (!check_range (value, bits, flags))
			    break;
			}
		    }
		  else if (!check_range (value, bits, flags))
		    break;
		}
	      next_opcode++;
	    }

	  if (opcode->operands [i + 1] == 0)
	    as_fatal (_("value out of range"));
	  else
	    opcode = next_opcode;
	}
      else
	/* Not a constant, so use a long instruction.  */
	opcode += 2;
    }

  match = 0;

  /* Now search the opcode table table for one with operands
     that matches what we've got.  */
  while (!match)
    {
      match = 1;
      for (i = 0; opcode->operands[i]; i++)
	{
	  int flags = d10v_operands[opcode->operands[i]].flags;
	  int X_op = myops[i].X_op;
	  int num = myops[i].X_add_number;

	  if (X_op == 0)
	    {
	      match = 0;
	      break;
	    }

	  if (flags & OPERAND_REG)
	    {
	      if ((X_op != O_register)
		  || (num & ~flags
		      & (OPERAND_GPR | OPERAND_ACC0 | OPERAND_ACC1
			 | OPERAND_FFLAG | OPERAND_CFLAG
			 | OPERAND_CONTROL))
		  || ((flags & OPERAND_SP) && ! (num & OPERAND_SP)))
		{
		  match = 0;
		  break;
		}
	    }

	  if (((flags & OPERAND_MINUS)   && ((X_op != O_absent) || (num != OPERAND_MINUS))) ||
	      ((flags & OPERAND_PLUS)    && ((X_op != O_absent) || (num != OPERAND_PLUS))) ||
	      ((flags & OPERAND_ATMINUS) && ((X_op != O_absent) || (num != OPERAND_ATMINUS))) ||
	      ((flags & OPERAND_ATPAR)   && ((X_op != O_absent) || (num != OPERAND_ATPAR))) ||
	      ((flags & OPERAND_ATSIGN)  && ((X_op != O_absent) || ((num != OPERAND_ATSIGN) && (num != OPERAND_ATPAR)))))
	    {
	      match = 0;
	      break;
	    }

	  /* Unfortunately, for the indirect operand in instructions such
	     as ``ldb r1, @(c,r14)'' this function can be passed
	     X_op == O_register (because 'c' is a valid register name).
	     However we cannot just ignore the case when X_op == O_register
	     but flags & OPERAND_REG is null, so we check to see if a symbol
	     of the same name as the register exists.  If the symbol does
	     exist, then the parser was unable to distinguish the two cases
	     and we fix things here. (Ref: PR14826)  */

	  if (!(flags & OPERAND_REG) && (X_op == O_register))
	    {
	      symbolS * sym;

	      sym = find_symbol_matching_register (& myops[i]);

	      if (sym != NULL)
		{
		  myops[i].X_op = X_op = O_symbol;
		  myops[i].X_add_symbol = sym;
		}
	      else
		as_bad
		  (_("illegal operand - register name found where none expected"));
	    }
	}

      /* We're only done if the operands matched so far AND there
	     are no more to check.  */
      if (match && myops[i].X_op == 0)
	break;
      else
	match = 0;

      next_opcode = opcode + 1;

      if (next_opcode->opcode == 0)
	break;

      if (strcmp (next_opcode->name, opcode->name))
	break;

      opcode = next_opcode;
    }

  if (!match)
    {
      as_bad (_("bad opcode or operands"));
      return 0;
    }

  /* Check that all registers that are required to be even are.
     Also, if any operands were marked as registers, but were really symbols,
     fix that here.  */
  for (i = 0; opcode->operands[i]; i++)
    {
      if ((d10v_operands[opcode->operands[i]].flags & OPERAND_EVEN) &&
	  (myops[i].X_add_number & 1))
	as_fatal (_("Register number must be EVEN"));
      if ((d10v_operands[opcode->operands[i]].flags & OPERAND_NOSP)
	  && (myops[i].X_add_number & OPERAND_SP))
	as_bad (_("Unsupported use of sp"));
      if (myops[i].X_op == O_register)
	{
	  if (!(d10v_operands[opcode->operands[i]].flags & OPERAND_REG))
	    {
	      myops[i].X_op = O_symbol;
	      myops[i].X_add_symbol =
		symbol_find_or_make ((char *) myops[i].X_op_symbol);
	      myops[i].X_add_number = 0;
	      myops[i].X_op_symbol = NULL;
	    }
	}
      if ((d10v_operands[opcode->operands[i]].flags & OPERAND_CONTROL)
	  && (myops[i].X_add_number == OPERAND_CONTROL + 4
	      || myops[i].X_add_number == OPERAND_CONTROL + 5
	      || myops[i].X_add_number == OPERAND_CONTROL + 6
	      || myops[i].X_add_number == OPERAND_CONTROL + 12
	      || myops[i].X_add_number == OPERAND_CONTROL + 13
	      || myops[i].X_add_number == OPERAND_CONTROL + 15))
	as_warn (_("cr%ld is a reserved control register"),
		 myops[i].X_add_number - OPERAND_CONTROL);
    }
  return opcode;
}

/* Assemble a single instruction.
   Return an opcode, or -1 (an invalid opcode) on error.  */

static unsigned long
do_assemble (char *str, struct d10v_opcode **opcode)
{
  unsigned char *op_start, *op_end;
  char *save;
  char name[20];
  int nlen = 0;
  expressionS myops[6];

  /* Drop leading whitespace.  */
  while (*str == ' ')
    str++;

  /* Find the opcode end.  */
  for (op_start = op_end = (unsigned char *) str;
       *op_end && !is_end_of_line[*op_end] && *op_end != ' ';
       op_end++)
    {
      name[nlen] = TOLOWER (op_start[nlen]);
      nlen++;
      if (nlen == sizeof (name) - 1)
	break;
    }
  name[nlen] = 0;

  if (nlen == 0)
    return -1;

  /* Find the first opcode with the proper name.  */
  *opcode = (struct d10v_opcode *) hash_find (d10v_hash, name);
  if (*opcode == NULL)
    return -1;

  save = input_line_pointer;
  input_line_pointer = (char *) op_end;
  *opcode = find_opcode (*opcode, myops);
  if (*opcode == 0)
    return -1;
  input_line_pointer = save;

  return build_insn ((*opcode), myops, 0);
}

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

arelent *
tc_gen_reloc (asection *seg 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;
  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,
		    _("reloc %d not supported by object file format"),
		    (int) fixp->fx_r_type);
      return NULL;
    }

  if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
    reloc->address = fixp->fx_offset;

  reloc->addend = 0;

  return reloc;
}

int
md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
			       asection *seg ATTRIBUTE_UNUSED)
{
  abort ();
  return 0;
}

long
md_pcrel_from_section (fixS *fixp, segT sec)
{
  if (fixp->fx_addsy != (symbolS *) NULL
      && (!S_IS_DEFINED (fixp->fx_addsy)
	  || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
    return 0;
  return fixp->fx_frag->fr_address + fixp->fx_where;
}

void
md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
{
  char *where;
  unsigned long insn;
  long value = *valP;
  int op_type;
  int left = 0;

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

  op_type = fixP->fx_r_type;
  if (op_type & 2048)
    {
      op_type -= 2048;
      if (op_type & 1024)
	{
	  op_type -= 1024;
	  fixP->fx_r_type = BFD_RELOC_D10V_10_PCREL_L;
	  left = 1;
	}
      else if (op_type & 4096)
	{
	  op_type -= 4096;
	  fixP->fx_r_type = BFD_RELOC_D10V_18;
	}
      else
	fixP->fx_r_type =
	  get_reloc ((struct d10v_operand *) &d10v_operands[op_type]);
    }

  /* Fetch the instruction, insert the fully resolved operand
     value, and stuff the instruction back again.  */
  where = fixP->fx_frag->fr_literal + fixP->fx_where;
  insn = bfd_getb32 ((unsigned char *) where);

  switch (fixP->fx_r_type)
    {
    case BFD_RELOC_D10V_10_PCREL_L:
    case BFD_RELOC_D10V_10_PCREL_R:
    case BFD_RELOC_D10V_18_PCREL:
      /* If the fix is relative to a global symbol, not a section
	 symbol, then ignore the offset.
         XXX - Do we have to worry about branches to a symbol + offset ?  */
      if (fixP->fx_addsy != NULL
	  && S_IS_EXTERNAL (fixP->fx_addsy) )
        {
          segT fseg = S_GET_SEGMENT (fixP->fx_addsy);
          segment_info_type *segf = seg_info(fseg);

	  if ( segf && segf->sym != fixP->fx_addsy)
	    value = 0;
        }
      /* Fall through.  */
    case BFD_RELOC_D10V_18:
      /* Instruction addresses are always right-shifted by 2.  */
      value >>= AT_WORD_RIGHT_SHIFT;
      if (fixP->fx_size == 2)
	bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
      else
	{
	  struct d10v_opcode *rep, *repi;

	  rep = (struct d10v_opcode *) hash_find (d10v_hash, "rep");
	  repi = (struct d10v_opcode *) hash_find (d10v_hash, "repi");
	  if ((insn & FM11) == FM11
	      && ((repi != NULL
		   && (insn & repi->mask) == (unsigned) repi->opcode)
		  || (rep != NULL
		      && (insn & rep->mask) == (unsigned) rep->opcode))
	      && value < 4)
	    as_fatal
	      (_("line %d: rep or repi must include at least 4 instructions"),
	       fixP->fx_line);
	  insn =
	    d10v_insert_operand (insn, op_type, (offsetT) value, left, fixP);
	  bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
	}
      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;
    case BFD_RELOC_8:
      *where = value;
      break;

    case BFD_RELOC_VTABLE_INHERIT:
    case BFD_RELOC_VTABLE_ENTRY:
      fixP->fx_done = 0;
      return;

    default:
      as_fatal (_("line %d: unknown relocation type: 0x%x"),
		fixP->fx_line, fixP->fx_r_type);
    }
}

/* d10v_cleanup() is called after the assembler has finished parsing
   the input file, when a label is read from the input file, or when a
   stab directive is output.  Because the D10V assembler sometimes
   saves short instructions to see if it can package them with the
   next instruction, there may be a short instruction that still needs
   to be written.

   NOTE: accesses a global, etype.
   NOTE: invoked by various macros such as md_cleanup: see.  */

int
d10v_cleanup (void)
{
  segT seg;
  subsegT subseg;

  /* If cleanup was invoked because the assembler encountered, e.g., a
     user label, we write out the pending instruction, if any.  If it
     was invoked because the assembler is outputting a piece of line
     debugging information, though, we write out the pending
     instruction only if the --no-gstabs-packing command line switch
     has been specified.  */
  if (prev_opcode
      && etype == PACK_UNSPEC
      && (! outputting_stabs_line_debug || ! flag_allow_gstabs_packing))
    {
      seg = now_seg;
      subseg = now_subseg;

      if (prev_seg)
	subseg_set (prev_seg, prev_subseg);

      write_1_short (prev_opcode, prev_insn, fixups->next);
      subseg_set (seg, subseg);
      prev_opcode = NULL;
    }
  return 1;
}

void
d10v_frob_label (symbolS *lab)
{
  d10v_cleanup ();
  symbol_set_frag (lab, frag_now);
  S_SET_VALUE (lab, (valueT) frag_now_fix ());
  dwarf2_emit_label (lab);
}

/* Like normal .word, except support @word.
   Clobbers input_line_pointer, checks end-of-line.  */

static void
d10v_dot_word (int dummy ATTRIBUTE_UNUSED)
{
  expressionS exp;
  char *p;

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

  do
    {
      expression (&exp);
      if (!strncasecmp (input_line_pointer, "@word", 5))
	{
	  exp.X_add_number = 0;
	  input_line_pointer += 5;

	  p = frag_more (2);
	  fix_new_exp (frag_now, p - frag_now->fr_literal, 2,
		       &exp, 0, BFD_RELOC_D10V_18);
	}
      else
	emit_expr (&exp, 2);
    }
  while (*input_line_pointer++ == ',');

  input_line_pointer--;		/* Put terminator back into stream.  */
  demand_empty_rest_of_line ();
}

/* Mitsubishi asked that we support some old syntax that apparently
   had immediate operands starting with '#'.  This is in some of their
   sample code but is not documented (although it appears in some
   examples in their assembler manual). For now, we'll solve this
   compatibility problem by simply ignoring any '#' at the beginning
   of an operand.  */

/* Operands that begin with '#' should fall through to here.
   From expr.c.  */

void
md_operand (expressionS *expressionP)
{
  if (*input_line_pointer == '#' && ! do_not_ignore_hash)
    {
      input_line_pointer++;
      expression (expressionP);
    }
}

bfd_boolean
d10v_fix_adjustable (fixS *fixP)
{
  /* We need the symbol name for the VTABLE entries.  */
  if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
      || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
    return 0;

  return 1;
}

/* The target specific pseudo-ops which we support.  */
const pseudo_typeS md_pseudo_table[] =
{
  { "word",	d10v_dot_word,	2 },
  { NULL,       NULL,           0 }
};

void
md_assemble (char *str)
{
  /* etype is saved extype.  For multi-line instructions.  */
  packing_type extype = PACK_UNSPEC;		/* Parallel, etc.  */
  struct d10v_opcode *opcode;
  unsigned long insn;
  char *str2;

  if (etype == PACK_UNSPEC)
    {
      /* Look for the special multiple instruction separators.  */
      str2 = strstr (str, "||");
      if (str2)
	extype = PACK_PARALLEL;
      else
	{
	  str2 = strstr (str, "->");
	  if (str2)
	    extype = PACK_LEFT_RIGHT;
	  else
	    {
	      str2 = strstr (str, "<-");
	      if (str2)
		extype = PACK_RIGHT_LEFT;
	    }
	}

      /* str2 points to the separator, if there is one.  */
      if (str2)
	{
	  *str2 = 0;

	  /* If two instructions are present and we already have one saved,
	     then first write out the saved one.  */
	  d10v_cleanup ();

	  /* Assemble first instruction and save it.  */
	  prev_insn = do_assemble (str, &prev_opcode);
	  prev_seg = now_seg;
	  prev_subseg = now_subseg;
	  if (prev_insn == (unsigned long) -1)
	    as_fatal (_("can't find previous opcode "));
	  fixups = fixups->next;
	  str = str2 + 2;
	}
    }

  insn = do_assemble (str, &opcode);
  if (insn == (unsigned long) -1)
    {
      if (extype != PACK_UNSPEC)
	etype = extype;
      else
	as_bad (_("could not assemble: %s"), str);
      return;
    }

  if (etype != PACK_UNSPEC)
    {
      extype = etype;
      etype = PACK_UNSPEC;
    }

  /* If this is a long instruction, write it and any previous short
     instruction.  */
  if (opcode->format & LONG_OPCODE)
    {
      if (extype != PACK_UNSPEC)
	as_fatal (_("Unable to mix instructions as specified"));
      d10v_cleanup ();
      write_long (insn, fixups);
      prev_opcode = NULL;
      return;
    }

  if (prev_opcode
      && prev_seg
      && ((prev_seg != now_seg) || (prev_subseg != now_subseg)))
    d10v_cleanup ();

  if (prev_opcode
      && (0 == write_2_short (prev_opcode, prev_insn, opcode, insn, extype,
			      fixups)))
    {
      /* No instructions saved.  */
      prev_opcode = NULL;
    }
  else
    {
      if (extype != PACK_UNSPEC)
	as_fatal (_("Unable to mix instructions as specified"));
      /* Save last instruction so it may be packed on next pass.  */
      prev_opcode = opcode;
      prev_insn = insn;
      prev_seg = now_seg;
      prev_subseg = now_subseg;
      fixups = fixups->next;
    }
}

