/* tc-h8300.c -- Assemble code for the Renesas H8/300
   Copyright 1991-2013 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.  */

/* Written By Steve Chamberlain <sac@cygnus.com>.  */

#include "as.h"
#include "subsegs.h"
#include "dwarf2dbg.h"

#define DEFINE_TABLE
#define h8_opcodes ops
#include "opcode/h8300.h"
#include "safe-ctype.h"

#ifdef OBJ_ELF
#include "elf/h8.h"
#endif

const char comment_chars[] = ";";
const char line_comment_chars[] = "#";
const char line_separator_chars[] = "";

static void sbranch (int);
static void h8300hmode (int);
static void h8300smode (int);
static void h8300hnmode (int);
static void h8300snmode (int);
static void h8300sxmode (int);
static void h8300sxnmode (int);
static void pint (int);

int Hmode;
int Smode;
int Nmode;
int SXmode;

#define PSIZE (Hmode && !Nmode ? L_32 : L_16)

static int bsize = L_8;		/* Default branch displacement.  */

struct h8_instruction
{
  int length;
  int noperands;
  int idx;
  int size;
  const struct h8_opcode *opcode;
};

static struct h8_instruction *h8_instructions;

static void
h8300hmode (int arg ATTRIBUTE_UNUSED)
{
  Hmode = 1;
  Smode = 0;
  if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300h))
    as_warn (_("could not set architecture and machine"));
}

static void
h8300smode (int arg ATTRIBUTE_UNUSED)
{
  Smode = 1;
  Hmode = 1;
  if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300s))
    as_warn (_("could not set architecture and machine"));
}

static void
h8300hnmode (int arg ATTRIBUTE_UNUSED)
{
  Hmode = 1;
  Smode = 0;
  Nmode = 1;
  if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300hn))
    as_warn (_("could not set architecture and machine"));
}

static void
h8300snmode (int arg ATTRIBUTE_UNUSED)
{
  Smode = 1;
  Hmode = 1;
  Nmode = 1;
  if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300sn))
    as_warn (_("could not set architecture and machine"));
}

static void
h8300sxmode (int arg ATTRIBUTE_UNUSED)
{
  Smode = 1;
  Hmode = 1;
  SXmode = 1;
  if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300sx))
    as_warn (_("could not set architecture and machine"));
}

static void
h8300sxnmode (int arg ATTRIBUTE_UNUSED)
{
  Smode = 1;
  Hmode = 1;
  SXmode = 1;
  Nmode = 1;
  if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300sxn))
    as_warn (_("could not set architecture and machine"));
}

static void
sbranch (int size)
{
  bsize = size;
}

static void
pint (int arg ATTRIBUTE_UNUSED)
{
  cons (Hmode ? 4 : 2);
}

/* Like obj_elf_section, but issues a warning for new
   sections which do not have an attribute specification.  */

static void
h8300_elf_section (int push)
{
  static const char * known_data_sections [] = { ".rodata", ".tdata", ".tbss" };
  static const char * known_data_prefixes [] = { ".debug", ".zdebug", ".gnu.warning" };
  char * saved_ilp = input_line_pointer;
  char * name;

  name = obj_elf_section_name ();
  if (name == NULL)
    return;

  if (* input_line_pointer != ','
      && bfd_get_section_by_name (stdoutput, name) == NULL)
    {
      signed int i;

      /* Ignore this warning for well known data sections.  */
      for (i = ARRAY_SIZE (known_data_sections); i--;)
	if (strcmp (name, known_data_sections[i]) == 0)
	  break;

      if (i < 0)
	for (i = ARRAY_SIZE (known_data_prefixes); i--;)
	  if (strncmp (name, known_data_prefixes[i],
		       strlen (known_data_prefixes[i])) == 0)
	    break;

      if (i < 0)
	as_warn (_("new section '%s' defined without attributes - this might cause problems"), name);
    }

  /* FIXME: We ought to free the memory allocated by obj_elf_section_name()
     for 'name', but we do not know if it was taken from the obstack, via
     demand_copy_C_string(), or xmalloc()ed.  */
  input_line_pointer = saved_ilp;
  obj_elf_section (push);
}

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

const pseudo_typeS md_pseudo_table[] =
{
  {"h8300h",  h8300hmode,  0},
  {"h8300hn", h8300hnmode, 0},
  {"h8300s",  h8300smode,  0},
  {"h8300sn", h8300snmode, 0},
  {"h8300sx", h8300sxmode, 0},
  {"h8300sxn", h8300sxnmode, 0},
  {"sbranch", sbranch, L_8},
  {"lbranch", sbranch, L_16},

  {"int", pint, 0},
  {"data.b", cons, 1},
  {"data.w", cons, 2},
  {"data.l", cons, 4},
  {"form", listing_psize, 0},
  {"heading", listing_title, 0},
  {"import",  s_ignore, 0},
  {"page",    listing_eject, 0},
  {"program", s_ignore, 0},

#ifdef OBJ_ELF
  {"section",   h8300_elf_section, 0},
  {"section.s", h8300_elf_section, 0},
  {"sect",      h8300_elf_section, 0},
  {"sect.s",    h8300_elf_section, 0},
#endif

  {0, 0, 0}
};

const char EXP_CHARS[] = "eE";

/* Chars that mean this number is a floating point constant
   As in 0f12.456
   or    0d1.2345e12.  */
const char FLT_CHARS[] = "rRsSfFdDxXpP";

static struct hash_control *opcode_hash_control;	/* Opcode mnemonics.  */

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

void
md_begin (void)
{
  unsigned int nopcodes;
  struct h8_opcode *p, *p1;
  struct h8_instruction *pi;
  char prev_buffer[100];
  int idx = 0;

  if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300))
    as_warn (_("could not set architecture and machine"));

  opcode_hash_control = hash_new ();
  prev_buffer[0] = 0;

  nopcodes = sizeof (h8_opcodes) / sizeof (struct h8_opcode);
  
  h8_instructions = (struct h8_instruction *)
    xmalloc (nopcodes * sizeof (struct h8_instruction));

  pi = h8_instructions;
  p1 = h8_opcodes;
  /* We do a minimum amount of sorting on the opcode table; this is to
     make it easy to describe the mova instructions without unnecessary
     code duplication.
     Sorting only takes place inside blocks of instructions of the form
     X/Y, so for example mova/b, mova/w and mova/l can be intermixed.  */
  while (p1)
    {
      struct h8_opcode *first_skipped = 0;
      int len, cmplen = 0;
      char *src = p1->name;
      char *dst, *buffer;

      if (p1->name == 0)
	break;
      /* Strip off any . part when inserting the opcode and only enter
	 unique codes into the hash table.  */
      dst = buffer = malloc (strlen (src) + 1);
      while (*src)
	{
	  if (*src == '.')
	    {
	      src++;
	      break;
	    }
	  if (*src == '/')
	    cmplen = src - p1->name + 1;
	  *dst++ = *src++;
	}
      *dst = 0;
      len = dst - buffer;
      if (cmplen == 0)
	cmplen = len;
      hash_insert (opcode_hash_control, buffer, (char *) pi);
      strcpy (prev_buffer, buffer);
      idx++;

      for (p = p1; p->name; p++)
	{
	  /* A negative TIME is used to indicate that we've added this opcode
	     already.  */
	  if (p->time == -1)
	    continue;
	  if (strncmp (p->name, buffer, cmplen) != 0
	      || (p->name[cmplen] != '\0' && p->name[cmplen] != '.'
		  && p->name[cmplen - 1] != '/'))
	    {
	      if (first_skipped == 0)
		first_skipped = p;
	      break;
	    }
	  if (strncmp (p->name, buffer, len) != 0)
	    {
	      if (first_skipped == 0)
		first_skipped = p;
	      continue;
	    }

	  p->time = -1;
	  pi->size = p->name[len] == '.' ? p->name[len + 1] : 0;
	  pi->idx = idx;

	  /* Find the number of operands.  */
	  pi->noperands = 0;
	  while (pi->noperands < 3 && p->args.nib[pi->noperands] != (op_type) E)
	    pi->noperands++;

	  /* Find the length of the opcode in bytes.  */
	  pi->length = 0;
	  while (p->data.nib[pi->length * 2] != (op_type) E)
	    pi->length++;

	  pi->opcode = p;
	  pi++;
	}
      p1 = first_skipped;
    }

  /* Add entry for the NULL vector terminator.  */
  pi->length = 0;
  pi->noperands = 0;
  pi->idx = 0;
  pi->size = 0;
  pi->opcode = 0;

  linkrelax = 1;
}

struct h8_op
{
  op_type mode;
  unsigned reg;
  expressionS exp;
};

static void clever_message (const struct h8_instruction *, struct h8_op *);
static void fix_operand_size (struct h8_op *, int);
static void build_bytes (const struct h8_instruction *, struct h8_op *);
static void do_a_fix_imm (int, int, struct h8_op *, int, const struct h8_instruction *);
static void check_operand (struct h8_op *, unsigned int, char *);
static const struct h8_instruction * get_specific (const struct h8_instruction *, struct h8_op *, int) ;
static char *get_operands (unsigned, char *, struct h8_op *);
static void get_operand (char **, struct h8_op *, int);
static int parse_reg (char *, op_type *, unsigned *, int);
static char *skip_colonthing (char *, int *);
static char *parse_exp (char *, struct h8_op *);

static int constant_fits_size_p (struct h8_op *, int, int);

/*
  parse operands
  WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
  r0l,r0h,..r7l,r7h
  @WREG
  @WREG+
  @-WREG
  #const
  ccr
*/

/* Try to parse a reg name.  Return the number of chars consumed.  */

static int
parse_reg (char *src, op_type *mode, unsigned int *reg, int direction)
{
  char *end;
  int len;

  /* Cribbed from get_symbol_end.  */
  if (!is_name_beginner (*src) || *src == '\001')
    return 0;
  end = src + 1;
  while ((is_part_of_name (*end) && *end != '.') || *end == '\001')
    end++;
  len = end - src;

  if (len == 2 && TOLOWER (src[0]) == 's' && TOLOWER (src[1]) == 'p')
    {
      *mode = PSIZE | REG | direction;
      *reg = 7;
      return len;
    }
  if (len == 3 && 
      TOLOWER (src[0]) == 'c' && 
      TOLOWER (src[1]) == 'c' && 
      TOLOWER (src[2]) == 'r')
    {
      *mode = CCR;
      *reg = 0;
      return len;
    }
  if (len == 3 && 
      TOLOWER (src[0]) == 'e' && 
      TOLOWER (src[1]) == 'x' && 
      TOLOWER (src[2]) == 'r')
    {
      *mode = EXR;
      *reg = 1;
      return len;
    }
  if (len == 3 && 
      TOLOWER (src[0]) == 'v' && 
      TOLOWER (src[1]) == 'b' && 
      TOLOWER (src[2]) == 'r')
    {
      *mode = VBR;
      *reg = 6;
      return len;
    }
  if (len == 3 && 
      TOLOWER (src[0]) == 's' && 
      TOLOWER (src[1]) == 'b' && 
      TOLOWER (src[2]) == 'r')
    {
      *mode = SBR;
      *reg = 7;
      return len;
    }
  if (len == 2 && TOLOWER (src[0]) == 'f' && TOLOWER (src[1]) == 'p')
    {
      *mode = PSIZE | REG | direction;
      *reg = 6;
      return len;
    }
  if (len == 3 && TOLOWER (src[0]) == 'e' && TOLOWER (src[1]) == 'r' &&
      src[2] >= '0' && src[2] <= '7')
    {
      *mode = L_32 | REG | direction;
      *reg = src[2] - '0';
      if (!Hmode)
	as_warn (_("Reg not valid for H8/300"));
      return len;
    }
  if (len == 2 && TOLOWER (src[0]) == 'e' && src[1] >= '0' && src[1] <= '7')
    {
      *mode = L_16 | REG | direction;
      *reg = src[1] - '0' + 8;
      if (!Hmode)
	as_warn (_("Reg not valid for H8/300"));
      return len;
    }

  if (TOLOWER (src[0]) == 'r')
    {
      if (src[1] >= '0' && src[1] <= '7')
	{
	  if (len == 3 && TOLOWER (src[2]) == 'l')
	    {
	      *mode = L_8 | REG | direction;
	      *reg = (src[1] - '0') + 8;
	      return len;
	    }
	  if (len == 3 && TOLOWER (src[2]) == 'h')
	    {
	      *mode = L_8 | REG | direction;
	      *reg = (src[1] - '0');
	      return len;
	    }
	  if (len == 2)
	    {
	      *mode = L_16 | REG | direction;
	      *reg = (src[1] - '0');
	      return len;
	    }
	}
    }

  return 0;
}


/* Parse an immediate or address-related constant and store it in OP.
   If the user also specifies the operand's size, store that size
   in OP->MODE, otherwise leave it for later code to decide.  */

static char *
parse_exp (char *src, struct h8_op *op)
{
  char *save;

  save = input_line_pointer;
  input_line_pointer = src;
  expression (&op->exp);
  if (op->exp.X_op == O_absent)
    as_bad (_("missing operand"));
  src = input_line_pointer;
  input_line_pointer = save;

  return skip_colonthing (src, &op->mode);
}


/* If SRC starts with an explicit operand size, skip it and store the size
   in *MODE.  Leave *MODE unchanged otherwise.  */

static char *
skip_colonthing (char *src, int *mode)
{
  if (*src == ':')
    {
      src++;
      *mode &= ~SIZE;
      if (src[0] == '8' && !ISDIGIT (src[1]))
	*mode |= L_8;
      else if (src[0] == '2' && !ISDIGIT (src[1]))
	*mode |= L_2;
      else if (src[0] == '3' && !ISDIGIT (src[1]))
	*mode |= L_3;
      else if (src[0] == '4' && !ISDIGIT (src[1]))
	*mode |= L_4;
      else if (src[0] == '5' && !ISDIGIT (src[1]))
	*mode |= L_5;
      else if (src[0] == '2' && src[1] == '4' && !ISDIGIT (src[2]))
	*mode |= L_24;
      else if (src[0] == '3' && src[1] == '2' && !ISDIGIT (src[2]))
	*mode |= L_32;
      else if (src[0] == '1' && src[1] == '6' && !ISDIGIT (src[2]))
	*mode |= L_16;
      else
	as_bad (_("invalid operand size requested"));

      while (ISDIGIT (*src))
	src++;
    }
  return src;
}

/* The many forms of operand:

   Rn			Register direct
   @Rn			Register indirect
   @(exp[:16], Rn)	Register indirect with displacement
   @Rn+
   @-Rn
   @aa:8		absolute 8 bit
   @aa:16		absolute 16 bit
   @aa			absolute 16 bit

   #xx[:size]		immediate data
   @(exp:[8], pc)	pc rel
   @@aa[:8]		memory indirect.  */

static int
constant_fits_width_p (struct h8_op *operand, offsetT width)
{
  offsetT num;

  num = ((operand->exp.X_add_number & 0xffffffff) ^ 0x80000000) - 0x80000000;
  return (num & ~width) == 0 || (num | width) == ~0;
}

static int
constant_fits_size_p (struct h8_op *operand, int size, int no_symbols)
{
  offsetT num;

  if (no_symbols
      && (operand->exp.X_add_symbol != 0 || operand->exp.X_op_symbol != 0))
    return 0;
  num = operand->exp.X_add_number & 0xffffffff;
  switch (size)
    {
    case L_2:
      return (num & ~3) == 0;
    case L_3:
      return (num & ~7) == 0;
    case L_3NZ:
      return num >= 1 && num < 8;
    case L_4:
      return (num & ~15) == 0;
    case L_5:
      return num >= 1 && num < 32;
    case L_8:
      num = (num ^ 0x80000000) - 0x80000000;
      return (num & ~0xFF) == 0 || (num | 0x7F) == ~0;
    case L_8U:
      return (num & ~0xFF) == 0;
    case L_16:
      num = (num ^ 0x80000000) - 0x80000000;
      return (num & ~0xFFFF) == 0 || (num | 0x7FFF) == ~0;
    case L_16U:
      return (num & ~0xFFFF) == 0;
    case L_32:
      return 1;
    default:
      abort ();
    }
}

static void
get_operand (char **ptr, struct h8_op *op, int direction)
{
  char *src = *ptr;
  op_type mode;
  unsigned int num;
  unsigned int len;

  op->mode = 0;

  /* Check for '(' and ')' for instructions ldm and stm.  */
  if (src[0] == '(' && src[8] == ')')
    ++ src;

  /* Gross.  Gross.  ldm and stm have a format not easily handled
     by get_operand.  We deal with it explicitly here.  */
  if (TOLOWER (src[0]) == 'e' && TOLOWER (src[1]) == 'r' && 
      ISDIGIT (src[2]) && src[3] == '-' &&
      TOLOWER (src[4]) == 'e' && TOLOWER (src[5]) == 'r' && ISDIGIT (src[6]))
    {
      int low, high;

      low = src[2] - '0';
      high = src[6] - '0';

       /* Check register pair's validity as per tech note TN-H8*-193A/E
	  from Renesas for H8S and H8SX hardware manual.  */
      if (   !(low == 0 && (high == 1 || high == 2 || high == 3))
          && !(low == 1 && (high == 2 || high == 3 || high == 4) && SXmode)
          && !(low == 2 && (high == 3 || ((high == 4 || high == 5) && SXmode)))
          && !(low == 3 && (high == 4 || high == 5 || high == 6) && SXmode)
          && !(low == 4 && (high == 5 || high == 6))
          && !(low == 4 && high == 7 && SXmode)
          && !(low == 5 && (high == 6 || high == 7) && SXmode)
          && !(low == 6 && high == 7 && SXmode))
	as_bad (_("Invalid register list for ldm/stm\n"));

      /* Even sicker.  We encode two registers into op->reg.  One
	 for the low register to save, the other for the high
	 register to save;  we also set the high bit in op->reg
	 so we know this is "very special".  */
      op->reg = 0x80000000 | (high << 8) | low;
      op->mode = REG;
      if (src[7] == ')')
	*ptr = src + 8;
      else
	*ptr = src + 7;
      return;
    }

  len = parse_reg (src, &op->mode, &op->reg, direction);
  if (len)
    {
      src += len;
      if (*src == '.')
	{
	  int size = op->mode & SIZE;
	  switch (src[1])
	    {
	    case 'l': case 'L':
	      if (size != L_32)
		as_warn (_("mismatch between register and suffix"));
	      op->mode = (op->mode & ~MODE) | LOWREG;
	      break;
	    case 'w': case 'W':
	      if (size != L_32 && size != L_16)
		as_warn (_("mismatch between register and suffix"));
	      op->mode = (op->mode & ~MODE) | LOWREG;
	      op->mode = (op->mode & ~SIZE) | L_16;
	      break;
	    case 'b': case 'B':
	      op->mode = (op->mode & ~MODE) | LOWREG;
	      if (size != L_32 && size != L_8)
		as_warn (_("mismatch between register and suffix"));
	      op->mode = (op->mode & ~MODE) | LOWREG;
	      op->mode = (op->mode & ~SIZE) | L_8;
	      break;
	    default:
	      as_warn (_("invalid suffix after register."));
	      break;
	    }
	  src += 2;
	}
      *ptr = src;
      return;
    }

  if (*src == '@')
    {
      src++;
      if (*src == '@')
	{
	  *ptr = parse_exp (src + 1, op);
	  if (op->exp.X_add_number >= 0x100)
	    {
	      int divisor = 1;

	      op->mode = VECIND;
	      /* FIXME : 2?  or 4?  */
	      if (op->exp.X_add_number >= 0x400)
		as_bad (_("address too high for vector table jmp/jsr"));
	      else if (op->exp.X_add_number >= 0x200)
		divisor = 4;
	      else
		divisor = 2;

	      op->exp.X_add_number = op->exp.X_add_number / divisor - 0x80;
	    }
	  else
	    op->mode = MEMIND;
	  return;
	}

      if (*src == '-' || *src == '+')
	{
	  len = parse_reg (src + 1, &mode, &num, direction);
	  if (len == 0)
	    {
	      /* Oops, not a reg after all, must be ordinary exp.  */
	      op->mode = ABS | direction;
	      *ptr = parse_exp (src, op);
	      return;
	    }

	  if (((mode & SIZE) != PSIZE)
	      /* For Normal mode accept 16 bit and 32 bit pointer registers.  */
	      && (!Nmode || ((mode & SIZE) != L_32)))
	    as_bad (_("Wrong size pointer register for architecture."));

	  op->mode = src[0] == '-' ? RDPREDEC : RDPREINC;
	  op->reg = num;
	  *ptr = src + 1 + len;
	  return;
	}
      if (*src == '(')
	{
	  src++;

	  /* See if this is @(ERn.x, PC).  */
	  len = parse_reg (src, &mode, &op->reg, direction);
	  if (len != 0 && (mode & MODE) == REG && src[len] == '.')
	    {
	      switch (TOLOWER (src[len + 1]))
		{
		case 'b':
		  mode = PCIDXB | direction;
		  break;
		case 'w':
		  mode = PCIDXW | direction;
		  break;
		case 'l':
		  mode = PCIDXL | direction;
		  break;
		default:
		  mode = 0;
		  break;
		}
	      if (mode
		  && src[len + 2] == ','
		  && TOLOWER (src[len + 3]) != 'p' 
		  && TOLOWER (src[len + 4]) != 'c'
		  && src[len + 5] != ')')
		{
		  *ptr = src + len + 6;
		  op->mode |= mode;
		  return;
		}
	      /* Fall through into disp case - the grammar is somewhat
		 ambiguous, so we should try whether it's a DISP operand
		 after all ("ER3.L" might be a poorly named label...).  */
	    }

	  /* Disp.  */

	  /* Start off assuming a 16 bit offset.  */

	  src = parse_exp (src, op);
	  if (*src == ')')
	    {
	      op->mode |= ABS | direction;
	      *ptr = src + 1;
	      return;
	    }

	  if (*src != ',')
	    {
	      as_bad (_("expected @(exp, reg16)"));
	      return;
	    }
	  src++;

	  len = parse_reg (src, &mode, &op->reg, direction);
	  if (len == 0 || (mode & MODE) != REG)
	    {
	      as_bad (_("expected @(exp, reg16)"));
	      return;
	    }
	  src += len;
	  if (src[0] == '.')
	    {
	      switch (TOLOWER (src[1]))
		{
		case 'b':
		  op->mode |= INDEXB | direction;
		  break;
		case 'w':
		  op->mode |= INDEXW | direction;
		  break;
		case 'l':
		  op->mode |= INDEXL | direction;
		  break;
		default:
		  as_bad (_("expected .L, .W or .B for register in indexed addressing mode"));
		}
	      src += 2;
	      op->reg &= 7;
	    }
	  else
	    op->mode |= DISP | direction;
	  src = skip_colonthing (src, &op->mode);

	  if (*src != ')' && '(')
	    {
	      as_bad (_("expected @(exp, reg16)"));
	      return;
	    }
	  *ptr = src + 1;
	  return;
	}
      len = parse_reg (src, &mode, &num, direction);

      if (len)
	{
	  src += len;
	  if (*src == '+' || *src == '-')
	    {
	      if (((mode & SIZE) != PSIZE)
		  /* For Normal mode accept 16 bit and 32 bit pointer registers.  */
		  && (!Nmode || ((mode & SIZE) != L_32)))
		as_bad (_("Wrong size pointer register for architecture."));
	      op->mode = *src == '+' ? RSPOSTINC : RSPOSTDEC;
	      op->reg = num;
	      src++;
	      *ptr = src;
	      return;
	    }
	  if (((mode & SIZE) != PSIZE)
	      /* For Normal mode accept 16 bit and 32 bit pointer registers.  */
	      && (!Nmode || ((mode & SIZE) != L_32)))
	    as_bad (_("Wrong size pointer register for architecture."));

	  op->mode = direction | IND | PSIZE;
	  op->reg = num;
	  *ptr = src;

	  return;
	}
      else
	{
	  /* must be a symbol */

	  op->mode = ABS | direction;
	  *ptr = parse_exp (src, op);
	  return;
	}
    }

  if (*src == '#')
    {
      op->mode = IMM;
      *ptr = parse_exp (src + 1, op);
      return;
    }
  else if (strncmp (src, "mach", 4) == 0 || 
	   strncmp (src, "macl", 4) == 0 ||
	   strncmp (src, "MACH", 4) == 0 || 
	   strncmp (src, "MACL", 4) == 0)
    {
      op->reg = TOLOWER (src[3]) == 'l';
      op->mode = MACREG;
      *ptr = src + 4;
      return;
    }
  else
    {
      op->mode = PCREL;
      *ptr = parse_exp (src, op);
    }
}

static char *
get_operands (unsigned int noperands, char *op_end, struct h8_op *operand)
{
  char *ptr = op_end;

  switch (noperands)
    {
    case 0:
      break;

    case 1:
      ptr++;
      get_operand (&ptr, operand + 0, SRC);
      if (*ptr == ',')
	{
	  ptr++;
	  get_operand (&ptr, operand + 1, DST);
	}
      break;

    case 2:
      ptr++;
      get_operand (&ptr, operand + 0, SRC);
      if (*ptr == ',')
	ptr++;
      get_operand (&ptr, operand + 1, DST);
      break;

    case 3:
      ptr++;
      get_operand (&ptr, operand + 0, SRC);
      if (*ptr == ',')
	ptr++;
      get_operand (&ptr, operand + 1, DST);
      if (*ptr == ',')
	ptr++;
      get_operand (&ptr, operand + 2, OP3);
      break;

    default:
      abort ();
    }

  return ptr;
}

/* MOVA has special requirements.  Rather than adding twice the amount of
   addressing modes, we simply special case it a bit.  */
static void
get_mova_operands (char *op_end, struct h8_op *operand)
{
  char *ptr = op_end;

  if (ptr[1] != '@' || ptr[2] != '(')
    goto error;
  ptr += 3;
  operand[0].mode = 0;
  ptr = parse_exp (ptr, &operand[0]);

  if (*ptr !=',')
    goto error;
  ptr++;
  get_operand (&ptr, operand + 1, DST);

  if (*ptr =='.')
    {
      ptr++;
      switch (*ptr++)
	{
	case 'b': case 'B':
	  operand[0].mode = (operand[0].mode & ~MODE) | INDEXB;
	  break;
	case 'w': case 'W':
	  operand[0].mode = (operand[0].mode & ~MODE) | INDEXW;
	  break;
	case 'l': case 'L':
	  operand[0].mode = (operand[0].mode & ~MODE) | INDEXL;
	  break;
	default:
	  goto error;
	}
    }
  else if ((operand[1].mode & MODE) == LOWREG)
    {
      switch (operand[1].mode & SIZE) 
	{
	case L_8:
	  operand[0].mode = (operand[0].mode & ~MODE) | INDEXB;
	  break;
	case L_16:
	  operand[0].mode = (operand[0].mode & ~MODE) | INDEXW;
	  break;
	case L_32:
	  operand[0].mode = (operand[0].mode & ~MODE) | INDEXL;
	  break;
	default:
	  goto error;
	}
    }
  else
    goto error;

  if (*ptr++ != ')' || *ptr++ != ',')
    goto error;
  get_operand (&ptr, operand + 2, OP3);
  /* See if we can use the short form of MOVA.  */
  if (((operand[1].mode & MODE) == REG || (operand[1].mode & MODE) == LOWREG)
      && (operand[2].mode & MODE) == REG
      && (operand[1].reg & 7) == (operand[2].reg & 7))
    {
      operand[1].mode = operand[2].mode = 0;
      operand[0].reg = operand[2].reg & 7;
    }
  return;

 error:
  as_bad (_("expected valid addressing mode for mova: \"@(disp, ea.sz),ERn\""));
}

static void
get_rtsl_operands (char *ptr, struct h8_op *operand)
{
  int mode, len, type = 0;
  unsigned int num, num2;

  ptr++;
  if (*ptr == '(')
    {
      ptr++;
      type = 1;
    }
  len = parse_reg (ptr, &mode, &num, SRC);
  if (len == 0 || (mode & MODE) != REG)
    {
      as_bad (_("expected register"));
      return;
    }
  ptr += len;
  if (*ptr == '-')
    {
      len = parse_reg (++ptr, &mode, &num2, SRC);
      if (len == 0 || (mode & MODE) != REG)
	{
	  as_bad (_("expected register"));
	  return;
	}
      ptr += len;
      /* CONST_xxx are used as placeholders in the opcode table.  */
      num = num2 - num;
      if (num > 3)
	{
	  as_bad (_("invalid register list"));
	  return;
	}
    }
  else
    num2 = num, num = 0;
  if (type == 1 && *ptr++ != ')')
    {
      as_bad (_("expected closing paren"));
      return;
    }
  operand[0].mode = RS32;
  operand[1].mode = RD32;
  operand[0].reg = num;
  operand[1].reg = num2;
}

/* Passed a pointer to a list of opcodes which use different
   addressing modes, return the opcode which matches the opcodes
   provided.  */

static const struct h8_instruction *
get_specific (const struct h8_instruction *instruction,
	      struct h8_op *operands, int size)
{
  const struct h8_instruction *this_try = instruction;
  const struct h8_instruction *found_other = 0, *found_mismatched = 0;
  int found = 0;
  int this_index = instruction->idx;
  int noperands = 0;

  /* There's only one ldm/stm and it's easier to just
     get out quick for them.  */
  if (OP_KIND (instruction->opcode->how) == O_LDM
      || OP_KIND (instruction->opcode->how) == O_STM)
    return this_try;

  while (noperands < 3 && operands[noperands].mode != 0)
    noperands++;

  while (this_index == instruction->idx && !found)
    {
      int this_size;

      found = 1;
      this_try = instruction++;
      this_size = this_try->opcode->how & SN;

      if (this_try->noperands != noperands)
	found = 0;
      else if (this_try->noperands > 0)
	{
	  int i;

	  for (i = 0; i < this_try->noperands && found; i++)
	    {
	      op_type op = this_try->opcode->args.nib[i];
	      int op_mode = op & MODE;
	      int op_size = op & SIZE;
	      int x = operands[i].mode;
	      int x_mode = x & MODE;
	      int x_size = x & SIZE;

	      if (op_mode == LOWREG && (x_mode == REG || x_mode == LOWREG))
		{
		  if ((x_size == L_8 && (operands[i].reg & 8) == 0)
		      || (x_size == L_16 && (operands[i].reg & 8) == 8))
		    as_warn (_("can't use high part of register in operand %d"), i);

		  if (x_size != op_size)
		    found = 0;
		}
	      else if (op_mode == REG)
		{
		  if (x_mode == LOWREG)
		    x_mode = REG;
		  if (x_mode != REG)
		    found = 0;

		  if (x_size == L_P)
		    x_size = (Hmode ? L_32 : L_16);
		  if (op_size == L_P)
		    op_size = (Hmode ? L_32 : L_16);

		  /* The size of the reg is v important.  */
		  if (op_size != x_size)
		    found = 0;
		}
	      else if (op_mode & CTRL)	/* control register */
		{
		  if (!(x_mode & CTRL))
		    found = 0;

		  switch (x_mode)
		    {
		    case CCR:
		      if (op_mode != CCR &&
			  op_mode != CCR_EXR &&
			  op_mode != CC_EX_VB_SB)
			found = 0;
		      break;
		    case EXR:
		      if (op_mode != EXR &&
			  op_mode != CCR_EXR &&
			  op_mode != CC_EX_VB_SB)
			found = 0;
		      break;
		    case MACH:
		      if (op_mode != MACH &&
			  op_mode != MACREG)
			found = 0;
		      break;
		    case MACL:
		      if (op_mode != MACL &&
			  op_mode != MACREG)
			found = 0;
		      break;
		    case VBR:
		      if (op_mode != VBR &&
			  op_mode != VBR_SBR &&
			  op_mode != CC_EX_VB_SB)
			found = 0;
		      break;
		    case SBR:
		      if (op_mode != SBR &&
			  op_mode != VBR_SBR &&
			  op_mode != CC_EX_VB_SB)
			found = 0;
		      break;
		    }
		}
	      else if ((op & ABSJMP) && (x_mode == ABS || x_mode == PCREL))
		{
		  operands[i].mode &= ~MODE;
		  operands[i].mode |= ABSJMP;
		  /* But it may not be 24 bits long.  */
		  if (x_mode == ABS && !Hmode)
		    {
		      operands[i].mode &= ~SIZE;
		      operands[i].mode |= L_16;
		    }
		  if ((operands[i].mode & SIZE) == L_32
		      && (op_mode & SIZE) != L_32)
		   found = 0;
		}
	      else if (x_mode == IMM && op_mode != IMM)
		{
		  offsetT num = operands[i].exp.X_add_number & 0xffffffff;
		  if (op_mode == KBIT || op_mode == DBIT)
		    /* This is ok if the immediate value is sensible.  */;
		  else if (op_mode == CONST_2)
		    found = num == 2;
		  else if (op_mode == CONST_4)
		    found = num == 4;
		  else if (op_mode == CONST_8)
		    found = num == 8;
		  else if (op_mode == CONST_16)
		    found = num == 16;
		  else
		    found = 0;
		}
	      else if (op_mode == PCREL && op_mode == x_mode)
		{
		  /* movsd, bsr/bc and bsr/bs only come in PCREL16 flavour:
		     If x_size is L_8, promote it.  */
		  if (OP_KIND (this_try->opcode->how) == O_MOVSD
		      || OP_KIND (this_try->opcode->how) == O_BSRBC
		      || OP_KIND (this_try->opcode->how) == O_BSRBS)
		    if (x_size == L_8)
		      x_size = L_16;

		  /* The size of the displacement is important.  */
		  if (op_size != x_size)
		    found = 0;
		}
	      else if ((op_mode == DISP || op_mode == IMM || op_mode == ABS
			|| op_mode == INDEXB || op_mode == INDEXW
			|| op_mode == INDEXL)
		       && op_mode == x_mode)
		{
		  /* Promote a L_24 to L_32 if it makes us match.  */
		  if (x_size == L_24 && op_size == L_32)
		    {
		      x &= ~SIZE;
		      x |= x_size = L_32;
		    }

		  if (((x_size == L_16 && op_size == L_16U)
		       || (x_size == L_8 && op_size == L_8U)
		       || (x_size == L_3 && op_size == L_3NZ))
		      /* We're deliberately more permissive for ABS modes.  */
		      && (op_mode == ABS
			  || constant_fits_size_p (operands + i, op_size,
						   op & NO_SYMBOLS)))
		    x_size = op_size;

		  if (x_size != 0 && op_size != x_size)
		    found = 0;
		  else if (x_size == 0
			   && ! constant_fits_size_p (operands + i, op_size,
						      op & NO_SYMBOLS))
		    found = 0;
		}
	      else if (op_mode != x_mode)
		{
		  found = 0;
		}
	    }
	}
      if (found)
	{
	  if ((this_try->opcode->available == AV_H8SX && ! SXmode)
	      || (this_try->opcode->available == AV_H8S && ! Smode)
	      || (this_try->opcode->available == AV_H8H && ! Hmode))
	    found = 0, found_other = this_try;
	  else if (this_size != size && (this_size != SN && size != SN))
	    found_mismatched = this_try, found = 0;

	}
    }
  if (found)
    return this_try;
  if (found_other)
    {
      as_warn (_("Opcode `%s' with these operand types not available in %s mode"),
	       found_other->opcode->name,
	       (! Hmode && ! Smode ? "H8/300"
		: SXmode ? "H8sx"
		: Smode ? "H8/300S"
		: "H8/300H"));
    }
  else if (found_mismatched)
    {
      as_warn (_("mismatch between opcode size and operand size"));
      return found_mismatched;
    }
  return 0;
}

static void
check_operand (struct h8_op *operand, unsigned int width, char *string)
{
  if (operand->exp.X_add_symbol == 0
      && operand->exp.X_op_symbol == 0)
    {
      /* No symbol involved, let's look at offset, it's dangerous if
	 any of the high bits are not 0 or ff's, find out by oring or
	 anding with the width and seeing if the answer is 0 or all
	 fs.  */

      if (! constant_fits_width_p (operand, width))
	{
	  if (width == 255
	      && (operand->exp.X_add_number & 0xff00) == 0xff00)
	    {
	      /* Just ignore this one - which happens when trying to
		 fit a 16 bit address truncated into an 8 bit address
		 of something like bset.  */
	    }
	  else if (strcmp (string, "@") == 0
		   && width == 0xffff
		   && (operand->exp.X_add_number & 0xff8000) == 0xff8000)
	    {
	      /* Just ignore this one - which happens when trying to
		 fit a 24 bit address truncated into a 16 bit address
		 of something like mov.w.  */
	    }
	  else
	    {
	      as_warn (_("operand %s0x%lx out of range."), string,
		       (unsigned long) operand->exp.X_add_number);
	    }
	}
    }
}

/* RELAXMODE has one of 3 values:

   0 Output a "normal" reloc, no relaxing possible for this insn/reloc

   1 Output a relaxable 24bit absolute mov.w address relocation
     (may relax into a 16bit absolute address).

   2 Output a relaxable 16/24 absolute mov.b address relocation
     (may relax into an 8bit absolute address).  */

static void
do_a_fix_imm (int offset, int nibble, struct h8_op *operand, int relaxmode, const struct h8_instruction *this_try)
{
  int idx;
  int size;
  int where;
  char *bytes = frag_now->fr_literal + offset;

  char *t = ((operand->mode & MODE) == IMM) ? "#" : "@";

  if (operand->exp.X_add_symbol == 0)
    {
      switch (operand->mode & SIZE)
	{
	case L_2:
	  check_operand (operand, 0x3, t);
	  bytes[0] |= (operand->exp.X_add_number & 3) << (nibble ? 0 : 4);
	  break;
	case L_3:
	case L_3NZ:
	  check_operand (operand, 0x7, t);
	  bytes[0] |= (operand->exp.X_add_number & 7) << (nibble ? 0 : 4);
	  break;
	case L_4:
	  check_operand (operand, 0xF, t);
	  bytes[0] |= (operand->exp.X_add_number & 15) << (nibble ? 0 : 4);
	  break;
	case L_5:
	  check_operand (operand, 0x1F, t);
	  bytes[0] |= operand->exp.X_add_number & 31;
	  break;
	case L_8:
	case L_8U:
	  check_operand (operand, 0xff, t);
	  bytes[0] |= operand->exp.X_add_number;
	  break;
	case L_16:
	case L_16U:
	  check_operand (operand, 0xffff, t);
	  bytes[0] |= operand->exp.X_add_number >> 8;
	  bytes[1] |= operand->exp.X_add_number >> 0;
#ifdef OBJ_ELF
	  /* MOVA needs both relocs to relax the second operand properly.  */
	  if (relaxmode != 0
	      && (OP_KIND(this_try->opcode->how) == O_MOVAB
		  || OP_KIND(this_try->opcode->how) == O_MOVAW
		  || OP_KIND(this_try->opcode->how) == O_MOVAL))
	    {
	      idx = BFD_RELOC_16;
	      fix_new_exp (frag_now, offset, 2, &operand->exp, 0, idx);
	    }
#endif
	  break;
	case L_24:
	  check_operand (operand, 0xffffff, t);
	  bytes[0] |= operand->exp.X_add_number >> 16;
	  bytes[1] |= operand->exp.X_add_number >> 8;
	  bytes[2] |= operand->exp.X_add_number >> 0;
	  break;

	case L_32:
	  /* This should be done with bfd.  */
	  bytes[0] |= operand->exp.X_add_number >> 24;
	  bytes[1] |= operand->exp.X_add_number >> 16;
	  bytes[2] |= operand->exp.X_add_number >> 8;
	  bytes[3] |= operand->exp.X_add_number >> 0;
	  if (relaxmode != 0)
	    {
#ifdef OBJ_ELF
	      if ((operand->mode & MODE) == DISP && relaxmode == 1)
		idx = BFD_RELOC_H8_DISP32A16;
	      else
#endif
		idx = (relaxmode == 2) ? R_MOV24B1 : R_MOVL1;
	      fix_new_exp (frag_now, offset, 4, &operand->exp, 0, idx);
	    }
	  break;
	}
    }
  else
    {
      switch (operand->mode & SIZE)
	{
	case L_24:
	case L_32:
	  size = 4;
	  where = (operand->mode & SIZE) == L_24 ? -1 : 0;
#ifdef OBJ_ELF
	  if ((operand->mode & MODE) == DISP && relaxmode == 1)
	    idx = BFD_RELOC_H8_DISP32A16;
	  else
#endif
	  if (relaxmode == 2)
	    idx = R_MOV24B1;
	  else if (relaxmode == 1)
	    idx = R_MOVL1;
	  else
	    idx = R_RELLONG;
	  break;
	default:
	  as_bad (_("Can't work out size of operand.\n"));
	case L_16:
	case L_16U:
	  size = 2;
	  where = 0;
	  if (relaxmode == 2)
	    idx = R_MOV16B1;
	  else
	    idx = R_RELWORD;
	  operand->exp.X_add_number =
	    ((operand->exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
	  operand->exp.X_add_number |= (bytes[0] << 8) | bytes[1];
	  break;
	case L_8:
	  size = 1;
	  where = 0;
	  idx = R_RELBYTE;
	  operand->exp.X_add_number =
	    ((operand->exp.X_add_number & 0xff) ^ 0x80) - 0x80;
	  operand->exp.X_add_number |= bytes[0];
	}

      fix_new_exp (frag_now,
		   offset + where,
		   size,
		   &operand->exp,
		   0,
		   idx);
    }
}

/* Now we know what sort of opcodes it is, let's build the bytes.  */

static void
build_bytes (const struct h8_instruction *this_try, struct h8_op *operand)
{
  int i;
  char *output = frag_more (this_try->length);
  const op_type *nibble_ptr = this_try->opcode->data.nib;
  op_type c;
  unsigned int nibble_count = 0;
  int op_at[3];
  int nib = 0;
  int movb = 0;
  char asnibbles[100];
  char *p = asnibbles;
  int high, low;

  if (!Hmode && this_try->opcode->available != AV_H8)
    as_warn (_("Opcode `%s' with these operand types not available in H8/300 mode"),
	     this_try->opcode->name);
  else if (!Smode 
	   && this_try->opcode->available != AV_H8 
	   && this_try->opcode->available != AV_H8H)
    as_warn (_("Opcode `%s' with these operand types not available in H8/300H mode"),
	     this_try->opcode->name);
  else if (!SXmode 
	   && this_try->opcode->available != AV_H8
	   && this_try->opcode->available != AV_H8H
	   && this_try->opcode->available != AV_H8S)
    as_warn (_("Opcode `%s' with these operand types not available in H8/300S mode"),
	     this_try->opcode->name);

  while (*nibble_ptr != (op_type) E)
    {
      int d;

      nib = 0;
      c = *nibble_ptr++;

      d = (c & OP3) == OP3 ? 2 : (c & DST) == DST ? 1 : 0;

      if (c < 16)
	nib = c;
      else
	{
	  int c2 = c & MODE;

	  if (c2 == REG || c2 == LOWREG
	      || c2 == IND || c2 == PREINC || c2 == PREDEC
	      || c2 == POSTINC || c2 == POSTDEC)
	    {
	      nib = operand[d].reg;
	      if (c2 == LOWREG)
		nib &= 7;
	    }

	  else if (c & CTRL)	/* Control reg operand.  */
	    nib = operand[d].reg;

	  else if ((c & DISPREG) == (DISPREG))
	    {
	      nib = operand[d].reg;
	    }
	  else if (c2 == ABS)
	    {
	      operand[d].mode = c;
	      op_at[d] = nibble_count;
	      nib = 0;
	    }
	  else if (c2 == IMM || c2 == PCREL || c2 == ABS
		   || (c & ABSJMP) || c2 == DISP)
	    {
	      operand[d].mode = c;
	      op_at[d] = nibble_count;
	      nib = 0;
	    }
	  else if ((c & IGNORE) || (c & DATA))
	    nib = 0;

	  else if (c2 == DBIT)
	    {
	      switch (operand[0].exp.X_add_number)
		{
		case 1:
		  nib = c;
		  break;
		case 2:
		  nib = 0x8 | c;
		  break;
		default:
		  as_bad (_("Need #1 or #2 here"));
		}
	    }
	  else if (c2 == KBIT)
	    {
	      switch (operand[0].exp.X_add_number)
		{
		case 1:
		  nib = 0;
		  break;
		case 2:
		  nib = 8;
		  break;
		case 4:
		  if (!Hmode)
		    as_warn (_("#4 not valid on H8/300."));
		  nib = 9;
		  break;

		default:
		  as_bad (_("Need #1 or #2 here"));
		  break;
		}
	      /* Stop it making a fix.  */
	      operand[0].mode = 0;
	    }

	  if (c & MEMRELAX)
	    operand[d].mode |= MEMRELAX;

	  if (c & B31)
	    nib |= 0x8;

	  if (c & B21)
	    nib |= 0x4;

	  if (c & B11)
	    nib |= 0x2;

	  if (c & B01)
	    nib |= 0x1;

	  if (c2 == MACREG)
	    {
	      if (operand[0].mode == MACREG)
		/* stmac has mac[hl] as the first operand.  */
		nib = 2 + operand[0].reg;
	      else
		/* ldmac has mac[hl] as the second operand.  */
		nib = 2 + operand[1].reg;
	    }
	}
      nibble_count++;

      *p++ = nib;
    }

  /* Disgusting.  Why, oh why didn't someone ask us for advice
     on the assembler format.  */
  if (OP_KIND (this_try->opcode->how) == O_LDM)
    {
      high = (operand[1].reg >> 8) & 0xf;
      low  = (operand[1].reg) & 0xf;
      asnibbles[2] = high - low;
      asnibbles[7] = high;
    }
  else if (OP_KIND (this_try->opcode->how) == O_STM)
    {
      high = (operand[0].reg >> 8) & 0xf;
      low  = (operand[0].reg) & 0xf;
      asnibbles[2] = high - low;
      asnibbles[7] = low;
    }

  for (i = 0; i < this_try->length; i++)
    output[i] = (asnibbles[i * 2] << 4) | asnibbles[i * 2 + 1];

  /* Note if this is a mov.b or a bit manipulation instruction
     there is a special relaxation which only applies.  */
  if (   this_try->opcode->how == O (O_MOV,   SB)
      || this_try->opcode->how == O (O_BCLR,  SB)
      || this_try->opcode->how == O (O_BAND,  SB)
      || this_try->opcode->how == O (O_BIAND, SB)
      || this_try->opcode->how == O (O_BILD,  SB)
      || this_try->opcode->how == O (O_BIOR,  SB)
      || this_try->opcode->how == O (O_BIST,  SB)
      || this_try->opcode->how == O (O_BIXOR, SB)
      || this_try->opcode->how == O (O_BLD,   SB)
      || this_try->opcode->how == O (O_BNOT,  SB)
      || this_try->opcode->how == O (O_BOR,   SB)
      || this_try->opcode->how == O (O_BSET,  SB)
      || this_try->opcode->how == O (O_BST,   SB)
      || this_try->opcode->how == O (O_BTST,  SB)
      || this_try->opcode->how == O (O_BXOR,  SB))
    movb = 1;

  /* Output any fixes.  */
  for (i = 0; i < this_try->noperands; i++)
    {
      int x = operand[i].mode;
      int x_mode = x & MODE;

      if (x_mode == IMM || x_mode == DISP)
	{
#ifndef OBJ_ELF
	  /* Remove MEMRELAX flag added in h8300.h on mov with
	     addressing mode "register indirect with displacement".  */
	  if (x_mode == DISP)
	    x &= ~MEMRELAX;
#endif
	  do_a_fix_imm (output - frag_now->fr_literal + op_at[i] / 2,
			op_at[i] & 1, operand + i, (x & MEMRELAX) != 0,
			this_try);
	}
      else if (x_mode == ABS)
	do_a_fix_imm (output - frag_now->fr_literal + op_at[i] / 2,
		      op_at[i] & 1, operand + i,
		      (x & MEMRELAX) ? movb + 1 : 0,
		      this_try);

      else if (x_mode == PCREL)
	{
	  int size16 = (x & SIZE) == L_16;
	  int size = size16 ? 2 : 1;
	  int type = size16 ? R_PCRWORD : R_PCRBYTE;
	  fixS *fixP;

	  check_operand (operand + i, size16 ? 0x7fff : 0x7f, "@");

	  if (operand[i].exp.X_add_number & 1)
	    as_warn (_("branch operand has odd offset (%lx)\n"),
		     (unsigned long) operand->exp.X_add_number);
#ifndef OBJ_ELF
	  /* The COFF port has always been off by one, changing it
	     now would be an incompatible change, so we leave it as-is.

	     We don't want to do this for ELF as we want to be
	     compatible with the proposed ELF format from Hitachi.  */
	  operand[i].exp.X_add_number -= 1;
#endif
	  if (size16)
	    {
	      operand[i].exp.X_add_number =
		((operand[i].exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
	    }
	  else
	    {
	      operand[i].exp.X_add_number =
		((operand[i].exp.X_add_number & 0xff) ^ 0x80) - 0x80;
	    }

	  /* For BRA/S.  */
	  if (! size16)
	    operand[i].exp.X_add_number |= output[op_at[i] / 2];

	  fixP = fix_new_exp (frag_now,
			      output - frag_now->fr_literal + op_at[i] / 2,
			      size,
			      &operand[i].exp,
			      1,
			      type);
	  fixP->fx_signed = 1;
	}
      else if (x_mode == MEMIND)
	{
	  check_operand (operand + i, 0xff, "@@");
	  fix_new_exp (frag_now,
		       output - frag_now->fr_literal + 1,
		       1,
		       &operand[i].exp,
		       0,
		       R_MEM_INDIRECT);
	}
      else if (x_mode == VECIND)
	{
	  check_operand (operand + i, 0x7f, "@@");
	  /* FIXME: approximating the effect of "B31" here...
	     This is very hackish, and ought to be done a better way.  */
	  operand[i].exp.X_add_number |= 0x80;
	  fix_new_exp (frag_now,
		       output - frag_now->fr_literal + 1,
		       1,
		       &operand[i].exp,
		       0,
		       R_MEM_INDIRECT);
	}
      else if (x & ABSJMP)
	{
	  int where = 0;
	  bfd_reloc_code_real_type reloc_type = R_JMPL1;

#ifdef OBJ_ELF
	  /* To be compatible with the proposed H8 ELF format, we
	     want the relocation's offset to point to the first byte
	     that will be modified, not to the start of the instruction.  */
	  
	  if ((operand->mode & SIZE) == L_32)
	    {
	      where = 2;
	      reloc_type = R_RELLONG;
	    }
	  else
	    where = 1;
#endif

	  /* This jmp may be a jump or a branch.  */

	  check_operand (operand + i, 
			 SXmode ? 0xffffffff : Hmode ? 0xffffff : 0xffff, 
			 "@");

	  if (operand[i].exp.X_add_number & 1)
	    as_warn (_("branch operand has odd offset (%lx)\n"),
		     (unsigned long) operand->exp.X_add_number);

	  if (!Hmode)
	    operand[i].exp.X_add_number =
	      ((operand[i].exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
	  fix_new_exp (frag_now,
		       output - frag_now->fr_literal + where,
		       4,
		       &operand[i].exp,
		       0,
		       reloc_type);
	}
    }
}

/* Try to give an intelligent error message for common and simple to
   detect errors.  */

static void
clever_message (const struct h8_instruction *instruction,
		struct h8_op *operand)
{
  /* Find out if there was more than one possible opcode.  */

  if ((instruction + 1)->idx != instruction->idx)
    {
      int argn;

      /* Only one opcode of this flavour, try to guess which operand
         didn't match.  */
      for (argn = 0; argn < instruction->noperands; argn++)
	{
	  switch (instruction->opcode->args.nib[argn])
	    {
	    case RD16:
	      if (operand[argn].mode != RD16)
		{
		  as_bad (_("destination operand must be 16 bit register"));
		  return;

		}
	      break;

	    case RS8:
	      if (operand[argn].mode != RS8)
		{
		  as_bad (_("source operand must be 8 bit register"));
		  return;
		}
	      break;

	    case ABS16DST:
	      if (operand[argn].mode != ABS16DST)
		{
		  as_bad (_("destination operand must be 16bit absolute address"));
		  return;
		}
	      break;
	    case RD8:
	      if (operand[argn].mode != RD8)
		{
		  as_bad (_("destination operand must be 8 bit register"));
		  return;
		}
	      break;

	    case ABS16SRC:
	      if (operand[argn].mode != ABS16SRC)
		{
		  as_bad (_("source operand must be 16bit absolute address"));
		  return;
		}
	      break;

	    }
	}
    }
  as_bad (_("invalid operands"));
}


/* If OPERAND is part of an address, adjust its size and value given
   that it addresses SIZE bytes.

   This function decides how big non-immediate constants are when no
   size was explicitly given.  It also scales down the assembly-level
   displacement in an @(d:2,ERn) operand.  */

static void
fix_operand_size (struct h8_op *operand, int size)
{
  if (SXmode && (operand->mode & MODE) == DISP)
    {
      /* If the user didn't specify an operand width, see if we
	 can use @(d:2,ERn).  */
      if ((operand->mode & SIZE) == 0
	  && operand->exp.X_add_symbol == 0
	  && operand->exp.X_op_symbol == 0
	  && (operand->exp.X_add_number == size
	      || operand->exp.X_add_number == size * 2
	      || operand->exp.X_add_number == size * 3))
	operand->mode |= L_2;

      /* Scale down the displacement in an @(d:2,ERn) operand.
	 X_add_number then contains the desired field value.  */
      if ((operand->mode & SIZE) == L_2)
	{
	  if (operand->exp.X_add_number % size != 0)
	    as_warn (_("operand/size mis-match"));
	  operand->exp.X_add_number /= size;
	}
    }

  if ((operand->mode & SIZE) == 0)
    switch (operand->mode & MODE)
      {
      case DISP:
      case INDEXB:
      case INDEXW:
      case INDEXL:
      case ABS:
	/* Pick a 24-bit address unless we know that a 16-bit address
	   is safe.  get_specific() will relax L_24 into L_32 where
	   necessary.  */
	if (Hmode
	    && !Nmode 
	    && ((((addressT) operand->exp.X_add_number + 0x8000)
		 & 0xffffffff) > 0xffff
		|| operand->exp.X_add_symbol != 0
		|| operand->exp.X_op_symbol != 0))
	  operand->mode |= L_24;
	else
	  operand->mode |= L_16;
	break;

      case PCREL:
	if ((((addressT) operand->exp.X_add_number + 0x80)
	     & 0xffffffff) <= 0xff)
	  {
	    if (operand->exp.X_add_symbol != NULL)
	      operand->mode |= bsize;
	    else
	      operand->mode |= L_8;
	  }
	else
	  operand->mode |= L_16;
	break;
      }
}


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

void
md_assemble (char *str)
{
  char *op_start;
  char *op_end;
  struct h8_op operand[3];
  const struct h8_instruction *instruction;
  const struct h8_instruction *prev_instruction;

  char *dot = 0;
  char *slash = 0;
  char c;
  int size, i;

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

  /* Find the op code end.  */
  for (op_start = op_end = str;
       *op_end != 0 && *op_end != ' ';
       op_end++)
    {
      if (*op_end == '.')
	{
	  dot = op_end + 1;
	  *op_end = 0;
	  op_end += 2;
	  break;
	}
      else if (*op_end == '/' && ! slash)
	slash = op_end;
    }

  if (op_end == op_start)
    {
      as_bad (_("can't find opcode "));
    }
  c = *op_end;

  *op_end = 0;

  /* The assembler stops scanning the opcode at slashes, so it fails
     to make characters following them lower case.  Fix them.  */
  if (slash)
    while (*++slash)
      *slash = TOLOWER (*slash);

  instruction = (const struct h8_instruction *)
    hash_find (opcode_hash_control, op_start);

  if (instruction == NULL)
    {
      as_bad (_("unknown opcode"));
      return;
    }

  /* We used to set input_line_pointer to the result of get_operands,
     but that is wrong.  Our caller assumes we don't change it.  */

  operand[0].mode = 0;
  operand[1].mode = 0;
  operand[2].mode = 0;

  if (OP_KIND (instruction->opcode->how) == O_MOVAB
      || OP_KIND (instruction->opcode->how) == O_MOVAW
      || OP_KIND (instruction->opcode->how) == O_MOVAL)
    get_mova_operands (op_end, operand);
  else if (OP_KIND (instruction->opcode->how) == O_RTEL
	   || OP_KIND (instruction->opcode->how) == O_RTSL)
    get_rtsl_operands (op_end, operand);
  else
    get_operands (instruction->noperands, op_end, operand);

  *op_end = c;
  prev_instruction = instruction;

  /* Now we have operands from instruction.
     Let's check them out for ldm and stm.  */
  if (OP_KIND (instruction->opcode->how) == O_LDM)
    {
      /* The first operand must be @er7+, and the
	 second operand must be a register pair.  */
      if ((operand[0].mode != RSINC)
           || (operand[0].reg != 7)
           || ((operand[1].reg & 0x80000000) == 0))
	as_bad (_("invalid operand in ldm"));
    }
  else if (OP_KIND (instruction->opcode->how) == O_STM)
    {
      /* The first operand must be a register pair,
	 and the second operand must be @-er7.  */
      if (((operand[0].reg & 0x80000000) == 0)
            || (operand[1].mode != RDDEC)
            || (operand[1].reg != 7))
	as_bad (_("invalid operand in stm"));
    }

  size = SN;
  if (dot)
    {
      switch (TOLOWER (*dot))
	{
	case 'b':
	  size = SB;
	  break;

	case 'w':
	  size = SW;
	  break;

	case 'l':
	  size = SL;
	  break;
	}
    }
  if (OP_KIND (instruction->opcode->how) == O_MOVAB ||
      OP_KIND (instruction->opcode->how) == O_MOVAW ||
      OP_KIND (instruction->opcode->how) == O_MOVAL)
    {
      switch (operand[0].mode & MODE)
	{
	case INDEXB:
	default:
	  fix_operand_size (&operand[1], 1);
	  break;
	case INDEXW:
	  fix_operand_size (&operand[1], 2);
	  break;
	case INDEXL:
	  fix_operand_size (&operand[1], 4);
	  break;
	}
    }
  else
    {
      for (i = 0; i < 3 && operand[i].mode != 0; i++)
	switch (size)
	  {
	  case SN:
	  case SB:
	  default:
	    fix_operand_size (&operand[i], 1);
	    break;
	  case SW:
	    fix_operand_size (&operand[i], 2);
	    break;
	  case SL:
	    fix_operand_size (&operand[i], 4);
	    break;
	  }
    }

  instruction = get_specific (instruction, operand, size);

  if (instruction == 0)
    {
      /* Couldn't find an opcode which matched the operands.  */
      char *where = frag_more (2);

      where[0] = 0x0;
      where[1] = 0x0;
      clever_message (prev_instruction, operand);

      return;
    }

  build_bytes (instruction, operand);

  dwarf2_emit_insn (instruction->length);
}

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

/* Various routines to kill one day.  */

char *
md_atof (int type, char *litP, int *sizeP)
{
  return ieee_md_atof (type, litP, sizeP, TRUE);
}

#define OPTION_H_TICK_HEX      (OPTION_MD_BASE)

const char *md_shortopts = "";
struct option md_longopts[] = {
  { "h-tick-hex", no_argument,	      NULL, OPTION_H_TICK_HEX  },
  {NULL, no_argument, NULL, 0}
};

size_t md_longopts_size = sizeof (md_longopts);

int
md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
{
  switch (c)
    {
    case OPTION_H_TICK_HEX:
      enable_h_tick_hex = 1;
      break;

    default:
      return 0;
    }
  return 1;
}

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

void
tc_aout_fix_to_chars (void)
{
  printf (_("call to tc_aout_fix_to_chars \n"));
  abort ();
}

void
md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
		 segT seg ATTRIBUTE_UNUSED,
		 fragS *fragP ATTRIBUTE_UNUSED)
{
  printf (_("call to md_convert_frag \n"));
  abort ();
}

valueT
md_section_align (segT segment, valueT size)
{
  int align = bfd_get_section_alignment (stdoutput, segment);
  return ((size + (1 << align) - 1) & (-1 << align));
}

void
md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
{
  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
  long val = *valP;

  switch (fixP->fx_size)
    {
    case 1:
      *buf++ = val;
      break;
    case 2:
      *buf++ = (val >> 8);
      *buf++ = val;
      break;
    case 4:
      *buf++ = (val >> 24);
      *buf++ = (val >> 16);
      *buf++ = (val >> 8);
      *buf++ = val;
      break;
    case 8:
      /* This can arise when the .quad or .8byte pseudo-ops are used.
	 Returning here (without setting fx_done) will cause the code
	 to attempt to generate a reloc which will then fail with the
	 slightly more helpful error message: "Cannot represent
	 relocation type BFD_RELOC_64".  */
      return;
    default:
      abort ();
    }

  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
    fixP->fx_done = 1;
}

int
md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
			       segT segment_type ATTRIBUTE_UNUSED)
{
  printf (_("call to md_estimate_size_before_relax \n"));
  abort ();
}

/* Put number into target byte order.  */
void
md_number_to_chars (char *ptr, valueT use, int nbytes)
{
  number_to_chars_bigendian (ptr, use, nbytes);
}

long
md_pcrel_from (fixS *fixp)
{
  as_bad_where (fixp->fx_file, fixp->fx_line,
		_("Unexpected reference to a symbol in a non-code section"));
  return 0;
}

arelent *
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
{
  arelent *rel;
  bfd_reloc_code_real_type r_type;

  if (fixp->fx_addsy && fixp->fx_subsy)
    {
      if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
	  || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
	{
	  as_bad_where (fixp->fx_file, fixp->fx_line,
			_("Difference of symbols in different sections is not supported"));
	  return NULL;
	}
    }

  rel = xmalloc (sizeof (arelent));
  rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
  *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
  rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
  rel->addend = fixp->fx_offset;

  r_type = fixp->fx_r_type;

#define DEBUG 0
#if DEBUG
  fprintf (stderr, "%s\n", bfd_get_reloc_code_name (r_type));
  fflush (stderr);
#endif
  rel->howto = bfd_reloc_type_lookup (stdoutput, r_type);
  if (rel->howto == NULL)
    {
      as_bad_where (fixp->fx_file, fixp->fx_line,
		    _("Cannot represent relocation type %s"),
		    bfd_get_reloc_code_name (r_type));
      return NULL;
    }

  return rel;
}
