/* tc-metag.c -- Assembler for the Imagination Technologies Meta.
   Copyright (C) 2013-2016 Free Software Foundation, Inc.
   Contributed by Imagination Technologies Ltd.

   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 "subsegs.h"
#include "symcat.h"
#include "safe-ctype.h"
#include "hashtab.h"
#include "libbfd.h"

#include <stdio.h>

#include "opcode/metag.h"

const char comment_chars[]        = "!";
const char line_comment_chars[]   = "!#";
const char line_separator_chars[] = ";";
const char FLT_CHARS[]            = "rRsSfFdDxXpP";
const char EXP_CHARS[]            = "eE";
const char metag_symbol_chars[]   = "[";

static char register_chars[256];
static char mnemonic_chars[256];

#define is_register_char(x) (register_chars[(unsigned char) x])
#define is_mnemonic_char(x) (mnemonic_chars[(unsigned char) x])
#define is_whitespace_char(x) (((x) == ' ') || ((x) == '\t'))
#define is_space_char(x) ((x) == ' ')

#define FPU_PREFIX_CHAR 'f'
#define DSP_PREFIX_CHAR 'd'

/* Instruction mnemonics that need disambiguating with respect to prefixes.  */
#define FFB_INSN        "ffb"
#define DCACHE_INSN     "dcache"
#define DEFR_INSN       "defr"

#define FPU_DOUBLE_CHAR 'd'
#define FPU_PAIR_CHAR   'l'

#define DSP_DUAL_CHAR	'l'

#define END_OF_INSN     '\0'

/* Maximum length of a mnemonic including all suffixes.  */
#define MAX_MNEMONIC_LEN 16
/* Maximum length of a register name.  */
#define MAX_REG_LEN      17

/* Addressing modes must be enclosed with square brackets.  */
#define ADDR_BEGIN_CHAR '['
#define ADDR_END_CHAR   ']'
/* Immediates must be prefixed with a hash.  */
#define IMM_CHAR        '#'

#define COMMA           ','
#define PLUS            '+'
#define MINUS           '-'

/* Short units are those that can be encoded with 2 bits.  */
#define SHORT_UNITS     "D0, D1, A0 or A1"

static unsigned int mcpu_opt = CoreMeta12;
static unsigned int mfpu_opt = 0;
static unsigned int mdsp_opt = 0;

const char * md_shortopts = "m:";

struct option md_longopts[] =
{
  {NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof (md_longopts);

/* Parser hash tables.  */
static htab_t mnemonic_htab;
static htab_t reg_htab;
static htab_t dsp_reg_htab;
static htab_t dsp_tmpl_reg_htab[2];
static htab_t scond_htab;

#define GOT_NAME "__GLOBAL_OFFSET_TABLE__"
symbolS * GOT_symbol;

enum fpu_insn_width {
  FPU_WIDTH_SINGLE,
  FPU_WIDTH_DOUBLE,
  FPU_WIDTH_PAIR,
};

#define FPU_ACTION_ABS_CHAR   'a'
#define FPU_ACTION_INV_CHAR   'i'
#define FPU_ACTION_QUIET_CHAR 'q'
#define FPU_ACTION_ZERO_CHAR  'z'

#define FPU_ACTION_ABS        0x1
#define FPU_ACTION_INV        0x2
#define FPU_ACTION_QUIET      0x4
#define FPU_ACTION_ZERO       0x8

enum dsp_insn_width {
  DSP_WIDTH_SINGLE,
  DSP_WIDTH_DUAL,
};

#define DSP_ACTION_QR64_CHAR     'q'
#define DSP_ACTION_UMUL_CHAR     'u'
#define DSP_ACTION_ROUND_CHAR    'r'
#define DSP_ACTION_CLAMP9_CHAR   'g'
#define DSP_ACTION_CLAMP8_CHAR   'b'
#define DSP_ACTION_MOD_CHAR      'm'
#define DSP_ACTION_ACC_ZERO_CHAR 'z'
#define DSP_ACTION_ACC_ADD_CHAR  'p'
#define DSP_ACTION_ACC_SUB_CHAR  'n'
#define DSP_ACTION_OV_CHAR       'o'

#define DSP_ACTION_QR64          0x001
#define DSP_ACTION_UMUL          0x002
#define DSP_ACTION_ROUND         0x004
#define DSP_ACTION_CLAMP9        0x008
#define DSP_ACTION_CLAMP8        0x010
#define DSP_ACTION_MOD           0x020
#define DSP_ACTION_ACC_ZERO      0x040
#define DSP_ACTION_ACC_ADD       0x080
#define DSP_ACTION_ACC_SUB       0x100
#define DSP_ACTION_OV            0x200

#define DSP_DAOPPAME_8_CHAR    'b'
#define DSP_DAOPPAME_16_CHAR   'w'
#define DSP_DAOPPAME_TEMP_CHAR 't'
#define DSP_DAOPPAME_HIGH_CHAR 'h'

#define DSP_DAOPPAME_8         0x1
#define DSP_DAOPPAME_16        0x2
#define DSP_DAOPPAME_TEMP      0x4
#define DSP_DAOPPAME_HIGH      0x8

/* Structure holding information about a parsed instruction.  */
typedef struct {
  /* Instruction type.  */
  enum insn_type type;
  /* Split condition code. */
  enum scond_code scond;

  /* Instruction bits.  */
  unsigned int bits;
  /* Size of the instruction in bytes.  */
  size_t len;

  /* FPU instruction encoding.  */
  enum fpu_insn_width fpu_width;
  unsigned int fpu_action_flags;

  /* DSP instruction encoding. */
  enum dsp_insn_width dsp_width;
  unsigned int dsp_action_flags;
  unsigned int dsp_daoppame_flags;

  /* Reloc encoding information, maximum of one reloc per insn.  */
  enum bfd_reloc_code_real reloc_type;
  int reloc_pcrel;
  expressionS reloc_exp;
  unsigned int reloc_size;
} metag_insn;

/* Structure holding information about a parsed addressing mode.  */
typedef struct {
  const metag_reg *base_reg;
  const metag_reg *offset_reg;

  expressionS exp;

  enum bfd_reloc_code_real reloc_type;

  /* Whether we have an immediate or not.  */
  unsigned short immediate:1;
  /* Whether or not the base register is updated.  */
  unsigned short update:1;
  /* Whether the operation uses the address pre or post increment.  */
  unsigned short post_increment:1;
  /* Whether the immediate should be negated.  */
  unsigned short negate:1;
} metag_addr;

/* Linked list of possible parsers for this instruction.  */
typedef struct _insn_templates {
  const insn_template *template;
  struct _insn_templates *next;
} insn_templates;

/* Parse an instruction that takes no operands.  */
static const char *
parse_none (const char *line, metag_insn *insn,
	    const insn_template *template)
{
  insn->bits = template->meta_opcode;
  insn->len = 4;
  return line;
}

/* Return the next non-whitespace character in LINE or NULL.  */
static const char *
skip_whitespace (const char *line)
{
  const char *l = line;

  if (is_whitespace_char (*l))
    {
      l++;
    }

  return l;
}

/* Return the next non-space character in LINE or NULL.  */
static const char *
skip_space (const char *line)
{
  const char *l = line;

  if (is_space_char (*l))
    {
      l++;
    }

  return l;
}

/* Return the character after the current one in LINE if the current
   character is a comma, otherwise NULL.  */
static const char *
skip_comma (const char *line)
{
  const char *l = line;

  if (l == NULL || *l != COMMA)
    return NULL;

  l++;

  return l;
}

/* Return the metag_reg struct corresponding to NAME or NULL if no such
   register exists.  */
static const metag_reg *
parse_gp_reg (const char *name)
{
  const metag_reg *reg;
  metag_reg entry;

  entry.name = name;

  reg = (const metag_reg *) htab_find (reg_htab, &entry);

  return reg;
}

/* Parse a list of up to COUNT GP registers from LINE, returning the
   registers parsed in REGS and the number parsed in REGS_READ. Return
   a pointer to the next character or NULL.  */
static const char *
parse_gp_regs_list (const char *line, const metag_reg **regs, size_t count,
		    size_t *regs_read)
{
  const char *l = line;
  char reg_buf[MAX_REG_LEN];
  int seen_regs = 0;
  size_t i;

  for (i = 0; i < count; i++)
    {
      size_t len = 0;
      const char *next;

      next = l;

      if (i > 0)
	{
	  l = skip_comma (l);
	  if (l == NULL)
	    {
	      *regs_read = seen_regs;
	      return next;
	    }
	}

      while (is_register_char (*l))
	{
	  reg_buf[len] = *l;
	  l++;
	  len++;
	  if (!(len < MAX_REG_LEN))
	    return NULL;
	}

      reg_buf[len] = '\0';

      if (len)
	{
	  const metag_reg *reg = parse_gp_reg (reg_buf);

	  if (!reg)
	    {
	      *regs_read = seen_regs;
	      return next;
	    }
	  else
	    {
	      regs[i] = reg;
	      seen_regs++;
	    }
	}
      else
	{
	  *regs_read = seen_regs;
	  return next;
	}
    }

  *regs_read = seen_regs;
  return l;
}

/* Parse a list of exactly COUNT GP registers from LINE, returning the
   registers parsed in REGS. Return a pointer to the next character or NULL.  */
static const char *
parse_gp_regs (const char *line, const metag_reg **regs, size_t count)
{
  const char *l = line;
  size_t regs_read = 0;

  l = parse_gp_regs_list (l, regs, count, &regs_read);

  if (regs_read != count)
    return NULL;
  else
    return l;
}

/* Parse a list of exactly COUNT FPU registers from LINE, returning the
   registers parsed in REGS. Return a pointer to the next character or NULL.  */
static const char *
parse_fpu_regs (const char *line, const metag_reg **regs, size_t count)
{
  const char *l = line;
  size_t regs_read = 0;

  l = parse_gp_regs_list (l, regs, count, &regs_read);

  if (regs_read != count)
    return NULL;
  else
    {
      size_t i;
      for (i = 0; i < count; i++)
	{
	  if (regs[i]->unit != UNIT_FX)
	    return NULL;
	}
      return l;
    }
}

/* Return TRUE if REG1 and REG2 are in paired units.  */
static bfd_boolean
is_unit_pair (const metag_reg *reg1, const metag_reg *reg2)
{
  if ((reg1->unit == UNIT_A0 &&
       (reg2->unit == UNIT_A1)) ||
      (reg1->unit == UNIT_A1 &&
       (reg2->unit == UNIT_A0)) ||
      (reg1->unit == UNIT_D0 &&
       (reg2->unit == UNIT_D1)) ||
      (reg1->unit == UNIT_D1 &&
       (reg2->unit == UNIT_D0)))
    return TRUE;

  return FALSE;
}

/* Return TRUE if REG1 and REG2 form a register pair.  */
static bfd_boolean
is_reg_pair (const metag_reg *reg1, const metag_reg *reg2)
{
  if (reg1->unit == UNIT_FX &&
      reg2->unit == UNIT_FX &&
      reg2->no == reg1->no + 1)
    return TRUE;

  if (reg1->no != reg2->no)
    return FALSE;

  return is_unit_pair (reg1, reg2);
}

/* Parse a pair of GP registers from LINE, returning the registers parsed
   in REGS. Return a pointer to the next character or NULL.  */
static const char *
parse_pair_gp_regs (const char *line, const metag_reg **regs)
{
  const char *l = line;

  l = parse_gp_regs (line, regs, 2);

  if (l == NULL)
    {
      l = parse_gp_regs (line, regs, 1);

      if (l == NULL)
	return NULL;

      if (regs[0]->unit == UNIT_RD)
	return l;
      else
	return NULL;
    }

  if (is_reg_pair (regs[0], regs[1]))
    return l;

  return NULL;
}

/* Parse a unit-to-unit MOV instruction.  */
static const char *
parse_mov_u2u (const char *line, metag_insn *insn,
	       const insn_template *template)
{
  const metag_reg *regs[2];

  line = parse_gp_regs (line, regs, 2);

  if (line == NULL)
    return NULL;

  if (!mfpu_opt && (regs[0]->unit == UNIT_FX || regs[1]->unit == UNIT_FX))
    {
      as_bad (_("no floating point unit specified"));
      return NULL;
    }

  insn->bits = (template->meta_opcode |
		(regs[1]->no << 19) |
		(regs[0]->no << 14) |
		(regs[1]->unit << 10) |
		(regs[0]->unit << 5));
  insn->len = 4;
  return line;
}

/* Parse a MOV to port instruction.  */
static const char *
parse_mov_port (const char *line, metag_insn *insn,
		const insn_template *template)
{
  const char *l = line;
  unsigned int is_movl = MINOR_OPCODE (template->meta_opcode) == MOVL_MINOR;
  const metag_reg *dest_regs[2];
  const metag_reg *port_regs[1];

  if (is_movl)
    l = parse_gp_regs (l, dest_regs, 2);
  else
    l = parse_gp_regs (l, dest_regs, 1);

  if (l == NULL)
    return NULL;

  if (template->insn_type == INSN_FPU && dest_regs[0]->unit != UNIT_FX)
    return NULL;

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  l = parse_gp_regs (l, port_regs, 1);

  if (l == NULL)
    return NULL;

  if (port_regs[0]->unit != UNIT_RD ||
      port_regs[0]->no != 0)
    return NULL;

  if (is_movl)
    {
      if (!is_unit_pair (dest_regs[0], dest_regs[1]))
	return NULL;

      insn->bits = (template->meta_opcode |
		    (dest_regs[0]->no << 14) |
		    (dest_regs[1]->no << 9) |
		    ((dest_regs[0]->unit & SHORT_UNIT_MASK) << 5));
    }
  else
    insn->bits = (template->meta_opcode |
		  (dest_regs[0]->no << 14) |
		  (dest_regs[0]->unit << 5));

  insn->len = 4;
  return l;
}

/* Parse a MOVL to TTREC instruction.  */
static const char *
parse_movl_ttrec (const char *line, metag_insn *insn,
		  const insn_template *template)
{
  const char *l = line;
  const metag_reg *src_regs[2];
  const metag_reg *dest_regs[1];

  l = parse_gp_regs (l, dest_regs, 1);

  if (l == NULL)
    return NULL;

  if (dest_regs[0]->unit != UNIT_TT ||
      dest_regs[0]->no != 3)
    return NULL;

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  l = parse_gp_regs (l, src_regs, 2);

  if (l == NULL)
    return NULL;

  if (!is_unit_pair (src_regs[0], src_regs[1]))
    return NULL;

  insn->bits = (template->meta_opcode |
		(src_regs[0]->no << 19) |
		(src_regs[1]->no << 14) |
		((src_regs[0]->unit & SHORT_UNIT_MASK) << 7));

  insn->len = 4;
  return l;
}

/* Parse an incrementing or decrementing addressing mode.  */
static const char *
parse_addr_incr_op (const char *line, metag_addr *addr)
{
  const char *l = line;
  const char *ll;

  ll = l + 1;

  if (*l == PLUS &&
      *ll == PLUS)
    {
      addr->update = 1;
      ll++;
      return ll;
    }
  else if (*l == MINUS &&
	   *ll == MINUS)
    {
      addr->update = 1;
      addr->negate = 1;
      ll++;
      return ll;
    }
  return NULL;
}

/* Parse an pre-incrementing or pre-decrementing addressing mode.  */
static const char *
parse_addr_pre_incr_op (const char *line, metag_addr *addr)
{
  return parse_addr_incr_op (line, addr);
}

/* Parse an post-incrementing or post-decrementing addressing mode.  */
static const char *
parse_addr_post_incr_op (const char *line, metag_addr *addr)
{
  const char *l;

  l = parse_addr_incr_op (line, addr);

  if (l == NULL)
    return NULL;

  addr->post_increment = 1;

  return l;
}

/* Parse an infix addressing mode.  */
static const char *
parse_addr_op (const char *line, metag_addr *addr)
{
  const char *l = line;
  const char *ll;

  ll = l + 1;

  if (*l == PLUS)
    {
      if (*ll == PLUS)
	{
	  addr->update = 1;
	  ll++;
	  return ll;
	}
      l++;
      return l;
    }
  return NULL;
}

/* Parse the immediate portion of an addrssing mode.  */
static const char *
parse_imm_addr (const char *line, metag_addr *addr)
{
  const char *l = line;
  char *save_input_line_pointer;
  expressionS *exp = &addr->exp;

  /* Skip #.  */
  if (*l == '#')
    l++;
  else
    return NULL;

  save_input_line_pointer = input_line_pointer;
  input_line_pointer = (char *) l;

  expression (exp);

  l = input_line_pointer;
  input_line_pointer = save_input_line_pointer;

  if (exp->X_op == O_absent || exp->X_op == O_big)
    {
      return NULL;
    }
  else if (exp->X_op == O_constant)
    {
      return l;
    }
  else
    {
      if (exp->X_op == O_PIC_reloc &&
	  exp->X_md == BFD_RELOC_METAG_GETSET_GOT)
	{
	  exp->X_op = O_symbol;
	  addr->reloc_type = BFD_RELOC_METAG_GETSET_GOT;
	}
      else if (exp->X_op == O_PIC_reloc &&
	       exp->X_md == BFD_RELOC_METAG_TLS_IE)
	{
	  exp->X_op = O_symbol;
	  addr->reloc_type = BFD_RELOC_METAG_TLS_IE;
	}
      else if (exp->X_op == O_PIC_reloc &&
	  exp->X_md == BFD_RELOC_METAG_GOTOFF)
	{
	  exp->X_op = O_symbol;
	  addr->reloc_type = BFD_RELOC_METAG_GETSET_GOTOFF;
	}
      else
	addr->reloc_type = BFD_RELOC_METAG_GETSETOFF;
      return l;
    }
}

/* Parse the offset portion of an addressing mode (register or immediate).  */
static const char *
parse_addr_offset (const char *line, metag_addr *addr, int size)
{
  const char *l = line;
  const metag_reg *regs[1];

  if (*l == IMM_CHAR)
    {
      /* ++ is a valid operator in our addressing but not in an expr. Make
	 sure that the expression parser never sees it.  */
      char *ppp = strstr(l, "++");
      char ppch = '+';

      if (ppp)
	*ppp = '\0';

      l = parse_imm_addr (l, addr);

      if (ppp)
	*ppp = ppch;

      if (l == NULL)
	return NULL;

      if (addr->exp.X_add_number % size)
	{
	  as_bad (_("offset must be a multiple of %d"), size);
	  return NULL;
	}

      addr->immediate = 1;
      return l;
    }
  else
    {
      l = parse_gp_regs (l, regs, 1);

      if (l == NULL)
	return NULL;

      if (regs[0]->unit != addr->base_reg->unit)
	{
	  as_bad (_("offset and base must be from the same unit"));
	  return NULL;
	}

      addr->offset_reg = regs[0];
      return l;
    }
}

/* Parse an addressing mode.  */
static const char *
parse_addr (const char *line, metag_addr *addr, unsigned int size)
{
  const char *l = line;
  const char *ll;
  const metag_reg *regs[1];

  /* Skip opening square bracket.  */
  l++;

  ll = parse_addr_pre_incr_op (l, addr);

  if (ll != NULL)
    l = ll;

  l = parse_gp_regs (l, regs, 1);

  if (l == NULL)
    return NULL;

  addr->base_reg = regs[0];

  if (*l == ADDR_END_CHAR)
    {
      addr->exp.X_op = O_constant;
      addr->exp.X_add_symbol = NULL;
      addr->exp.X_op_symbol = NULL;
      if (addr->update == 1)
	{
	  /* We have a pre increment/decrement.  */
	  addr->exp.X_add_number = size;
	}
      else
	{
	  /* Simple register with no offset (0 immediate).  */
	  addr->exp.X_add_number = 0;
	}
      addr->immediate = 1;
      l++;
      return l;
    }

  /* We already had a pre increment/decrement.  */
  if (addr->update == 1)
    return NULL;

  ll = parse_addr_post_incr_op (l, addr);

  if (ll && *ll == ADDR_END_CHAR)
    {
      if (addr->update == 1)
	{
	  /* We have a post increment/decrement.  */
	  addr->exp.X_op = O_constant;
	  addr->exp.X_add_number = size;
	  addr->exp.X_add_symbol = NULL;
	  addr->exp.X_op_symbol = NULL;
	  addr->post_increment = 1;
	}
      addr->immediate = 1;
      ll++;
      return ll;
    }

  addr->post_increment = 0;

  l = parse_addr_op (l, addr);

  if (l == NULL)
    return NULL;

  l = parse_addr_offset (l, addr, size);

  if (l == NULL)
    return NULL;

  if (*l == ADDR_END_CHAR)
    {
      l++;
      return l;
    }

  /* We already had a pre increment/decrement. */
  if (addr->update == 1)
    return NULL;

  l = parse_addr_post_incr_op (l, addr);

  if (l == NULL)
    return NULL;

  if (*l == ADDR_END_CHAR)
    {
      l++;
      return l;
    }

  return NULL;
}

/* Parse a GET or pipeline MOV instruction.  */
static const char *
parse_get (const char *line, const metag_reg **regs, metag_addr *addr,
	   unsigned int size, bfd_boolean is_mov)
{
  const char *l = line;

  if (size == 8)
    {
      l = parse_pair_gp_regs (l, regs);

      if (l == NULL)
	  return NULL;
    }
  else
    {
      l = parse_gp_regs (l, regs, 1);

      if (l == NULL)
	{
	  if (!is_mov)
	    as_bad (_("invalid destination register"));
	  return NULL;
	}
    }

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  l = parse_addr (l, addr, size);

  if (l == NULL)
    {
      if (!is_mov)
	as_bad (_("invalid memory operand"));
      return NULL;
    }

  return l;
}

/* Parse a SET instruction.  */
static const char *
parse_set (const char *line, const metag_reg **regs, metag_addr *addr,
	   unsigned int size)
{
  const char *l = line;

  l = parse_addr (l, addr, size);

  if (l == NULL)
    {
	  as_bad (_("invalid memory operand"));
	  return NULL;
    }

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  if (size == 8)
    {
      const char *ll = l;

      ll = parse_pair_gp_regs (l, regs);

      if (ll == NULL)
	{
	  /* Maybe this is an RD register, which is 64 bits wide so needs no
	     pair.  */
	  l = parse_gp_regs (l, regs, 1);

	  if (l == NULL ||
	      regs[0]->unit != UNIT_RD)
	    {
	      return NULL;
	    }
	}
      else
	l = ll;
    }
  else
    {
      l = parse_gp_regs (l, regs, 1);

      if (l == NULL)
	{
	  as_bad (_("invalid source register"));
	  return NULL;
	}
    }

  return l;
}

/* Check a signed integer value can be represented in the given number
   of bits.  */
static bfd_boolean
within_signed_range (int value, unsigned int bits)
{
  int min_val = -(1 << (bits - 1));
  int max_val = (1 << (bits - 1)) - 1;
  return (value <= max_val) && (value >= min_val);
}

/* Check an unsigned integer value can be represented in the given number
   of bits.  */
static bfd_boolean
within_unsigned_range (unsigned int value, unsigned int bits)
{
  return value < (unsigned int)(1 << bits);
}

/* Return TRUE if UNIT can be expressed using a short code.  */
static bfd_boolean
is_short_unit (enum metag_unit unit)
{
  switch (unit)
    {
    case UNIT_A0:
    case UNIT_A1:
    case UNIT_D0:
    case UNIT_D1:
      return TRUE;
    default:
      return FALSE;
    }
}

/* Copy reloc data from ADDR to INSN.  */
static void
copy_addr_reloc (metag_insn *insn, metag_addr *addr)
{
  memcpy (&insn->reloc_exp, &addr->exp, sizeof(insn->reloc_exp));
  insn->reloc_type = addr->reloc_type;
}

/* Parse a GET, SET or pipeline MOV instruction.  */
static const char *
parse_get_set (const char *line, metag_insn *insn,
	       const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[2];
  metag_addr addr;
  unsigned int size = metag_get_set_size_bytes (template->meta_opcode);
  bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
  unsigned int reg_no;

  memset(&addr, 0, sizeof(addr));
  addr.reloc_type = BFD_RELOC_UNUSED;

  if (is_get)
    {
      bfd_boolean is_mov = strncmp (template->name, "MOV", 3) == 0;

      l = parse_get (l, regs, &addr, size, is_mov);

      if (l == NULL)
	return NULL;

      if (!(regs[0]->unit == UNIT_D0 ||
	    regs[0]->unit == UNIT_D1 ||
	    regs[0]->unit == UNIT_A0 ||
	    regs[0]->unit == UNIT_A1 ||
	    (regs[0]->unit == UNIT_RD && is_mov) ||
	    (regs[0]->unit == UNIT_CT && size == 4) ||
	    (regs[0]->unit == UNIT_PC && size == 4) ||
	    (regs[0]->unit == UNIT_TR && size == 4) ||
	    (regs[0]->unit == UNIT_TT && (size == 4 || size == 8)) ||
	    regs[0]->unit == UNIT_FX))
	{
	  as_bad (_("invalid destination unit"));
	  return NULL;
	}

      if (regs[0]->unit == UNIT_RD)
	{
	  if (regs[0]->no == 0)
	    {
	      as_bad (_("mov cannot use RD port as destination"));
	      return NULL;
	    }
	}

      reg_no = regs[0]->no;
    }
  else
    {
      l = parse_set (l, regs, &addr, size);

      if (l == NULL)
	return NULL;

      if (!(regs[0]->unit == UNIT_D0 ||
	    regs[0]->unit == UNIT_D1 ||
	    regs[0]->unit == UNIT_A0 ||
	    regs[0]->unit == UNIT_A1 ||
	    regs[0]->unit == UNIT_RD ||
	    (regs[0]->unit == UNIT_CT && size == 4) ||
	    (regs[0]->unit == UNIT_PC && size == 4) ||
	    (regs[0]->unit == UNIT_TR && size == 4) ||
	    (regs[0]->unit == UNIT_TT && (size == 4 || size == 8)) ||
	    regs[0]->unit == UNIT_FX))
	{
	  as_bad (_("invalid source unit"));
	  return NULL;
	}

      if (addr.immediate == 0 &&
	  (regs[0]->unit == addr.base_reg->unit ||
	   (size == 8 && is_unit_pair (regs[0], addr.base_reg))))
	{
	  as_bad (_("source and address units must not be shared for this addressing mode"));
	  return NULL;
	}

      if (regs[0]->unit == UNIT_RD)
	{
	  if (regs[0]->no != 0)
	    {
	      as_bad (_("set can only use RD port as source"));
	      return NULL;
	    }
	  reg_no = 16;
	}
      else
	reg_no = regs[0]->no;
    }

  insn->bits = (template->meta_opcode |
		(reg_no << 19) |
		(regs[0]->unit << 1));

  if (!is_short_unit (addr.base_reg->unit))
    {
      as_bad (_("base unit must be one of %s"), SHORT_UNITS);
      return NULL;
    }

  insn->bits |= ((addr.base_reg->no << 14) |
		 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));

  if (addr.immediate)
    {
      int offset = addr.exp.X_add_number;

      copy_addr_reloc (insn, &addr);

      if (addr.negate)
	offset = -offset;

      offset = offset / (int)size;

      if (!within_signed_range (offset, GET_SET_IMM_BITS))
	{
	  /* We already tried to encode as an extended GET/SET.  */
	  as_bad (_("offset value out of range"));
	  return NULL;
	}

      offset = offset & GET_SET_IMM_MASK;

      insn->bits |= (0x1 << 25);
      insn->bits |= (offset << 8);
    }
  else
    {
      insn->bits |= (addr.offset_reg->no << 9);
    }

  if (addr.update)
    insn->bits |= (0x1 << 7);

  if (addr.post_increment)
    insn->bits |= 0x1;

  insn->len = 4;
  return l;
}

/* Parse an extended GET or SET instruction.  */
static const char *
parse_get_set_ext (const char *line, metag_insn *insn,
		   const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[2];
  metag_addr addr;
  unsigned int size = metag_get_set_ext_size_bytes (template->meta_opcode);
  bfd_boolean is_get = MINOR_OPCODE (template->meta_opcode) == GET_EXT_MINOR;
  bfd_boolean is_mov = MINOR_OPCODE (template->meta_opcode) == MOV_EXT_MINOR;
  unsigned int reg_unit;

  memset(&addr, 0, sizeof(addr));
  addr.reloc_type = BFD_RELOC_UNUSED;

  if (is_get || is_mov)
    {
      l = parse_get (l, regs, &addr, size, is_mov);
    }
  else
    {
      l = parse_set (l, regs, &addr, size);
    }

  if (l == NULL)
    return NULL;

  /* Extended GET/SET does not support incrementing addressing.  */
  if (addr.update)
    return NULL;

  if (is_mov)
    {
      if (regs[0]->unit != UNIT_RD)
	{
	  as_bad (_("destination unit must be RD"));
	  return NULL;
	}
      reg_unit = 0;
    }
  else
    {
      if (!is_short_unit (regs[0]->unit))
	{
	  return NULL;
	}
      reg_unit = regs[0]->unit;
    }

  insn->bits = (template->meta_opcode |
		(regs[0]->no << 19) |
		((reg_unit & SHORT_UNIT_MASK) << 3));

  if (!is_short_unit (addr.base_reg->unit))
    {
      as_bad (_("base unit must be one of %s"), SHORT_UNITS);
      return NULL;
    }

  if (addr.base_reg->no > 1)
    {
      return NULL;
    }

  insn->bits |= ((addr.base_reg->no & EXT_BASE_REG_MASK) |
		 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));

  if (addr.immediate)
    {
      int offset = addr.exp.X_add_number;

      copy_addr_reloc (insn, &addr);

      if (addr.negate)
	offset = -offset;

      offset = offset / (int)size;

      if (!within_signed_range (offset, GET_SET_EXT_IMM_BITS))
	{
	  /* Parsing as a standard GET/SET provides a smaller offset.  */
	  as_bad (_("offset value out of range"));
	  return NULL;
	}

      offset = offset & GET_SET_EXT_IMM_MASK;

      insn->bits |= (offset << 7);
    }
  else
    {
      return NULL;
    }

  insn->len = 4;
  return l;
}

/* Parse an MGET or MSET instruction addressing mode.  */
static const char *
parse_mget_mset_addr (const char *line, metag_addr *addr)
{
  const char *l = line;
  const char *ll;
  const metag_reg *regs[1];

  /* Skip opening square bracket.  */
  l++;

  l = parse_gp_regs (l, regs, 1);

  if (l == NULL)
    return NULL;

  addr->base_reg = regs[0];

  ll = parse_addr_post_incr_op (l, addr);

  if (ll != NULL)
    l = ll;

  if (addr->negate == 1)
    return NULL;

  if (*l == ADDR_END_CHAR)
    {
      l++;
      return l;
    }

  return NULL;
}

/* Parse an MGET instruction.  */
static const char *
parse_mget (const char *line, const metag_reg **regs, metag_addr *addr,
	    size_t *regs_read)
{
  const char *l = line;

  l = parse_gp_regs_list (l, regs, MGET_MSET_MAX_REGS, regs_read);

  if (l == NULL ||
      *regs_read == 0)
    {
      as_bad (_("invalid destination register list"));
      return NULL;
    }

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  l = parse_mget_mset_addr (l, addr);

  if (l == NULL)
    {
	  as_bad (_("invalid memory operand"));
	  return NULL;
    }

  return l;
}

/* Parse an MSET instruction.  */
static const char *
parse_mset (const char *line, const metag_reg **regs, metag_addr *addr,
	    size_t *regs_read)
{
  const char *l = line;

  l = parse_mget_mset_addr (l, addr);

  if (l == NULL)
    {
	  as_bad (_("invalid memory operand"));
	  return NULL;
    }

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  l = parse_gp_regs_list (l, regs, MGET_MSET_MAX_REGS, regs_read);

  if (l == NULL ||
      *regs_read == 0)
    {
      as_bad (_("invalid source register list"));
      return NULL;
    }

  return l;
}

/* Take a register list REGS of size REGS_READ and convert it into an
   rmask value if possible. Return the rmask value in RMASK and the
   lowest numbered register in LOWEST_REG. Return TRUE if the conversion
   was successful.  */
static bfd_boolean
check_rmask (const metag_reg **regs, size_t regs_read, bfd_boolean is_fpu,
	     bfd_boolean is_64bit, unsigned int *lowest_reg,
	     unsigned int *rmask)
{
  unsigned int reg_unit = regs[0]->unit;
  size_t i;

  for (i = 0; i < regs_read; i++)
    {
      if (is_fpu)
	{
	  if (is_64bit && regs[i]->no % 2)
	    {
	      as_bad (_("register list must be even numbered"));
	      return FALSE;
	    }
	}
      else if (regs[i]->unit != reg_unit)
	{
	  as_bad (_("register list must be from the same unit"));
	  return FALSE;
	}

      if (regs[i]->no < *lowest_reg)
	*lowest_reg = regs[i]->no;
    }

  for (i = 0; i < regs_read; i++)
    {
      unsigned int next_bit, next_reg;
      if (regs[i]->no == *lowest_reg)
	continue;

      if (is_fpu && is_64bit)
	next_reg = ((regs[i]->no / 2) - ((*lowest_reg / 2) + 1));
      else
	next_reg = (regs[i]->no - (*lowest_reg + 1));

      next_bit = (1 << next_reg);

      if (*rmask & next_bit)
	{
	  as_bad (_("register list must not contain duplicates"));
	  return FALSE;
	}

      *rmask |= next_bit;
    }

  return TRUE;
}

/* Parse an MGET or MSET instruction.  */
static const char *
parse_mget_mset (const char *line, metag_insn *insn,
		 const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[MGET_MSET_MAX_REGS];
  metag_addr addr;
  bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
  bfd_boolean is_fpu = (MINOR_OPCODE (template->meta_opcode) & 0x6) == 0x6;
  bfd_boolean is_64bit = (MINOR_OPCODE (template->meta_opcode) & 0x1) == 0x1;
  size_t regs_read = 0;
  unsigned int rmask = 0, reg_unit = 0, lowest_reg = 0xffffffff;

  memset(&addr, 0, sizeof(addr));
  addr.reloc_type = BFD_RELOC_UNUSED;

  if (is_get)
    {
      l = parse_mget (l, regs, &addr, &regs_read);
    }
  else
    {
      l = parse_mset (l, regs, &addr, &regs_read);
    }

  if (l == NULL)
    return NULL;

  if (!check_rmask (regs, regs_read, is_fpu, is_64bit, &lowest_reg, &rmask))
    return NULL;

  reg_unit = regs[0]->unit;

  if (is_fpu)
    {
      if (reg_unit != UNIT_FX)
	return NULL;

      reg_unit = 0;
    }
  else if (reg_unit == UNIT_FX)
    return NULL;

  insn->bits = (template->meta_opcode |
		(lowest_reg << 19) |
		((reg_unit & SHORT_UNIT_MASK) << 3));

  if (!is_short_unit (addr.base_reg->unit))
    {
      as_bad (_("base unit must be one of %s"), SHORT_UNITS);
      return NULL;
    }

  insn->bits |= ((addr.base_reg->no << 14) |
		 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));

  insn->bits |= (rmask & RMASK_MASK) << 7;

  insn->len = 4;
  return l;
}

/* Parse a list of registers for MMOV pipeline prime.  */
static const char *
parse_mmov_prime_list (const char *line, const metag_reg **regs,
		       unsigned int *rmask)
{
  const char *l = line;
  const metag_reg *ra_regs[MMOV_MAX_REGS];
  size_t regs_read = 0, i;
  unsigned int mask = 0;

  l = parse_gp_regs_list (l, regs, 1, &regs_read);

  /* First register must be a port. */
  if (l == NULL || regs[0]->unit != UNIT_RD)
    return NULL;

  l = skip_comma (l);

  if (l == NULL)
    return NULL;

  l = parse_gp_regs_list (l, ra_regs, MMOV_MAX_REGS, &regs_read);

  if (l == NULL)
    return NULL;

  /* Check remaining registers match the first.

     Note that we also accept RA (0x10) as input for the remaining registers.
     Whilst this doesn't represent the instruction in any way we're stuck
     with it because the embedded assembler accepts it.  */
  for (i = 0; i < regs_read; i++)
    {
      if (ra_regs[i]->unit != UNIT_RD ||
	  (ra_regs[i]->no != 0x10 && ra_regs[i]->no != regs[0]->no))
	return NULL;

      mask = (mask << 1) | 0x1;
    }

  *rmask = mask;

  return l;
}

/* Parse a MMOV instruction.  */
static const char *
parse_mmov (const char *line, metag_insn *insn,
	    const insn_template *template)
{
  const char *l = line;
  unsigned int is_fpu = template->insn_type == INSN_FPU;
  unsigned int is_prime = ((MINOR_OPCODE (template->meta_opcode) & 0x2) &&
			   !is_fpu);
  unsigned int is_64bit = MINOR_OPCODE (template->meta_opcode) & 0x1;
  unsigned int rmask = 0;

  if (is_prime)
    {
      const metag_reg *reg;
      metag_addr addr;

      memset (&addr, 0, sizeof(addr));

      l = parse_mmov_prime_list (l, &reg, &rmask);

      if (l == NULL)
	return NULL;

      l = skip_comma (l);

      if (l == NULL)
	return NULL;

      l = parse_mget_mset_addr (l, &addr);

      if (l == NULL)
	{
	  as_bad (_("invalid memory operand"));
	  return NULL;
	}

      insn->bits = (template->meta_opcode |
		    (reg->no << 19) |
		    (addr.base_reg->no << 14) |
		    ((rmask & RMASK_MASK) << 7) |
		    ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));
    }
  else
    {
      const metag_reg *regs[MMOV_MAX_REGS + 1];
      unsigned int lowest_reg = 0xffffffff;
      size_t regs_read = 0;

      l = parse_gp_regs_list (l, regs, MMOV_MAX_REGS + 1, &regs_read);

      if (l == NULL || regs_read == 0)
	return NULL;

      if (!is_short_unit (regs[0]->unit) &&
	  !(is_fpu && regs[0]->unit == UNIT_FX))
	{
	  return NULL;
	}

      if (!(regs[regs_read-1]->unit == UNIT_RD &&
	    regs[regs_read-1]->no == 0))
	{
	  return NULL;
	}

      if (!check_rmask (regs, regs_read - 1, is_fpu, is_64bit, &lowest_reg,
			&rmask))
	return NULL;

      if (is_fpu)
	{
	  insn->bits = (template->meta_opcode |
			(regs[0]->no << 14) |
			((rmask & RMASK_MASK) << 7));
	}
      else
	{
	  insn->bits = (template->meta_opcode |
			(regs[0]->no << 19) |
			((rmask & RMASK_MASK) << 7) |
			((regs[0]->unit & SHORT_UNIT_MASK) << 3));
	}
    }

  insn->len = 4;
  return l;
}

/* Parse an immediate constant.  */
static const char *
parse_imm_constant (const char *line, metag_insn *insn, int *value)
{
  const char *l = line;
  char *save_input_line_pointer;
  expressionS *exp = &insn->reloc_exp;

  /* Skip #. */
  if (*l == '#')
    l++;
  else
    return NULL;

  save_input_line_pointer = input_line_pointer;
  input_line_pointer = (char *) l;

  expression (exp);

  l = input_line_pointer;
  input_line_pointer = save_input_line_pointer;

  if (exp->X_op == O_constant)
    {
      *value = exp->X_add_number;

      return l;
    }
  else
    {
      return NULL;
    }
}

/* Parse an MDRD instruction.  */
static const char *
parse_mdrd (const char *line, metag_insn *insn,
	    const insn_template *template)
{
  const char *l = line;
  unsigned int rmask = 0;
  int value = 0, i;

  l = parse_imm_constant (l, insn, &value);

  if (l == NULL)
    return NULL;

  if (value < 1 || value > 8)
    {
      as_bad (_("MDRD value must be between 1 and 8"));
      return NULL;
    }

  for (i = 1; i < value; i++)
    {
      rmask <<= 1;
      rmask |= 1;
    }

  insn->bits = (template->meta_opcode |
		(rmask << 7));

  insn->len = 4;
  return l;
}

/* Parse a conditional SET instruction.  */
static const char *
parse_cond_set (const char *line, metag_insn *insn,
		const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[2];
  metag_addr addr;
  unsigned int size = metag_cond_set_size_bytes (template->meta_opcode);
  unsigned int reg_no;

  memset(&addr, 0, sizeof(addr));
  addr.reloc_type = BFD_RELOC_UNUSED;

  l = parse_set (l, regs, &addr, size);

  if (l == NULL)
    return NULL;

  if (regs[0]->unit == UNIT_RD)
    {
      if (regs[0]->no != 0)
	{
	  as_bad (_("set can only use RD port as source"));
	  return NULL;
	}
      reg_no = 16;
    }
  else
    reg_no = regs[0]->no;

  if (addr.update)
    return NULL;

  if (!(addr.immediate &&
	addr.exp.X_add_number == 0))
    return NULL;

  insn->bits = (template->meta_opcode |
		(reg_no << 19) |
		(regs[0]->unit << 10));

  if (!is_short_unit (addr.base_reg->unit))
    {
      as_bad (_("base unit must be one of %s"), SHORT_UNITS);
      return NULL;
    }

  insn->bits |= ((addr.base_reg->no << 14) |
		 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));

  insn->len = 4;
  return l;
}

/* Parse an XFR instruction.  */
static const char *
parse_xfr (const char *line, metag_insn *insn,
	   const insn_template *template)
{
  const char *l = line;
  metag_addr dest_addr, src_addr;
  unsigned int size = 4;

  memset(&dest_addr, 0, sizeof(dest_addr));
  memset(&src_addr, 0, sizeof(src_addr));
  dest_addr.reloc_type = BFD_RELOC_UNUSED;
  src_addr.reloc_type = BFD_RELOC_UNUSED;

  l = parse_addr (l, &dest_addr, size);

  if (l == NULL ||
      dest_addr.immediate == 1)
    {
	  as_bad (_("invalid destination memory operand"));
	  return NULL;
    }

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  l = parse_addr (l, &src_addr, size);

  if (l == NULL ||
      src_addr.immediate == 1)
    {
	  as_bad (_("invalid source memory operand"));
	  return NULL;
    }

  if (!is_short_unit (dest_addr.base_reg->unit) ||
      !is_short_unit (src_addr.base_reg->unit))
    {
      as_bad (_("address units must be one of %s"), SHORT_UNITS);
      return NULL;
    }

  if ((dest_addr.base_reg->unit != dest_addr.offset_reg->unit) ||
      (src_addr.base_reg->unit != src_addr.offset_reg->unit))
    {
      as_bad (_("base and offset must be from the same unit"));
      return NULL;
    }

  if (dest_addr.update == 1 &&
      src_addr.update == 1 &&
      dest_addr.post_increment != src_addr.post_increment)
    {
      as_bad (_("source and destination increment mode must agree"));
      return NULL;
    }

  insn->bits = (template->meta_opcode |
		(src_addr.base_reg->no << 19) |
		(src_addr.offset_reg->no << 14) |
		((src_addr.base_reg->unit & SHORT_UNIT_MASK) << 2));

  insn->bits |= ((dest_addr.base_reg->no << 9) |
		 (dest_addr.offset_reg->no << 4) |
		 ((dest_addr.base_reg->unit & SHORT_UNIT_MASK)));

  if (dest_addr.update == 1)
    insn->bits |= (1 << 26);

  if (src_addr.update == 1)
    insn->bits |= (1 << 27);

  if (dest_addr.post_increment == 1 ||
      src_addr.post_increment == 1)
    insn->bits |= (1 << 24);

  insn->len = 4;
  return l;
}

/* Parse an 8bit immediate value.  */
static const char *
parse_imm8 (const char *line, metag_insn *insn, int *value)
{
  const char *l = line;
  char *save_input_line_pointer;
  expressionS *exp = &insn->reloc_exp;

  /* Skip #. */
  if (*l == '#')
    l++;
  else
    return NULL;

  save_input_line_pointer = input_line_pointer;
  input_line_pointer = (char *) l;

  expression (exp);

  l = input_line_pointer;
  input_line_pointer = save_input_line_pointer;

  if (exp->X_op == O_absent || exp->X_op == O_big)
    {
      return NULL;
    }
  else if (exp->X_op == O_constant)
    {
      *value = exp->X_add_number;
    }
  else
    {
      insn->reloc_type = BFD_RELOC_METAG_REL8;
      insn->reloc_pcrel = 0;
    }

  return l;
}

/* Parse a 16bit immediate value.  */
static const char *
parse_imm16 (const char *line, metag_insn *insn, int *value)
{
  const char *l = line;
  char *save_input_line_pointer;
  expressionS *exp = &insn->reloc_exp;
  bfd_boolean is_hi = FALSE;
  bfd_boolean is_lo = FALSE;

  /* Skip #. */
  if (*l == '#')
    l++;
  else
    return NULL;

  if (strncasecmp (l, "HI", 2) == 0)
    {
      is_hi = TRUE;
      l += 2;
    }
  else if (strncasecmp (l, "LO", 2) == 0)
    {
      is_lo = TRUE;
      l += 2;
    }

  save_input_line_pointer = input_line_pointer;
  input_line_pointer = (char *) l;

  expression (exp);

  l = input_line_pointer;
  input_line_pointer = save_input_line_pointer;

  if (exp->X_op == O_absent || exp->X_op == O_big)
    {
      return NULL;
    }
  else if (exp->X_op == O_constant)
    {
      if (is_hi)
	*value = (exp->X_add_number >> 16) & IMM16_MASK;
      else if (is_lo)
	*value = exp->X_add_number & IMM16_MASK;
      else
	*value = exp->X_add_number;
    }
  else
    {
      if (exp->X_op == O_PIC_reloc)
	{
	  exp->X_op = O_symbol;

	  if (exp->X_md == BFD_RELOC_METAG_GOTOFF)
	    {
	      if (is_hi)
		insn->reloc_type = BFD_RELOC_METAG_HI16_GOTOFF;
	      else if (is_lo)
		insn->reloc_type = BFD_RELOC_METAG_LO16_GOTOFF;
	      else
		return NULL;
	    }
	  else if (exp->X_md == BFD_RELOC_METAG_PLT)
	    {
	      if (is_hi)
		insn->reloc_type = BFD_RELOC_METAG_HI16_PLT;
	      else if (is_lo)
		insn->reloc_type = BFD_RELOC_METAG_LO16_PLT;
	      else
		return NULL;
	    }
	  else if (exp->X_md == BFD_RELOC_METAG_TLS_LDO)
	    {
	      if (is_hi)
		insn->reloc_type = BFD_RELOC_METAG_TLS_LDO_HI16;
	      else if (is_lo)
		insn->reloc_type = BFD_RELOC_METAG_TLS_LDO_LO16;
	      else
		return NULL;
	    }
	  else if (exp->X_md == BFD_RELOC_METAG_TLS_IENONPIC)
	    {
	      if (is_hi)
		insn->reloc_type = BFD_RELOC_METAG_TLS_IENONPIC_HI16;
	      else if (is_lo)
		insn->reloc_type = BFD_RELOC_METAG_TLS_IENONPIC_LO16;
	      else
		return NULL;
	    }
	  else if (exp->X_md == BFD_RELOC_METAG_TLS_LE)
	    {
	      if (is_hi)
		insn->reloc_type = BFD_RELOC_METAG_TLS_LE_HI16;
	      else if (is_lo)
		insn->reloc_type = BFD_RELOC_METAG_TLS_LE_LO16;
	      else
		return NULL;
	    }
	  else if (exp->X_md == BFD_RELOC_METAG_TLS_GD ||
		   exp->X_md == BFD_RELOC_METAG_TLS_LDM)
	    insn->reloc_type = exp->X_md;
	}
      else
	{
	  if (exp->X_op == O_symbol && exp->X_add_symbol == GOT_symbol)
	    {
	      if (is_hi)
		insn->reloc_type = BFD_RELOC_METAG_HI16_GOTPC;
	      else if (is_lo)
		insn->reloc_type = BFD_RELOC_METAG_LO16_GOTPC;
	      else
		return NULL;
	    }
	  else
	    {
	      if (is_hi)
		insn->reloc_type = BFD_RELOC_METAG_HIADDR16;
	      else if (is_lo)
		insn->reloc_type = BFD_RELOC_METAG_LOADDR16;
	      else
		insn->reloc_type = BFD_RELOC_METAG_REL16;
	    }
	}

      insn->reloc_pcrel = 0;
    }

  return l;
}

/* Parse a MOV to control unit instruction.  */
static const char *
parse_mov_ct (const char *line, metag_insn *insn,
	      const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[1];
  unsigned int top = template->meta_opcode & 0x1;
  unsigned int is_trace = (template->meta_opcode >> 2) & 0x1;
  unsigned int sign_extend = 0;
  int value = 0;

  l = parse_gp_regs (l, regs, 1);

  if (l == NULL)
    return NULL;

  if (is_trace)
    {
      if (regs[0]->unit != UNIT_TT)
	return NULL;
    }
  else
    {
      if (regs[0]->unit != UNIT_CT)
	return NULL;
    }

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  l = parse_imm16 (l, insn, &value);

  if (l == NULL)
    return NULL;

  if (value < 0)
    sign_extend = 1;

  insn->bits = (template->meta_opcode |
		(regs[0]->no << 19) |
		((value & IMM16_MASK) << 3));

  if (sign_extend == 1 && top == 0)
    insn->bits |= (1 << 1);

  insn->len = 4;
  return l;
}

/* Parse a SWAP instruction.  */
static const char *
parse_swap (const char *line, metag_insn *insn,
	    const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[2];

  l = parse_gp_regs (l, regs, 2);

  if (l == NULL)
    return NULL;

  /* PC.r | CT.r | TR.r | TT.r are treated as if they are a single unit.  */
  switch (regs[0]->unit)
    {
    case UNIT_PC:
    case UNIT_CT:
    case UNIT_TR:
    case UNIT_TT:
      if (regs[1]->unit == UNIT_PC
	  || regs[1]->unit == UNIT_CT
	  || regs[1]->unit == UNIT_TR
	  || regs[1]->unit == UNIT_TT)
	{
	  as_bad (_("PC, CT, TR and TT are treated as if they are a single unit but operands must be in different units"));
	  return NULL;
	}

    default:
      /* Registers must be in different units.  */
      if (regs[0]->unit == regs[1]->unit)
	{
	  as_bad (_("source and destination register must be in different units"));
	  return NULL;
	}
      break;
    }

  insn->bits = (template->meta_opcode
		| (regs[1]->no << 19)
		| (regs[0]->no << 14)
		| (regs[1]->unit << 10)
		| (regs[0]->unit << 5));

  insn->len = 4;
  return l;
}

/* Parse a JUMP instruction.  */
static const char *
parse_jump (const char *line, metag_insn *insn,
	    const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[1];
  int value = 0;

  l = parse_gp_regs (l, regs, 1);

  if (l == NULL)
    return NULL;

  if (!is_short_unit (regs[0]->unit))
    {
      as_bad (_("register unit must be one of %s"), SHORT_UNITS);
      return FALSE;
    }

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  l = parse_imm16 (l, insn, &value);

  if (l == NULL)
    return NULL;

  insn->bits = (template->meta_opcode |
		(regs[0]->no << 19) |
		(regs[0]->unit & SHORT_UNIT_MASK) |
		((value & IMM16_MASK) << 3));

  insn->len = 4;
  return l;
}

/* Parse a 19bit immediate value.  */
static const char *
parse_imm19 (const char *line, metag_insn *insn, int *value)
{
  const char *l = line;
  char *save_input_line_pointer;
  expressionS *exp = &insn->reloc_exp;

  /* Skip #.  */
  if (*l == '#')
    l++;

  save_input_line_pointer = input_line_pointer;
  input_line_pointer = (char *) l;

  expression (exp);

  l = input_line_pointer;
  input_line_pointer = save_input_line_pointer;

  if (exp->X_op == O_absent || exp->X_op == O_big)
    {
      return NULL;
    }
  else if (exp->X_op == O_constant)
    {
      *value = exp->X_add_number;
    }
  else
    {
      if (exp->X_op == O_PIC_reloc)
	{
	  exp->X_op = O_symbol;

	  if (exp->X_md == BFD_RELOC_METAG_PLT)
	    insn->reloc_type = BFD_RELOC_METAG_RELBRANCH_PLT;
	  else
	    return NULL;
	}
      else
	insn->reloc_type = BFD_RELOC_METAG_RELBRANCH;
      insn->reloc_pcrel = 1;
    }

  return l;
}

/* Parse a CALLR instruction.  */
static const char *
parse_callr (const char *line, metag_insn *insn,
	     const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[1];
  int value = 0;

  l = parse_gp_regs (l, regs, 1);

  if (l == NULL)
    return NULL;

  if (!is_short_unit (regs[0]->unit))
    {
      as_bad (_("link register unit must be one of %s"), SHORT_UNITS);
      return NULL;
    }

  if (regs[0]->no & ~CALLR_REG_MASK)
    {
      as_bad (_("link register must be in a low numbered register"));
      return NULL;
    }

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  l = parse_imm19 (l, insn, &value);

  if (l == NULL)
    return NULL;

  if (!within_signed_range (value / 4, IMM19_BITS))
    {
      as_bad (_("target out of range"));
      return NULL;
    }

  insn->bits = (template->meta_opcode |
		(regs[0]->no & CALLR_REG_MASK) |
		((regs[0]->unit & SHORT_UNIT_MASK) << 3) |
		((value & IMM19_MASK) << 5));

  insn->len = 4;
  return l;
}

/* Return the value for the register field if we apply the O2R modifier
   to operand 2 REG, combined with UNIT_BIT derived from the destination
   register or source1. Uses address unit O2R if IS_ADDR is set.  */
static int
lookup_o2r (unsigned int is_addr, unsigned int unit_bit, const metag_reg *reg)
{
  if (reg->no & ~O2R_REG_MASK)
    return -1;

  if (is_addr)
    {
      if (unit_bit)
	{
	  switch (reg->unit)
	    {
	    case UNIT_D1:
	      return reg->no;
	    case UNIT_D0:
	      return (1 << 3) | reg->no;
	    case UNIT_RD:
	      return (2 << 3) | reg->no;
	    case UNIT_A0:
	      return (3 << 3) | reg->no;
	    default:
	      return -1;
	    }
	}
      else
	{
	  switch (reg->unit)
	    {
	    case UNIT_A1:
	      return reg->no;
	    case UNIT_D0:
	      return (1 << 3) | reg->no;
	    case UNIT_RD:
	      return (2 << 3) | reg->no;
	    case UNIT_D1:
	      return (3 << 3) | reg->no;
	    default:
	      return -1;
	    }
	}
    }
  else
    {
      if (unit_bit)
	{
	  switch (reg->unit)
	    {
	    case UNIT_A1:
	      return reg->no;
	    case UNIT_D0:
	      return (1 << 3) | reg->no;
	    case UNIT_RD:
	      return (2 << 3) | reg->no;
	    case UNIT_A0:
	      return (3 << 3) | reg->no;
	    default:
	      return -1;
	    }
	}
      else
	{
	  switch (reg->unit)
	    {
	    case UNIT_A1:
	      return reg->no;
	    case UNIT_D1:
	      return (1 << 3) | reg->no;
	    case UNIT_RD:
	      return (2 << 3) | reg->no;
	    case UNIT_A0:
	      return (3 << 3) | reg->no;
	    default:
	      return -1;
	    }
	}
    }
}

/* Parse GP ALU instruction.  */
static const char *
parse_alu (const char *line, metag_insn *insn,
	   const insn_template *template)
{
  const char *l = line;
  const metag_reg *dest_regs[1];
  const metag_reg *src_regs[2];
  int value = 0;
  unsigned int o1z = 0;
  unsigned int imm = (template->meta_opcode >> 25) & 0x1;
  unsigned int cond = (template->meta_opcode >> 26) & 0x1;
  unsigned int ca = (template->meta_opcode >> 5) & 0x1;
  unsigned int top = template->meta_opcode & 0x1;
  unsigned int sign_extend = 0;
  unsigned int is_addr_op = MAJOR_OPCODE (template->meta_opcode) == OPC_ADDR;
  unsigned int is_mul = MAJOR_OPCODE (template->meta_opcode) == OPC_MUL;
  unsigned int unit_bit = 0;
  bfd_boolean is_quickrot = template->arg_type & GP_ARGS_QR;

  l = parse_gp_regs (l, dest_regs, 1);

  if (l == NULL)
    return NULL;

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  if (is_addr_op)
    {
      if (dest_regs[0]->unit == UNIT_A0)
	unit_bit = 0;
      else if (dest_regs[0]->unit == UNIT_A1)
	unit_bit = 1;
    }
  else
    {
      if (dest_regs[0]->unit == UNIT_D0)
	unit_bit = 0;
      else if (dest_regs[0]->unit == UNIT_D1)
	unit_bit = 1;
    }

  if ((MAJOR_OPCODE (template->meta_opcode) == OPC_ADDR ||
      MAJOR_OPCODE (template->meta_opcode) == OPC_ADD ||
       MAJOR_OPCODE (template->meta_opcode) == OPC_SUB) &&
      ((template->meta_opcode >> 2) & 0x1))
    o1z = 1;

  if (imm)
    {
      if (!cond)
	{
	  if (is_addr_op)
	    {
	      if (dest_regs[0]->unit == UNIT_A0)
		unit_bit = 0;
	      else if (dest_regs[0]->unit == UNIT_A1)
		unit_bit = 1;
	      else
		return NULL;
	    }
	  else
	    {
	      if (dest_regs[0]->unit == UNIT_D0)
		unit_bit = 0;
	      else if (dest_regs[0]->unit == UNIT_D1)
		unit_bit = 1;
	      else
		return NULL;
	    }
	}

      if (cond)
	{
	  l = parse_gp_regs (l, src_regs, 1);

	  if (l == NULL)
	    return NULL;

	  l = skip_comma (l);

	  if (l == NULL ||
	      *l == END_OF_INSN)
	    return NULL;

	  if (is_addr_op)
	    {
	      if (src_regs[0]->unit == UNIT_A0)
		unit_bit = 0;
	      else if (src_regs[0]->unit == UNIT_A1)
		unit_bit = 1;
	      else
		return NULL;
	    }
	  else
	    {
	      if (src_regs[0]->unit == UNIT_D0)
		unit_bit = 0;
	      else if (src_regs[0]->unit == UNIT_D1)
		unit_bit = 1;
	      else
		return NULL;
	    }

	  if (src_regs[0]->unit != dest_regs[0]->unit && !ca)
	    return NULL;

	  l = parse_imm8 (l, insn, &value);

	  if (l == NULL)
	    return NULL;

	  if (!within_unsigned_range (value, IMM8_BITS))
	    return NULL;

	  insn->bits = (template->meta_opcode |
			(dest_regs[0]->no << 19) |
			(src_regs[0]->no << 14) |
			((value & IMM8_MASK) << 6));

	  if (ca)
	    {
	      if (is_addr_op)
		{
		  if (src_regs[0]->unit == UNIT_A0)
		    unit_bit = 0;
		  else if (src_regs[0]->unit == UNIT_A1)
		    unit_bit = 1;
		  else
		    return NULL;
		}
	      else
		{
		  if (src_regs[0]->unit == UNIT_D0)
		    unit_bit = 0;
		  else if (src_regs[0]->unit == UNIT_D1)
		    unit_bit = 1;
		  else
		    return NULL;
		}

	      insn->bits |= dest_regs[0]->unit << 1;
	    }
	}
      else if (o1z)
	{
	  l = parse_imm16 (l, insn, &value);

	  if (l == NULL)
	    return NULL;

	  if (value < 0)
	    {
	      if (!within_signed_range (value, IMM16_BITS))
		{
		  as_bad (_("immediate out of range"));
		  return NULL;
		}
	      sign_extend = 1;
	    }
	  else
	    {
	      if (!within_unsigned_range (value, IMM16_BITS))
		{
		  as_bad (_("immediate out of range"));
		  return NULL;
		}
	    }

	  insn->bits = (template->meta_opcode |
			(dest_regs[0]->no << 19) |
			((value & IMM16_MASK) << 3));
	}
      else
	{
	  l = parse_gp_regs (l, src_regs, 1);

	  if (l == NULL)
	    return NULL;

	  if (!(src_regs[0]->unit == dest_regs[0]->unit))
	    return NULL;

	  /* CPC is valid for address ops. */
	  if (src_regs[0]->no != dest_regs[0]->no &&
	      !(is_addr_op && src_regs[0]->no == 0x10))
	    return NULL;

	  l = skip_comma (l);

	  if (l == NULL ||
	      *l == END_OF_INSN)
	    return NULL;

	  l = parse_imm16 (l, insn, &value);

	  if (l == NULL)
	    return NULL;

	  if (value < 0)
	    {
	      if (!within_signed_range (value, IMM16_BITS))
		{
		  as_bad (_("immediate out of range"));
		  return NULL;
		}
	      sign_extend = 1;
	    }
	  else
	    {
	      if (!within_unsigned_range (value, IMM16_BITS))
		{
		  as_bad (_("immediate out of range"));
		  return NULL;
		}
	    }

	  insn->bits = (template->meta_opcode |
			(dest_regs[0]->no << 19) |
			(src_regs[0]->no << 19) |
			((value & IMM16_MASK) << 3));
	}
    }
  else
    {
      unsigned int o2r = 0;
      int rs2;

      if (cond || !o1z)
	l = parse_gp_regs (l, src_regs, 2);
      else
	l = parse_gp_regs (l, src_regs, 1);

      if (l == NULL)
	return NULL;

      if (cond || !o1z)
	{
	  if (is_addr_op)
	    {
	      if (src_regs[0]->unit == UNIT_A0)
		unit_bit = 0;
	      else if (src_regs[0]->unit == UNIT_A1)
		unit_bit = 1;
	      else
		return NULL;
	    }
	  else
	    {
	      if (src_regs[0]->unit == UNIT_D0)
		unit_bit = 0;
	      else if (src_regs[0]->unit == UNIT_D1)
		unit_bit = 1;
	      else
		return NULL;
	    }
	}
      else
	{
	  if (is_addr_op)
	    {
	      if (dest_regs[0]->unit == UNIT_A0)
		unit_bit = 0;
	      else if (dest_regs[0]->unit == UNIT_A1)
		unit_bit = 1;
	      else
		return NULL;
	    }
	  else
	    {
	      if (dest_regs[0]->unit == UNIT_D0)
		unit_bit = 0;
	      else if (dest_regs[0]->unit == UNIT_D1)
		unit_bit = 1;
	      else
		return NULL;
	    }
	}

      if (cond)
	{
	  if (src_regs[0]->unit != src_regs[1]->unit)
	    {
	      rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[1]);

	      if (rs2 < 0)
		return NULL;

	      o2r = 1;
	    }
	  else
	    {
	      rs2 = src_regs[1]->no;
	    }

	  insn->bits = (template->meta_opcode |
			(dest_regs[0]->no << 19) |
			(src_regs[0]->no << 14) |
			(rs2 << 9));

	  if (is_mul)
	    {
	      if (dest_regs[0]->unit != src_regs[0]->unit && is_mul)
		{
		  if (ca)
		    {
		      insn->bits |= dest_regs[0]->unit << 1;
		    }
		  else
		    return NULL;
		}
	    }
	  else
	    insn->bits |= dest_regs[0]->unit << 5;
	}
      else if (o1z)
	{
	  if (dest_regs[0]->unit != src_regs[0]->unit)
	    {
	      rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[0]);

	      if (rs2 < 0)
		return NULL;

	      o2r = 1;
	    }
	  else
	    {
	      rs2 = src_regs[0]->no;
	    }

	  insn->bits = (template->meta_opcode |
			(dest_regs[0]->no << 19) |
			(rs2 << 9));
	}
      else
	{
	  if (dest_regs[0]->unit != src_regs[0]->unit)
	    return NULL;

	  if (dest_regs[0]->unit != src_regs[1]->unit)
	    {
	      rs2 = lookup_o2r (is_addr_op, unit_bit, src_regs[1]);

	      if (rs2 < 0)
		return NULL;

	      o2r = 1;
	    }
	  else
	    {
	      rs2 = src_regs[1]->no;
	    }

	  insn->bits = (template->meta_opcode |
			(dest_regs[0]->no << 19) |
			(src_regs[0]->no << 14) |
			(rs2 << 9));
	}

      if (o2r)
	insn->bits |= 1;
    }

  if (is_quickrot)
    {
      const metag_reg *qr_regs[1];
      bfd_boolean limit_regs = imm && cond;

      l = skip_comma (l);

      if (l == NULL ||
	  *l == END_OF_INSN)
	return NULL;

      l = parse_gp_regs (l, qr_regs, 1);

      if (l == NULL)
	return NULL;

      if (!((unit_bit == 0 && qr_regs[0]->unit != UNIT_A0) ||
	    !(unit_bit == 1 && qr_regs[0]->unit != UNIT_A1)))
	{
	  as_bad (_("invalid quickrot unit specified"));
	  return NULL;
	}

      switch (qr_regs[0]->no)
	{
	case 2:
	  break;
	case 3:
	  if (!limit_regs)
	    {
	      insn->bits |= (1 << 7);
	      break;
	    }
	default:
	  as_bad (_("invalid quickrot register specified"));
	  return NULL;
	}
    }

  if (sign_extend == 1 && top == 0)
    insn->bits |= (1 << 1);

  insn->bits |= unit_bit << 24;
  insn->len = 4;
  return l;
}

/* Parse a B instruction.  */
static const char *
parse_branch (const char *line, metag_insn *insn,
	      const insn_template *template)
{
  const char *l = line;
  int value = 0;

  l = parse_imm19 (l, insn, &value);

  if (l == NULL)
    return NULL;

  if (!within_signed_range (value / 4, IMM19_BITS))
    {
      as_bad (_("target out of range"));
      return NULL;
    }

  insn->bits = (template->meta_opcode |
		((value & IMM19_MASK) << 5));

  insn->len = 4;
  return l;
}

/* Parse a KICK instruction.  */
static const char *
parse_kick (const char *line, metag_insn *insn,
	    const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[2];

  l = parse_gp_regs (l, regs, 2);

  if (l == NULL)
    return NULL;

  if (regs[1]->unit != UNIT_TR)
    {
      as_bad (_("source register must be in the trigger unit"));
      return NULL;
    }

  insn->bits = (template->meta_opcode |
		(regs[1]->no << 19) |
		(regs[0]->no << 14) |
		(regs[0]->unit << 5));

  insn->len = 4;
  return l;
}

/* Parse a SWITCH instruction.  */
static const char *
parse_switch (const char *line, metag_insn *insn,
	      const insn_template *template)
{
  const char *l = line;
  int value = 0;

  l = parse_imm_constant (l, insn, &value);

  if (l == NULL)
    return NULL;

  if (!within_unsigned_range (value, IMM24_BITS))
    {
      as_bad (_("target out of range"));
      return NULL;
    }

  insn->bits = (template->meta_opcode |
		(value & IMM24_MASK));

  insn->len = 4;
  return l;
}

/* Parse a shift instruction.  */
static const char *
parse_shift (const char *line, metag_insn *insn,
	     const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[2];
  const metag_reg *src2_regs[1];
  int value = 0;
  unsigned int cond = (template->meta_opcode >> 26) & 0x1;
  unsigned int ca = (template->meta_opcode >> 5) & 0x1;
  unsigned int unit_bit = 0;

  l = parse_gp_regs (l, regs, 2);

  if (l == NULL)
    return NULL;

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  if (regs[1]->unit == UNIT_D0)
    unit_bit = 0;
  else if (regs[1]->unit == UNIT_D1)
    unit_bit = 1;
  else
    return NULL;

  if (regs[0]->unit != regs[1]->unit && !(cond && ca))
    return NULL;

  if (*l == '#')
    {
      l = parse_imm_constant (l, insn, &value);

      if (l == NULL)
	return NULL;

      if (!within_unsigned_range (value, IMM5_BITS))
	return NULL;

      insn->bits = (template->meta_opcode |
		    (1 << 25) |
		    (regs[0]->no << 19) |
		    (regs[1]->no << 14) |
		    ((value & IMM5_MASK) << 9));
    }
  else
    {
      l = parse_gp_regs (l, src2_regs, 1);

      if (l == NULL)
	return NULL;

      insn->bits = (template->meta_opcode |
		    (regs[0]->no << 19) |
		    (regs[1]->no << 14) |
		    (src2_regs[0]->no << 9));

      if (src2_regs[0]->unit != regs[1]->unit)
	{
	  as_bad(_("Source registers must be in the same unit"));
	  return NULL;
	}
    }

  if (regs[0]->unit != regs[1]->unit)
    {
      if (cond && ca)
	{
	  if (regs[1]->unit == UNIT_D0)
	    unit_bit = 0;
	  else if (regs[1]->unit == UNIT_D1)
	    unit_bit = 1;
	  else
	    return NULL;

	  insn->bits |= ((1 << 5) |
			 (regs[0]->unit << 1));
	}
      else
	return NULL;
    }

  insn->bits |= unit_bit << 24;
  insn->len = 4;
  return l;
}

/* Parse a MIN or MAX instruction.  */
static const char *
parse_min_max (const char *line, metag_insn *insn,
	       const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[3];

  l = parse_gp_regs (l, regs, 3);

  if (l == NULL)
    return NULL;

  if (!(regs[0]->unit == UNIT_D0 ||
	regs[0]->unit == UNIT_D1))
      return NULL;

  if (!(regs[0]->unit == regs[1]->unit &&
	regs[1]->unit == regs[2]->unit))
      return NULL;

  insn->bits = (template->meta_opcode |
		(regs[0]->no << 19) |
		(regs[1]->no << 14) |
		(regs[2]->no << 9));

  if (regs[0]->unit == UNIT_D1)
    insn->bits |= (1 << 24);

  insn->len = 4;
  return l;
}

/* Parse a bit operation instruction.  */
static const char *
parse_bitop (const char *line, metag_insn *insn,
	     const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[2];
  unsigned int swap_inst = MAJOR_OPCODE (template->meta_opcode) == OPC_MISC;
  unsigned int is_bexl = 0;

  if (swap_inst &&
      ((template->meta_opcode >> 1) & 0xb) == 0xa)
    is_bexl = 1;

  l = parse_gp_regs (l, regs, 2);

  if (l == NULL)
    return NULL;

  if (!(regs[0]->unit == UNIT_D0 ||
	regs[0]->unit == UNIT_D1))
      return NULL;

  if (is_bexl)
    {
      if (regs[0]->unit == UNIT_D0 &&
	  regs[1]->unit != UNIT_D1)
	return NULL;
      else if (regs[0]->unit == UNIT_D1 &&
	       regs[1]->unit != UNIT_D0)
	return NULL;
    }
  else if (!(regs[0]->unit == regs[1]->unit))
      return NULL;

  insn->bits = (template->meta_opcode |
		(regs[0]->no << 19) |
		(regs[1]->no << 14));

  if (swap_inst)
    {
      if (regs[1]->unit == UNIT_D1)
	insn->bits |= 1;
    }
  else
    {
      if (regs[1]->unit == UNIT_D1)
	insn->bits |= (1 << 24);
    }

  insn->len = 4;
  return l;
}

/* Parse a CMP or TST instruction.  */
static const char *
parse_cmp (const char *line, metag_insn *insn,
	   const insn_template *template)
{
  const char *l = line;
  const metag_reg *dest_regs[1];
  const metag_reg *src_regs[1];
  int value = 0;
  unsigned int imm = (template->meta_opcode >> 25) & 0x1;
  unsigned int cond = (template->meta_opcode >> 26) & 0x1;
  unsigned int top = template->meta_opcode & 0x1;
  unsigned int sign_extend = 0;
  unsigned int unit_bit = 0;

  l = parse_gp_regs (l, dest_regs, 1);

  if (l == NULL)
    return NULL;

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  if (dest_regs[0]->unit == UNIT_D0)
    unit_bit = 0;
  else if (dest_regs[0]->unit == UNIT_D1)
    unit_bit = 1;
  else
    return NULL;

  if (imm)
    {
      if (cond)
	{
	  l = parse_imm_constant (l, insn, &value);

	  if (l == NULL)
	    return NULL;

	  if (!within_unsigned_range (value, IMM8_BITS))
	    return NULL;

	  insn->bits = (template->meta_opcode |
			(dest_regs[0]->no << 14) |
			((value & IMM8_MASK) << 6));

	}
      else
	{
	  l = parse_imm16 (l, insn, &value);

	  if (l == NULL)
	    return NULL;

	  if (value < 0)
	    {
	      if (!within_signed_range (value, IMM16_BITS))
		{
		  as_bad (_("immediate out of range"));
		  return NULL;
		}
	      sign_extend = 1;
	    }
	  else
	    {
	      if (!within_unsigned_range (value, IMM16_BITS))
		{
		  as_bad (_("immediate out of range"));
		  return NULL;
		}
	    }

	  insn->bits = (template->meta_opcode |
			(dest_regs[0]->no << 19) |
			((value & IMM16_MASK) << 3));
	}
    }
  else
    {
      unsigned int o2r = 0;
      int rs2;

      l = parse_gp_regs (l, src_regs, 1);

      if (l == NULL)
	return NULL;

      if (dest_regs[0]->unit != src_regs[0]->unit)
	{
	  rs2 = lookup_o2r (0, unit_bit, src_regs[0]);

	  if (rs2 < 0)
	    return NULL;

	  o2r = 1;
	}
      else
	{
	  rs2 = src_regs[0]->no;
	}

      insn->bits = (template->meta_opcode |
		    (dest_regs[0]->no << 14) |
		    (rs2 << 9));

      if (o2r)
	insn->bits |= 1;
    }

  if (sign_extend == 1 && top == 0)
    insn->bits |= (1 << 1);

  insn->bits |= unit_bit << 24;
  insn->len = 4;
  return l;
}

/* Parse a CACHEW instruction.  */
static const char *
parse_cachew (const char *line, metag_insn *insn,
	      const insn_template *template)
{
  const char *l = line;
  const metag_reg *src_regs[2];
  unsigned int size = ((template->meta_opcode >> 1) & 0x1) ? 8 : 4;
  metag_addr addr;
  int offset;

  memset(&addr, 0, sizeof(addr));
  addr.reloc_type = BFD_RELOC_UNUSED;

  l = parse_addr (l, &addr, size);

  if (l == NULL ||
      !is_short_unit (addr.base_reg->unit) ||
      addr.update ||
      !addr.immediate)
    {
	  as_bad (_("invalid memory operand"));
	  return NULL;
    }

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  if (size == 4)
    l = parse_gp_regs (l, src_regs, 1);
  else
    l = parse_pair_gp_regs (l, src_regs);

  if (l == NULL ||
      !is_short_unit (src_regs[0]->unit))
    {
      as_bad (_("invalid source register"));
      return NULL;
    }

  offset = addr.exp.X_add_number;

  if (addr.negate)
    offset = -offset;

  offset = offset / 64;

  if (!within_signed_range (offset, GET_SET_IMM_BITS))
    {
      as_bad (_("offset value out of range"));
      return NULL;
    }

  insn->bits = (template->meta_opcode |
		(src_regs[0]->no << 19) |
		(addr.base_reg->no << 14) |
		((offset & GET_SET_IMM_MASK) << 8) |
		((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) |
		((src_regs[0]->unit & SHORT_UNIT_MASK) << 3));

  insn->len = 4;
  return l;
}

/* Parse a CACHEW instruction.  */
static const char *
parse_cacher (const char *line, metag_insn *insn,
	      const insn_template *template)
{
  const char *l = line;
  const metag_reg *dest_regs[2];
  unsigned int size = ((template->meta_opcode >> 1) & 0x1) ? 8 : 4;
  metag_addr addr;
  int offset;

  memset(&addr, 0, sizeof(addr));
  addr.reloc_type = BFD_RELOC_UNUSED;

  if (size == 4)
    l = parse_gp_regs (l, dest_regs, 1);
  else
    l = parse_pair_gp_regs (l, dest_regs);

  if (l == NULL ||
      !is_short_unit (dest_regs[0]->unit))
    {
      as_bad (_("invalid destination register"));
      return NULL;
    }

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  l = parse_addr (l, &addr, size);

  if (l == NULL ||
      !is_short_unit (addr.base_reg->unit) ||
      addr.update ||
      !addr.immediate)
    {
	  as_bad (_("invalid memory operand"));
	  return NULL;
    }

  offset = addr.exp.X_add_number;

  if (addr.negate)
    offset = -offset;

  offset = offset / (int)size;

  if (!within_signed_range (offset, GET_SET_IMM_BITS))
    {
      as_bad (_("offset value out of range"));
      return NULL;
    }

  insn->bits = (template->meta_opcode |
		(dest_regs[0]->no << 19) |
		(addr.base_reg->no << 14) |
		((offset & GET_SET_IMM_MASK) << 8) |
		((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) |
		((dest_regs[0]->unit & SHORT_UNIT_MASK) << 3));

  insn->len = 4;
  return l;
}

/* Parse an ICACHE instruction.  */
static const char *
parse_icache (const char *line, metag_insn *insn,
	      const insn_template *template)
{
  const char *l = line;
  int offset;
  int pfcount;

  l = parse_imm_constant (l, insn, &offset);

  if (l == NULL)
    return NULL;

  if (!within_signed_range (offset, IMM15_BITS))
    return NULL;

  l = skip_comma (l);

  l = parse_imm_constant (l, insn, &pfcount);

  if (l == NULL)
    return NULL;

  if (!within_unsigned_range (pfcount, IMM4_BITS))
    return NULL;

  insn->bits = (template->meta_opcode |
		((offset & IMM15_MASK) << 9) |
		((pfcount & IMM4_MASK) << 1));

  insn->len = 4;
  return l;
}

/* Parse a LNKGET instruction.  */
static const char *
parse_lnkget (const char *line, metag_insn *insn,
	      const insn_template *template)
{
  const char *l = line;
  const metag_reg *dest_regs[2];
  unsigned int size = metag_get_set_ext_size_bytes (template->meta_opcode);
  metag_addr addr;
  int offset;

  memset(&addr, 0, sizeof(addr));
  addr.reloc_type = BFD_RELOC_UNUSED;

  if (size == 8)
    l = parse_pair_gp_regs (l, dest_regs);
  else
    l = parse_gp_regs (l, dest_regs, 1);

  if (l == NULL ||
      !is_short_unit (dest_regs[0]->unit))
    {
      as_bad (_("invalid destination register"));
      return NULL;
    }

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  l = parse_addr (l, &addr, size);

  if (l == NULL ||
      !is_short_unit (addr.base_reg->unit) ||
      addr.update ||
      !addr.immediate)
    {
	  as_bad (_("invalid memory operand"));
	  return NULL;
    }

  offset = addr.exp.X_add_number;

  if (addr.negate)
    offset = -offset;

  offset = offset / size;

  if (!within_signed_range (offset, GET_SET_IMM_BITS))
    {
      as_bad (_("offset value out of range"));
      return NULL;
    }

  insn->bits = (template->meta_opcode |
		(dest_regs[0]->no << 19) |
		(addr.base_reg->no << 14) |
		((offset & GET_SET_IMM_MASK) << 8) |
		((addr.base_reg->unit & SHORT_UNIT_MASK) << 5) |
		((dest_regs[0]->unit & SHORT_UNIT_MASK) << 3));

  insn->len = 4;
  return l;
}

/* Parse an FPU MOV instruction.  */
static const char *
parse_fmov (const char *line, metag_insn *insn,
	    const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[2];

  l = parse_fpu_regs (l, regs, 2);

  if (l == NULL)
    return NULL;

  insn->bits = (template->meta_opcode |
		(regs[0]->no << 19) |
		(regs[1]->no << 14));

  if (insn->fpu_width == FPU_WIDTH_DOUBLE)
    insn->bits |= (1 << 5);
  else if (insn->fpu_width == FPU_WIDTH_PAIR)
    insn->bits |= (1 << 6);

  insn->len = 4;
  return l;
}

/* Parse an FPU MMOV instruction.  */
static const char *
parse_fmmov (const char *line, metag_insn *insn,
	     const insn_template *template)
{
  const char *l = line;
  bfd_boolean to_fpu = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;
  bfd_boolean is_mmovl = MINOR_OPCODE (template->meta_opcode) & 0x1;
  size_t regs_read = 0;
  const metag_reg *regs[16];
  unsigned int lowest_data_reg = 0xffffffff;
  unsigned int lowest_fpu_reg = 0xffffffff;
  unsigned int rmask = 0, data_unit;
  size_t i;
  int last_reg = -1;

  if (insn->fpu_width != FPU_WIDTH_SINGLE)
    return NULL;

  l = parse_gp_regs_list (l, regs, 16, &regs_read);

  if (l == NULL)
    return NULL;

  if (regs_read % 2)
    return NULL;

  if (to_fpu)
    {
      for (i = 0; i < regs_read / 2; i++)
	{
	  if (regs[i]->unit != UNIT_FX)
	    return NULL;

	  if (last_reg == -1)
	    {
	      last_reg = regs[i]->no;
	      lowest_fpu_reg = last_reg;
	    }
	  else
	    {
	      if (is_mmovl)
		{
		  if (regs[i]->no != (unsigned int)(last_reg + 2))
		    return NULL;
		}
	      else if (regs[i]->no != (unsigned int)(last_reg + 1))
		return NULL;

	      last_reg = regs[i]->no;
	    }
	}

      if (regs[i]->unit == UNIT_D0)
	data_unit = 0;
      else if (regs[i]->unit == UNIT_D1)
	data_unit = 1;
      else
	return NULL;

      if (!check_rmask (&regs[i], regs_read / 2, TRUE, FALSE, &lowest_data_reg,
			&rmask))
	return NULL;
    }
  else
    {
      if (regs[0]->unit == UNIT_D0)
	data_unit = 0;
      else if (regs[0]->unit == UNIT_D1)
	data_unit = 1;
      else
	return NULL;

      if (!check_rmask (regs, regs_read / 2, TRUE, FALSE, &lowest_data_reg,
			&rmask))
	return NULL;

      for (i = regs_read / 2; i < regs_read; i++)
	{
	  if (regs[i]->unit != UNIT_FX)
	    return NULL;

	  if (last_reg == -1)
	    {
	      last_reg = regs[i]->no;
	      lowest_fpu_reg = last_reg;
	    }
	  else
	    {
	      if (is_mmovl)
		{
		  if (regs[i]->no != (unsigned int)(last_reg + 2))
		    return NULL;
		}
	      else if (regs[i]->no != (unsigned int)(last_reg + 1))
		return NULL;

	      last_reg = regs[i]->no;
	    }
	}
    }

  insn->bits = (template->meta_opcode |
		((lowest_data_reg & REG_MASK) << 19) |
		((lowest_fpu_reg & REG_MASK) << 14) |
		((rmask & RMASK_MASK) << 7) |
		data_unit);

  insn->len = 4;
  return l;
}

/* Parse an FPU data unit MOV instruction.  */
static const char *
parse_fmov_data (const char *line, metag_insn *insn,
	    const insn_template *template)
{
  const char *l = line;
  unsigned int to_fpu = ((template->meta_opcode >> 7) & 0x1);
  const metag_reg *regs[2];
  unsigned int base_unit;

  if (insn->fpu_width == FPU_WIDTH_PAIR)
    return NULL;

  l = parse_gp_regs (l, regs, 2);

  if (l == NULL)
    return NULL;

  if (to_fpu)
    {
      if (regs[0]->unit != UNIT_FX)
	return NULL;

      if (regs[1]->unit == UNIT_D0)
	base_unit = 0;
      else if (regs[1]->unit == UNIT_D1)
	base_unit = 1;
      else
	return NULL;
    }
  else
    {
      if (regs[0]->unit == UNIT_D0)
	base_unit = 0;
      else if (regs[0]->unit == UNIT_D1)
	base_unit = 1;
      else
	return NULL;

      if (regs[1]->unit != UNIT_FX)
	return NULL;
    }

  insn->bits = (template->meta_opcode |
		(base_unit << 24) |
		(regs[0]->no << 19) |
		(regs[1]->no << 9));

  insn->len = 4;
  return l;
}

/* Parse an FPU immediate MOV instruction.  */
static const char *
parse_fmov_i (const char *line, metag_insn *insn,
	      const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[1];
  int value = 0;

  l = parse_fpu_regs (l, regs, 1);

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  l = parse_imm16 (l, insn, &value);

  if (l == NULL)
    return NULL;

  insn->bits = (template->meta_opcode |
		(regs[0]->no << 19) |
		((value & IMM16_MASK) << 3));

  if (insn->fpu_width == FPU_WIDTH_DOUBLE)
    insn->bits |= (1 << 1);
  else if (insn->fpu_width == FPU_WIDTH_PAIR)
    insn->bits |= (1 << 2);

  insn->len = 4;
  return l;
}

/* Parse an FPU PACK instruction.  */
static const char *
parse_fpack (const char *line, metag_insn *insn,
	     const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[3];

  l = parse_fpu_regs (l, regs, 3);

  if (l == NULL)
    return NULL;

  if (regs[0]->no % 2)
    {
      as_bad (_("destination register should be even numbered"));
      return NULL;
    }

  insn->bits = (template->meta_opcode |
		(regs[0]->no << 19) |
		(regs[1]->no << 14) |
		(regs[2]->no << 9));

  insn->len = 4;
  return l;
}

/* Parse an FPU SWAP instruction.  */
static const char *
parse_fswap (const char *line, metag_insn *insn,
	     const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[2];

  if (insn->fpu_width != FPU_WIDTH_PAIR)
    return NULL;

  l = parse_fpu_regs (l, regs, 2);

  if (l == NULL)
    return NULL;

  if (regs[0]->no % 2)
    return NULL;

  if (regs[1]->no % 2)
    return NULL;

  insn->bits = (template->meta_opcode |
		(regs[0]->no << 19) |
		(regs[1]->no << 14));

  insn->len = 4;
  return l;
}

/* Parse an FPU CMP instruction.  */
static const char *
parse_fcmp (const char *line, metag_insn *insn,
	    const insn_template *template)
{
  const char *l = line, *l2;
  const metag_reg *regs1[1];
  const metag_reg *regs2[1];

  l = parse_fpu_regs (l, regs1, 1);

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  l2 = parse_fpu_regs (l, regs2, 1);

  if (l2 != NULL)
    {
      insn->bits = (regs2[0]->no << 9);
    }
  else
    {
      int constant = 0;
      l2 = parse_imm_constant (l, insn, &constant);
      if (!l2 || constant != 0)
	{
	  as_bad (_("comparison must be with register or #0"));
	  return NULL;
	}
      insn->bits = (1 << 8);
    }

  insn->bits |= (template->meta_opcode |
		 (regs1[0]->no << 14));

  if (insn->fpu_action_flags & FPU_ACTION_ABS)
    insn->bits |= (1 << 19);

  if (insn->fpu_action_flags & FPU_ACTION_QUIET)
    insn->bits |= (1 << 7);

  if (insn->fpu_width == FPU_WIDTH_PAIR)
    insn->bits |= (1 << 6);
  else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
    insn->bits |= (1 << 5);

  insn->len = 4;
  return l2;
}

/* Parse an FPU MIN or MAX instruction.  */
static const char *
parse_fminmax (const char *line, metag_insn *insn,
	       const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[3];

  l = parse_fpu_regs (l, regs, 3);

  if (l == NULL)
    return NULL;

  insn->bits = (template->meta_opcode |
		(regs[0]->no << 19) |
		(regs[1]->no << 14) |
		(regs[2]->no << 9));

  if (insn->fpu_width == FPU_WIDTH_PAIR)
    insn->bits |= (1 << 6);
  else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
    insn->bits |= (1 << 5);

  insn->len = 4;
  return l;
}

/* Parse an FPU data conversion instruction.  */
static const char *
parse_fconv (const char *line, metag_insn *insn,
	     const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[2];

  if (insn->fpu_width == FPU_WIDTH_PAIR)
    {
      if (strncasecmp (template->name, "FTOH", 4) &&
	  strncasecmp (template->name, "HTOF", 4) &&
	  strncasecmp (template->name, "FTOI", 4) &&
	  strncasecmp (template->name, "ITOF", 4))
	{
	  as_bad (_("instruction cannot operate on pair values"));
	  return NULL;
	}
    }

  if (insn->fpu_action_flags & FPU_ACTION_ZERO)
    {
      if (strncasecmp (template->name, "FTOI", 4) &&
	  strncasecmp (template->name, "DTOI", 4) &&
	  strncasecmp (template->name, "DTOL", 4))
	{
	  as_bad (_("zero flag is not valid for this instruction"));
	  return NULL;
	}
    }

  l = parse_fpu_regs (l, regs, 2);

  if (l == NULL)
    return NULL;

  if (!strncasecmp (template->name, "DTOL", 4) ||
      !strncasecmp (template->name, "LTOD", 4))
    {
      if (regs[0]->no % 2)
	{
	  as_bad (_("destination register should be even numbered"));
	  return NULL;
	}

      if (regs[1]->no % 2)
	{
	  as_bad (_("source register should be even numbered"));
	  return NULL;
	}
    }

  insn->bits = (template->meta_opcode |
		(regs[0]->no << 19) |
		(regs[1]->no << 14));

  if (insn->fpu_width == FPU_WIDTH_PAIR)
    insn->bits |= (1 << 6);

  if (insn->fpu_action_flags & FPU_ACTION_ZERO)
    insn->bits |= (1 << 12);

  insn->len = 4;
  return l;
}

/* Parse an FPU extended data conversion instruction.  */
static const char *
parse_fconvx (const char *line, metag_insn *insn,
	      const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[2];
  int fraction_bits = 0;

  if (insn->fpu_width == FPU_WIDTH_PAIR)
    {
      if (strncasecmp (template->name, "FTOX", 4) &&
	  strncasecmp (template->name, "XTOF", 4))
	{
	  as_bad (_("instruction cannot operate on pair values"));
	  return NULL;
	}
    }

  l = parse_fpu_regs (l, regs, 2);

  l = skip_comma (l);

  if (l == NULL ||
      *l == END_OF_INSN)
    return NULL;

  l = parse_imm_constant (l, insn, &fraction_bits);

  if (l == NULL)
    return NULL;

  insn->bits = (template->meta_opcode |
		(regs[0]->no << 19) |
		(regs[1]->no << 14));

  if (strncasecmp (template->name, "DTOXL", 5) &&
      strncasecmp (template->name, "XLTOD", 5))
    {
      if (!within_unsigned_range (fraction_bits, IMM5_BITS))
	{
	  as_bad (_("fraction bits value out of range"));
	  return NULL;
	}
      insn->bits |= ((fraction_bits & IMM5_MASK) << 9);
    }
  else
    {
      if (!within_unsigned_range (fraction_bits, IMM6_BITS))
	{
	  as_bad (_("fraction bits value out of range"));
	  return NULL;
	}
      insn->bits |= ((fraction_bits & IMM6_MASK) << 8);
    }

  if (insn->fpu_width == FPU_WIDTH_PAIR)
    insn->bits |= (1 << 6);

  insn->len = 4;
  return l;
}

/* Parse an FPU basic arithmetic instruction.  */
static const char *
parse_fbarith (const char *line, metag_insn *insn,
	       const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[3];

  l = parse_fpu_regs (l, regs, 3);

  if (l == NULL)
    return NULL;

  insn->bits = (template->meta_opcode |
		(regs[0]->no << 19) |
		(regs[1]->no << 14) |
		(regs[2]->no << 9));

  if (insn->fpu_width == FPU_WIDTH_PAIR)
    insn->bits |= (1 << 6);
  else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
    insn->bits |= (1 << 5);

  if (insn->fpu_action_flags & FPU_ACTION_INV)
    insn->bits |= (1 << 7);

  insn->len = 4;
  return l;
}

/* Parse a floating point accumulator name.  */
static const char *
parse_acf (const char *line, int *part)
{
  const char *l = line;
  size_t i;

  for (i = 0; i < sizeof(metag_acftab)/sizeof(metag_acftab[0]); i++)
    {
      const metag_acf *acf = &metag_acftab[i];
      size_t name_len = strlen (acf->name);

      if (strncasecmp (l, acf->name, name_len) == 0)
	{
	  l += name_len;
	  *part = acf->part;
	  return l;
	}
    }
  return NULL;
}

/* Parse an FPU extended arithmetic instruction.  */
static const char *
parse_fearith (const char *line, metag_insn *insn,
	       const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[3];
  bfd_boolean is_muz = (MINOR_OPCODE (template->meta_opcode) == 0x6 &&
			((template->meta_opcode >> 4) & 0x1));
  unsigned int is_o3o = template->meta_opcode & 0x1;
  unsigned int is_mac = 0;
  unsigned int is_maw = 0;

  if (!strncasecmp (template->name, "MAW", 3))
    is_maw = 1;

  if (!strncasecmp (template->name, "MAC", 3))
    {
      int part;
      l = parse_acf (l, &part);

      if (l == NULL || part != 0)
	return NULL;

      l = skip_comma (l);

      l = parse_fpu_regs (l, &regs[1], 2);

      is_mac = 1;
    }
  else
    {
      if (is_o3o && is_maw)
	l = parse_fpu_regs (l, regs, 2);
      else
	l = parse_fpu_regs (l, regs, 3);
    }

  if (l == NULL)
    return NULL;

  if (is_o3o && is_maw)
    insn->bits = (template->meta_opcode |
		  (regs[1]->no << 9));
  else
    insn->bits = (template->meta_opcode |
		  (regs[1]->no << 14));

  if (!(is_o3o && is_maw))
    insn->bits |= (regs[2]->no << 9);

  if (is_o3o && is_maw)
    insn->bits |= (regs[0]->no << 14);
  else if (!is_mac)
    insn->bits |= (regs[0]->no << 19);

  if (insn->fpu_width == FPU_WIDTH_PAIR)
    insn->bits |= (1 << 6);
  else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
    insn->bits |= (1 << 5);

  if (!is_mac && !is_maw)
    if (insn->fpu_action_flags & FPU_ACTION_INV)
      insn->bits |= (1 << 7);

  if (is_muz)
    if (insn->fpu_action_flags & FPU_ACTION_QUIET)
      insn->bits |= (1 << 1);

  insn->len = 4;
  return l;
}

/* Parse an FPU RCP or RSQ instruction.  */
static const char *
parse_frec (const char *line, metag_insn *insn,
	    const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[2];

  l = parse_fpu_regs (l, regs, 2);

  if (l == NULL)
    return NULL;

  insn->bits = (template->meta_opcode |
		(regs[0]->no << 19) |
		(regs[1]->no << 14));

  if (insn->fpu_width == FPU_WIDTH_PAIR)
    insn->bits |= (1 << 6);
  else if (insn->fpu_width == FPU_WIDTH_DOUBLE)
    insn->bits |= (1 << 5);

  if (insn->fpu_action_flags & FPU_ACTION_ZERO)
    insn->bits |= (1 << 10);
  else if (insn->fpu_action_flags & FPU_ACTION_QUIET)
    insn->bits |= (1 << 9);

  if (insn->fpu_action_flags & FPU_ACTION_INV)
    insn->bits |= (1 << 7);

  insn->len = 4;
  return l;
}

/* Parse an FPU vector arithmetic instruction.  */
static const char *
parse_fsimd (const char *line, metag_insn *insn,
	     const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[3];

  if (insn->fpu_width != FPU_WIDTH_PAIR)
    {
      as_bad (_("simd instructions operate on pair values (L prefix)"));
      return NULL;
    }

  l = parse_fpu_regs (l, regs, 3);

  if (l == NULL)
    return NULL;

  if (regs[0]->no % 2)
    {
      as_bad (_("destination register should be even numbered"));
      return NULL;
    }

  if ((regs[1]->no % 2) ||
      (regs[2]->no % 2))
    {
      as_bad (_("source registers should be even numbered"));
      return NULL;
    }

  insn->bits = (template->meta_opcode |
		(regs[0]->no << 19) |
		(regs[1]->no << 14) |
		(regs[2]->no << 9));

  if (insn->fpu_action_flags & FPU_ACTION_INV)
    insn->bits |= (1 << 7);

  insn->len = 4;
  return l;
}

/* Parse an FPU accumulator GET or SET instruction. */
static const char *
parse_fget_set_acf (const char *line, metag_insn *insn,
		    const insn_template *template)
{
  const char *l = line;
  int part;
  metag_addr addr;
  bfd_boolean is_get = MAJOR_OPCODE (template->meta_opcode) == OPC_GET;

  memset(&addr, 0, sizeof(addr));
  addr.reloc_type = BFD_RELOC_UNUSED;

  if (is_get)
    {
      l = parse_acf (l, &part);

      l = skip_comma (l);

      if (l == NULL)
	return NULL;

      l = parse_mget_mset_addr (l, &addr);
    }
  else
    {
      l = parse_mget_mset_addr (l, &addr);

      l = skip_comma (l);

      if (l == NULL)
	return NULL;

      l = parse_acf (l, &part);
    }

  if (l == NULL)
    return NULL;

  insn->bits = (template->meta_opcode |
		(part << 19));

  if (!is_short_unit (addr.base_reg->unit))
    {
      as_bad (_("base unit must be one of %s"), SHORT_UNITS);
      return NULL;
    }

  insn->bits |= ((addr.base_reg->no << 14) |
		 ((addr.base_reg->unit & SHORT_UNIT_MASK) << 5));

  insn->len = 4;
  return l;
}

/* Copy the name of the next register in LINE to REG_BUF.  */
static size_t
strip_reg_name(const char *line, char *reg_buf)
{
  const char *l = line;
  size_t len = 0;

  while (is_register_char (*l))
    {
      reg_buf[len] = *l;
      l++;
      len++;
      if (!(len < MAX_REG_LEN))
	return 0;
    }

  if (len)
    reg_buf[len] = '\0';

  return len;
}

/* Parse a DSP register from LINE into REG using only the registers
   from DSP_REGTAB. Return the next character or NULL.  */
static const char *
__parse_dsp_reg (const char *line, const metag_reg **reg, htab_t dsp_regtab)
{
  const char *l = line;
  char name[MAX_REG_LEN];
  size_t len = 0;
  metag_reg entry;
  const metag_reg *_reg;

  /* We don't entirely strip the register name because we might
     actually want to match whole string in the register table,
     e.g. "D0AW.1++" not just "D0AW.1". The string length of the table
     entry limits our comaprison to a reasonable bound anyway.  */
  while (is_register_char (*l) || *l == PLUS)
    {
      name[len] = *l;
      l++;
      len++;
      if (!(len < MAX_REG_LEN))
	return NULL;
    }

  if (!len)
    return NULL;

  name[len] = '\0';
  entry.name = name;

  _reg = (const metag_reg *) htab_find (dsp_regtab, &entry);
  if (!_reg)
    return NULL;

  *reg = _reg;

  return l;
}

/* Parse a DSP register and setup "reg" with a metag_reg whose "no"
   member is suitable for encoding into a DSP insn register field.  */
static const char *
parse_dsp_insn_reg (const char *line, const metag_reg **reg)
{
  return __parse_dsp_reg (line, reg, dsp_reg_htab);
}

/* Parse a DSP register and setup "reg" with a metag_reg whose "no"
   member is suitable for encoding into a DSP template definition insn
   register field.

   There is a separate table for whether we're doing a load or a store
   definition. "load" specifies which table to look at.  */
static const char *
parse_dsp_template_reg (const char *line, const metag_reg **reg,
			bfd_boolean load)
{
  return __parse_dsp_reg (line, reg, dsp_tmpl_reg_htab[load]);
}

/* Parse a single DSP register from LINE.  */
static const char *
parse_dsp_reg (const char *line, const metag_reg **reg,
	       bfd_boolean tmpl, bfd_boolean load)
{
  if (tmpl)
    return parse_dsp_template_reg (line, reg, load);
  else
    return parse_dsp_insn_reg (line, reg);
}

/* Return TRUE if UNIT is an address unit.  */
static bfd_boolean
is_addr_unit (enum metag_unit unit)
{
  switch (unit)
    {
    case UNIT_A0:
    case UNIT_A1:
      return TRUE;
    default:
      return FALSE;
    }
}

/* Return TRUE if UNIT1 and UNIT2 are equivalent units.  */
static bfd_boolean
is_same_data_unit (enum metag_unit unit1, enum metag_unit unit2)
{
  if (unit1 == unit2)
    return TRUE;

  switch (unit1)
    {
    case UNIT_D0:
      if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_RAM_D0)
	return TRUE;
      break;
    case UNIT_D1:
      if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_RAM_D1)
	return TRUE;
      break;
    case UNIT_ACC_D0:
      if (unit2 == UNIT_D0 || unit2 == UNIT_RAM_D0)
	return TRUE;
      break;
    case UNIT_ACC_D1:
      if (unit2 == UNIT_D1 || unit2 == UNIT_RAM_D1)
	return TRUE;
      break;
    case UNIT_RAM_D0:
      if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_D0)
	return TRUE;
      break;
    case UNIT_RAM_D1:
      if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_D1)
	return TRUE;
      break;
    default:
      return FALSE;
    }

  return FALSE;
}

/* Return TRUE if the register NUM is a quickrot control register.  */
static bfd_boolean
is_quickrot_reg (unsigned int num)
{
  switch (num)
    {
    case 2:
    case 3:
      return TRUE;
    }

  return FALSE;
}

/* Return TRUE if REG is an accumulator register.  */
static bfd_boolean
is_accumulator_reg (const metag_reg *reg)
{
  if (reg->unit == UNIT_ACC_D0 || reg->unit == UNIT_ACC_D1)
    return TRUE;

  return FALSE;
}

/* Return TRUE if REG is a DSP RAM register.  */
static bfd_boolean
is_dspram_reg (const metag_reg *reg)
{
  if (reg->unit == UNIT_RAM_D0 || reg->unit == UNIT_RAM_D1)
      return TRUE;

  return FALSE;
}

static const char *
__parse_gp_reg (const char *line, const metag_reg **reg, bfd_boolean load)
{
  const char *l = line;
  char reg_buf[MAX_REG_LEN];
  size_t len = 0;

  if (l == NULL)
    return NULL;

  /* Parse [DSPRAM.x].  */
  if (*l == ADDR_BEGIN_CHAR)
    {
      l++;

      if (l == NULL)
	return NULL;

      l = parse_dsp_reg (l, reg, TRUE, load);
      if (l == NULL)
	return NULL;

      if (*l == ADDR_END_CHAR)
	l++;
      else
	{
	  as_bad (_("expected ']', not %c in %s"), *l, l);
	  return NULL;
	}

      return l;
    }
  else
    {

      len = strip_reg_name (l, reg_buf);
      if (!len)
	return NULL;

      l += len;
      *reg = parse_gp_reg (reg_buf);
      if (*reg == NULL)
	return NULL;
    }

  return l;
}

/* Parse a list of DSP/GP registers. TRY_GP indicates whether we
   should try to parse the register as a general-purpose register if
   we fail to parse it as a DSP one. TMPL indicates whether the
   registers are part of a template definition instruction. If this is
   a template definition instruction LOAD says whether it's a load
   template insn. FIRST_DST indicates whether the first register is
   a destination operand.  */
static const char *
parse_dsp_regs_list (const char *line, const metag_reg **regs, size_t count,
		     size_t *regs_read, bfd_boolean try_gp, bfd_boolean tmpl,
		     bfd_boolean load, bfd_boolean first_dst)
{
  const char *l = line;
  int seen_regs = 0;
  size_t i;
  const metag_reg *reg;

  for (i = 0; i < count; i++)
    {
      const char *next, *ll;

      next = l;

      if (i > 0)
	{
	  l = skip_comma (l);
	  if (l == NULL)
	    {
	      *regs_read = seen_regs;
	      return next;
	    }
	}

      ll = parse_dsp_reg (l, &reg, tmpl, load);

      if (!ll)
	{
	  if (try_gp)
	    {
	      l = __parse_gp_reg (l, &reg, !(first_dst && i == 0));
	      if (l == NULL)
		{
		  *regs_read = seen_regs;
		  return next;
		}
	      regs[i] = reg;
	      seen_regs++;
	    }
	  else
	    {
	      *regs_read = seen_regs;
	      return l;
	    }
	}
      else
	{
	  regs[i] = reg;
	  seen_regs++;
	  l = ll;
	}
    }

  *regs_read = seen_regs;
  return l;
}

/* Parse the following memory references:

     - [Ax.r]
     - [Ax.r++]
     - [Ax.r--]
     - [Ax.r+Ax.r++]
     - [Ax.r-Ax.r--]

     - [DSPRam]
     - [DSPRam++]
     - [DSPRam+DSPRam++]
     - [DSPRam-DSPRam--]  */
static const char *
parse_dsp_addr (const char *line, metag_addr *addr, unsigned int size,
		bfd_boolean load)
{
  const char *l = line, *ll;
  const metag_reg *regs[1];
  size_t regs_read;

  /* Skip opening square bracket.  */
  l++;

  l = parse_dsp_regs_list (l, regs, 1, &regs_read, TRUE, TRUE, load, FALSE);

  if (l == NULL)
    return NULL;

  if (!is_addr_unit (regs[0]->unit) &&
      !is_dspram_reg (regs[0]))
    {
      as_bad (_("invalid register for memory access"));
      return NULL;
    }

  addr->base_reg = regs[0];

  if (*l == ADDR_END_CHAR)
    {
      addr->exp.X_op = O_constant;
      addr->exp.X_add_symbol = NULL;
      addr->exp.X_op_symbol = NULL;

      /* Simple register with no offset (0 immediate).  */
      addr->exp.X_add_number = 0;

      addr->immediate = 1;
      l++;

      return l;
    }

  ll = parse_addr_post_incr_op (l, addr);

  if (ll && *ll == ADDR_END_CHAR)
    {
      if (addr->update == 1)
	{
	  /* We have a post increment/decrement.  */
	  addr->exp.X_op = O_constant;
	  addr->exp.X_add_number = size;
	  addr->exp.X_add_symbol = NULL;
	  addr->exp.X_op_symbol = NULL;
	  addr->post_increment = 1;
	}
      addr->immediate = 1;
      ll++;
      return ll;
    }

  addr->post_increment = 0;

  l = parse_addr_op (l, addr);

  if (l == NULL)
    return NULL;

  l = parse_dsp_regs_list (l, regs, 1, &regs_read, TRUE, TRUE, load, FALSE);

  if (l == NULL)
    return NULL;

  if (regs[0]->unit != addr->base_reg->unit)
    {
      as_bad (_("offset and base must be from the same unit"));
      return NULL;
    }

  addr->offset_reg = regs[0];

  if (*l == ADDR_END_CHAR)
    {
      l++;
      return l;
    }

  l = parse_addr_post_incr_op (l, addr);

  if (l == NULL)
    return NULL;

  if (*l == ADDR_END_CHAR)
    {
      l++;
      return l;
    }

  return NULL;
}

/* Parse a DSP GET or SET instruction.  */
static const char *
parse_dget_set (const char *line, metag_insn *insn,
		const insn_template *template)
{
  const char *l = line;
  metag_addr addr;
  int unit = 0;
  int rd_reg = 0;
  bfd_boolean is_get = (template->meta_opcode & 0x100);
  bfd_boolean is_dual = (template->meta_opcode & 0x4);
  bfd_boolean is_template = FALSE;
  const metag_reg *regs[2];
  unsigned int size;
  size_t count, regs_read;

  memset(&addr, 0, sizeof(addr));
  addr.reloc_type = BFD_RELOC_UNUSED;

  size = is_dual ? 8 : 4;
  count = is_dual ? 2 : 1;

  if (is_get)
    {
      /* GETL can be used on one template table entry.  */
      if (*l == 'T')
	count = 1;

      l = parse_dsp_regs_list (l, regs, count, &regs_read, FALSE,
			       FALSE, FALSE, FALSE);
      l = skip_comma (l);

      if (l == NULL)
	{
	  as_bad (_("unexpected end of line"));
	  return NULL;
	}

      l = parse_addr (l, &addr, size);
    }
  else
    {
      l = parse_addr (l, &addr, size);

      l = skip_comma (l);

      if (l == NULL)
	return NULL;

      /* GETL can be used on one template table entry.  */
      if (*l == 'T')
	count = 1;

      l = parse_dsp_regs_list (l, regs, count, &regs_read, FALSE, FALSE,
			       FALSE, FALSE);
    }

  if (l == NULL)
    return NULL;

  /* The first register dictates the unit.  */
  if (regs[0]->unit == UNIT_DT)
      is_template = TRUE;
  else
    {
      if (regs[0]->unit == UNIT_D0 || regs[0]->unit == UNIT_RAM_D0 ||
	  regs[0]->unit == UNIT_ACC_D0)
	unit = 0;
      else
	unit = 1;
    }

  rd_reg = regs[0]->no;

  /* The 'H' modifier allows a DSP GET/SET instruction to target the
     upper 8-bits of an accumulator. It is _only_ valid for the
     accumulators.  */
  if (insn->dsp_daoppame_flags & DSP_DAOPPAME_HIGH)
    {
      if (is_template || !(rd_reg >= 16 && rd_reg < 20))
	{
	  as_bad (_("'H' modifier only valid for accumulator registers"));
	  return NULL;
	}

      /* Top 8-bits of the accumulator.  */
      rd_reg |= 8;
    }

  if (is_template)
    {
      insn->bits = (template->meta_opcode | (1 << 1));
    }
  else
    {
      insn->bits = (template->meta_opcode | unit);
    }

  insn->bits |= (rd_reg << 19);

  if (addr.immediate)
    {
      int offset = addr.exp.X_add_number;

      if (addr.negate)
	offset = -offset;

      offset = offset / (int)size;

      if (!within_signed_range (offset, DGET_SET_IMM_BITS))
	{
	  as_bad (_("offset value out of range"));
	  return NULL;
	}

      offset = offset & DGET_SET_IMM_MASK;

      insn->bits |= (1 << 13);
      insn->bits |= (offset << 9);
    }
  else
    {
      int au = (addr.base_reg->unit == UNIT_A1);

      insn->bits |= (au << 18);
      insn->bits |= ((addr.base_reg->no & REG_MASK) << 14);
      insn->bits |= ((addr.offset_reg->no & REG_MASK) << 9);
    }

  if (is_dual)
      insn->bits |= (1 << 2);

  if (!is_addr_unit (addr.base_reg->unit))
    {
      as_bad (_("base unit must be either A0 or A1"));
      return NULL;
    }

  unit = (addr.base_reg->unit == UNIT_A0) ? 0 : 1;
  insn->bits |= ((addr.base_reg->no << 14) | (unit << 18));

  insn->len = 4;

  return l;
}

/* Parse a DSP template instruction.  */
static const char *
parse_dtemplate (const char *line, metag_insn *insn,
		 const insn_template *template)
{
  const char *l = line;
  const metag_reg *regs[TEMPLATE_NUM_REGS];
  bfd_boolean daop_only = FALSE;
  int regs_val[4];
  int regs_which[4] = { -1, -1, -1, -1};	/* Register or immediate?  */
  int i;

  for (i = 0; i < TEMPLATE_NUM_REGS; i++)
    {
      if (l == NULL)
	{
	  as_bad (_("unexpected end of line"));
	  return NULL;
	}

      /* We may only have 3 register operands.  */
      if (*l == END_OF_INSN && i == 3)
	{
	  daop_only = TRUE;
	  break;
	}

      if (i != 0)
	{
	  l = skip_comma (l);
	  if (l == NULL)
	    return NULL;
	}

      if (*l == IMM_CHAR)
	{
	  l = parse_imm_constant (l, insn, &regs_val[i]);
	  if (l == NULL)
	    {
	      as_bad (_("invalid immediate"));
	      return NULL;
	    }
	  regs_which[i] = 0;
	}
      else
	{
	  /* We can't tell from the template instantiation whether
	     this is a load or store. So we have to try looking up the
	     register name in both the load and store tables.  */
	  const char *l2 = l;
	  l = __parse_gp_reg (l, &regs[i], TRUE);
	  if (l == NULL)
	    {
	      /* Try the store table too.  */
	      l = __parse_gp_reg (l2, &regs[i], FALSE);
	      if (l == NULL)
		{
		  /* Then try a DSP register.  */
		  l = parse_dsp_insn_reg (l2, &regs[i]);
		  if (l == NULL || regs[i]->unit == UNIT_DT)
		    {
		      as_bad (_("invalid register"));
		      return NULL;
		    }
		}
	    }
	  regs_which[i] = 1;
	}
    }

  insn->bits = template->meta_opcode;

  if (regs_which[0] == 0)
    insn->bits |= (regs_val[0] << 19);
  else if (regs_which[0] == 1)
    insn->bits |= (regs[0]->no << 19);

  if (regs_which[1] == 0)
    insn->bits |= (regs_val[1] << 14);
  else if (regs_which[1] == 1)
    insn->bits |= (regs[1]->no << 14);

  if (regs_which[2] == 0)
    insn->bits |= (regs_val[2] << 9);
  else if (regs_which[2] == 1)
    insn->bits |= (regs[2]->no << 9);

  if (regs_which[3] == 0)
    insn->bits |= (regs_val[3] << 4);
  else if (regs_which[3] == 1)
    insn->bits |= (regs[3]->no << 4);

  /* DaOp only.  */
  if (daop_only)
    insn->bits |= (0x3 << 24); /* Set the minor opcode.  */
  else if (insn->dsp_daoppame_flags & DSP_DAOPPAME_HIGH) /* Half Load/Store.  */
    insn->bits |= (0x5 << 24); /* Set the minor opcode.  */

  insn->len = 4;

  return l;
}

/* Parse a DSP Template definiton memory reference, e.g
   [A0.7+A0.5++]. DSPRAM is set to true by this function if this
   template definition is a DSP RAM template definition.  */
static const char *
template_mem_ref(const char *line, metag_addr *addr,
		 bfd_boolean *dspram, int size, bfd_boolean load)
{
  const char *l = line;

  l = parse_dsp_addr (l, addr, size, load);

  if (l != NULL)
    {
      if (is_addr_unit(addr->base_reg->unit))
	*dspram = FALSE;
      else
	*dspram = TRUE;
    }

  return l;
}

/* Sets LOAD to TRUE if this is a Template load definiton (otherwise
   it's a store). Fills out ADDR, TEMPLATE_REG and ADDR_UNIT.  */
static const char *
parse_template_regs (const char *line, bfd_boolean *load,
		     unsigned int *addr_unit,
		     const metag_reg **template_reg, metag_addr *addr,
		     bfd_boolean *dspram, int size)
{
  const char *l = line;

  if (l == NULL)
    return NULL;

  /* DSP Template load definition (Tx, [Ax]) */
  if (*l == 'T')
    {
      *load = TRUE;
      l = parse_dsp_reg (l, &template_reg[0], FALSE, FALSE);
      if (l == NULL)
	return NULL;

      l = skip_comma (l);

      l = template_mem_ref (l, addr, dspram, size, *load);

      if (addr->base_reg->unit == UNIT_A1)
	*addr_unit = 1;

    }
  else if (*l == ADDR_BEGIN_CHAR) /* DSP Template store ([Ax], Tx) */
    {
      *load = FALSE;
      l = template_mem_ref (l, addr, dspram, size, *load);
      l = skip_comma(l);

      if (l == NULL)
	return NULL;

      l = parse_dsp_reg (l, &template_reg[0], FALSE, FALSE);
      if (l == NULL)
	return NULL;

      if (addr->base_reg->unit == UNIT_A1)
	*addr_unit = 1;
    }
  else
    {
      as_bad (_("invalid register operand"));
      return NULL;
    }

  return l;
}

#define INVALID_SHIFT (-1)

static metag_reg _reg;

/* Parse a template instruction definition.  */
static const char *
interpret_template_regs(const char *line, metag_insn *insn,
			const metag_reg **regs,
			int *regs_shift, bfd_boolean *load, bfd_boolean *dspram,
			int size, int *ls_shift, int *au_shift,
			unsigned int *au, int *imm, int *imm_shift,
			unsigned int *imm_mask)
{
  const char *l = line;
  metag_addr addr;
  const metag_reg *template_reg[1];

  memset (&addr, 0, sizeof(addr));

  regs_shift[0] = 19;
  regs_shift[1] = INVALID_SHIFT;

  insn->bits |= (1 << 1);

  l = skip_whitespace (l);

  l = parse_template_regs (l, load, au, template_reg,
			   &addr, dspram, size);
  if (l == NULL)
    {
      as_bad (_("could not parse template definition"));
      return NULL;
    }

  regs[2] = template_reg[0];
  regs_shift[2] = 9;

  /* DSPRAM definition.  */
  if (*dspram)
    {

      _reg = *addr.base_reg;

      if (addr.immediate)
	{
	  /* Set the post-increment bit in the register field.  */
	  if (addr.update)
	    _reg.no |= 0x1;
	}
      else
	{
	  /* The bottom bit of the increment register tells us
	     whether it's increment register 0 or 1.  */
	  if (addr.offset_reg->no & 0x1)
	    _reg.no |= 0x3;
	  else
	    _reg.no |= 0x2;
	}

      regs[0] = &_reg;

      insn->bits |= (0x3 << 17); /* This signifies a DSPRAM definition.  */
    }
  else /* DaOpPaMe definition.  */
    {
      regs[0] = addr.base_reg;
      if (addr.immediate)
	{
	  /* Set the I bit.  */
	  insn->bits |= (1 << 18);

	  if (addr.update == 1)
	    {
	      if (addr.negate == 1)
		*imm = 0x3;
	      else
		*imm = 0x1;
	    }

	  *imm_shift = 14;
	  *imm_mask = 0x3;
	}
      else
	{
	  /* Setup the offset register.  */
	  regs[1] = addr.offset_reg;
	  regs_shift[1] = 14;
	}
      *au_shift = 23;
    }

  *ls_shift = 13;

  return l;
}

/* Does this combination of units need the O2R bit and can it be encoded?  */
static bfd_boolean
units_need_o2r (enum metag_unit unit1, enum metag_unit unit2)
{
  if (unit1 == unit2)
    return FALSE;

  if (unit1 == UNIT_D0 || unit1 == UNIT_ACC_D0 || unit1 == UNIT_RAM_D0)
    {
      if (unit2 == UNIT_ACC_D0 || unit2 == UNIT_RAM_D0 || unit2 == UNIT_D0)
	return FALSE;

      switch (unit2)
	{
	case UNIT_A1:
	case UNIT_D1:
	case UNIT_RD:
	case UNIT_A0:
	  return TRUE;
	default:
	  return FALSE;
	}
    }

  if (unit1 == UNIT_D1 || unit1 == UNIT_ACC_D1 || unit1 == UNIT_RAM_D1)
    {
      if (unit2 == UNIT_ACC_D1 || unit2 == UNIT_RAM_D1 || unit2 == UNIT_D1)
	return FALSE;

      switch (unit2)
	{
	case UNIT_A1:
	case UNIT_D0:
	case UNIT_RD:
	case UNIT_A0:
	  return TRUE;
	default:
	  return FALSE;
	}
    }

  return FALSE;
}

/* Return TRUE if this is a DSP data unit.  */
static bfd_boolean
is_dsp_data_unit (const metag_reg *reg)
{
  switch (reg->unit)
    {
    case UNIT_D0:
    case UNIT_D1:
    case UNIT_ACC_D0:
    case UNIT_ACC_D1:
    case UNIT_RAM_D0:
    case UNIT_RAM_D1:
      return TRUE;
    default:
      return FALSE;
    }
}

static metag_reg o2r_reg;

/* Parse a DaOpPaMe load template definition.  */
static const char *
parse_dalu (const char *line, metag_insn *insn,
	    const insn_template *template)
{
  const char *l = line;
  const char *ll;
  const metag_reg *regs[4];
  metag_addr addr;
  size_t regs_read;
  bfd_boolean is_mov = MAJOR_OPCODE (template->meta_opcode) == OPC_ADD;
  bfd_boolean is_cmp = ((MAJOR_OPCODE (template->meta_opcode) == OPC_CMP) &&
			((template->meta_opcode & 0xee) == 0));
  bfd_boolean is_dual = (insn->dsp_width == DSP_WIDTH_DUAL);
  bfd_boolean is_quickrot64 = ((insn->dsp_action_flags & DSP_ACTION_QR64) != 0);
  int l1_shift = INVALID_SHIFT;
  bfd_boolean load = FALSE;
  int ls_shift = INVALID_SHIFT;
  bfd_boolean ar = FALSE;
  int ar_shift = INVALID_SHIFT;
  int regs_shift[3] = { INVALID_SHIFT, INVALID_SHIFT, INVALID_SHIFT };
  int imm = 0;
  int imm_shift = INVALID_SHIFT;
  unsigned int imm_mask = 0;
  unsigned int au = 0;
  int au_shift = INVALID_SHIFT;
  unsigned int du = 0;
  int du_shift = INVALID_SHIFT;
  unsigned int sc = ((insn->dsp_action_flags & DSP_ACTION_OV) != 0);
  int sc_shift = INVALID_SHIFT;
  unsigned int om = ((insn->dsp_action_flags & DSP_ACTION_MOD) != 0);
  int om_shift = INVALID_SHIFT;
  unsigned int o2r = 0;
  int o2r_shift = INVALID_SHIFT;
  unsigned int qr = 0;
  int qr_shift = INVALID_SHIFT;
  int qd_shift = INVALID_SHIFT;
  unsigned int qn = 0;
  int qn_shift = INVALID_SHIFT;
  unsigned int a1 = ((insn->dsp_action_flags & (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ZERO)) != 0);
  int a1_shift = INVALID_SHIFT;
  unsigned int a2 = ((insn->dsp_action_flags & (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD)) != 0);
  int a2_shift = INVALID_SHIFT;
  unsigned su = ((insn->dsp_action_flags & DSP_ACTION_UMUL) != 0);
  int su_shift = INVALID_SHIFT;
  unsigned int ac;
  int ac_shift = INVALID_SHIFT;
  unsigned int mx = (((insn->dsp_daoppame_flags & DSP_DAOPPAME_8) != 0) ||
		     (insn->dsp_daoppame_flags & DSP_DAOPPAME_16) != 0);
  int mx_shift = INVALID_SHIFT;
  int size = is_dual ? 8 : 4;
  bfd_boolean dspram;
  bfd_boolean conditional = (MINOR_OPCODE (template->meta_opcode) & 0x4);

  /* XFIXME: check the flags are valid with the instruction.  */
  if (is_quickrot64 && !(template->arg_type & DSP_ARGS_QR))
    {
      as_bad (_("QUICKRoT 64-bit extension not applicable to this instruction"));
      return NULL;
    }

  insn->bits = template->meta_opcode;

  memset (regs, 0, sizeof (regs));
  memset (&addr, 0, sizeof (addr));

  /* There are the following forms of DSP ALU instructions,

   * Group 1:
      19. D[T]  Op    De.r,Dx.r,De.r
      1.  D[T]  Op    De.r,Dx.r,De.r|ACe.r	[Accumulator in src 2]
      3.  D[T]  Op    De.r,Dx.r,De.r[,Ae.r]	[QUICKRoT]
      2.  D[T]  Op    ACe.e,ACx.r,ACo.e		[cross-unit accumulator op]
      5.  D[T]  Op    De.r|ACe.r,Dx.r,De.r
      20. D[T]  Op    De.r,Dx.r|ACx.r,De.r
      8.  D     Opcc  De.r,Dx.r,Rx.r
      6.  D     Op    De.r,Dx.r,Rx.r|RD
      17. D     Op    De.r|ACe.r,Dx.r,Rx.r|RD
      7.  D     Op    De.e,Dx.r,#I16

   * Group 2:
      4.  D[T]  Op    Dx.r,De.r
      10. D     Op    Dx.r,Rx.r|RD
      13. D     Op    Dx.r,Rx.r
      11. D     Op    Dx.r,#I16
      12. D[T]  Op    De.r,Dx.r
      14. D     Op    DSPe.r,Dx.r
      15. D     Op    DSPx.r,#I16
      16. D     Op    De.r,DSPx.r
      18. D     Op    De.r,Dx.r|ACx.r

   * Group 3:
      22. D     Op    De.r,Dx.r|ACx.r,De.r|#I5
      23. D     Op    Ux.r,Dx.r|ACx.r,De.r|#I5
      21. D     Op    De.r,Dx.r|ACx.r,#I5  */

  /* Group 1.  */
  if (template->arg_type & DSP_ARGS_1)
    {
      du_shift = 24;

      /* Could this be a cross-unit accumulator op,
	 e.g. ACe.e,ACx.r,ACo.e */
      if (template->arg_type & DSP_ARGS_XACC)
	{
	  ll = parse_dsp_regs_list (l, regs, 3, &regs_read, FALSE, FALSE,
				    FALSE, FALSE);
	  if (ll != NULL && regs_read == 3
	      && is_accumulator_reg (regs[0]))
	    {
	      if (regs[0]->unit != regs[1]->unit ||
		  regs[2]->unit == regs[1]->unit)
		{
		  as_bad (_("invalid operands for cross-unit op"));
		  return NULL;
		}

	      du = (regs[1]->unit == UNIT_ACC_D1);
	      regs_shift[1] = 19;
	      l = ll;

	      /* All cross-unit accumulator ops have bits 8 and 6 set.  */
	      insn->bits |= (5 << 6);

	      goto check_for_template;
	    }

	  /* If we reach here, this instruction is not a
	     cross-unit accumulator op.  */
	}

      if (template->arg_type & DSP_ARGS_SPLIT8)
	om_shift = 7;

      sc_shift = 5;
      l1_shift = 4;
      o2r_shift = 0;

      /* De.r|ACe.r,Dx.r,De.r */
      if (template->arg_type & DSP_ARGS_DACC)
	{
	  /* XFIXME: these need moving?  */
	  a2_shift = 7;
	  su_shift = 6;
	  a1_shift = 2;
	  om_shift = 3;

	  ll = parse_dsp_reg (l, &regs[0], FALSE, FALSE);
	  if (ll != NULL)
	    {
	      /* Using ACe.r as the dst requires one of the P,N or Z
		 flags to be used.  */
	      if (!(insn->dsp_action_flags &
		    (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD|DSP_ACTION_ACC_ZERO)))
		{
		  as_bad (_("missing flags: one of 'P', 'N' or 'Z' required"));
		  return NULL;
		}

	      l = ll;
	      l = skip_comma (l);
	      l = parse_dsp_regs_list (l, &regs[1], 2, &regs_read,
				       TRUE, FALSE, FALSE, FALSE);
	      if (l == NULL || regs_read != 2)
		{
		  as_bad (_("invalid register"));
		  return NULL;
		}

	      if (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_RAM_D1)
		du = 1;

	      regs_shift[0] = 19;
	      regs_shift[1] = 14;
	      regs_shift[2] = 9;
	      goto check_for_template;
	    }

	  /* If we reach here, this instruction does not use the
	     accumulator as the destination register.  */
	  if ((insn->dsp_action_flags &
	       (DSP_ACTION_ACC_SUB|DSP_ACTION_ACC_ADD|DSP_ACTION_ACC_ZERO)))
	    {
	      as_bad (_("'P', 'N' or 'Z' flags may only be specified when accumulating"));
	      return NULL;
	    }
	}

      regs_shift[0] = 19;


      l = parse_dsp_regs_list (l, regs, 2, &regs_read, TRUE, FALSE, FALSE, TRUE);
      if (l == NULL || regs_read != 2)
	return NULL;

      l = skip_comma (l);
      if (l == NULL)
	return NULL;

      if (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_RAM_D1)
	du = 1;

      if (is_accumulator_reg(regs[0]) && !(template->arg_type & DSP_ARGS_DACC))
       {
	 as_bad (_("accumulator not a valid destination"));
	 return NULL;
       }

      /* Check for immediate, e.g. De.r,Dx.r,#I16 */
      if (*l == IMM_CHAR)
	{
	  l = parse_imm16 (l, insn, &imm);
	  if (l == NULL)
	    {
	      as_bad (_("invalid immediate value"));
	      return NULL;
	    }

	  if (!within_signed_range (imm, IMM16_BITS))
	    {
	      as_bad (_("immediate value out of range"));
	      return NULL;
	    }

	  if (regs[0]->unit != regs[1]->unit || regs[0]->no != regs[1]->no)
	    {
	      as_bad (_("immediate value not allowed when source & dest differ"));
	      return NULL;
	    }

	  imm_mask = 0xffff;
	  imm_shift = 3;

	  /* Set the I-bit */
	  insn->bits |= (1 << 25);

	  insn->bits |= (0x3 << 0);

	  l1_shift = 2;

	  /* Remove any bits that have been set in the immediate
	     field.  */
	  insn->bits &= ~(imm_mask << imm_shift);
	}
      else
	{

	  regs_shift[1] = 14;
	  regs_shift[2] = 9;

	  /* Is Rs2 an accumulator reg, e.g. De.r,Dx.r,De.r|ACe.r */
	  ll = parse_dsp_reg (l, &regs[2], FALSE, FALSE);
	  if (ll != NULL)
	    {
	      l = ll;

	      if (!(template->arg_type & DSP_ARGS_ACC2))
		{
		  as_bad (_("invalid register operand: %s"), regs[2]->name);
		  return NULL;
		}

	      om_shift = 3;
	      ar_shift = 7;
	      ar = TRUE;
	    }
	  else
	    {
	      /* De.r,Dx.r,De.r */
	      l = __parse_gp_reg (l, &regs[2], TRUE);
	      if (l == NULL)
		return NULL;
	    }

	  if (template->arg_type & DSP_ARGS_ACC2)
	    om_shift = 3;

	  /* Is this a QUICKRoT instruction? De.r,Dx.r,De.r[,Ae.r] */
	  if (template->arg_type & DSP_ARGS_QR)
	    {
	      if (conditional)
		qn_shift = 5;
	      else
		{
		  qn_shift = 7;
		  qr_shift = 6;
		  qd_shift = 5;
		}

	      l = skip_comma (l);
	      if (l == NULL)
		{
		  as_bad (_("QUICKRoT extension requires 4 registers"));
		  return NULL;
		}

	      l = __parse_gp_reg (l, &regs[3], TRUE);
	      if (l == NULL)
		{
		  as_bad (_("invalid fourth register"));
		  return NULL;
		}

	      if (!is_addr_unit (regs[3]->unit) ||
		  !is_quickrot_reg (regs[3]->no))
		{
		  as_bad (_("A0.2,A0.3,A1.2,A1.3 required for QUICKRoT register"));
		  return NULL;
		}

	      qn = (regs[3]->no == 3);
	    }
	}

    check_for_template:
      /* This is the common exit path. Check for o2r.  */
      if (regs[2] != NULL)
	{
	  o2r = units_need_o2r (regs[1]->unit, regs[2]->unit);
	  if (o2r)
	    {
	      o2r_reg.no = lookup_o2r (0, du, regs[2]);
	      o2r_reg.unit = regs[2]->unit;
	      regs[2] = &o2r_reg;
	    }
	}

      /* Check any DSP RAM pointers are valid for this unit.  */
      if ((du && (regs[0]->unit == UNIT_RAM_D0)) ||
	  (!du && (regs[0]->unit == UNIT_RAM_D1)) ||
	  (du && (regs[1]->unit == UNIT_RAM_D0)) ||
	  (!du && (regs[1]->unit == UNIT_RAM_D1)) ||
	  (du && regs[2] && (regs[2]->unit == UNIT_RAM_D0)) ||
	  (!du && regs[2] && (regs[2]->unit == UNIT_RAM_D1))) {
	as_bad (_("DSP RAM pointer in incorrect unit"));
	return NULL;
      }

      /* Is this a template definition?  */
      if (IS_TEMPLATE_DEF (insn))
	{
	  l = interpret_template_regs(l, insn, regs, regs_shift, &load,
				      &dspram, size, &ls_shift, &au_shift,
				      &au, &imm, &imm_shift, &imm_mask);

	  if (l == NULL)
	    return NULL;

	  if (!dspram)
	    mx_shift = 0;
	}

      goto matched;
    }

  /* Group 2.  */
  if (template->arg_type & DSP_ARGS_2)
    {
      bfd_boolean is_xsd = ((MAJOR_OPCODE (template->meta_opcode) == OPC_MISC) &&
			    (MINOR_OPCODE (template->meta_opcode) == 0xa));
      bfd_boolean is_fpu_mov = template->insn_type == INSN_DSP_FPU;
      bfd_boolean to_fpu = (template->meta_opcode >> 7) & 0x1;

      if (is_xsd)
	du_shift = 0;
      else
	du_shift = 24;

      l1_shift = 4;

      /* CMPs and TSTs don't store to their destination operand.  */
      ll = __parse_gp_reg (l, regs, is_cmp);
      if (ll == NULL)
	{
	  /* DSPe.r,Dx.r or DSPx.r,#I16 */
	  if (template->arg_type & DSP_ARGS_DSP_SRC1)
	    {
	      l = parse_dsp_reg (l, regs, FALSE, FALSE);
	      if (l == NULL)
		{
		  as_bad (_("invalid register operand #1"));
		  return NULL;
		}

	      /* Only MOV instructions have a DSP register as a
		 destination. Set the MOV DSPe.r opcode. The simple
		 OR'ing is OK because the usual MOV opcode is 0x00.  */
	      insn->bits = (0x91 << 24);
	      du_shift = 0;
	      l1_shift = 2;
	      regs_shift[0] = 19;
	    }
	  else
	    {
	      as_bad (_("invalid register operand #2"));
	      return NULL;
	    }
	}
      else
	{
	  l = ll;

	  /* Everything but CMP and TST.  */
	  if (MAJOR_OPCODE (template->meta_opcode) == OPC_ADD ||
	      MAJOR_OPCODE (template->meta_opcode) == OPC_SUB ||
	      MAJOR_OPCODE (insn->bits) == OPC_9 ||
	      MAJOR_OPCODE (template->meta_opcode) == OPC_MISC ||
	      ((template->meta_opcode & 0x0000002c) != 0))
	    regs_shift[0] = 19;
	  else
	    regs_shift[0] = 14;
	}

      if (!is_dsp_data_unit (regs[0]) && !(regs[0]->unit == UNIT_FX &&
					   is_fpu_mov && to_fpu))
	return NULL;

      du = (regs[0]->unit == UNIT_D1 || regs[0]->unit == UNIT_RAM_D1 ||
	    regs[0]->unit == UNIT_ACC_D1);

      l = skip_comma (l);

      if (*l == IMM_CHAR)
	{
	  if (template->arg_type & DSP_ARGS_IMM &&
	      !(is_mov && (MAJOR_OPCODE (insn->bits) != OPC_9)))
	    {
	      l = parse_imm16 (l, insn, &imm);
	      if (l == NULL)
		{
		  as_bad (_("invalid immediate value"));
		  return NULL;
		}

	      if (!within_signed_range (imm, IMM16_BITS))
		return NULL;

	      l1_shift = 2;
	      regs_shift[0] = 19;

	      imm_mask = 0xffff;
	      imm_shift = 3;

	      /* Set the I-bit unless it's a MOV because they're
		 different.  */
	      if (!(is_mov && MAJOR_OPCODE (insn->bits) == OPC_9))
		insn->bits |= (1 << 25);

	      /* All instructions that takes immediates also have bit 1 set.  */
	      insn->bits |= (1 << 1);

	      if (MAJOR_OPCODE (insn->bits) != OPC_9)
		insn->bits |= (1 << 0);

	      insn->bits &= ~(1 << 8);
	    }
	  else
	    {
	      as_bad (_("this instruction does not accept an immediate"));
	      return NULL;
	    }
	}
      else
	{
	  if (MAJOR_OPCODE (insn->bits) != OPC_9)
	    {
	      insn->bits |= (1 << 8);
	      l1_shift = 4;
	    }

	  ll = __parse_gp_reg (l, &regs[1], TRUE);
	  if (ll == NULL)
	    {
	      if (template->arg_type & DSP_ARGS_DSP_SRC2)
		{
		  l = parse_dsp_reg (l, &regs[1], FALSE, FALSE);
		  if (l == NULL)
		    {
		      as_bad (_("invalid register operand #3"));
		      return NULL;
		    }

		  /* MOV and NEG.  */
		  if ((is_mov && (MAJOR_OPCODE (insn->bits) != OPC_9)) ||
		      MAJOR_OPCODE (template->meta_opcode) == OPC_SUB)
		    {
		      if (is_accumulator_reg (regs[1]))
			{
			  if (is_fpu_mov)
			    {
			      as_bad (_("this instruction does not accept an accumulator"));
			      return NULL;
			    }
			  ar_shift = 7;
			  ar = 1;
			  regs_shift[1] = 9;
			}
		      else
			{
			  du_shift = 0;
			  l1_shift = 2;
			  regs_shift[1] = 14;
			  insn->bits = (0x92 << 24); /* Set opcode.  */
			}
		    }
		}
	      else
		{
		  as_bad (_("invalid register operand #4"));
		  return NULL;
		}
	    }
	  else
	    {
	      /* Set the o2r bit if required.  */
	      if (!is_fpu_mov && units_need_o2r (regs[0]->unit, regs[1]->unit))
		{
		  o2r_reg = *regs[1];
		  o2r_reg.no = lookup_o2r (0, du, regs[1]);
		  regs[1] = &o2r_reg;
		  o2r_shift = 0;
		  o2r = 1;
		}
	      else if (!is_dsp_data_unit (regs[1]) &&
		       !(is_fpu_mov && !to_fpu && regs[1]->unit == UNIT_FX))
		return NULL;

	      if (is_fpu_mov && to_fpu)
		du = (regs[1]->unit == UNIT_D1 ||
		      regs[1]->unit == UNIT_RAM_D1 ||
		      regs[1]->unit == UNIT_ACC_D1);

	      l = ll;

	      if (MAJOR_OPCODE (insn->bits) == OPC_ADD ||
		  MAJOR_OPCODE (template->meta_opcode) == OPC_SUB ||
		  (((template->meta_opcode & 0x0000002c) == 0) &&
		   MAJOR_OPCODE (template->meta_opcode) != OPC_MISC))
		regs_shift[1] = 9;
	      else
		regs_shift[1] = 14;
	    }
	}

      /* If it's an 0x0 MOV or NEG set some lower bits.  */
      if ((MAJOR_OPCODE (insn->bits) == OPC_ADD ||
	   MAJOR_OPCODE (template->meta_opcode) == OPC_SUB) && !is_fpu_mov)
	{
	  om_shift = 3;
	  sc_shift = 5;
	  insn->bits |= (1 << 2);
	}

      /* Check for template definitons.  */
      if (IS_TEMPLATE_DEF (insn))
	{
	  l = interpret_template_regs(l, insn, regs, regs_shift, &load,
				      &dspram, size, &ls_shift, &au_shift,
				      &au, &imm, &imm_shift, &imm_mask);
	  mx_shift = 0;

	  if (l == NULL)
	    return NULL;
	}
      goto matched;
    }

  /* Group 3.  */
  du_shift = 24;
  l1_shift = 4;

  l = __parse_gp_reg (l, regs, FALSE);
  if (l == NULL)
    {
      as_bad (_("invalid register operand"));
      return NULL;
    }

  l = skip_comma (l);

  if (*l == 'A')
    {
      l = parse_dsp_reg (l, &regs[1], FALSE, FALSE);
      if (l == NULL)
	{
	  as_bad (_("invalid accumulator register"));
	  return NULL;
	}
      ac = 1;
      ac_shift = 0;
    }
  else
    {
      l = __parse_gp_reg (l, &regs[1], TRUE);
      if (l == NULL)
	{
	  as_bad (_("invalid register operand"));
	  return NULL;
	}
    }

  regs_shift[0] = 19;
  regs_shift[1] = 14;

  du = (regs[1]->unit == UNIT_D1 || regs[1]->unit == UNIT_ACC_D1
	|| regs[1]->unit == UNIT_RAM_D1);

  l = skip_comma (l);

  if (*l == IMM_CHAR)
    {
      l = parse_imm_constant (l, insn, &imm);
      if (l == NULL)
	{
	  as_bad (_("invalid immediate value"));
	  return NULL;
	}

      if (!within_unsigned_range (imm, IMM5_BITS))
	return NULL;

      imm_mask = 0x1f;
      imm_shift = 9;

      /* Set the I-bit */
      insn->bits |= (1 << 25);
    }
  else
    {
      regs_shift[2] = 9;
      l = __parse_gp_reg (l, &regs[2], TRUE);
      if (l == NULL)
	return NULL;
    }

  /* Check for post-processing R,G,B flags. Conditional instructions
     do not have these bits.  */
  if (insn->dsp_action_flags & DSP_ACTION_CLAMP9)
    {
      if ((template->meta_opcode >> 26) & 0x1)
	{
	  as_bad (_("conditional instruction cannot use G flag"));
	  return NULL;
	}

      insn->bits |= (1 << 3);
    }

  if (insn->dsp_action_flags & DSP_ACTION_CLAMP8)
    {
      if ((template->meta_opcode >> 26) & 0x1)
	{
	  as_bad (_("conditional instruction cannot use B flag"));
	  return NULL;
	}

      insn->bits |= (0x3 << 2);
    }

  if (insn->dsp_action_flags & DSP_ACTION_ROUND)
    {
      if ((template->meta_opcode >> 26) & 0x1)
	{
	  as_bad (_("conditional instruction cannot use R flag"));
	  return NULL;
	}
      insn->bits |= (1 << 2);
    }

  /* Conditional Data Unit Shift instructions cannot be dual unit.  */
  if ((template->meta_opcode >> 26) & 0x1)
    ls_shift = INVALID_SHIFT;

  /* The Condition Is Always (CA) bit must be set if we're targetting a
     Ux.r register as the destination. This means that we can't have
     any other condition bits set.  */
  if (!is_same_data_unit (regs[1]->unit, regs[0]->unit))
    {
      /* Set both the Conditional bit and the Condition is Always bit.  */
      insn->bits |= (1 << 26);
      insn->bits |= (1 << 5);

      /* Fill out the Ud field.  */
      insn->bits |= (regs[0]->unit << 1);
    }

  if (IS_TEMPLATE_DEF (insn))
    {
      l = interpret_template_regs(l, insn, regs, regs_shift, &load,
				  &dspram, size, &ls_shift, &au_shift,
				  &au, &imm, &imm_shift, &imm_mask);

      if (l == NULL)
	return NULL;

      if (!dspram)
	mx_shift = 5;
    }

  /* Fall through.  */
 matched:

  /* Set the registers and immediate values.  */
  if (regs_shift[0] != INVALID_SHIFT)
    insn->bits |= (regs[0]->no << regs_shift[0]);

  if (regs_shift[1] != INVALID_SHIFT)
    insn->bits |= (regs[1]->no << regs_shift[1]);

  if (regs_shift[2] != INVALID_SHIFT)
    insn->bits |= (regs[2]->no << regs_shift[2]);

  /* Does this insn have an 'IMM' bit? The immediate value should
     already have been masked.  */
  if (imm_shift != INVALID_SHIFT)
    insn->bits |= ((imm & imm_mask) << imm_shift);

  /* Does this insn have an 'AU' bit? */
  if (au_shift != INVALID_SHIFT)
    insn->bits |= (au << au_shift);

  /* Does this instruction have an 'LS' bit?  */
  if (ls_shift != INVALID_SHIFT)
    insn->bits |= (load << ls_shift);

  /* Does this instruction have an 'AR' bit?  */
  if (ar)
      insn->bits |= (1 << ar_shift);

  if (du_shift != INVALID_SHIFT)
    insn->bits |= (du << du_shift);

  if (sc_shift != INVALID_SHIFT)
    insn->bits |= (sc << sc_shift);

  if (om_shift != INVALID_SHIFT)
    insn->bits |= (om << om_shift);

  if (o2r_shift != INVALID_SHIFT)
    insn->bits |= (o2r << o2r_shift);

  if (qn_shift != INVALID_SHIFT)
    insn->bits |= (qn << qn_shift);

  if (qr_shift != INVALID_SHIFT)
    insn->bits |= (qr << qr_shift);

  if (qd_shift != INVALID_SHIFT)
    insn->bits |= (is_quickrot64 << qd_shift);

  if (a1_shift != INVALID_SHIFT)
    insn->bits |= (a1 << a1_shift);

  if (a2_shift != INVALID_SHIFT)
    insn->bits |= (a2 << a2_shift);

  if (su_shift != INVALID_SHIFT)
    insn->bits |= (su << su_shift);

  if (imm_shift != INVALID_SHIFT)
    insn->bits |= ((imm & imm_mask) << imm_shift);

  if (ac_shift != INVALID_SHIFT)
    insn->bits |= (ac << ac_shift);

  if (mx_shift != INVALID_SHIFT)
    insn->bits |= (mx << mx_shift);

  if (is_dual)
    {
      if (l1_shift == INVALID_SHIFT)
	{
	  as_bad (_("'L' modifier not valid for this instruction"));
	  return NULL;
	}

      insn->bits |= (1 << l1_shift);
    }

  insn->len = 4;

  return l;
}

typedef const char *(*insn_parser)(const char *, metag_insn *,
				   const insn_template *);

/* Parser table.  */
static const insn_parser insn_parsers[ENC_MAX] =
  {
    [ENC_NONE] = parse_none,
    [ENC_MOV_U2U] = parse_mov_u2u,
    [ENC_MOV_PORT] = parse_mov_port,
    [ENC_MMOV] = parse_mmov,
    [ENC_MDRD] = parse_mdrd,
    [ENC_MOVL_TTREC] = parse_movl_ttrec,
    [ENC_GET_SET] = parse_get_set,
    [ENC_GET_SET_EXT] = parse_get_set_ext,
    [ENC_MGET_MSET] = parse_mget_mset,
    [ENC_COND_SET] = parse_cond_set,
    [ENC_XFR] = parse_xfr,
    [ENC_MOV_CT] = parse_mov_ct,
    [ENC_SWAP] = parse_swap,
    [ENC_JUMP] = parse_jump,
    [ENC_CALLR] = parse_callr,
    [ENC_ALU] = parse_alu,
    [ENC_SHIFT] = parse_shift,
    [ENC_MIN_MAX] = parse_min_max,
    [ENC_BITOP] = parse_bitop,
    [ENC_CMP] = parse_cmp,
    [ENC_BRANCH] = parse_branch,
    [ENC_KICK] = parse_kick,
    [ENC_SWITCH] = parse_switch,
    [ENC_CACHER] = parse_cacher,
    [ENC_CACHEW] = parse_cachew,
    [ENC_ICACHE] = parse_icache,
    [ENC_LNKGET] = parse_lnkget,
    [ENC_FMOV] = parse_fmov,
    [ENC_FMMOV] = parse_fmmov,
    [ENC_FMOV_DATA] = parse_fmov_data,
    [ENC_FMOV_I] = parse_fmov_i,
    [ENC_FPACK] = parse_fpack,
    [ENC_FSWAP] = parse_fswap,
    [ENC_FCMP] = parse_fcmp,
    [ENC_FMINMAX] = parse_fminmax,
    [ENC_FCONV] = parse_fconv,
    [ENC_FCONVX] = parse_fconvx,
    [ENC_FBARITH] = parse_fbarith,
    [ENC_FEARITH] = parse_fearith,
    [ENC_FREC] = parse_frec,
    [ENC_FSIMD] = parse_fsimd,
    [ENC_FGET_SET_ACF] = parse_fget_set_acf,
    [ENC_DGET_SET] = parse_dget_set,
    [ENC_DTEMPLATE] = parse_dtemplate,
    [ENC_DALU] = parse_dalu,
  };

struct metag_core_option
{
  const char *name;
  unsigned int value;
};

/* CPU type options.  */
static const struct metag_core_option metag_cpus[] =
  {
    {"all",               CoreMeta11|CoreMeta12|CoreMeta21},
    {"metac11",           CoreMeta11},
    {"metac12",           CoreMeta12},
    {"metac21",           CoreMeta21},
    {NULL,                0},
  };

/* FPU type options.  */
static const struct metag_core_option metag_fpus[] =
  {
    {"metac21",           FpuMeta21},
    {NULL,                0},
  };

/* DSP type options.  */
static const struct metag_core_option metag_dsps[] =
  {
    {"metac21",           DspMeta21},
    {NULL,                0},
  };

/* Parse a CPU command line option.  */
static int
metag_parse_cpu (const char * str)
{
  const struct metag_core_option * opt;
  int optlen;

  optlen = strlen (str);

  if (optlen == 0)
    {
      as_bad (_("missing cpu name `%s'"), str);
      return 0;
    }

  for (opt = metag_cpus; opt->name != NULL; opt++)
    if (strncmp (opt->name, str, optlen) == 0)
      {
	mcpu_opt = opt->value;
	return 1;
      }

  as_bad (_("unknown cpu `%s'"), str);
  return 0;
}

/* Parse an FPU command line option.  */
static int
metag_parse_fpu (const char * str)
{
  const struct metag_core_option * opt;
  int optlen;

  optlen = strlen (str);

  if (optlen == 0)
    {
      as_bad (_("missing fpu name `%s'"), str);
      return 0;
    }

  for (opt = metag_fpus; opt->name != NULL; opt++)
    if (strncmp (opt->name, str, optlen) == 0)
      {
	mfpu_opt = opt->value;
	return 1;
      }

  as_bad (_("unknown fpu `%s'"), str);
  return 0;
}

/* Parse a DSP command line option.  */
static int
metag_parse_dsp (const char * str)
{
  const struct metag_core_option * opt;
  int optlen;

  optlen = strlen (str);

  if (optlen == 0)
    {
      as_bad (_("missing DSP name `%s'"), str);
      return 0;
    }

  for (opt = metag_dsps; opt->name != NULL; opt++)
    if (strncmp (opt->name, str, optlen) == 0)
      {
	mdsp_opt = opt->value;
	return 1;
      }

  as_bad (_("unknown DSP `%s'"), str);
  return 0;
}

struct metag_long_option
{
  const char * option;                /* Substring to match.  */
  const char * help;                  /* Help information.  */
  int (* func) (const char * subopt); /* Function to decode sub-option.  */
  const char * deprecated;            /* If non-null, print this message.  */
};

struct metag_long_option metag_long_opts[] =
  {
    {"mcpu=", N_("<cpu name>\t  assemble for CPU <cpu name>"),
     metag_parse_cpu, NULL},
    {"mfpu=", N_("<fpu name>\t  assemble for FPU architecture <fpu name>"),
     metag_parse_fpu, NULL},
    {"mdsp=", N_("<dsp name>\t  assemble for DSP architecture <dsp name>"),
     metag_parse_dsp, NULL},
    {NULL, NULL, 0, NULL}
  };

int
md_parse_option (int c, const char * arg)
{
  struct metag_long_option *lopt;

  for (lopt = metag_long_opts; lopt->option != NULL; lopt++)
    {
      /* These options are expected to have an argument.  */
      if (c == lopt->option[0]
	  && arg != NULL
	  && strncmp (arg, lopt->option + 1,
		      strlen (lopt->option + 1)) == 0)
	{
#if WARN_DEPRECATED
	      /* If the option is deprecated, tell the user.  */
	      if (lopt->deprecated != NULL)
		as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
			   _(lopt->deprecated));
#endif

	      /* Call the sup-option parser.  */
	      return lopt->func (arg + strlen (lopt->option) - 1);
	}
    }

  return 0;
}

void
md_show_usage (FILE * stream)
{
  struct metag_long_option *lopt;

  fprintf (stream, _(" Meta specific command line options:\n"));

  for (lopt = metag_long_opts; lopt->option != NULL; lopt++)
    if (lopt->help != NULL)
      fprintf (stream, "  -%s%s\n", lopt->option, _(lopt->help));
}

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

void
md_begin (void)
{
  int c;

  for (c = 0; c < 256; c++)
    {
      if (ISDIGIT (c))
	{
	  register_chars[c] = c;
	  /* LOCK0, LOCK1, LOCK2.  */
	  mnemonic_chars[c] = c;
	}
      else if (ISLOWER (c))
	{
	  register_chars[c] = c;
	  mnemonic_chars[c] = c;
	}
      else if (ISUPPER (c))
	{
	  register_chars[c] = c;
	  mnemonic_chars[c] = c;
	}
      else if (c == '.')
	{
	  register_chars[c] = c;
	}
    }
}

/* Parse a split condition code prefix.  */
static const char *
parse_split_condition (const char *line, metag_insn *insn)
{
  const char *l = line;
  const split_condition *scond;
  split_condition entry;
  char buf[4];

  memcpy (buf, l, 4);
  buf[3] = '\0';

  entry.name = buf;

  scond = (const split_condition *) htab_find (scond_htab, &entry);

  if (!scond)
    return NULL;

  insn->scond = scond->code;

  return l + strlen (scond->name);
}

/* Parse an instruction prefix - F for float, D for DSP - and associated
   flags and condition codes.  */
static const char *
parse_prefix (const char *line, metag_insn *insn)
{
  const char *l = line;

  l = skip_whitespace (l);

  insn->type = INSN_GP;

  if (TOLOWER (*l) == FPU_PREFIX_CHAR)
    {
      if (strncasecmp (l, FFB_INSN, strlen(FFB_INSN)))
	{
	  insn->type = INSN_FPU;

	  l++;

	  if (*l == END_OF_INSN)
	    {
	      as_bad (_("premature end of floating point prefix"));
	      return NULL;
	    }

	  if (TOLOWER (*l) == FPU_DOUBLE_CHAR)
	    {
	      insn->fpu_width = FPU_WIDTH_DOUBLE;
	      l++;
	    }
	  else if (TOLOWER (*l) == FPU_PAIR_CHAR)
	    {
	      const char *l2 = l;

	      /* Check this isn't a split condition beginning with L.  */
	      l2 = parse_split_condition (l2, insn);

	      if (l2 && is_whitespace_char (*l2))
		{
		  l = l2;
		}
	      else
		{
		  insn->fpu_width = FPU_WIDTH_PAIR;
		  l++;
		}
	    }
	  else
	    {
	      insn->fpu_width = FPU_WIDTH_SINGLE;
	    }

	  if (TOLOWER (*l) == FPU_ACTION_ABS_CHAR)
	    {
	      insn->fpu_action_flags |= FPU_ACTION_ABS;
	      l++;
	    }
	  else if (TOLOWER (*l) == FPU_ACTION_INV_CHAR)
	    {
	      insn->fpu_action_flags |= FPU_ACTION_INV;
	      l++;
	    }

	  if (TOLOWER (*l) == FPU_ACTION_QUIET_CHAR)
	    {
	      insn->fpu_action_flags |= FPU_ACTION_QUIET;
	      l++;
	    }

	  if (TOLOWER (*l) == FPU_ACTION_ZERO_CHAR)
	    {
	      insn->fpu_action_flags |= FPU_ACTION_ZERO;
	      l++;
	    }

	  if (! is_whitespace_char (*l))
	    {
	      l = parse_split_condition (l, insn);

	      if (!l)
		{
		  as_bad (_("unknown floating point prefix character"));
		  return NULL;
		}
	    }

	  l = skip_space (l);
	}
    }
  else if (TOLOWER (*l) == DSP_PREFIX_CHAR)
    {
      if (strncasecmp (l, DCACHE_INSN, strlen (DCACHE_INSN)) &&
	  strncasecmp (l, DEFR_INSN, strlen (DEFR_INSN)))
	{
	  const char *ll = l;
	  insn->type = INSN_DSP;

	  l++;

	  insn->dsp_width = DSP_WIDTH_SINGLE;

	  while (!is_whitespace_char (*l))
	    {
	      /* We have to check for split condition codes first
		 because they are the longest strings to match,
		 e.g. if the string contains "LLS" we want it to match
		 the split condition code "LLS", not the dual unit
		 character "L".  */
	      ll = l;
	      l = parse_split_condition (l, insn);

	      if (l == NULL)
		l = ll;
	      else
		continue;

	      /* Accept an FPU prefix char which may be used when doing
		 template MOV with FPU registers. */
	      if (TOLOWER(*l) == FPU_PREFIX_CHAR)
		{
		  insn->type = INSN_DSP_FPU;
		  l++;
		  continue;
		}

	      if (TOLOWER(*l) == DSP_DUAL_CHAR)
		{
		  insn->dsp_width = DSP_WIDTH_DUAL;
		  l++;
		  continue;
		}

	      if (TOLOWER(*l) == DSP_ACTION_QR64_CHAR)
		{
		  insn->dsp_action_flags |= DSP_ACTION_QR64;
		  l++;
		  continue;
		}

	      if (TOLOWER(*l) == DSP_ACTION_UMUL_CHAR)
		{
		  insn->dsp_action_flags |= DSP_ACTION_UMUL;
		  l++;
		  continue;
		}

	      if (TOLOWER(*l) == DSP_ACTION_ROUND_CHAR)
		{
		  insn->dsp_action_flags |= DSP_ACTION_ROUND;
		  l++;
		  continue;
		}

	      if (TOLOWER(*l) == DSP_ACTION_CLAMP9_CHAR)
		{
		  insn->dsp_action_flags |= DSP_ACTION_CLAMP9;
		  l++;
		  continue;
		}

	      if (TOLOWER(*l) == DSP_ACTION_CLAMP8_CHAR)
		{
		  insn->dsp_action_flags |= DSP_ACTION_CLAMP8;
		  l++;
		  continue;
		}

	      if (TOLOWER(*l) == DSP_ACTION_MOD_CHAR)
		{
		  insn->dsp_action_flags |= DSP_ACTION_MOD;
		  l++;
		  continue;
		}

	      if (TOLOWER(*l) == DSP_ACTION_ACC_ZERO_CHAR)
		{
		  insn->dsp_action_flags |= DSP_ACTION_ACC_ZERO;
		  l++;
		  continue;
		}

	      if (TOLOWER(*l) == DSP_ACTION_ACC_ADD_CHAR)
		{
		  insn->dsp_action_flags |= DSP_ACTION_ACC_ADD;
		  l++;
		  continue;
		}

	      if (TOLOWER(*l) == DSP_ACTION_ACC_SUB_CHAR)
		{
		  insn->dsp_action_flags |= DSP_ACTION_ACC_SUB;
		  l++;
		  continue;
		}

	      if (TOLOWER(*l) == DSP_ACTION_OV_CHAR)
		{
		  insn->dsp_action_flags |= DSP_ACTION_OV;
		  l++;
		  continue;
		}

	      if (TOLOWER(*l) == DSP_DAOPPAME_8_CHAR)
		{
		  insn->dsp_daoppame_flags |= DSP_DAOPPAME_8;
		  l++;
		  continue;
		}

	      if (TOLOWER(*l) == DSP_DAOPPAME_16_CHAR)
		{
		  insn->dsp_daoppame_flags |= DSP_DAOPPAME_16;
		  l++;
		  continue;
		}

	      if (TOLOWER(*l) == DSP_DAOPPAME_TEMP_CHAR)
		{
		  insn->dsp_daoppame_flags |= DSP_DAOPPAME_TEMP;
		  l++;
		  continue;
		}

	      if (TOLOWER(*l) == DSP_DAOPPAME_HIGH_CHAR)
		{
		  insn->dsp_daoppame_flags |= DSP_DAOPPAME_HIGH;
		  l++;
		  continue;
		}

	      as_bad (_("unknown DSP prefix character %c %s"), *l, l);
	      return NULL;
	    }

	  l = skip_space (l);
	}
    }

  return l;
}

/* Return a list of appropriate instruction parsers for MNEMONIC.  */
static insn_templates *
find_insn_templates (const char *mnemonic)
{
  insn_template template;
  insn_templates entry;
  insn_templates *slot;

  entry.template = &template;

  memcpy ((void *)&entry.template->name, &mnemonic, sizeof (char *));

  slot = (insn_templates *) htab_find (mnemonic_htab, &entry);

  if (slot)
    return slot;

  return NULL;
}

/* Make an uppercase copy of SRC into DST and return DST.  */
static char *
strupper (char * dst, const char *src)
{
  size_t i = 0;

  while (src[i])
    {
      dst[i] = TOUPPER (src[i]);
      i++;
    }

  dst[i] = 0;

  return dst;
}

/* Calculate a hash value for a template. */
static hashval_t
hash_templates (const void *p)
{
  insn_templates *tp = (insn_templates *)p;
  char buf[MAX_MNEMONIC_LEN];

  strupper (buf, tp->template->name);

  return htab_hash_string (buf);
}

/* Check if two templates are equal.  */
static int
eq_templates (const void *a, const void *b)
{
  insn_templates *ta = (insn_templates *)a;
  insn_templates *tb = (insn_templates *)b;
  return strcasecmp (ta->template->name, tb->template->name) == 0;
}

/* Create the hash table required for parsing instructions.  */
static void
create_mnemonic_htab (void)
{
  size_t i, num_templates = sizeof(metag_optab)/sizeof(metag_optab[0]);

  mnemonic_htab = htab_create_alloc (num_templates, hash_templates,
				     eq_templates, NULL, xcalloc, free);

  for (i = 0; i < num_templates; i++)
    {
      const insn_template *template = &metag_optab[i];
      insn_templates **slot = NULL;
      insn_templates *new_entry;

      new_entry = XNEW (insn_templates);

      new_entry->template = template;
      new_entry->next = NULL;

      slot = (insn_templates **) htab_find_slot (mnemonic_htab, new_entry,
						 INSERT);

      if (*slot)
	{
	  insn_templates *last_entry = *slot;

	  while (last_entry->next)
	    last_entry = last_entry->next;

	  last_entry->next = new_entry;
	}
      else
	{
	  *slot = new_entry;
	}
    }
}

/* Calculate a hash value for a register. */
static hashval_t
hash_regs (const void *p)
{
  metag_reg *rp = (metag_reg *)p;
  char buf[MAX_REG_LEN];

  strupper (buf, rp->name);

  return htab_hash_string (buf);
}

/* Check if two registers are equal.  */
static int
eq_regs (const void *a, const void *b)
{
  metag_reg *ra = (metag_reg *)a;
  metag_reg *rb = (metag_reg *)b;
  return strcasecmp (ra->name, rb->name) == 0;
}

/* Create the hash table required for parsing registers.  */
static void
create_reg_htab (void)
{
  size_t i, num_regs = sizeof(metag_regtab)/sizeof(metag_regtab[0]);

  reg_htab = htab_create_alloc (num_regs, hash_regs,
				eq_regs, NULL, xcalloc, free);

  for (i = 0; i < num_regs; i++)
    {
      const metag_reg *reg = &metag_regtab[i];
      const metag_reg **slot;

      slot = (const metag_reg **) htab_find_slot (reg_htab, reg, INSERT);

      if (!*slot)
	*slot = reg;
    }
}

/* Create the hash table required for parsing DSP registers.  */
static void
create_dspreg_htabs (void)
{
  size_t i, num_regs = sizeof(metag_dsp_regtab)/sizeof(metag_dsp_regtab[0]);
  size_t h;

  dsp_reg_htab = htab_create_alloc (num_regs, hash_regs,
				    eq_regs, NULL, xcalloc, free);

  for (i = 0; i < num_regs; i++)
    {
      const metag_reg *reg = &metag_dsp_regtab[i];
      const metag_reg **slot;

      slot = (const metag_reg **) htab_find_slot (dsp_reg_htab, reg, INSERT);

      /* Make sure there are no hash table collisions, which would
	 require chaining entries.  */
      BFD_ASSERT (*slot == NULL);
      *slot = reg;
    }

  num_regs = sizeof(metag_dsp_tmpl_regtab[0])/sizeof(metag_dsp_tmpl_regtab[0][0]);

  for (h = 0; h < 2; h++)
    {
      dsp_tmpl_reg_htab[h] = htab_create_alloc (num_regs, hash_regs,
						eq_regs, NULL, xcalloc, free);
    }

  for (h = 0; h < 2; h++)
    {
      for (i = 0; i < num_regs; i++)
	{
	  const metag_reg *reg = &metag_dsp_tmpl_regtab[h][i];
	  const metag_reg **slot;
	  slot = (const metag_reg **) htab_find_slot (dsp_tmpl_reg_htab[h],
						      reg, INSERT);

	  /* Make sure there are no hash table collisions, which would
	     require chaining entries.  */
	  BFD_ASSERT (*slot == NULL);
	  *slot = reg;
	}
    }
}

/* Calculate a hash value for a split condition code. */
static hashval_t
hash_scond (const void *p)
{
  split_condition *cp = (split_condition *)p;
  char buf[4];

  strupper (buf, cp->name);

  return htab_hash_string (buf);
}

/* Check if two split condition codes are equal.  */
static int
eq_scond (const void *a, const void *b)
{
  split_condition *ra = (split_condition *)a;
  split_condition *rb = (split_condition *)b;

  return strcasecmp (ra->name, rb->name) == 0;
}

/* Create the hash table required for parsing split condition codes.  */
static void
create_scond_htab (void)
{
  size_t i, nentries;

  nentries = sizeof (metag_scondtab) / sizeof (metag_scondtab[0]);

  scond_htab = htab_create_alloc (nentries, hash_scond, eq_scond,
				  NULL, xcalloc, free);
  for (i = 0; i < nentries; i++)
    {
      const split_condition *scond = &metag_scondtab[i];
      const split_condition **slot;

      slot = (const split_condition **) htab_find_slot (scond_htab,
							scond, INSERT);
      /* Make sure there are no hash table collisions, which would
	 require chaining entries.  */
      BFD_ASSERT (*slot == NULL);
      *slot = scond;
    }
}

/* Entry point for instruction parsing.  */
static bfd_boolean
parse_insn (const char *line, metag_insn *insn)
{
  char mnemonic[MAX_MNEMONIC_LEN];
  const char *l = line;
  size_t mnemonic_len = 0;
  insn_templates *templates;

  l = skip_space (l);

  while (is_mnemonic_char(*l))
    {
      l++;
      mnemonic_len++;
    }

  if (mnemonic_len >= MAX_MNEMONIC_LEN)
    {
      as_bad (_("instruction mnemonic too long: %s"), line);
      return FALSE;
    }

  strncpy(mnemonic, line, mnemonic_len);

  mnemonic[mnemonic_len] = '\0';

  templates = find_insn_templates (mnemonic);

  if (templates)
    {
      insn_templates *current_template = templates;

      l = skip_space (l);

      while (current_template)
	{
	  const insn_template *template = current_template->template;
	  enum insn_encoding encoding = template->encoding;
	  insn_parser parser = insn_parsers[encoding];

	  current_template = current_template->next;

	  if (template->insn_type == INSN_GP &&
	      !(template->core_flags & mcpu_opt))
	    continue;

	  if (template->insn_type == INSN_FPU &&
	      !(template->core_flags & mfpu_opt))
	    continue;

	  if (template->insn_type == INSN_DSP &&
	      !(template->core_flags & mdsp_opt))
	    continue;

	  if (template->insn_type == INSN_DSP_FPU &&
	      !((template->core_flags & mdsp_opt) &&
		(template->core_flags & mfpu_opt)))
	    continue;

	  /* DSP instructions always require special decoding */
	  if ((insn->type == INSN_DSP && (template->insn_type != INSN_DSP)) ||
	      ((template->insn_type == INSN_DSP) && insn->type != INSN_DSP) ||
	      (insn->type == INSN_DSP_FPU && (template->insn_type != INSN_DSP_FPU)) ||
	      ((template->insn_type == INSN_DSP_FPU) && insn->type != INSN_DSP_FPU))
	    continue;

	  if (parser)
	    {
	      const char *end = parser(l, insn, template);

	      if (end != NULL)
		{
		  if (*end != END_OF_INSN)
		    as_bad (_("junk at end of line: \"%s\""), line);
		  else
		    return TRUE;
		}
	    }
	}

      as_bad (_("failed to assemble instruction: \"%s\""), line);
    }
  else
    {
      if (insn->type == INSN_FPU)
	as_bad (_("unknown floating point mnemonic: \"%s\""), mnemonic);
      else
	as_bad (_("unknown mnemonic: \"%s\""), mnemonic);
    }
  return FALSE;
}

static void
output_insn (metag_insn *insn)
{
  char *output;

  output = frag_more (insn->len);
  dwarf2_emit_insn (insn->len);

  if (insn->reloc_type != BFD_RELOC_UNUSED)
    {
      fix_new_exp (frag_now, output - frag_now->fr_literal,
		   insn->reloc_size, &insn->reloc_exp,
		   insn->reloc_pcrel, insn->reloc_type);
    }

  md_number_to_chars (output, insn->bits, insn->len);
}

void
md_assemble (char *line)
{
  const char *l = line;
  metag_insn insn;

  memset (&insn, 0, sizeof(insn));

  insn.reloc_type = BFD_RELOC_UNUSED;
  insn.reloc_pcrel = 0;
  insn.reloc_size = 4;

  if (!mnemonic_htab)
    {
      create_mnemonic_htab ();
      create_reg_htab ();
      create_dspreg_htabs ();
      create_scond_htab ();
    }

  l = parse_prefix (l, &insn);

  if (l == NULL)
    return;

  if (insn.type == INSN_DSP &&
      !mdsp_opt)
    {
      as_bad (_("cannot assemble DSP instruction, DSP option not set: %s"),
	      line);
      return;
    }
  else if (insn.type == INSN_FPU &&
	   !mfpu_opt)
    {
      as_bad (_("cannot assemble FPU instruction, FPU option not set: %s"),
	      line);
      return;
    }

  if (!parse_insn (l, &insn))
    return;

  output_insn (&insn);
}

void
md_operand (expressionS * expressionP)
{
  if (* input_line_pointer == IMM_CHAR)
    {
      input_line_pointer ++;
      expression (expressionP);
    }
}

valueT
md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
{
  return size;
}

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

/* Functions concerning relocs.  */

/* The location from which a PC relative jump should be calculated,
   given a PC relative reloc.  */

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))
      || metag_force_relocation (fixP))
    {
      /* The symbol is undefined (or is defined but not in this section).
	 Let the linker figure it out.  */
      return 0;
    }

  return fixP->fx_frag->fr_address + fixP->fx_where;
}

/* Write a value out to the object file, using the appropriate endianness.  */

void
md_number_to_chars (char * buf, valueT val, int n)
{
  number_to_chars_littleendian (buf, val, n);
}

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

/* Equal to MAX_PRECISION in atof-ieee.c */
#define MAX_LITTLENUMS 6

const char *
md_atof (int type, char * litP, int * sizeP)
{
  int              i;
  int              prec;
  LITTLENUM_TYPE   words [MAX_LITTLENUMS];
  char *           t;

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

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

   /* FIXME: Some targets allow other format chars for bigger sizes here.  */

    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 (i = 0; i < prec; i++)
    {
      md_number_to_chars (litP, (valueT) words[i],
			  sizeof (LITTLENUM_TYPE));
      litP += sizeof (LITTLENUM_TYPE);
    }

  return 0;
}

/* If this function returns non-zero, it prevents the relocation
   against symbol(s) in the FIXP from being replaced with relocations
   against section symbols, and guarantees that a relocation will be
   emitted even when the value can be resolved locally.  */

int
metag_force_relocation (fixS * fix)
{
  switch (fix->fx_r_type)
    {
    case BFD_RELOC_METAG_RELBRANCH_PLT:
    case BFD_RELOC_METAG_TLS_LE:
    case BFD_RELOC_METAG_TLS_IE:
    case BFD_RELOC_METAG_TLS_LDO:
    case BFD_RELOC_METAG_TLS_LDM:
    case BFD_RELOC_METAG_TLS_GD:
      return 1;
    default:
      ;
    }

  return generic_force_reloc (fix);
}

bfd_boolean
metag_fix_adjustable (fixS * fixP)
{
  if (fixP->fx_addsy == NULL)
    return 1;

  /* Prevent all adjustments to global symbols.  */
  if (S_IS_EXTERNAL (fixP->fx_addsy))
    return 0;
  if (S_IS_WEAK (fixP->fx_addsy))
    return 0;

  if (fixP->fx_r_type == BFD_RELOC_METAG_HI16_GOTOFF ||
      fixP->fx_r_type == BFD_RELOC_METAG_LO16_GOTOFF ||
      fixP->fx_r_type == BFD_RELOC_METAG_GETSET_GOTOFF ||
      fixP->fx_r_type == BFD_RELOC_METAG_GETSET_GOT ||
      fixP->fx_r_type == BFD_RELOC_METAG_HI16_GOTPC ||
      fixP->fx_r_type == BFD_RELOC_METAG_LO16_GOTPC ||
      fixP->fx_r_type == BFD_RELOC_METAG_HI16_PLT ||
      fixP->fx_r_type == BFD_RELOC_METAG_LO16_PLT ||
      fixP->fx_r_type == BFD_RELOC_METAG_RELBRANCH_PLT)
    return 0;

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

  return 1;
}

/* Return an initial guess of the length by which a fragment must grow to
   hold a branch to reach its destination.
   Also updates fr_type/fr_subtype as necessary.

   Called just before doing relaxation.
   Any symbol that is now undefined will not become defined.
   The guess for fr_var is ACTUALLY the growth beyond fr_fix.
   Whatever we do to grow fr_fix or fr_var contributes to our returned value.
   Although it may not be explicit in the frag, pretend fr_var starts with a
   0 value.  */

int
md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
			       segT    segment ATTRIBUTE_UNUSED)
{
  /* No assembler relaxation is defined (or necessary) for this port.  */
  abort ();
}

/* *fragP has been relaxed to its final size, and now needs to have
   the bytes inside it modified to conform to the new size.

   Called after relaxation is finished.
   fragP->fr_type == rs_machine_dependent.
   fragP->fr_subtype is the subtype of what the address relaxed to.  */

void
md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED,
		 fragS * fragP ATTRIBUTE_UNUSED)
{
  /* No assembler relaxation is defined (or necessary) for this port.  */
  abort ();
}

/* This is called from HANDLE_ALIGN in tc-metag.h.  */

void
metag_handle_align (fragS * fragP)
{
  static unsigned char const noop[4] = { 0xfe, 0xff, 0xff, 0xa0 };
  int bytes, fix;
  char *p;

  if (fragP->fr_type != rs_align_code)
    return;

  bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
  p = fragP->fr_literal + fragP->fr_fix;
  fix = 0;

  if (bytes & 3)
    {
      fix = bytes & 3;
      memset (p, 0, fix);
      p += fix;
      bytes -= fix;
    }

  while (bytes >= 4)
    {
      memcpy (p, noop, 4);
      p += 4;
      bytes -= 4;
      fix += 4;
    }

  fragP->fr_fix += fix;
  fragP->fr_var = 4;
}

static char *
metag_end_of_match (char * cont, const char * what)
{
  int len = strlen (what);

  if (strncasecmp (cont, what, strlen (what)) == 0
      && ! is_part_of_name (cont[len]))
    return cont + len;

  return NULL;
}

int
metag_parse_name (char const * name, expressionS * exprP, enum expr_mode mode,
		  char * nextcharP)
{
  char *next = input_line_pointer;
  char *next_end;
  int reloc_type;
  operatorT op_type;
  segT segment;

  exprP->X_op_symbol = NULL;
  exprP->X_md = BFD_RELOC_UNUSED;

  if (strcmp (name, GOT_NAME) == 0)
    {
      if (! GOT_symbol)
	GOT_symbol = symbol_find_or_make (name);

      exprP->X_add_symbol = GOT_symbol;
    no_suffix:
      /* If we have an absolute symbol or a
	 reg, then we know its value now.  */
      segment = S_GET_SEGMENT (exprP->X_add_symbol);
      if (mode != expr_defer && segment == absolute_section)
	{
	  exprP->X_op = O_constant;
	  exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
	  exprP->X_add_symbol = NULL;
	}
      else if (mode != expr_defer && segment == reg_section)
	{
	  exprP->X_op = O_register;
	  exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
	  exprP->X_add_symbol = NULL;
	}
      else
	{
	  exprP->X_op = O_symbol;
	  exprP->X_add_number = 0;
	}

      return 1;
    }

  exprP->X_add_symbol = symbol_find_or_make (name);

  if (*nextcharP != '@')
    goto no_suffix;
  else if ((next_end = metag_end_of_match (next + 1, "GOTOFF")))
    {
      reloc_type = BFD_RELOC_METAG_GOTOFF;
      op_type = O_PIC_reloc;
    }
  else if ((next_end = metag_end_of_match (next + 1, "GOT")))
    {
      reloc_type = BFD_RELOC_METAG_GETSET_GOT;
      op_type = O_PIC_reloc;
    }
  else if ((next_end = metag_end_of_match (next + 1, "PLT")))
    {
      reloc_type = BFD_RELOC_METAG_PLT;
      op_type = O_PIC_reloc;
    }
  else if ((next_end = metag_end_of_match (next + 1, "TLSGD")))
    {
      reloc_type = BFD_RELOC_METAG_TLS_GD;
      op_type = O_PIC_reloc;
    }
  else if ((next_end = metag_end_of_match (next + 1, "TLSLDM")))
    {
      reloc_type = BFD_RELOC_METAG_TLS_LDM;
      op_type = O_PIC_reloc;
    }
  else if ((next_end = metag_end_of_match (next + 1, "TLSLDO")))
    {
      reloc_type = BFD_RELOC_METAG_TLS_LDO;
      op_type = O_PIC_reloc;
    }
  else if ((next_end = metag_end_of_match (next + 1, "TLSIE")))
    {
      reloc_type = BFD_RELOC_METAG_TLS_IE;
      op_type = O_PIC_reloc;
    }
  else if ((next_end = metag_end_of_match (next + 1, "TLSIENONPIC")))
    {
      reloc_type = BFD_RELOC_METAG_TLS_IENONPIC;
      op_type = O_PIC_reloc;	/* FIXME: is this correct? */
    }
  else if ((next_end = metag_end_of_match (next + 1, "TLSLE")))
    {
      reloc_type = BFD_RELOC_METAG_TLS_LE;
      op_type = O_PIC_reloc;
    }
  else
    goto no_suffix;

  *input_line_pointer = *nextcharP;
  input_line_pointer = next_end;
  *nextcharP = *input_line_pointer;
  *input_line_pointer = '\0';

  exprP->X_op = op_type;
  exprP->X_add_number = 0;
  exprP->X_md = reloc_type;

  return 1;
}

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

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

  reloc		      = XNEW (arelent);
  reloc->sym_ptr_ptr  = XNEW (asymbol *);
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
  reloc->address      = fixp->fx_frag->fr_address + fixp->fx_where;

  reloc->addend = fixp->fx_offset;
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);

  if (reloc->howto == (reloc_howto_type *) NULL)
    {
      as_bad_where (fixp->fx_file, fixp->fx_line,
		    /* xgettext:c-format.  */
		    _("reloc %d not supported by object file format"),
		    (int) fixp->fx_r_type);

      xfree (reloc);

      return NULL;
    }

  return reloc;
}

static unsigned int
md_chars_to_number (char *val, int n)
{
  int retval;
  unsigned char * where = (unsigned char *) val;

  for (retval = 0; n--;)
    {
      retval <<= 8;
      retval |= where[n];
    }
  return retval;
}

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

  switch (fixP->fx_r_type)
    {
    case BFD_RELOC_METAG_TLS_GD:
    case BFD_RELOC_METAG_TLS_LE_HI16:
    case BFD_RELOC_METAG_TLS_LE_LO16:
    case BFD_RELOC_METAG_TLS_IE:
    case BFD_RELOC_METAG_TLS_IENONPIC_HI16:
    case BFD_RELOC_METAG_TLS_IENONPIC_LO16:
    case BFD_RELOC_METAG_TLS_LDM:
    case BFD_RELOC_METAG_TLS_LDO_HI16:
    case BFD_RELOC_METAG_TLS_LDO_LO16:
      S_SET_THREAD_LOCAL (fixP->fx_addsy);
      /* Fall through */

    case BFD_RELOC_METAG_HIADDR16:
    case BFD_RELOC_METAG_LOADDR16:
    case BFD_RELOC_VTABLE_INHERIT:
    case BFD_RELOC_VTABLE_ENTRY:
      fixP->fx_done = FALSE;
      break;

    case BFD_RELOC_METAG_REL8:
      if (!within_unsigned_range (value, IMM8_BITS))
	{
	  as_bad_where (fixP->fx_file, fixP->fx_line,
			"rel8 out of range %d", value);
	}
      else
	{
	  unsigned int newval;
	  newval = md_chars_to_number (buf, 4);
	  newval = (newval & 0xffffc03f) | ((value & IMM8_MASK) << 6);
	  md_number_to_chars (buf, newval, 4);
	}
      break;
    case BFD_RELOC_METAG_REL16:
      if (!within_unsigned_range (value, IMM16_BITS))
	{
	  as_bad_where (fixP->fx_file, fixP->fx_line,
			"rel16 out of range %d", value);
	}
      else
	{
	  unsigned int newval;
	  newval = md_chars_to_number (buf, 4);
	  newval = (newval & 0xfff80007) | ((value & IMM16_MASK) << 3);
	  md_number_to_chars (buf, newval, 4);
	}
      break;

    case BFD_RELOC_8:
      md_number_to_chars (buf, value, 1);
      break;
    case BFD_RELOC_16:
      md_number_to_chars (buf, value, 2);
      break;
    case BFD_RELOC_32:
      md_number_to_chars (buf, value, 4);
      break;
    case BFD_RELOC_64:
      md_number_to_chars (buf, value, 8);

    case BFD_RELOC_METAG_RELBRANCH:
      if (!value)
	break;

      value = value / 4;

      if (!within_signed_range (value, IMM19_BITS))
	{
	  as_bad_where (fixP->fx_file, fixP->fx_line,
			"relbranch out of range %d", value);
	}
      else
	{
	  unsigned int newval;
	  newval = md_chars_to_number (buf, 4);
	  newval = (newval & 0xff00001f) | ((value & IMM19_MASK) << 5);
	  md_number_to_chars (buf, newval, 4);
	}
	break;
    default:
      break;
    }

  if (fixP->fx_addsy == NULL)
    fixP->fx_done = TRUE;
}
