/* tc-d30v.c -- Assembler code for the Mitsubishi D30V
   Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008,
   2009, 2010 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/d30v.h"
#include "dwarf2dbg.h"

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

#if HAVE_LIMITS_H
#include <limits.h>
#endif

#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif

#define NOP_MULTIPLY 1
#define NOP_ALL 2
static int warn_nops = 0;
static int Optimizing = 0;
static int warn_register_name_conflicts = 1;

#define FORCE_SHORT	1
#define FORCE_LONG	2

/* EXEC types.  */
typedef enum _exec_type
{
  EXEC_UNKNOWN,			/* No order specified.  */
  EXEC_PARALLEL,		/* Done in parallel (FM=00).  */
  EXEC_SEQ,			/* Sequential (FM=01).  */
  EXEC_REVSEQ			/* Reverse sequential (FM=10).  */
} exec_type_enum;

/* Fixups.  */
#define MAX_INSN_FIXUPS  5

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

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

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

/* Whether current and previous instruction are word multiply insns.  */
static int cur_mul32_p = 0;
static int prev_mul32_p = 0;

/*  The flag_explicitly_parallel is true iff the instruction being assembled
    has been explicitly written as a parallel short-instruction pair by the
    human programmer.  It is used in parallel_ok () to distinguish between
    those dangerous parallelizations attempted by the human, which are to be
    allowed, and those attempted by the assembler, which are not.  It is set
    from md_assemble ().  */
static int flag_explicitly_parallel = 0;
static int flag_xp_state = 0;

/* Whether current and previous left sub-instruction disables
   execution of right sub-instruction.  */
static int cur_left_kills_right_p = 0;
static int prev_left_kills_right_p = 0;

/* The known current alignment of the current section.  */
static int d30v_current_align;
static segT d30v_current_align_seg;

/* The last seen label in the current section.  This is used to auto-align
   labels preceding instructions.  */
static symbolS *d30v_last_label;

/* Two nops.  */
#define NOP_LEFT   ((long long) NOP << 32)
#define NOP_RIGHT  ((long long) NOP)
#define NOP2 (FM00 | NOP_LEFT | NOP_RIGHT)

struct option md_longopts[] =
{
  {NULL, no_argument, NULL, 0}
};

size_t md_longopts_size = sizeof (md_longopts);

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

/* Do a binary search of the pre_defined_registers array to see if
   NAME is a valid regiter 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 = reg_name_cnt () - 1;

  do
    {
      middle = (low + high) / 2;
      cmp = strcasecmp (name, pre_defined_registers[middle].name);
      if (cmp < 0)
	high = middle - 1;
      else if (cmp > 0)
	low = middle + 1;
      else
	{
	  if (symbol_find (name) != NULL)
	    {
	      if (warn_register_name_conflicts)
		as_warn (_("Register name %s conflicts with symbol of the same name"),
			 name);
	    }

	  return pre_defined_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;

  /* Don't bother checking 32-bit values.  */
  if (bits == 32)
    {
      if (sizeof (unsigned long) * CHAR_BIT == 32)
	return 0;

      /* We don't record signed or unsigned for 32-bit quantities.
	 Allow either.  */
      min = -((unsigned long) 1 << (bits - 1));
      max = ((unsigned long) 1 << bits) - 1;
      return (long) num < min || (long) num > max;
    }

  if (flags & OPERAND_SHIFT)
    {
      /* We know that all shifts are right by three bits.  */
      num >>= 3;

      if (flags & OPERAND_SIGNED)
	{
	  unsigned long sign_bit = ((unsigned long) -1L >> 4) + 1;
	  num = (num ^ sign_bit) - sign_bit;
	}
    }

  if (flags & OPERAND_SIGNED)
    {
      max = ((unsigned long) 1 << (bits - 1)) - 1;
      min = - ((unsigned long) 1 << (bits - 1));
      return (long) num > max || (long) num < min;
    }
  else
    {
      max = ((unsigned long) 1 << bits) - 1;
      return num > (unsigned long) max;
    }
}

void
md_show_usage (FILE *stream)
{
  fprintf (stream, _("\nD30V options:\n\
-O                      Make adjacent short instructions parallel if possible.\n\
-n                      Warn about all NOPs inserted by the assembler.\n\
-N			Warn about NOPs inserted after word multiplies.\n\
-c                      Warn about symbols whoes names match register names.\n\
-C                      Opposite of -C.  -c is the default.\n"));
}

int
md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
{
  switch (c)
    {
      /* Optimize.  Will attempt to parallelize operations.  */
    case 'O':
      Optimizing = 1;
      break;

      /* Warn about all NOPS that the assembler inserts.  */
    case 'n':
      warn_nops = NOP_ALL;
      break;

      /* Warn about the NOPS that the assembler inserts because of the
	 multiply hazard.  */
    case 'N':
      warn_nops = NOP_MULTIPLY;
      break;

    case 'c':
      warn_register_name_conflicts = 1;
      break;

    case 'C':
      warn_register_name_conflicts = 0;
      break;

    default:
      return 0;
    }
  return 1;
}

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

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_get_section_alignment (stdoutput, seg);
  return ((addr + (1 << align) - 1) & (-1 << align));
}

void
md_begin (void)
{
  struct d30v_opcode *opcode;
  d30v_hash = hash_new ();

  /* Insert opcode names into a hash table.  */
  for (opcode = (struct d30v_opcode *) d30v_opcode_table; opcode->name; opcode++)
      hash_insert (d30v_hash, opcode->name, (char *) opcode);

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

  d30v_current_align_seg = now_seg;
}

/* 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' || *p == ' ' || *p == ',')
	break;
      p++;
    }

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

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

  return 0;
}

static bfd_reloc_code_real_type
get_reloc (const struct d30v_operand *op, int rel_flag)
{
  switch (op->bits)
    {
    case 6:
      if (op->flags & OPERAND_SHIFT)
	return BFD_RELOC_D30V_9_PCREL;
      else
	return BFD_RELOC_D30V_6;
      break;
    case 12:
      if (!(op->flags & OPERAND_SHIFT))
	as_warn (_("unexpected 12-bit reloc type"));
      if (rel_flag == RELOC_PCREL)
	return BFD_RELOC_D30V_15_PCREL;
      else
	return BFD_RELOC_D30V_15;
    case 18:
      if (!(op->flags & OPERAND_SHIFT))
	as_warn (_("unexpected 18-bit reloc type"));
      if (rel_flag == RELOC_PCREL)
	return BFD_RELOC_D30V_21_PCREL;
      else
	return BFD_RELOC_D30V_21;
    case 32:
      if (rel_flag == RELOC_PCREL)
	return BFD_RELOC_D30V_32_PCREL;
      else
	return BFD_RELOC_D30V_32;
    default:
      return 0;
    }
}

/* Parse a string of operands and return an array of expressions.  */

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

  if (cmp_hack)
    {
      exp[numops].X_op = O_absent;
      exp[numops++].X_add_number = cmp_hack - 1;
    }

  while (*p)
    {
      while (*p == ' ' || *p == '\t' || *p == ',')
	p++;

      if (*p == 0 || *p == '\n' || *p == '\r')
	break;

      if (*p == '@')
	{
	  p++;
	  exp[numops].X_op = O_absent;
	  if (*p == '(')
	    {
	      p++;
	      exp[numops].X_add_number = OPERAND_ATPAR;
	      post = postfix (p);
	    }
	  else if (*p == '-')
	    {
	      p++;
	      exp[numops].X_add_number = OPERAND_ATMINUS;
	    }
	  else
	    {
	      exp[numops].X_add_number = OPERAND_ATSIGN;
	      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.  */
	  expression (&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;
	}
      post = 0;
    }

  exp[numops].X_op = 0;

  return numops;
}

/* Generate the instruction.
   It does everything but write the FM bits.  */

static long long
build_insn (struct d30v_insn *opcode, expressionS *opers)
{
  int i, bits, shift, flags;
  unsigned long number, id = 0;
  long long insn;
  struct d30v_opcode *op = opcode->op;
  struct d30v_format *form = opcode->form;

  insn =
    opcode->ecc << 28 | op->op1 << 25 | op->op2 << 20 | form->modifier << 18;

  for (i = 0; form->operands[i]; i++)
    {
      flags = d30v_operand_table[form->operands[i]].flags;

      /* Must be a register or number.  */
      if (!(flags & OPERAND_REG) && !(flags & OPERAND_NUM)
	  && !(flags & OPERAND_NAME) && !(flags & OPERAND_SPECIAL))
	continue;

      bits = d30v_operand_table[form->operands[i]].bits;
      if (flags & OPERAND_SHIFT)
	bits += 3;

      shift = 12 - d30v_operand_table[form->operands[i]].position;
      if (opers[i].X_op != O_symbol)
	number = opers[i].X_add_number;
      else
	number = 0;
      if (flags & OPERAND_REG)
	{
	  /* Check for mvfsys or mvtsys control registers.  */
	  if (flags & OPERAND_CONTROL && (number & 0x7f) > MAX_CONTROL_REG)
	    {
	      /* PSWL or PSWH.  */
	      id = (number & 0x7f) - MAX_CONTROL_REG;
	      number = 0;
	    }
	  else if (number & OPERAND_FLAG)
	    /* NUMBER is a flag register.  */
	    id = 3;

	  number &= 0x7F;
	}
      else if (flags & OPERAND_SPECIAL)
	number = id;

      if (opers[i].X_op != O_register && opers[i].X_op != O_constant
	  && !(flags & OPERAND_NAME))
	{
	  /* Now create a fixup.  */
	  if (fixups->fc >= MAX_INSN_FIXUPS)
	    as_fatal (_("too many fixups"));

	  fixups->fix[fixups->fc].reloc =
	    get_reloc (d30v_operand_table + form->operands[i], op->reloc_flag);
	  fixups->fix[fixups->fc].size = 4;
	  fixups->fix[fixups->fc].exp = opers[i];
	  fixups->fix[fixups->fc].operand = form->operands[i];
	  if (fixups->fix[fixups->fc].reloc == BFD_RELOC_D30V_9_PCREL)
	    fixups->fix[fixups->fc].pcrel = RELOC_PCREL;
	  else
	    fixups->fix[fixups->fc].pcrel = op->reloc_flag;
	  (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: %ld"), number);
      if (bits < 31)
	number &= 0x7FFFFFFF >> (31 - bits);
      if (flags & OPERAND_SHIFT)
	number >>= 3;
      if (bits == 32)
	{
	  /* It's a LONG instruction.  */
	  insn |= ((number & 0xffffffff) >> 26);	/* Top 6 bits.  */
	  insn <<= 32;			/* Shift the first word over.  */
	  insn |= ((number & 0x03FC0000) << 2);		/* Next 8 bits.  */
	  insn |= number & 0x0003FFFF;			/* Bottom 18 bits.  */
	}
      else
	insn |= number << shift;
    }

  return insn;
}

static void
d30v_number_to_chars (char *buf,	/* Return 'nbytes' of chars here.  */
		      long long value,	/* The value of the bits.  */
		      int n)		/* Number of bytes in the output.  */
{
  while (n--)
    {
      buf[n] = value & 0xff;
      value >>= 8;
    }
}

/* Write out a long form instruction.  */

static void
write_long (struct d30v_insn *opcode ATTRIBUTE_UNUSED,
	    long long insn,
	    Fixups *fx)
{
  int i, where;
  char *f = frag_more (8);

  dwarf2_emit_insn (8);
  insn |= FM11;
  d30v_number_to_chars (f, insn, 8);

  for (i = 0; i < fx->fc; i++)
    {
      if (fx->fix[i].reloc)
	{
	  where = f - frag_now->fr_literal;
	  fix_new_exp (frag_now, where, fx->fix[i].size, &(fx->fix[i].exp),
		       fx->fix[i].pcrel, fx->fix[i].reloc);
	}
    }

  fx->fc = 0;
}

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

static void
write_1_short (struct d30v_insn *opcode,
	       long long insn,
	       Fixups *fx,
	       int use_sequential)
{
  char *f = frag_more (8);
  int i, where;

  dwarf2_emit_insn (8);
  if (warn_nops == NOP_ALL)
    as_warn (_("%s NOP inserted"), use_sequential ?
	     _("sequential") : _("parallel"));

  /* The other container needs to be NOP.  */
  if (use_sequential)
    {
      /* Use a sequential NOP rather than a parallel one,
	 as the current instruction is a FLAG_MUL32 type one
	 and the next instruction is a load.  */

      /* According to 4.3.1: for FM=01, sub-instructions performed
	 only by IU cannot be encoded in L-container.  */
      if (opcode->op->unit == IU)
	/* Right then left.  */
	insn |= FM10 | NOP_LEFT;
      else
	/* Left then right.  */
	insn = FM01 | (insn << 32) | NOP_RIGHT;
    }
  else
    {
      /* According to 4.3.1: for FM=00, sub-instructions performed
	 only by IU cannot be encoded in L-container.  */
      if (opcode->op->unit == IU)
	/* Right container.  */
	insn |= FM00 | NOP_LEFT;
      else
	/* Left container.  */
	insn = FM00 | (insn << 32) | NOP_RIGHT;
    }

  d30v_number_to_chars (f, insn, 8);

  for (i = 0; i < fx->fc; i++)
    {
      if (fx->fix[i].reloc)
	{
	  where = f - frag_now->fr_literal;
	  fix_new_exp (frag_now,
		       where,
		       fx->fix[i].size,
		       &(fx->fix[i].exp),
		       fx->fix[i].pcrel,
		       fx->fix[i].reloc);
	}
    }

  fx->fc = 0;
}

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

static int
parallel_ok (struct d30v_insn *op1,
	     unsigned long insn1,
	     struct d30v_insn *op2,
	     unsigned long insn2,
	     exec_type_enum exec_type)
{
  int i, j, shift, regno, bits, ecc;
  unsigned long flags, mask, flags_set1, flags_set2, flags_used1, flags_used2;
  unsigned long ins, mod_reg[2][3], used_reg[2][3], flag_reg[2];
  struct d30v_format *f;
  struct d30v_opcode *op;

  /* Section 4.3: Both instructions must not be IU or MU only.  */
  if ((op1->op->unit == IU && op2->op->unit == IU)
      || (op1->op->unit == MU && op2->op->unit == MU))
    return 0;

  /* First instruction must not be a jump to safely optimize, unless this
     is an explicit parallel operation.  */
  if (exec_type != EXEC_PARALLEL
      && (op1->op->flags_used & (FLAG_JMP | FLAG_JSR)))
    return 0;

  /* If one instruction is /TX or /XT and the other is /FX or /XF respectively,
     then it is safe to allow the two to be done as parallel ops, since only
     one will ever be executed at a time.  */
  if ((op1->ecc == ECC_TX && op2->ecc == ECC_FX)
      || (op1->ecc == ECC_FX && op2->ecc == ECC_TX)
      || (op1->ecc == ECC_XT && op2->ecc == ECC_XF)
      || (op1->ecc == ECC_XF && op2->ecc == ECC_XT))
    return 1;

  /* [0] r0-r31
     [1] r32-r63
     [2] a0, a1, flag registers.  */
  for (j = 0; j < 2; j++)
    {
      if (j == 0)
	{
	  f = op1->form;
	  op = op1->op;
	  ecc = op1->ecc;
	  ins = insn1;
	}
      else
	{
	  f = op2->form;
	  op = op2->op;
	  ecc = op2->ecc;
	  ins = insn2;
	}

      flag_reg[j] = 0;
      mod_reg[j][0] = mod_reg[j][1] = 0;
      used_reg[j][0] = used_reg[j][1] = 0;

      if (flag_explicitly_parallel)
	{
	  /* For human specified parallel instructions we have been asked
	     to ignore the possibility that both instructions could modify
	     bits in the PSW, so we initialise the mod & used arrays to 0.
	     We have been asked, however, to refuse to allow parallel
	     instructions which explicitly set the same flag register,
	     eg "cmpne f0,r1,0x10 || cmpeq f0, r5, 0x2", so further on we test
	     for the use of a flag register and set a bit in the mod or used
	     array appropriately.  */
	  mod_reg[j][2]  = 0;
	  used_reg[j][2] = 0;
	}
      else
	{
	  mod_reg[j][2] = (op->flags_set & FLAG_ALL);
	  used_reg[j][2] = (op->flags_used & FLAG_ALL);
	}

      /* BSR/JSR always sets R62.  */
      if (op->flags_used & FLAG_JSR)
	mod_reg[j][1] = (1L << (62 - 32));

      /* Conditional execution affects the flags_used.  */
      switch (ecc)
	{
	case ECC_TX:
	case ECC_FX:
	  used_reg[j][2] |= flag_reg[j] = FLAG_0;
	  break;

	case ECC_XT:
	case ECC_XF:
	  used_reg[j][2] |= flag_reg[j] = FLAG_1;
	  break;

	case ECC_TT:
	case ECC_TF:
	  used_reg[j][2] |= flag_reg[j] = (FLAG_0 | FLAG_1);
	  break;
	}

      for (i = 0; f->operands[i]; i++)
	{
	  flags = d30v_operand_table[f->operands[i]].flags;
	  shift = 12 - d30v_operand_table[f->operands[i]].position;
	  bits = d30v_operand_table[f->operands[i]].bits;
	  if (bits == 32)
	    mask = 0xffffffff;
	  else
	    mask = 0x7FFFFFFF >> (31 - bits);

	  if ((flags & OPERAND_PLUS) || (flags & OPERAND_MINUS))
	    {
	      /* This is a post-increment or post-decrement.
		 The previous register needs to be marked as modified.  */
	      shift = 12 - d30v_operand_table[f->operands[i - 1]].position;
	      regno = (ins >> shift) & 0x3f;
	      if (regno >= 32)
		mod_reg[j][1] |= 1L << (regno - 32);
	      else
		mod_reg[j][0] |= 1L << regno;
	    }
	  else if (flags & OPERAND_REG)
	    {
	      regno = (ins >> shift) & mask;
	      /* The memory write functions don't have a destination
                 register.  */
	      if ((flags & OPERAND_DEST) && !(op->flags_set & FLAG_MEM))
		{
		  /* MODIFIED registers and flags.  */
		  if (flags & OPERAND_ACC)
		    {
		      if (regno == 0)
			mod_reg[j][2] |= FLAG_A0;
		      else if (regno == 1)
			mod_reg[j][2] |= FLAG_A1;
		      else
			abort ();
		    }
		  else if (flags & OPERAND_FLAG)
		    mod_reg[j][2] |= 1L << regno;
		  else if (!(flags & OPERAND_CONTROL))
		    {
		      int r, z;

		      /* Need to check if there are two destination
			 registers, for example ld2w.  */
		      if (flags & OPERAND_2REG)
			z = 1;
		      else
			z = 0;

		      for (r = regno; r <= regno + z; r++)
			{
			  if (r >= 32)
			    mod_reg[j][1] |= 1L << (r - 32);
			  else
			    mod_reg[j][0] |= 1L << r;
			}
		    }
		}
	      else
		{
		  /* USED, but not modified registers and flags.  */
		  if (flags & OPERAND_ACC)
		    {
		      if (regno == 0)
			used_reg[j][2] |= FLAG_A0;
		      else if (regno == 1)
			used_reg[j][2] |= FLAG_A1;
		      else
			abort ();
		    }
		  else if (flags & OPERAND_FLAG)
		    used_reg[j][2] |= 1L << regno;
		  else if (!(flags & OPERAND_CONTROL))
		    {
		      int r, z;

		      /* Need to check if there are two source
			 registers, for example st2w.  */
		      if (flags & OPERAND_2REG)
			z = 1;
		      else
			z = 0;

		      for (r = regno; r <= regno + z; r++)
			{
			  if (r >= 32)
			    used_reg[j][1] |= 1L << (r - 32);
			  else
			    used_reg[j][0] |= 1L << r;
			}
		    }
		}
	    }
	}
    }

  flags_set1 = op1->op->flags_set;
  flags_set2 = op2->op->flags_set;
  flags_used1 = op1->op->flags_used;
  flags_used2 = op2->op->flags_used;

  /* Check for illegal combinations with ADDppp/SUBppp.  */
  if (((flags_set1 & FLAG_NOT_WITH_ADDSUBppp) != 0
       && (flags_used2 & FLAG_ADDSUBppp) != 0)
      || ((flags_set2 & FLAG_NOT_WITH_ADDSUBppp) != 0
	  && (flags_used1 & FLAG_ADDSUBppp) != 0))
    return 0;

  /* Load instruction combined with half-word multiply is illegal.  */
  if (((flags_used1 & FLAG_MEM) != 0 && (flags_used2 & FLAG_MUL16))
      || ((flags_used2 & FLAG_MEM) != 0 && (flags_used1 & FLAG_MUL16)))
    return 0;

  /* Specifically allow add || add by removing carry, overflow bits dependency.
     This is safe, even if an addc follows since the IU takes the argument in
     the right container, and it writes its results last.
     However, don't paralellize add followed by addc or sub followed by
     subb.  */
  if (mod_reg[0][2] == FLAG_CVVA && mod_reg[1][2] == FLAG_CVVA
      && (used_reg[0][2] & ~flag_reg[0]) == 0
      && (used_reg[1][2] & ~flag_reg[1]) == 0
      && op1->op->unit == EITHER && op2->op->unit == EITHER)
    {
      mod_reg[0][2] = mod_reg[1][2] = 0;
    }

  for (j = 0; j < 3; j++)
    {
      /* If the second instruction depends on the first, we obviously
	 cannot parallelize.  Note, the mod flag implies use, so
	 check that as well.  */
      /* If flag_explicitly_parallel is set, then the case of the
	 second instruction using a register the first instruction
	 modifies is assumed to be okay; we trust the human.  We
	 don't trust the human if both instructions modify the same
	 register but we do trust the human if they modify the same
	 flags.  */
      /* We have now been requested not to trust the human if the
	 instructions modify the same flag registers either.  */
      if (flag_explicitly_parallel)
	{
	  if ((mod_reg[0][j] & mod_reg[1][j]) != 0)
	    return 0;
	}
      else
	if ((mod_reg[0][j] & (mod_reg[1][j] | used_reg[1][j])) != 0)
	  return 0;
    }

  return 1;
}

/* Write out a short form instruction if possible.
   Return number of instructions not written out.  */

static int
write_2_short (struct d30v_insn *opcode1,
	       long long insn1,
	       struct d30v_insn *opcode2,
	       long long insn2,
	       exec_type_enum exec_type,
	       Fixups *fx)
{
  long long insn = NOP2;
  char *f;
  int i, j, where;

  if (exec_type == EXEC_SEQ
      && (opcode1->op->flags_used & (FLAG_JMP | FLAG_JSR))
      && ((opcode1->op->flags_used & FLAG_DELAY) == 0)
      && ((opcode1->ecc == ECC_AL) || ! Optimizing))
    {
      /* Unconditional, non-delayed branches kill instructions in
	 the right bin.  Conditional branches don't always but if
	 we are not optimizing, then we have been asked to produce
	 an error about such constructs.  For the purposes of this
	 test, subroutine calls are considered to be branches.  */
      write_1_short (opcode1, insn1, fx->next, FALSE);
      return 1;
    }

  /* Note: we do not have to worry about subroutine calls occurring
     in the right hand container.  The return address is always
     aligned to the next 64 bit boundary, be that 64 or 32 bit away.  */
  switch (exec_type)
    {
    case EXEC_UNKNOWN:	/* Order not specified.  */
      if (Optimizing
	  && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type)
	  && ! (   (opcode1->op->unit == EITHER_BUT_PREFER_MU
		 || opcode1->op->unit == MU)
		&&
		(   opcode2->op->unit == EITHER_BUT_PREFER_MU
		 || opcode2->op->unit == MU)))
	{
	  /* Parallel.  */
	  exec_type = EXEC_PARALLEL;

	  if (opcode1->op->unit == IU
	      || opcode2->op->unit == MU
	      || opcode2->op->unit == EITHER_BUT_PREFER_MU)
	    insn = FM00 | (insn2 << 32) | insn1;
	  else
	    {
	      insn = FM00 | (insn1 << 32) | insn2;
	      fx = fx->next;
	    }
	}
      else if ((opcode1->op->flags_used & (FLAG_JMP | FLAG_JSR)
		&& ((opcode1->op->flags_used & FLAG_DELAY) == 0))
	       || opcode1->op->flags_used & FLAG_RP)
	{
	  /* We must emit (non-delayed) branch type instructions
	     on their own with nothing in the right container.  */
	  /* We must treat repeat instructions likewise, since the
	     following instruction has to be separate from the repeat
	     in order to be repeated.  */
	  write_1_short (opcode1, insn1, fx->next, FALSE);
	  return 1;
	}
      else if (prev_left_kills_right_p)
	{
	  /* The left instruction kils the right slot, so we
	     must leave it empty.  */
	  write_1_short (opcode1, insn1, fx->next, FALSE);
	  return 1;
	}
      else if (opcode1->op->unit == IU)
	{
	  if (opcode2->op->unit == EITHER_BUT_PREFER_MU)
	    {
	      /* Case 103810 is a request from Mitsubishi that opcodes
		 with EITHER_BUT_PREFER_MU should not be executed in
		 reverse sequential order.  */
	      write_1_short (opcode1, insn1, fx->next, FALSE);
	      return 1;
	    }

	  /* Reverse sequential.  */
	  insn = FM10 | (insn2 << 32) | insn1;
	  exec_type = EXEC_REVSEQ;
	}
      else
	{
	  /* Sequential.  */
	  insn = FM01 | (insn1 << 32) | insn2;
	  fx = fx->next;
	  exec_type = EXEC_SEQ;
	}
      break;

    case EXEC_PARALLEL:	/* Parallel.  */
      flag_explicitly_parallel = flag_xp_state;
      if (! parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
	as_bad (_("Instructions may not be executed in parallel"));
      else if (opcode1->op->unit == IU)
	{
	  if (opcode2->op->unit == IU)
	    as_bad (_("Two IU instructions may not be executed in parallel"));
	  as_warn (_("Swapping instruction order"));
	  insn = FM00 | (insn2 << 32) | insn1;
	}
      else if (opcode2->op->unit == MU)
	{
	  if (opcode1->op->unit == MU)
	    as_bad (_("Two MU instructions may not be executed in parallel"));
	  else if (opcode1->op->unit == EITHER_BUT_PREFER_MU)
	    as_warn (_("Executing %s in IU may not work"), opcode1->op->name);
	  as_warn (_("Swapping instruction order"));
	  insn = FM00 | (insn2 << 32) | insn1;
	}
      else
	{
	  if (opcode2->op->unit == EITHER_BUT_PREFER_MU)
	    as_warn (_("Executing %s in IU may not work in parallel execution"),
		     opcode2->op->name);

	  insn = FM00 | (insn1 << 32) | insn2;
	  fx = fx->next;
	}
      flag_explicitly_parallel = 0;
      break;

    case EXEC_SEQ:	/* Sequential.  */
      if (opcode1->op->unit == IU)
	as_bad (_("IU instruction may not be in the left container"));
      if (prev_left_kills_right_p)
	as_bad (_("special left instruction `%s' kills instruction "
		  "`%s' in right container"),
		opcode1->op->name, opcode2->op->name);
      insn = FM01 | (insn1 << 32) | insn2;
      fx = fx->next;
      break;

    case EXEC_REVSEQ:	/* Reverse sequential.  */
      if (opcode2->op->unit == MU)
	as_bad (_("MU instruction may not be in the right container"));
      if (opcode1->op->unit == EITHER_BUT_PREFER_MU)
	as_warn (_("Executing %s in reverse serial with %s may not work"),
		 opcode1->op->name, opcode2->op->name);
      else if (opcode2->op->unit == EITHER_BUT_PREFER_MU)
	as_warn (_("Executing %s in IU in reverse serial may not work"),
		 opcode2->op->name);
      insn = FM10 | (insn1 << 32) | insn2;
      fx = fx->next;
      break;

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

  f = frag_more (8);
  dwarf2_emit_insn (8);
  d30v_number_to_chars (f, insn, 8);

  /* If the previous instruction was a 32-bit multiply but it is put into a
     parallel container, mark the current instruction as being a 32-bit
     multiply.  */
  if (prev_mul32_p && exec_type == EXEC_PARALLEL)
    cur_mul32_p = 1;

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

	      fix_new_exp (frag_now,
			   where,
			   fx->fix[i].size,
			   &(fx->fix[i].exp),
			   fx->fix[i].pcrel,
			   fx->fix[i].reloc);
	    }
	}

      fx->fc = 0;
      fx = fx->next;
    }

  return 0;
}

/* Get a pointer to an entry in the format table.
   It must look at all formats for an opcode and use the operands
   to choose the correct one.  Return NULL on error.  */

static struct d30v_format *
find_format (struct d30v_opcode *opcode,
	     expressionS myops[],
	     int fsize,
	     int cmp_hack)
{
  int match, opcode_index, i = 0, j, k;
  struct d30v_format *fm;

  if (opcode == NULL)
    return NULL;

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

  while ((opcode_index = opcode->format[i++]) != 0)
    {
      if (fsize == FORCE_SHORT && opcode_index >= LONG)
	continue;

      if (fsize == FORCE_LONG && opcode_index < LONG)
	continue;

      fm = (struct d30v_format *) &d30v_format_table[opcode_index];
      k = opcode_index;
      while (fm->form == opcode_index)
	{
	  match = 1;
	  /* Now check the operands for compatibility.  */
	  for (j = 0; match && fm->operands[j]; j++)
	    {
	      int flags = d30v_operand_table[fm->operands[j]].flags;
	      int bits = d30v_operand_table[fm->operands[j]].bits;
	      int X_op = myops[j].X_op;
	      int num = myops[j].X_add_number;

	      if (flags & OPERAND_SPECIAL)
		break;
	      else if (X_op == O_illegal)
		match = 0;
	      else if (flags & OPERAND_REG)
		{
		  if (X_op != O_register
		      || ((flags & OPERAND_ACC) && !(num & OPERAND_ACC))
		      || (!(flags & OPERAND_ACC) && (num & OPERAND_ACC))
		      || ((flags & OPERAND_FLAG) && !(num & OPERAND_FLAG))
		      || (!(flags & (OPERAND_FLAG | OPERAND_CONTROL)) && (num & OPERAND_FLAG))
		      || ((flags & OPERAND_CONTROL)
			  && !(num & (OPERAND_CONTROL | OPERAND_FLAG))))
		    match = 0;
		}
	      else 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)))
		match = 0;
	      else if (flags & OPERAND_NUM)
		{
		  /* A number can be a constant or symbol expression.  */

		  /* If we have found a register name, but that name
		     also matches a symbol, then re-parse the name as
		     an expression.  */
		  if (X_op == O_register
		      && symbol_find ((char *) myops[j].X_op_symbol))
		    {
		      input_line_pointer = (char *) myops[j].X_op_symbol;
		      expression (&myops[j]);
		    }

		  /* Turn an expression into a symbol for later resolution.  */
		  if (X_op != O_absent && X_op != O_constant
		      && X_op != O_symbol && X_op != O_register
		      && X_op != O_big)
		    {
		      symbolS *sym = make_expr_symbol (&myops[j]);
		      myops[j].X_op = X_op = O_symbol;
		      myops[j].X_add_symbol = sym;
		      myops[j].X_add_number = num = 0;
		    }

		  if (fm->form >= LONG)
		    {
		      /* If we're testing for a LONG format, either fits.  */
		      if (X_op != O_constant && X_op != O_symbol)
			match = 0;
		    }
		  else if (fm->form < LONG
			   && ((fsize == FORCE_SHORT && X_op == O_symbol)
			       || (fm->form == SHORT_D2 && j == 0)))
		    match = 1;

		  /* This is the tricky part.  Will the constant or symbol
		     fit into the space in the current format?  */
		  else if (X_op == O_constant)
		    {
		      if (check_range (num, bits, flags))
			match = 0;
		    }
		  else if (X_op == O_symbol
			   && S_IS_DEFINED (myops[j].X_add_symbol)
			   && S_GET_SEGMENT (myops[j].X_add_symbol) == now_seg
			   && opcode->reloc_flag == RELOC_PCREL)
		    {
		      /* If the symbol is defined, see if the value will fit
			 into the form we're considering.  */
		      fragS *f;
		      long value;

		      /* Calculate the current address by running through the
			 previous frags and adding our current offset.  */
		      value = 0;
		      for (f = frchain_now->frch_root; f; f = f->fr_next)
			value += f->fr_fix + f->fr_offset;
		      value = (S_GET_VALUE (myops[j].X_add_symbol) - value
			       - (obstack_next_free (&frchain_now->frch_obstack)
				  - frag_now->fr_literal));
		      if (check_range (value, bits, flags))
			match = 0;
		    }
		  else
		    match = 0;
		}
	    }
	  /* We're only done if the operands matched so far AND there
	     are no more to check.  */
	  if (match && myops[j].X_op == 0)
	    {
	      /* Final check - issue a warning if an odd numbered register
		 is used as the first register in an instruction that reads
		 or writes 2 registers.  */

	      for (j = 0; fm->operands[j]; j++)
		if (myops[j].X_op == O_register
		    && (myops[j].X_add_number & 1)
		    && (d30v_operand_table[fm->operands[j]].flags & OPERAND_2REG))
		  as_warn (_("Odd numbered register used as target of multi-register instruction"));

	      return fm;
	    }
	  fm = (struct d30v_format *) &d30v_format_table[++k];
	}
    }
  return NULL;
}

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

#define NAME_BUF_LEN	20

static long long
do_assemble (char *str,
	     struct d30v_insn *opcode,
	     int shortp,
	     int is_parallel)
{
  char *op_start;
  char *save;
  char *op_end;
  char           name[NAME_BUF_LEN];
  int            cmp_hack;
  int            nlen = 0;
  int            fsize = (shortp ? FORCE_SHORT : 0);
  expressionS    myops[6];
  long long      insn;

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

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

  if (nlen == 0)
    return -1;

  name[nlen] = 0;

  /* If there is an execution condition code, handle it.  */
  if (*op_end == '/')
    {
      int i = 0;
      while ((i < ECC_MAX) && strncasecmp (d30v_ecc_names[i], op_end + 1, 2))
	i++;

      if (i == ECC_MAX)
	{
	  char tmp[4];
	  strncpy (tmp, op_end + 1, 2);
	  tmp[2] = 0;
	  as_bad (_("unknown condition code: %s"), tmp);
	  return -1;
	}
      opcode->ecc = i;
      op_end += 3;
    }
  else
    opcode->ecc = ECC_AL;

  /* CMP and CMPU change their name based on condition codes.  */
  if (!strncmp (name, "cmp", 3))
    {
      int p, i;
      char **d30v_str = (char **) d30v_cc_names;

      if (name[3] == 'u')
	p = 4;
      else
	p = 3;

      for (i = 1; *d30v_str && strncmp (*d30v_str, &name[p], 2); i++, d30v_str++)
	;

      /* cmpu only supports some condition codes.  */
      if (p == 4)
	{
	  if (i < 3 || i > 6)
	    {
	      name[p + 2] = 0;
	      as_bad (_("cmpu doesn't support condition code %s"), &name[p]);
	    }
	}

      if (!*d30v_str)
	{
	  name[p + 2] = 0;
	  as_bad (_("unknown condition code: %s"), &name[p]);
	}

      cmp_hack = i;
      name[p] = 0;
    }
  else
    cmp_hack = 0;

  /* Need to look for .s or .l.  */
  if (name[nlen - 2] == '.')
    {
      switch (name[nlen - 1])
	{
	case 's':
	  fsize = FORCE_SHORT;
	  break;
	case 'l':
	  fsize = FORCE_LONG;
	  break;
	}
      name[nlen - 2] = 0;
    }

  /* Find the first opcode with the proper name.  */
  opcode->op = (struct d30v_opcode *) hash_find (d30v_hash, name);
  if (opcode->op == NULL)
    {
      as_bad (_("unknown opcode: %s"), name);
      return -1;
    }

  save = input_line_pointer;
  input_line_pointer = op_end;
  while (!(opcode->form = find_format (opcode->op, myops, fsize, cmp_hack)))
    {
      opcode->op++;
      if (opcode->op->name == NULL || strcmp (opcode->op->name, name))
	{
	  as_bad (_("operands for opcode `%s' do not match any valid format"),
		  name);
	  return -1;
	}
    }
  input_line_pointer = save;

  insn = build_insn (opcode, myops);

  /* Propagate multiply status.  */
  if (insn != -1)
    {
      if (is_parallel && prev_mul32_p)
	cur_mul32_p = 1;
      else
	{
	  prev_mul32_p = cur_mul32_p;
	  cur_mul32_p  = (opcode->op->flags_used & FLAG_MUL32) != 0;
	}
    }

  /* Propagate left_kills_right status.  */
  if (insn != -1)
    {
      prev_left_kills_right_p = cur_left_kills_right_p;

      if (opcode->op->flags_set & FLAG_LKR)
	{
	  cur_left_kills_right_p = 1;

	  if (strcmp (opcode->op->name, "mvtsys") == 0)
	    {
	      /* Left kills right for only mvtsys only for
                 PSW/PSWH/PSWL/flags target.  */
	      if ((myops[0].X_op == O_register) &&
		  ((myops[0].X_add_number == OPERAND_CONTROL) || /* psw */
		   (myops[0].X_add_number == OPERAND_CONTROL+MAX_CONTROL_REG+2) || /* pswh */
		   (myops[0].X_add_number == OPERAND_CONTROL+MAX_CONTROL_REG+1) || /* pswl */
		   (myops[0].X_add_number == OPERAND_FLAG+0) || /* f0 */
		   (myops[0].X_add_number == OPERAND_FLAG+1) || /* f1 */
		   (myops[0].X_add_number == OPERAND_FLAG+2) || /* f2 */
		   (myops[0].X_add_number == OPERAND_FLAG+3) || /* f3 */
		   (myops[0].X_add_number == OPERAND_FLAG+4) || /* f4 */
		   (myops[0].X_add_number == OPERAND_FLAG+5) || /* f5 */
		   (myops[0].X_add_number == OPERAND_FLAG+6) || /* f6 */
		   (myops[0].X_add_number == OPERAND_FLAG+7))) /* f7 */
		{
		  cur_left_kills_right_p = 1;
		}
	      else
		{
		  /* Other mvtsys target registers don't kill right
                     instruction.  */
		  cur_left_kills_right_p = 0;
		}
	    } /* mvtsys */
	}
      else
	cur_left_kills_right_p = 0;
    }

  return insn;
}

/* Called internally to handle all alignment needs.  This takes care
   of eliding calls to frag_align if'n the cached current alignment
   says we've already got it, as well as taking care of the auto-aligning
   labels wrt code.  */

static void
d30v_align (int n, char *pfill, symbolS *label)
{
  /* The front end is prone to changing segments out from under us
     temporarily when -g is in effect.  */
  int switched_seg_p = (d30v_current_align_seg != now_seg);

  /* Do not assume that if 'd30v_current_align >= n' and
     '! switched_seg_p' that it is safe to avoid performing
     this alignment request.  The alignment of the current frag
     can be changed under our feet, for example by a .ascii
     directive in the source code.  cf testsuite/gas/d30v/reloc.s  */
  d30v_cleanup (FALSE);

  if (pfill == NULL)
    {
      if (n > 2
	  && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
	{
	  static char const nop[4] = { 0x00, 0xf0, 0x00, 0x00 };

	  /* First, make sure we're on a four-byte boundary, in case
	     someone has been putting .byte values the text section.  */
	  if (d30v_current_align < 2 || switched_seg_p)
	    frag_align (2, 0, 0);
	  frag_align_pattern (n, nop, sizeof nop, 0);
	}
      else
	frag_align (n, 0, 0);
    }
  else
    frag_align (n, *pfill, 0);

  if (!switched_seg_p)
    d30v_current_align = n;

  if (label != NULL)
    {
      symbolS     *sym;
      int          label_seen = FALSE;
      struct frag *old_frag;
      valueT       old_value;
      valueT       new_value;

      gas_assert (S_GET_SEGMENT (label) == now_seg);

      old_frag  = symbol_get_frag (label);
      old_value = S_GET_VALUE (label);
      new_value = (valueT) frag_now_fix ();

      /* It is possible to have more than one label at a particular
	 address, especially if debugging is enabled, so we must
	 take care to adjust all the labels at this address in this
	 fragment.  To save time we search from the end of the symbol
	 list, backwards, since the symbols we are interested in are
	 almost certainly the ones that were most recently added.
	 Also to save time we stop searching once we have seen at least
	 one matching label, and we encounter a label that is no longer
	 in the target fragment.  Note, this search is guaranteed to
	 find at least one match when sym == label, so no special case
	 code is necessary.  */
      for (sym = symbol_lastP; sym != NULL; sym = symbol_previous (sym))
	{
	  if (symbol_get_frag (sym) == old_frag
	      && S_GET_VALUE (sym) == old_value)
	    {
	      label_seen = TRUE;
	      symbol_set_frag (sym, frag_now);
	      S_SET_VALUE (sym, new_value);
	    }
	  else if (label_seen && symbol_get_frag (sym) != old_frag)
	    break;
	}
    }

  record_alignment (now_seg, n);
}

/* 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 D30V, it
   mostly handles the special VLIW parsing and packing and leaves the
   difficult stuff to do_assemble ().  */

static long long prev_insn = -1;
static struct d30v_insn prev_opcode;
static subsegT prev_subseg;
static segT prev_seg = 0;

void
md_assemble (char *str)
{
  struct d30v_insn opcode;
  long long insn;
  /* Execution type; parallel, etc.  */
  exec_type_enum extype = EXEC_UNKNOWN;
  /* Saved extype.  Used for multiline instructions.  */
  static exec_type_enum etype = EXEC_UNKNOWN;
  char *str2;

  if ((prev_insn != -1) && prev_seg
      && ((prev_seg != now_seg) || (prev_subseg != now_subseg)))
    d30v_cleanup (FALSE);

  if (d30v_current_align < 3)
    d30v_align (3, NULL, d30v_last_label);
  else if (d30v_current_align > 3)
    d30v_current_align = 3;
  d30v_last_label = NULL;

  flag_explicitly_parallel = 0;
  flag_xp_state = 0;
  if (etype == EXEC_UNKNOWN)
    {
      /* Look for the special multiple instruction separators.  */
      str2 = strstr (str, "||");
      if (str2)
	{
	  extype = EXEC_PARALLEL;
	  flag_xp_state = 1;
	}
      else
	{
	  str2 = strstr (str, "->");
	  if (str2)
	    extype = EXEC_SEQ;
	  else
	    {
	      str2 = strstr (str, "<-");
	      if (str2)
		extype = EXEC_REVSEQ;
	    }
	}

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

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

	  /* Assemble first instruction and save it.  */
	  prev_insn = do_assemble (str, &prev_opcode, 1, 0);
	  if (prev_insn == -1)
	    as_bad (_("Cannot assemble instruction"));
	  if (prev_opcode.form != NULL && prev_opcode.form->form >= LONG)
	    as_bad (_("First opcode is long.  Unable to mix instructions as specified."));
	  fixups = fixups->next;
	  str = str2 + 2;
	  prev_seg = now_seg;
	  prev_subseg = now_subseg;
	}
    }

  insn = do_assemble (str, &opcode,
		      (extype != EXEC_UNKNOWN || etype != EXEC_UNKNOWN),
		      extype == EXEC_PARALLEL);
  if (insn == -1)
    {
      if (extype != EXEC_UNKNOWN)
	etype = extype;
      as_bad (_("Cannot assemble instruction"));
      return;
    }

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

  /* Word multiply instructions must not be followed by either a load or a
     16-bit multiply instruction in the next cycle.  */
  if (   (extype != EXEC_REVSEQ)
      && prev_mul32_p
      && (opcode.op->flags_used & (FLAG_MEM | FLAG_MUL16)))
    {
      /* However, load and multiply should able to be combined in a parallel
	 operation, so check for that first.  */
      if (prev_insn != -1
	  && (opcode.op->flags_used & FLAG_MEM)
	  && opcode.form->form < LONG
	  && (extype == EXEC_PARALLEL || (Optimizing && extype == EXEC_UNKNOWN))
	  && parallel_ok (&prev_opcode, (long) prev_insn,
			  &opcode, (long) insn, extype)
	  && write_2_short (&prev_opcode, (long) prev_insn,
			    &opcode, (long) insn, extype, fixups) == 0)
	{
	  /* No instructions saved.  */
	  prev_insn = -1;
	  return;
	}
      else
	{
	  /* Can't parallelize, flush previous instruction and emit a
	     word of NOPS, unless the previous instruction is a NOP,
	     in which case just flush it, as this will generate a word
	     of NOPs for us.  */

	  if (prev_insn != -1 && (strcmp (prev_opcode.op->name, "nop") == 0))
	    d30v_cleanup (FALSE);
	  else
	    {
	      char *f;

	      if (prev_insn != -1)
		d30v_cleanup (TRUE);
	      else
		{
		  f = frag_more (8);
		  dwarf2_emit_insn (8);
		  d30v_number_to_chars (f, NOP2, 8);

		  if (warn_nops == NOP_ALL || warn_nops == NOP_MULTIPLY)
		    {
		      if (opcode.op->flags_used & FLAG_MEM)
			as_warn (_("word of NOPs added between word multiply and load"));
		      else
			as_warn (_("word of NOPs added between word multiply and 16-bit multiply"));
		    }
		}
	    }

	  extype = EXEC_UNKNOWN;
	}
    }
  else if (   (extype == EXEC_REVSEQ)
	   && cur_mul32_p
	   && (prev_opcode.op->flags_used & (FLAG_MEM | FLAG_MUL16)))
    {
      /* Can't parallelize, flush current instruction and add a
         sequential NOP.  */
      write_1_short (&opcode, (long) insn, fixups->next->next, TRUE);

      /* Make the previous instruction the current one.  */
      extype = EXEC_UNKNOWN;
      insn = prev_insn;
      now_seg = prev_seg;
      now_subseg = prev_subseg;
      prev_insn = -1;
      cur_mul32_p = prev_mul32_p;
      prev_mul32_p = 0;
      memcpy (&opcode, &prev_opcode, sizeof (prev_opcode));
    }

  /* If this is a long instruction, write it and any previous short
     instruction.  */
  if (opcode.form->form >= LONG)
    {
      if (extype != EXEC_UNKNOWN)
	as_bad (_("Instruction uses long version, so it cannot be mixed as specified"));
      d30v_cleanup (FALSE);
      write_long (&opcode, insn, fixups);
      prev_insn = -1;
    }
  else if ((prev_insn != -1)
	   && (write_2_short
	       (&prev_opcode, (long) prev_insn, &opcode,
		(long) insn, extype, fixups) == 0))
    {
      /* No instructions saved.  */
      prev_insn = -1;
    }
  else
    {
      if (extype != EXEC_UNKNOWN)
	as_bad (_("Unable to mix instructions as specified"));

      /* Save off last instruction so it may be packed on next pass.  */
      memcpy (&prev_opcode, &opcode, sizeof (prev_opcode));
      prev_insn = insn;
      prev_seg = now_seg;
      prev_subseg = now_subseg;
      fixups = fixups->next;
      prev_mul32_p = cur_mul32_p;
    }
}

/* 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 = xmalloc (sizeof (arelent));
  reloc->sym_ptr_ptr = xmalloc (sizeof (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 == 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;
    }

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

/* Called after the assembler has finished parsing the input file or
   after a label is defined.  Because the D30V 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
   written.  */

int
d30v_cleanup (int use_sequential)
{
  segT seg;
  subsegT subseg;

  if (prev_insn != -1)
    {
      seg = now_seg;
      subseg = now_subseg;
      subseg_set (prev_seg, prev_subseg);
      write_1_short (&prev_opcode, (long) prev_insn, fixups->next,
		     use_sequential);
      subseg_set (seg, subseg);
      prev_insn = -1;
      if (use_sequential)
	prev_mul32_p = FALSE;
    }

  return 1;
}

/* This function is called at the start of every line.  It checks to
   see if the first character is a '.', which indicates the start of a
   pseudo-op.  If it is, then write out any unwritten instructions.  */

void
d30v_start_line (void)
{
  char *c = input_line_pointer;

  while (ISSPACE (*c))
    c++;

  if (*c == '.')
    d30v_cleanup (FALSE);
}

static void
check_size (long value, int bits, char *file, int line)
{
  int tmp, max;

  if (value < 0)
    tmp = ~value;
  else
    tmp = value;

  max = (1 << (bits - 1)) - 1;

  if (tmp > max)
    as_bad_where (file, line, _("value too large to fit in %d bits"), bits);
}

/* d30v_frob_label() is called when after a label is recognized.  */

void
d30v_frob_label (symbolS *lab)
{
  /* Emit any pending instructions.  */
  d30v_cleanup (FALSE);

  /* Update the label's address with the current output pointer.  */
  symbol_set_frag (lab, frag_now);
  S_SET_VALUE (lab, (valueT) frag_now_fix ());

  /* Record this label for future adjustment after we find out what
     kind of data it references, and the required alignment therewith.  */
  d30v_last_label = lab;

  dwarf2_emit_label (lab);
}

/* Hook into cons for capturing alignment changes.  */

void
d30v_cons_align (int size)
{
  int log_size;

  /* Don't specially align anything in debug sections.  */
  if ((now_seg->flags & SEC_ALLOC) == 0
      || strcmp (now_seg->name, ".eh_frame") == 0)
    return;

  log_size = 0;
  while ((size >>= 1) != 0)
    ++log_size;

  if (d30v_current_align < log_size)
    d30v_align (log_size, (char *) NULL, NULL);
  else if (d30v_current_align > log_size)
    d30v_current_align = log_size;
  d30v_last_label = NULL;
}

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

  if (fixP->fx_addsy == (symbolS *) NULL)
    fixP->fx_done = 1;

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

  /* 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_8:  /* Check for a bad .byte directive.  */
      if (fixP->fx_addsy != NULL)
	as_bad (_("line %d: unable to place address of symbol '%s' into a byte"),
		fixP->fx_line, S_GET_NAME (fixP->fx_addsy));
      else if (((unsigned)value) > 0xff)
	as_bad (_("line %d: unable to place value %lx into a byte"),
		fixP->fx_line, value);
      else
	*(unsigned char *) where = value;
      break;

    case BFD_RELOC_16:  /* Check for a bad .short directive.  */
      if (fixP->fx_addsy != NULL)
	as_bad (_("line %d: unable to place address of symbol '%s' into a short"),
		fixP->fx_line, S_GET_NAME (fixP->fx_addsy));
      else if (((unsigned)value) > 0xffff)
	as_bad (_("line %d: unable to place value %lx into a short"),
		fixP->fx_line, value);
      else
	bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
      break;

    case BFD_RELOC_64:  /* Check for a bad .quad directive.  */
      if (fixP->fx_addsy != NULL)
	as_bad (_("line %d: unable to place address of symbol '%s' into a quad"),
		fixP->fx_line, S_GET_NAME (fixP->fx_addsy));
      else
	{
	  bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
	  bfd_putb32 (0, ((unsigned char *) where) + 4);
	}
      break;

    case BFD_RELOC_D30V_6:
      check_size (value, 6, fixP->fx_file, fixP->fx_line);
      insn |= value & 0x3F;
      bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
      break;

    case BFD_RELOC_D30V_9_PCREL:
      if (fixP->fx_where & 0x7)
	{
	  if (fixP->fx_done)
	    value += 4;
	  else
	    fixP->fx_r_type = BFD_RELOC_D30V_9_PCREL_R;
	}
      check_size (value, 9, fixP->fx_file, fixP->fx_line);
      insn |= ((value >> 3) & 0x3F) << 12;
      bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
      break;

    case BFD_RELOC_D30V_15:
      check_size (value, 15, fixP->fx_file, fixP->fx_line);
      insn |= (value >> 3) & 0xFFF;
      bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
      break;

    case BFD_RELOC_D30V_15_PCREL:
      if (fixP->fx_where & 0x7)
	{
	  if (fixP->fx_done)
	    value += 4;
	  else
	    fixP->fx_r_type = BFD_RELOC_D30V_15_PCREL_R;
	}
      check_size (value, 15, fixP->fx_file, fixP->fx_line);
      insn |= (value >> 3) & 0xFFF;
      bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
      break;

    case BFD_RELOC_D30V_21:
      check_size (value, 21, fixP->fx_file, fixP->fx_line);
      insn |= (value >> 3) & 0x3FFFF;
      bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
      break;

    case BFD_RELOC_D30V_21_PCREL:
      if (fixP->fx_where & 0x7)
	{
	  if (fixP->fx_done)
	    value += 4;
	  else
	    fixP->fx_r_type = BFD_RELOC_D30V_21_PCREL_R;
	}
      check_size (value, 21, fixP->fx_file, fixP->fx_line);
      insn |= (value >> 3) & 0x3FFFF;
      bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
      break;

    case BFD_RELOC_D30V_32:
      insn2 = bfd_getb32 ((unsigned char *) where + 4);
      insn |= (value >> 26) & 0x3F;		/* Top 6 bits.  */
      insn2 |= ((value & 0x03FC0000) << 2);	/* Next 8 bits.  */
      insn2 |= value & 0x0003FFFF;		/* Bottom 18 bits.  */
      bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
      bfd_putb32 ((bfd_vma) insn2, (unsigned char *) where + 4);
      break;

    case BFD_RELOC_D30V_32_PCREL:
      insn2 = bfd_getb32 ((unsigned char *) where + 4);
      insn |= (value >> 26) & 0x3F;		/* Top 6 bits.  */
      insn2 |= ((value & 0x03FC0000) << 2);	/* Next 8 bits.  */
      insn2 |= value & 0x0003FFFF;		/* Bottom 18 bits.  */
      bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
      bfd_putb32 ((bfd_vma) insn2, (unsigned char *) where + 4);
      break;

    case BFD_RELOC_32:
      bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
      break;

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

/* Handle the .align pseudo-op.  This aligns to a power of two.  We
   hook here to latch the current alignment.  */

static void
s_d30v_align (int ignore ATTRIBUTE_UNUSED)
{
  int align;
  char fill, *pfill = NULL;
  long max_alignment = 15;

  align = get_absolute_expression ();
  if (align > max_alignment)
    {
      align = max_alignment;
      as_warn (_("Alignment too large: %d assumed"), align);
    }
  else if (align < 0)
    {
      as_warn (_("Alignment negative: 0 assumed"));
      align = 0;
    }

  if (*input_line_pointer == ',')
    {
      input_line_pointer++;
      fill = get_absolute_expression ();
      pfill = &fill;
    }

  d30v_last_label = NULL;
  d30v_align (align, pfill, NULL);

  demand_empty_rest_of_line ();
}

/* Handle the .text pseudo-op.  This is like the usual one, but it
   clears the saved last label and resets known alignment.  */

static void
s_d30v_text (int i)

{
  s_text (i);
  d30v_last_label = NULL;
  d30v_current_align = 0;
  d30v_current_align_seg = now_seg;
}

/* Handle the .data pseudo-op.  This is like the usual one, but it
   clears the saved last label and resets known alignment.  */

static void
s_d30v_data (int i)
{
  s_data (i);
  d30v_last_label = NULL;
  d30v_current_align = 0;
  d30v_current_align_seg = now_seg;
}

/* Handle the .section pseudo-op.  This is like the usual one, but it
   clears the saved last label and resets known alignment.  */

static void
s_d30v_section (int ignore)
{
  obj_elf_section (ignore);
  d30v_last_label = NULL;
  d30v_current_align = 0;
  d30v_current_align_seg = now_seg;
}

/* The target specific pseudo-ops which we support.  */
const pseudo_typeS md_pseudo_table[] =
{
  { "word", cons, 4 },
  { "hword", cons, 2 },
  { "align", s_d30v_align, 0 },
  { "text", s_d30v_text, 0 },
  { "data", s_d30v_data, 0 },
  { "section", s_d30v_section, 0 },
  { "section.s", s_d30v_section, 0 },
  { "sect", s_d30v_section, 0 },
  { "sect.s", s_d30v_section, 0 },
  { NULL, NULL, 0 }
};
