/* tc-h8300.c -- Assemble code for the Hitachi H8/300
   Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation.

   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 2, 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, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.  */


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

#include <stdio.h>
#include "as.h"
#include "subsegs.h"
#include "bfd.h"
#define DEFINE_TABLE
#define h8_opcodes ops
#include "opcode/h8300.h"
#include <ctype.h>

const char comment_chars[] =
{';', 0};
const char line_separator_chars[] =
{0};
const char line_comment_chars[] = "#";

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

void cons ();

int Hmode;
int Smode;
#define PSIZE (Hmode ? L_32 : L_16)
#define DMODE (L_16)
#define DSYMMODE (Hmode ? L_24 : L_16)
int bsize = L_8;		/* default branch displacement */


void
h8300hmode ()
{
  Hmode = 1;
  Smode = 0;
}

void
h8300smode ()
{
  Smode = 1;
  Hmode = 1;
}
void
sbranch (size)
     int size;
{
  bsize = size;
}

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

const pseudo_typeS md_pseudo_table[] =
{

  {"h8300h", h8300hmode, 0},
  {"h8300s", h8300smode, 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},
  {0, 0, 0}
};

const int md_reloc_size;

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 ()
{
  struct h8_opcode *opcode;
  char prev_buffer[100];
  int idx = 0;

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

  for (opcode = h8_opcodes; opcode->name; opcode++)
    {
      /* Strip off any . part when inserting the opcode and only enter
         unique codes into the hash table
         */
      char *src = opcode->name;
      unsigned int len = strlen (src);
      char *dst = malloc (len + 1);
      char *buffer = dst;

      opcode->size = 0;
      while (*src)
	{
	  if (*src == '.')
	    {
	      src++;
	      opcode->size = *src;
	      break;
	    }
	  *dst++ = *src++;
	}
      *dst++ = 0;
      if (strcmp (buffer, prev_buffer))
	{
	  hash_insert (opcode_hash_control, buffer, (char *) opcode);
	  strcpy (prev_buffer, buffer);
	  idx++;
	}
      opcode->idx = idx;


      /* Find the number of operands */
      opcode->noperands = 0;
      while (opcode->args.nib[opcode->noperands] != E)
	opcode->noperands++;
      /* Find the length of the opcode in bytes */
      opcode->length = 0;
      while (opcode->data.nib[opcode->length * 2] != E)
	opcode->length++;
    }

  linkrelax = 1;
}


struct h8_exp
{
  char *e_beg;
  char *e_end;
  expressionS e_exp;
};
int dispreg;
int opsize;			/* Set when a register size is seen */


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

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

/* try and parse a reg name, returns number of chars consumed */
int
parse_reg (src, mode, reg, direction)
     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 == '\001')
    end++;
  len = end - src;

  if (len == 2 && src[0] == 's' && src[1] == 'p')
    {
      *mode = PSIZE | REG | direction;
      *reg = 7;
      return len;
    }
  if (len == 3 && src[0] == 'c' && src[1] == 'c' && src[2] == 'r')
    {
      *mode = CCR;
      *reg = 0;
      return len;
    }
  if (len == 3 && src[0] == 'e' && src[1] == 'x' && src[2] == 'r')
    {
      *mode = EXR;
      *reg = 0;
      return len;
    }
  if (len == 2 && src[0] == 'f' && src[1] == 'p')
    {
      *mode = PSIZE | REG | direction;
      *reg = 6;
      return len;
    }
  if (len == 3 && src[0] == 'e' && 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 && 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 (src[0] == 'r')
    {
      if (src[1] >= '0' && src[1] <= '7')
	{
	  if (len == 3 && src[2] == 'l')
	    {
	      *mode = L_8 | REG | direction;
	      *reg = (src[1] - '0') + 8;
	      return len;
	    }
	  if (len == 3 && 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;
}

char *
parse_exp (s, op)
     char *s;
     expressionS * op;
{
  char *save = input_line_pointer;
  char *new;

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

static char *
skip_colonthing (ptr, exp, mode)
     char *ptr;
     expressionS *exp;
     int *mode;
{
  if (*ptr == ':')
    {
      ptr++;
      *mode &= ~SIZE;
      if (*ptr == '8')
	{
	  ptr++;
	  /* ff fill any 8 bit quantity */
	 /* exp->X_add_number -= 0x100;*/
	  *mode |= L_8;
	}
      else
	{
	  if (*ptr == '2')
	    {
	      *mode |= L_24;
	    }
	  else if (*ptr == '3')
	    {
	      *mode |= L_32;
	    }
	  else if (*ptr == '1')
	    {
	      *mode |= L_16;
	    }
	  while (isdigit (*ptr))
	    ptr++;
	}
    }
  return ptr;
}

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

   */

char *
colonmod24 (op, src)
     struct h8_op *op;
     char *src;

{
  int mode = 0;
  src = skip_colonthing (src, &op->exp, &mode);

  if (!mode)
    {
      /* Choose a default mode */
      if (op->exp.X_add_number < -32768
	  || op->exp.X_add_number > 32767)
	{
	  if (Hmode)
	    mode = L_24;
	  else
	    mode = L_16;
	}
      else if (op->exp.X_add_symbol
	       || op->exp.X_op_symbol)
	mode = DSYMMODE;
      else
	mode = DMODE;
    }
  op->mode |= mode;
  return src;

}


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

  op->mode = E;

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

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

      if (high < low)
	as_bad (_("Invalid register list for ldm/stm\n"));

      if (low % 2)
	as_bad (_("Invalid register list for ldm/stm\n"));

      if (high - low > 3)
	as_bad (_("Invalid register list for ldm/stm\n"));

      if (high - low != 1
	  && low % 4)
	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;
      *ptr = src + 7;
      return;
    }

  len = parse_reg (src, &op->mode, &op->reg, direction);
  if (len)
    {
      *ptr = src + len;
      return;
    }

  if (*src == '@')
    {
      src++;
      if (*src == '@')
	{
	  src++;
	  src = parse_exp (src, &op->exp);

	  src = skip_colonthing (src, &op->exp, &op->mode);

	  *ptr = src;

	  op->mode = MEMIND;
	  return;

	}


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

	      return;


	    }


	  if ((mode & SIZE) != PSIZE)
	    as_bad (_("Wrong size pointer register for architecture."));
	  op->mode = RDDEC;
	  op->reg = num;
	  *ptr = src + len;
	  return;
	}
      if (*src == '(')
	{
	  /* Disp */
	  src++;

	  /* Start off assuming a 16 bit offset */


	  src = parse_exp (src, &op->exp);

	  src = colonmod24 (op, src);

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

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

	    }
	  src++;

	  len = parse_reg (src, &mode, &op->reg, direction);
	  if (len == 0 || !(mode & REG))
	    {
	      as_bad (_("expected @(exp, reg16)"));
	      return;
	    }
	  op->mode |= DISP | direction;
	  dispreg = op->reg;
	  src += len;
	  src = skip_colonthing (src, &op->exp, &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)
		as_bad (_("Wrong size pointer register for architecture."));
	      op->mode = RSINC;
	      op->reg = num;
	      *ptr = src;
	      return;
	    }
	  if ((mode & SIZE) != PSIZE)
	    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;
	  src = parse_exp (src, &op->exp);

	  *ptr = colonmod24 (op, src);

	  return;
	}
    }


  if (*src == '#')
    {
      src++;
      op->mode = IMM;
      src = parse_exp (src, &op->exp);
      *ptr = skip_colonthing (src, &op->exp, &op->mode);

      return;
    }
  else if (strncmp (src, "mach", 4) == 0
	   || strncmp (src, "macl", 4) == 0)
    {
      op->reg = src[3] == 'l';
      op->mode = MACREG;
      *ptr = src + 4;
      return;
    }
  else
    {
      src = parse_exp (src, &op->exp);
      /* Trailing ':' size ? */
      if (*src == ':')
	{
	  if (src[1] == '1' && src[2] == '6')
	    {
	      op->mode = PCREL | L_16;
	      src += 3;
	    }
	  else if (src[1] == '8')
	    {
	      op->mode = PCREL | L_8;
	      src += 2;
	    }
	  else
	    {
	      as_bad (_("expect :8 or :16 here"));
	    }
	}
      else
	{
	  op->mode = PCREL | bsize;
	}
      *ptr = src;
    }
}


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

  switch (noperands)
    {
    case 0:
      operand[0].mode = 0;
      operand[1].mode = 0;
      break;

    case 1:
      ptr++;
      get_operand (&ptr, operand + 0, 0, SRC);
      if (*ptr == ',')
	{
	  ptr++;
	  get_operand (&ptr, operand + 1, 1, DST);
	}
      else
	{
	  operand[1].mode = 0;
	}

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

    default:
      abort ();
    }


  return ptr;
}

/* Passed a pointer to a list of opcodes which use different
   addressing modes, return the opcode which matches the opcodes
   provided
   */
static
struct h8_opcode *
get_specific (opcode, operands, size)
     struct h8_opcode *opcode;
     struct h8_op *operands;
     int size;
{
  struct h8_opcode *this_try = opcode;
  int found = 0;

  unsigned int this_index = opcode->idx;

  /* There's only one ldm/stm and it's easier to just
     get out quick for them.  */
  if (strcmp (opcode->name, "stm.l") == 0
      || strcmp (opcode->name, "ldm.l") == 0)
    return this_try;

  while (this_index == opcode->idx && !found)
    {
      found = 1;

      this_try = opcode++;
      if (this_try->noperands == 0)
	{
	  int this_size;

	  this_size = this_try->how & SN;
	  if (this_size != size && (this_size != SB || size != SN))
	    found = 0;
	}
      else
	{
	  unsigned int i;

	  for (i = 0; i < this_try->noperands && found; i++)
	    {
	      op_type op = this_try->args.nib[i];
	      int x = operands[i].mode;

	      if ((op & (DISP | REG)) == (DISP | REG)
		  && ((x & (DISP | REG)) == (DISP | REG)))
		{
		  dispreg = operands[i].reg;
		}
	      else if (op & REG)
		{
		  if (!(x & REG))
		    found = 0;

		  if (x & L_P)
		    x = (x & ~L_P) | (Hmode ? L_32 : L_16);
		  if (op & L_P)
		    op = (op & ~L_P) | (Hmode ? L_32 : L_16);

		  opsize = op & SIZE;

		  /* The size of the reg is v important */
		  if ((op & SIZE) != (x & SIZE))
		    found = 0;
		}
	      else if ((op & ABSJMP) && (x & ABS))
		{
		  operands[i].mode &= ~ABS;
		  operands[i].mode |= ABSJMP;
		  /* But it may not be 24 bits long */
		  if (!Hmode)
		    {
		      operands[i].mode &= ~SIZE;
		      operands[i].mode |= L_16;
		    }
		}
	      else if ((op & (KBIT | DBIT)) && (x & IMM))
		{
		  /* This is ok if the immediate value is sensible */
		}
	      else if (op & PCREL)
		{
		  /* The size of the displacement is important */
		  if ((op & SIZE) != (x & SIZE))
		    found = 0;
		}
	      else if ((op & (DISP | IMM | ABS))
		       && (op & (DISP | IMM | ABS)) == (x & (DISP | IMM | ABS)))
		{
		  /* Promote a L_24 to L_32 if it makes us match.  */
		  if ((x & L_24) && (op & L_32))
		    {
		      x &= ~L_24;
		      x |= L_32;
		    }
		  /* Promote an L8 to L_16 if it makes us match.  */
		  if (op & ABS && op & L_8 && op & DISP) 
		    {
		      if (x & L_16)
			found= 1;
		    }
		  else if ((x & SIZE) != 0
			   && ((op & SIZE) != (x & SIZE)))
		    found = 0;
		}
	      else if ((op & MACREG) != (x & MACREG))
		{
		  found = 0;
		}
	      else if ((op & MODE) != (x & MODE))
		{
		  found = 0;
		}	
	    }
	}
    }
  if (found)
    return this_try;
  else
    return 0;
}

static void
check_operand (operand, width, string)
     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 ((operand->exp.X_add_number & ~width) != 0 &&
	  (operand->exp.X_add_number | width) != (~0))
	{
	  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 
	    {
	      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 (offset, operand, relaxmode)
     int offset;
     struct h8_op *operand;
     int relaxmode;
{
  int idx;
  int size;
  int where;


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

  if (operand->exp.X_add_symbol == 0)
    {
      char *bytes = frag_now->fr_literal + offset;
      switch (operand->mode & SIZE)
	{
	case L_2:
	  check_operand (operand, 0x3, t);
	  bytes[0] |= (operand->exp.X_add_number) << 4;
	  break;
	case L_3:
	  check_operand (operand, 0x7, t);
	  bytes[0] |= (operand->exp.X_add_number) << 4;
	  break;
	case L_8:
	  check_operand (operand, 0xff, t);
	  bytes[0] = operand->exp.X_add_number;
	  break;
	case L_16:
	  check_operand (operand, 0xffff, t);
	  bytes[0] = operand->exp.X_add_number >> 8;
	  bytes[1] = operand->exp.X_add_number >> 0;
	  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;
	  break;
	}

    }
  else
    {
      switch (operand->mode & SIZE)
	{

	case L_24:
	case L_32:
	  size = 4;
	  where = (operand->mode & SIZE) == L_24 ? -1 : 0;
	  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:
	  size = 2;
	  where = 0;
	  if (relaxmode == 2)
	    idx = R_MOV16B1;
	  else
	    idx = R_RELWORD;
	  operand->exp.X_add_number = (short)operand->exp.X_add_number;
	  break;
	case L_8:
	  size = 1;
	  where = 0;
	  idx = R_RELBYTE;
	  /* This used to use a cast to char, but that fails if char is an
	     unsigned type.  We can't use `signed char', as that isn't valid
	     K&R C.  */
	  if (operand->exp.X_add_number & 0x80)
	    operand->exp.X_add_number |= ((offsetT) -1 << 8);
	  else
	    operand->exp.X_add_number &= 0xff;
	}

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

}

/* Now we know what sort of opcodes it is, lets build the bytes -
 */
static void
build_bytes (this_try, operand)
     struct h8_opcode *this_try;
     struct h8_op *operand;
{
  unsigned int i;

  char *output = frag_more (this_try->length);
  op_type *nibble_ptr = this_try->data.nib;
  op_type c;
  unsigned int nibble_count = 0;
  int absat;
  int immat;
  int nib;
  int movb = 0;
  char asnibbles[30];
  char *p = asnibbles;

  if (!(this_try->inbase || Hmode))
    as_warn (_("Opcode `%s' with these operand types not available in H8/300 mode"),
	     this_try->name);

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

      d = (c & (DST | SRC_IN_DST)) != 0;

      if (c < 16)
	{
	  nib = c;
	}
      else
	{

	  if (c & (REG | IND | INC | DEC))
	    {
	      nib = operand[d].reg;
	    }
	  else if ((c & DISPREG) == (DISPREG))
	    {
	      nib = dispreg;
	    }
	  else if (c &  ABS )
	    {
	      operand[d].mode = c;
	      absat = nibble_count / 2;
	      nib = 0;
	    }
	  else if (c & (IMM | PCREL | ABS | ABSJMP | DISP))
	    {
	      operand[d].mode = c;
	      immat = nibble_count / 2;
	      nib = 0;
	    }
	  else if (c & IGNORE)
	    {
	      nib = 0;
	    }
	  else if (c & 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 (c & 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 & MACREG)
	    {
	      nib = 2 + operand[d].reg;
	    }
	}
      nibble_count++;

      *p++ = nib;
    }

  /* Disgusting.  Why, oh why didn't someone ask us for advice
     on the assembler format.  */
  if (strcmp (this_try->name, "stm.l") == 0
      || strcmp (this_try->name, "ldm.l") == 0)
    {
      int high, low;
      high = (operand[this_try->name[0] == 'l' ? 1 : 0].reg >> 8) & 0xf;
      low = operand[this_try->name[0] == 'l' ? 1 : 0].reg & 0xf;

      asnibbles[2] = high - low;
      asnibbles[7] = (this_try->name[0] == 'l') ? high : low;
    }

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

  /* Note if this is a movb instruction -- there's a special relaxation
     which only applies to them.  */
  if (strcmp (this_try->name, "mov.b") == 0)
    movb = 1;

  /* output any fixes */
  for (i = 0; i < 2; i++)
    {
      int x = operand[i].mode;

      if (x & (IMM | DISP))
	{
	  do_a_fix_imm (output - frag_now->fr_literal + immat,
			operand + i, x & MEMRELAX != 0);
	}
      else if (x & ABS)
	{
	  do_a_fix_imm (output - frag_now->fr_literal + absat,
			operand + i, x & MEMRELAX ? movb + 1 : 0);
	}
      else if (x & PCREL)
	{
	  int size16 = x & L_16;
	  int where = size16 ? 2 : 1;
	  int size = size16 ? 2 : 1;
	  int type = size16 ? R_PCRWORD : R_PCRBYTE;

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

	  operand[i].exp.X_add_number -= 1;
	  /* This used to use a cast to char, but that fails if char is an
	     unsigned type.  We can't use `signed char', as that isn't valid
	     K&R C.  */
	  if (operand[i].exp.X_add_number & 0x80)
	    operand[i].exp.X_add_number |= ((offsetT) -1 << 8);
	  else
	    operand[i].exp.X_add_number &= 0xff;

	  fix_new_exp (frag_now,
		       output - frag_now->fr_literal + where,
		       size,
		       &operand[i].exp,
		       1,
		       type);
	}
      else if (x & 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 & ABSJMP)
	{
	  /* This jmp may be a jump or a branch */

	  check_operand (operand + i, 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 = (short) operand[i].exp.X_add_number;
	  fix_new_exp (frag_now,
		       output - frag_now->fr_literal,
		       4,
		       &operand[i].exp,
		       0,
		       R_JMPL1);
	}
    }

}

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

static void
clever_message (opcode, operand)
     struct h8_opcode *opcode;
     struct h8_op *operand;
{
  /* Find out if there was more than one possible opccode */

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

      /* Only one opcode of this flavour, try and guess which operand
         didn't match */
      for (argn = 0; argn < opcode->noperands; argn++)
	{
	  switch (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"));
}

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



void
md_assemble (str)
     char *str;
{
  char *op_start;
  char *op_end;
  struct h8_op operand[2];
  struct h8_opcode *opcode;
  struct h8_opcode *prev_opcode;

  char *dot = 0;
  char c;
  int size;

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

  ;

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

  *op_end = 0;

  opcode = (struct h8_opcode *) hash_find (opcode_hash_control,
					   op_start);

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

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

  (void) get_operands (opcode->noperands, op_end, operand);
  *op_end = c;
  prev_opcode = opcode;

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

	case 'w':
	  size = SW;
	  break;

	case 'l':
	  size = SL;
	  break;
	}
    }
  opcode = get_specific (opcode, operand, size);

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

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

      return;
    }
  if (opcode->size && dot)
    {
      if (opcode->size != *dot)
	{
	  as_warn (_("mismatch between opcode size and operand size"));
	}
    }

  build_bytes (opcode, operand);

}

void
tc_crawl_symbol_chain (headers)
     object_headers * headers;
{
  printf (_("call to tc_crawl_symbol_chain \n"));
}

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

void
tc_headers_hook (headers)
     object_headers * headers;
{
  printf (_("call to tc_headers_hook \n"));
}

/* Various routines to kill one day */
/* Equal to MAX_PRECISION in atof-ieee.c */
#define MAX_LITTLENUMS 6

/* Turn a string in input_line_pointer into a floating point constant of type
   type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
   emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
   */
char *
md_atof (type, litP, sizeP)
     char type;
     char *litP;
     int *sizeP;
{
  int prec;
  LITTLENUM_TYPE words[MAX_LITTLENUMS];
  LITTLENUM_TYPE *wordP;
  char *t;
  char *atof_ieee ();

  switch (type)
    {
    case 'f':
    case 'F':
    case 's':
    case 'S':
      prec = 2;
      break;

    case 'd':
    case 'D':
    case 'r':
    case 'R':
      prec = 4;
      break;

    case 'x':
    case 'X':
      prec = 6;
      break;

    case 'p':
    case 'P':
      prec = 6;
      break;

    default:
      *sizeP = 0;
      return _("Bad call to MD_ATOF()");
    }
  t = atof_ieee (input_line_pointer, type, words);
  if (t)
    input_line_pointer = t;

  *sizeP = prec * sizeof (LITTLENUM_TYPE);
  for (wordP = words; prec--;)
    {
      md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
      litP += sizeof (LITTLENUM_TYPE);
    }
  return 0;
}

CONST char *md_shortopts = "";
struct option md_longopts[] = {
  {NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof(md_longopts);

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

void
md_show_usage (stream)
     FILE *stream;
{
}

void
tc_aout_fix_to_chars ()
{
  printf (_("call to tc_aout_fix_to_chars \n"));
  abort ();
}

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

valueT 
md_section_align (seg, size)
     segT seg;
     valueT size;
{
  return ((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));

}

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

  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;
    default:
      abort ();
    }
}

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

/* Put number into target byte order */

void
md_number_to_chars (ptr, use, nbytes)
     char *ptr;
     valueT use;
     int nbytes;
{
  number_to_chars_bigendian (ptr, use, nbytes);
}
long
md_pcrel_from (fixP)
     fixS *fixP;
{
  abort ();
}


void
tc_reloc_mangle (fix_ptr, intr, base)
     fixS *fix_ptr;
     struct internal_reloc *intr;
     bfd_vma base;

{
  symbolS *symbol_ptr;

  symbol_ptr = fix_ptr->fx_addsy;

  /* If this relocation is attached to a symbol then it's ok
     to output it */
  if (fix_ptr->fx_r_type == TC_CONS_RELOC)
    {
      /* cons likes to create reloc32's whatever the size of the reloc..
       */
      switch (fix_ptr->fx_size)
	{
	case 4:
	  intr->r_type = R_RELLONG;
	  break;
	case 2:
	  intr->r_type = R_RELWORD;
	  break;
	case 1:
	  intr->r_type = R_RELBYTE;
	  break;
	default:
	  abort ();

	}

    }
  else
    {
      intr->r_type = fix_ptr->fx_r_type;
    }

  intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
  intr->r_offset = fix_ptr->fx_offset;

  if (symbol_ptr)
    {
      if (symbol_ptr->sy_number != -1)
	intr->r_symndx = symbol_ptr->sy_number;
      else
	{
	  symbolS *segsym;

	  /* This case arises when a reference is made to `.'.  */
	  segsym = seg_info (S_GET_SEGMENT (symbol_ptr))->dot;
	  if (segsym == NULL)
	    intr->r_symndx = -1;
	  else
	    {
	      intr->r_symndx = segsym->sy_number;
	      intr->r_offset += S_GET_VALUE (symbol_ptr);
	    }
	}
    }
  else
    intr->r_symndx = -1;


}

/* end of tc-h8300.c */
