/* tc-mep.c -- Assembler for the Toshiba Media Processor.
   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007
   Free Software Foundation. Inc.

   This file is part of GAS, the GNU Assembler.

   GAS is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   GAS is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GAS; see the file COPYING.  If not, write to
   the Free Software Foundation, 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.  */

#include <stdio.h>
#include "as.h"
#include "dwarf2dbg.h"
#include "subsegs.h"
#include "symcat.h"
#include "opcodes/mep-desc.h"
#include "opcodes/mep-opc.h"
#include "cgen.h"
#include "elf/common.h"
#include "elf/mep.h"
#include "libbfd.h"
#include "xregex.h"

/* Structure to hold all of the different components describing
   an individual instruction.  */
typedef struct
{
  const CGEN_INSN *	insn;
  const CGEN_INSN *	orig_insn;
  CGEN_FIELDS		fields;
#if CGEN_INT_INSN_P
  CGEN_INSN_INT         buffer [1];
#define INSN_VALUE(buf) (*(buf))
#else
  unsigned char         buffer [CGEN_MAX_INSN_SIZE];
#define INSN_VALUE(buf) (buf)
#endif
  char *		addr;
  fragS *		frag;
  int                   num_fixups;
  fixS *                fixups [GAS_CGEN_MAX_FIXUPS];
  int                   indices [MAX_OPERAND_INSTANCES];
} mep_insn;

static int mode = CORE; /* Start in core mode. */
static int pluspresent = 0;
static int allow_disabled_registers = 0;
static int library_flag = 0;
static int mep_cop = EF_MEP_COP_NONE;

/* We're going to need to store all of the instructions along with
   their fixups so that we can parallelization grouping rules. */

static mep_insn saved_insns[MAX_SAVED_FIXUP_CHAINS];
static int num_insns_saved = 0;

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

static void mep_switch_to_vliw_mode (int);
static void mep_switch_to_core_mode (int);
static void mep_s_vtext (int);
static void mep_noregerr (int);

/* The target specific pseudo-ops which we support.  */
const pseudo_typeS md_pseudo_table[] =
{
  { "word",	cons,	                        4 },
  { "file",	(void (*) (int)) dwarf2_directive_file,   	0 },
  { "loc",	dwarf2_directive_loc,   	0 },
  { "vliw", 	mep_switch_to_vliw_mode,	0 },
  { "core", 	mep_switch_to_core_mode,	0 },
  { "vtext", 	mep_s_vtext,             	0 },
  { "noregerr",	mep_noregerr,	             	0 },
  { NULL, 	NULL,		        	0 }
};

/* Relocations against symbols are done in two
   parts, with a HI relocation and a LO relocation.  Each relocation
   has only 16 bits of space to store an addend.  This means that in
   order for the linker to handle carries correctly, it must be able
   to locate both the HI and the LO relocation.  This means that the
   relocations must appear in order in the relocation table.

   In order to implement this, we keep track of each unmatched HI
   relocation.  We then sort them so that they immediately precede the
   corresponding LO relocation. */

struct mep_hi_fixup
{
  struct mep_hi_fixup * next;	/* Next HI fixup.  */
  fixS * fixp;			/* This fixup.  */
  segT seg;			/* The section this fixup is in.  */
};

/* The list of unmatched HI relocs.  */
static struct mep_hi_fixup * mep_hi_fixup_list;


#define OPTION_EB		(OPTION_MD_BASE + 0)
#define OPTION_EL		(OPTION_MD_BASE + 1)
#define OPTION_CONFIG		(OPTION_MD_BASE + 2)
#define OPTION_AVERAGE		(OPTION_MD_BASE + 3)
#define OPTION_NOAVERAGE	(OPTION_MD_BASE + 4)
#define OPTION_MULT		(OPTION_MD_BASE + 5)
#define OPTION_NOMULT		(OPTION_MD_BASE + 6)
#define OPTION_DIV		(OPTION_MD_BASE + 7)
#define OPTION_NODIV		(OPTION_MD_BASE + 8)
#define OPTION_BITOPS		(OPTION_MD_BASE + 9)
#define OPTION_NOBITOPS		(OPTION_MD_BASE + 10)
#define OPTION_LEADZ		(OPTION_MD_BASE + 11)
#define OPTION_NOLEADZ		(OPTION_MD_BASE + 12)
#define OPTION_ABSDIFF		(OPTION_MD_BASE + 13)
#define OPTION_NOABSDIFF	(OPTION_MD_BASE + 14)
#define OPTION_MINMAX		(OPTION_MD_BASE + 15)
#define OPTION_NOMINMAX		(OPTION_MD_BASE + 16)
#define OPTION_CLIP		(OPTION_MD_BASE + 17)
#define OPTION_NOCLIP		(OPTION_MD_BASE + 18)
#define OPTION_SATUR		(OPTION_MD_BASE + 19)
#define OPTION_NOSATUR		(OPTION_MD_BASE + 20)
#define OPTION_COP32		(OPTION_MD_BASE + 21)
#define OPTION_REPEAT		(OPTION_MD_BASE + 25)
#define OPTION_NOREPEAT		(OPTION_MD_BASE + 26)
#define OPTION_DEBUG		(OPTION_MD_BASE + 27)
#define OPTION_NODEBUG		(OPTION_MD_BASE + 28)
#define OPTION_UCI		(OPTION_MD_BASE + 29)
#define OPTION_NOUCI		(OPTION_MD_BASE + 30)
#define OPTION_DSP		(OPTION_MD_BASE + 31)
#define OPTION_NODSP		(OPTION_MD_BASE + 32)
#define OPTION_LIBRARY		(OPTION_MD_BASE + 33)

struct option md_longopts[] = {
  { "EB",          no_argument, NULL, OPTION_EB},
  { "EL",          no_argument, NULL, OPTION_EL},
  { "mconfig",     required_argument, NULL, OPTION_CONFIG},
  { "maverage",    no_argument, NULL, OPTION_AVERAGE},
  { "mno-average", no_argument, NULL, OPTION_NOAVERAGE},
  { "mmult",       no_argument, NULL, OPTION_MULT},
  { "mno-mult",    no_argument, NULL, OPTION_NOMULT},
  { "mdiv",        no_argument, NULL, OPTION_DIV},
  { "mno-div",     no_argument, NULL, OPTION_NODIV},
  { "mbitops",     no_argument, NULL, OPTION_BITOPS},
  { "mno-bitops",  no_argument, NULL, OPTION_NOBITOPS},
  { "mleadz",      no_argument, NULL, OPTION_LEADZ},
  { "mno-leadz",   no_argument, NULL, OPTION_NOLEADZ},
  { "mabsdiff",    no_argument, NULL, OPTION_ABSDIFF},
  { "mno-absdiff", no_argument, NULL, OPTION_NOABSDIFF},
  { "mminmax",     no_argument, NULL, OPTION_MINMAX},
  { "mno-minmax",  no_argument, NULL, OPTION_NOMINMAX},
  { "mclip",       no_argument, NULL, OPTION_CLIP},
  { "mno-clip",    no_argument, NULL, OPTION_NOCLIP},
  { "msatur",      no_argument, NULL, OPTION_SATUR},
  { "mno-satur",   no_argument, NULL, OPTION_NOSATUR},
  { "mcop32",	   no_argument, NULL, OPTION_COP32},
  { "mdebug",      no_argument, NULL, OPTION_DEBUG},
  { "mno-debug",   no_argument, NULL, OPTION_NODEBUG},
  { "muci",        no_argument, NULL, OPTION_UCI},
  { "mno-uci",     no_argument, NULL, OPTION_NOUCI},
  { "mdsp",        no_argument, NULL, OPTION_DSP},
  { "mno-dsp",     no_argument, NULL, OPTION_NODSP},
  { "mlibrary",    no_argument, NULL, OPTION_LIBRARY},
  { NULL, 0, NULL, 0 } };
size_t md_longopts_size = sizeof (md_longopts);

const char * md_shortopts = "";
static int optbits = 0;
static int optbitset = 0;

int
md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
{
  int i, idx;
  switch (c)
    {
    case OPTION_EB:
      target_big_endian = 1;
      break;
    case OPTION_EL:
      target_big_endian = 0;
      break;
    case OPTION_CONFIG:
      idx = 0;
      for (i=1; mep_config_map[i].name; i++)
	if (strcmp (mep_config_map[i].name, arg) == 0)
	  {
	    idx = i;
	    break;
	  }
      if (!idx)
	{
	  fprintf (stderr, "Error: unknown configuration %s\n", arg);
	  return 0;
	}
      mep_config_index = idx;
      target_big_endian = mep_config_map[idx].big_endian;
      break;
    case OPTION_AVERAGE:
      optbits |= 1 << CGEN_INSN_OPTIONAL_AVE_INSN;
      optbitset |= 1 << CGEN_INSN_OPTIONAL_AVE_INSN;
      break;
    case OPTION_NOAVERAGE:
      optbits &= ~(1 << CGEN_INSN_OPTIONAL_AVE_INSN);
      optbitset |= 1 << CGEN_INSN_OPTIONAL_AVE_INSN;
      break;
    case OPTION_MULT:
      optbits |= 1 << CGEN_INSN_OPTIONAL_MUL_INSN;
      optbitset |= 1 << CGEN_INSN_OPTIONAL_MUL_INSN;
      break;
    case OPTION_NOMULT:
      optbits &= ~(1 << CGEN_INSN_OPTIONAL_MUL_INSN);
      optbitset |= 1 << CGEN_INSN_OPTIONAL_MUL_INSN;
      break;
    case OPTION_DIV:
      optbits |= 1 << CGEN_INSN_OPTIONAL_DIV_INSN;
      optbitset |= 1 << CGEN_INSN_OPTIONAL_DIV_INSN;
      break;
    case OPTION_NODIV:
      optbits &= ~(1 << CGEN_INSN_OPTIONAL_DIV_INSN);
      optbitset |= 1 << CGEN_INSN_OPTIONAL_DIV_INSN;
      break;
    case OPTION_BITOPS:
      optbits |= 1 << CGEN_INSN_OPTIONAL_BIT_INSN;
      optbitset |= 1 << CGEN_INSN_OPTIONAL_BIT_INSN;
      break;
    case OPTION_NOBITOPS:
      optbits &= ~(1 << CGEN_INSN_OPTIONAL_BIT_INSN);
      optbitset |= 1 << CGEN_INSN_OPTIONAL_BIT_INSN;
      break;
    case OPTION_LEADZ:
      optbits |= 1 << CGEN_INSN_OPTIONAL_LDZ_INSN;
      optbitset |= 1 << CGEN_INSN_OPTIONAL_LDZ_INSN;
      break;
    case OPTION_NOLEADZ:
      optbits &= ~(1 << CGEN_INSN_OPTIONAL_LDZ_INSN);
      optbitset |= 1 << CGEN_INSN_OPTIONAL_LDZ_INSN;
      break;
    case OPTION_ABSDIFF:
      optbits |= 1 << CGEN_INSN_OPTIONAL_ABS_INSN;
      optbitset |= 1 << CGEN_INSN_OPTIONAL_ABS_INSN;
      break;
    case OPTION_NOABSDIFF:
      optbits &= ~(1 << CGEN_INSN_OPTIONAL_ABS_INSN);
      optbitset |= 1 << CGEN_INSN_OPTIONAL_ABS_INSN;
      break;
    case OPTION_MINMAX:
      optbits |= 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN;
      optbitset |= 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN;
      break;
    case OPTION_NOMINMAX:
      optbits &= ~(1 << CGEN_INSN_OPTIONAL_MINMAX_INSN);
      optbitset |= 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN;
      break;
    case OPTION_CLIP:
      optbits |= 1 << CGEN_INSN_OPTIONAL_CLIP_INSN;
      optbitset |= 1 << CGEN_INSN_OPTIONAL_CLIP_INSN;
      break;
    case OPTION_NOCLIP:
      optbits &= ~(1 << CGEN_INSN_OPTIONAL_CLIP_INSN);
      optbitset |= 1 << CGEN_INSN_OPTIONAL_CLIP_INSN;
      break;
    case OPTION_SATUR:
      optbits |= 1 << CGEN_INSN_OPTIONAL_SAT_INSN;
      optbitset |= 1 << CGEN_INSN_OPTIONAL_SAT_INSN;
      break;
    case OPTION_NOSATUR:
      optbits &= ~(1 << CGEN_INSN_OPTIONAL_SAT_INSN);
      optbitset |= 1 << CGEN_INSN_OPTIONAL_SAT_INSN;
      break;
    case OPTION_COP32:
      optbits |= 1 << CGEN_INSN_OPTIONAL_CP_INSN;
      optbitset |= 1 << CGEN_INSN_OPTIONAL_CP_INSN;
      break;
    case OPTION_DEBUG:
      optbits |= 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN;
      optbitset |= 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN;
      break;
    case OPTION_NODEBUG:
      optbits &= ~(1 << CGEN_INSN_OPTIONAL_DEBUG_INSN);
      optbitset |= 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN;
      break;
    case OPTION_UCI:
      optbits |= 1 << CGEN_INSN_OPTIONAL_UCI_INSN;
      optbitset |= 1 << CGEN_INSN_OPTIONAL_UCI_INSN;
      break;
    case OPTION_NOUCI:
      optbits &= ~(1 << CGEN_INSN_OPTIONAL_UCI_INSN);
      optbitset |= 1 << CGEN_INSN_OPTIONAL_UCI_INSN;
      break;
    case OPTION_DSP:
      optbits |= 1 << CGEN_INSN_OPTIONAL_DSP_INSN;
      optbitset |= 1 << CGEN_INSN_OPTIONAL_DSP_INSN;
      break;
    case OPTION_NODSP:
      optbits &= ~(1 << CGEN_INSN_OPTIONAL_DSP_INSN);
      optbitset |= 1 << CGEN_INSN_OPTIONAL_DSP_INSN;
      break;
    case OPTION_LIBRARY:
      library_flag = EF_MEP_LIBRARY;
      break;
    case OPTION_REPEAT:
    case OPTION_NOREPEAT:
      break;
    default:
      return 0;
    }
  return 1;
}

void
md_show_usage (FILE *stream)
{
  fprintf (stream, _("MeP specific command line options:\n\
  -EB                     assemble for a big endian system\n\
  -EL                     assemble for a little endian system (default)\n\
  -mconfig=<name>         specify a chip configuration to use\n\
  -maverage -mno-average -mmult -mno-mult -mdiv -mno-div\n\
  -mbitops -mno-bitops -mleadz -mno-leadz -mabsdiff -mno-absdiff\n\
  -mminmax -mno-minmax -mclip -mno-clip -msatur -mno-satur -mcop32\n\
                          enable/disable the given opcodes\n\
\n\
  If -mconfig is given, the other -m options modify it.  Otherwise,\n\
  if no -m options are given, all core opcodes are enabled;\n\
  if any enabling -m options are given, only those are enabled;\n\
  if only disabling -m options are given, only those are disabled.\n\
"));
  if (mep_config_map[1].name)
    {
      int i;
      fprintf (stream, "  -mconfig=STR            specify the configuration to use\n");
      fprintf (stream, "  Configurations:");
      for (i=0; mep_config_map[i].name; i++)
	fprintf (stream, " %s", mep_config_map[i].name);
      fprintf (stream, "\n");
    }
}



static void
mep_check_for_disabled_registers (mep_insn *insn)
{
  static int initted = 0;
  static int has_mul_div = 0;
  static int has_cop = 0;
  static int has_debug = 0;
  unsigned int b, r;

  if (allow_disabled_registers)
    return;

#if !CGEN_INT_INSN_P
  if (target_big_endian)
    b = insn->buffer[0] * 256 + insn->buffer[1];
  else
    b = insn->buffer[1] * 256 + insn->buffer[0];
#else
  b = insn->buffer[0];
#endif

  if ((b & 0xfffff00e) == 0x7008 /* stc */
      || (b & 0xfffff00e) == 0x700a /* ldc */)
    {
      if (!initted)
	{
	  initted = 1;
	  if ((MEP_OMASK & (1 << CGEN_INSN_OPTIONAL_MUL_INSN))
	      || (MEP_OMASK & (1 << CGEN_INSN_OPTIONAL_DIV_INSN)))
	    has_mul_div = 1;
	  if (MEP_OMASK & (1 << CGEN_INSN_OPTIONAL_DEBUG_INSN))
	    has_debug = 1;
	  if (MEP_OMASK & (1 << CGEN_INSN_OPTIONAL_CP_INSN))
	    has_cop = 1;
	}

      r = ((b & 0x00f0) >> 4) | ((b & 0x0001) << 4);
      switch (r)
	{
	case 7: /* $hi */
	case 8: /* $lo */
	  if (!has_mul_div)
	    as_bad ("$hi and $lo are disabled when MUL and DIV are off");
	  break;
	case 12: /* $mb0 */
	case 13: /* $me0 */
	case 14: /* $mb1 */
	case 15: /* $me1 */
	  if (!has_cop)
	    as_bad ("$mb0, $me0, $mb1, and $me1 are disabled when COP is off");
	  break;
	case 24: /* $dbg */
	case 25: /* $depc */
	  if (!has_debug)
	    as_bad ("$dbg and $depc are disabled when DEBUG is off");
	  break;
	}
    }
}

static int
mep_machine (void)
{
  switch (MEP_CPU & EF_MEP_CPU_MASK)
    {
    default: break;
    case EF_MEP_CPU_C2: return bfd_mach_mep;
    case EF_MEP_CPU_C3: return bfd_mach_mep;
    case EF_MEP_CPU_C4: return bfd_mach_mep;
    case EF_MEP_CPU_C5: return bfd_mach_mep_c5;
    case EF_MEP_CPU_H1: return bfd_mach_mep_h1;
    }

  return bfd_mach_mep;
}

/* The MeP version of the cgen parse_operand function.  The only difference
   from the standard version is that we want to avoid treating '$foo' and
   '($foo...)' as references to a symbol called '$foo'.  The chances are
   that '$foo' is really a misspelt register.  */

static const char *
mep_parse_operand (CGEN_CPU_DESC cd, enum cgen_parse_operand_type want,
		   const char **strP, int opindex, int opinfo,
		   enum cgen_parse_operand_result *resultP, bfd_vma *valueP)
{
  if (want == CGEN_PARSE_OPERAND_INTEGER || want == CGEN_PARSE_OPERAND_ADDRESS)
    {
      const char *next;

      next = *strP;
      while (*next == '(')
	next++;
      if (*next == '$')
	return "Not a valid literal";
    }
  return gas_cgen_parse_operand (cd, want, strP, opindex, opinfo,
				 resultP, valueP);
}

void
md_begin ()
{
  /* Initialize the `cgen' interface.  */

  /* If the user specifies no options, we default to allowing
     everything.  If the user specifies any enabling options, we
     default to allowing only what is specified.  If the user
     specifies only disabling options, we only disable what is
     specified.  If the user specifies options and a config, the
     options modify the config.  */
  if (optbits && mep_config_index == 0)
    MEP_OMASK = optbits;
  else
    MEP_OMASK = (MEP_OMASK & ~optbitset) | optbits;

  mep_cop = mep_config_map[mep_config_index].cpu_flag & EF_MEP_COP_MASK;

  /* Set the machine number and endian.  */
  gas_cgen_cpu_desc = mep_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
					 CGEN_CPU_OPEN_ENDIAN,
					 target_big_endian
					 ? CGEN_ENDIAN_BIG
					 : CGEN_ENDIAN_LITTLE,
					 CGEN_CPU_OPEN_ISAS, 0,
					 CGEN_CPU_OPEN_END);
  mep_cgen_init_asm (gas_cgen_cpu_desc);

  /* This is a callback from cgen to gas to parse operands.  */
  cgen_set_parse_operand_fn (gas_cgen_cpu_desc, mep_parse_operand);

  /* Identify the architecture.  */
  bfd_default_set_arch_mach (stdoutput, bfd_arch_mep, mep_machine ());

  /* Store the configuration number and core.  */
  bfd_set_private_flags (stdoutput, MEP_CPU | MEP_CONFIG | library_flag);

  /* Initialize the array we'll be using to store fixups.  */
  gas_cgen_initialize_saved_fixups_array();
}

/* Variant of mep_cgen_assemble_insn.  Assemble insn STR of cpu CD as a 
   coprocessor instruction, if possible, into FIELDS, BUF, and INSN.  */

static const CGEN_INSN *
mep_cgen_assemble_cop_insn (CGEN_CPU_DESC cd,
			    const char *str,
			    CGEN_FIELDS *fields,
			    CGEN_INSN_BYTES_PTR buf,
			    const struct cgen_insn *pinsn)
{
  const char *start;
  CGEN_INSN_LIST *ilist;
  const char *errmsg = NULL;

  /* The instructions are stored in hashed lists. */
  ilist = CGEN_ASM_LOOKUP_INSN (gas_cgen_cpu_desc, 
				CGEN_INSN_MNEMONIC (pinsn));

  start = str;
  for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
    {
      const CGEN_INSN *insn = ilist->insn;
      if (strcmp (CGEN_INSN_MNEMONIC (ilist->insn), 
		  CGEN_INSN_MNEMONIC (pinsn)) == 0
	  && MEP_INSN_COP_P (ilist->insn)
	  && mep_cgen_insn_supported (cd, insn))
	{
	  str = start;

	  /* skip this insn if str doesn't look right lexically */
	  if (CGEN_INSN_RX (insn) != NULL &&
	      regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
	    continue;

	  /* Allow parse/insert handlers to obtain length of insn.  */
	  CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);

	  errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
	  if (errmsg != NULL)
	    continue;
	  
	  errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
					      (bfd_vma) 0);
	  if (errmsg != NULL)
	    continue;

	  return insn;
	}
    }
  return pinsn;
}

static void
mep_save_insn (mep_insn insn)
{
  /* Consider change MAX_SAVED_FIXUP_CHAINS to MAX_PARALLEL_INSNS. */
  if (num_insns_saved < 0 || num_insns_saved >= MAX_SAVED_FIXUP_CHAINS)
    {
      as_fatal("index into saved_insns[] out of bounds.");
      return;
    }
  saved_insns[num_insns_saved] = insn;
  gas_cgen_save_fixups(num_insns_saved);
  num_insns_saved++;
}

static void
mep_check_parallel32_scheduling (void)
{
  int insn0iscopro, insn1iscopro, insn0length, insn1length;

  /* More than two instructions means that either someone is referring to
     an internally parallel core or an internally parallel coprocessor,
     neither of which are supported at this time.  */
  if ( num_insns_saved > 2 )
    as_fatal("Internally paralled cores and coprocessors not supported.");

  /* If there are no insns saved, that's ok.  Just return.  This will
     happen when mep_process_saved_insns is called when the end of the
     source file is reached and there are no insns left to be processed.  */
  if (num_insns_saved == 0)
    return;

  /* Check some of the attributes of the first insn.  */
  insn0iscopro = MEP_INSN_COP_P (saved_insns[0].insn);
  insn0length = CGEN_FIELDS_BITSIZE (& saved_insns[0].fields);

  if (num_insns_saved == 2)
    {
      /* Check some of the attributes of the first insn.  */
      insn1iscopro = MEP_INSN_COP_P (saved_insns[1].insn);
      insn1length = CGEN_FIELDS_BITSIZE (& saved_insns[1].fields);

      if ((insn0iscopro && !insn1iscopro)
          || (insn1iscopro && !insn0iscopro))
	{
          /* We have one core and one copro insn.  If their sizes
             add up to 32, then the combination is valid.  */
	  if (insn0length + insn1length == 32)
	    return;
          else
	    as_bad ("core and copro insn lengths must total 32 bits.");
	}
      else
        as_bad ("vliw group must consist of 1 core and 1 copro insn."); 
    }
  else
    {
      /* If we arrive here, we have one saved instruction.  There are a
	 number of possible cases:

	 1.  The instruction is a 32 bit core or coprocessor insn and
             can be executed by itself.  Valid.

         2.  The instrucion is a core instruction for which a cop nop
             exists.  In this case, insert the cop nop into the saved
             insn array after the core insn and return.  Valid.

         3.  The instruction is a coprocessor insn for which a core nop
             exists.  In this case, move the coprocessor insn to the
             second element of the array and put the nop in the first
	     element then return.  Valid.

         4. The instruction is a core or coprocessor instruction for
            which there is no matching coprocessor or core nop to use
	    to form a valid vliw insn combination.  In this case, we
	    we have to abort.  */

      if (insn0length > 32)
	as_fatal ("Cannot use 48- or 64-bit insns with a 32 bit datapath.");

      if (insn0length == 32)
	return;

      /* Insn is smaller than datapath.  If there are no matching
         nops for this insn, then terminate assembly.  */
      if (CGEN_INSN_ATTR_VALUE (saved_insns[0].insn,
                                CGEN_INSN_VLIW32_NO_MATCHING_NOP))
	as_fatal ("No valid nop.");

      /* At this point we know that we have a single 16-bit insn that has 
	 a matching nop.  We have to assemble it and put it into the saved 
         insn and fixup chain arrays. */

      if (insn0iscopro)
	{
          char *errmsg;
          mep_insn insn;
         
          /* Move the insn and it's fixups to the second element of the
             saved insns arrary and insert a 16 bit core nope into the
             first element. */
             insn.insn = mep_cgen_assemble_insn (gas_cgen_cpu_desc, "nop",
                                                 &insn.fields, insn.buffer,
                                                 &errmsg);
             if (!insn.insn)
               {
                 as_bad ("%s", errmsg);
                 return;
               }

             /* Move the insn in element 0 to element 1 and insert the
                 nop into element 0.  Move the fixups in element 0 to
                 element 1 and save the current fixups to element 0.  
                 Really there aren't any fixups at this point because we're
                 inserting a nop but we might as well be general so that
                 if there's ever a need to insert a general insn, we'll
                 have an example. */
              saved_insns[1] = saved_insns[0];
              saved_insns[0] = insn;
              num_insns_saved++;
              gas_cgen_swap_fixups (0);
              gas_cgen_save_fixups (1);
	}
      else
	{
          char * errmsg;
          mep_insn insn;
	  int insn_num = saved_insns[0].insn->base->num;

	  /* Use 32 bit branches and skip the nop.  */
	  if (insn_num == MEP_INSN_BSR12
	      || insn_num == MEP_INSN_BEQZ
	      || insn_num == MEP_INSN_BNEZ)
	    return;

          /* Insert a 16-bit coprocessor nop.  Note that at the time */
          /* this was done, no 16-bit coprocessor nop was defined.   */
	  insn.insn = mep_cgen_assemble_insn (gas_cgen_cpu_desc, "cpnop16",
					      &insn.fields, insn.buffer,
					      &errmsg);
          if (!insn.insn)
            {
              as_bad ("%s", errmsg);
              return;
            }

          /* Now put the insn and fixups into the arrays.  */
          mep_save_insn (insn);
	}
    }
}

static void
mep_check_parallel64_scheduling (void)
{
  int insn0iscopro, insn1iscopro, insn0length, insn1length;

  /* More than two instructions means that someone is referring to an
     internally parallel core or an internally parallel coprocessor.  */
  /* These are not currently supported.  */
  if (num_insns_saved > 2)
    as_fatal ("Internally parallel cores of coprocessors not supported.");

  /* If there are no insns saved, that's ok.  Just return.  This will
     happen when mep_process_saved_insns is called when the end of the
     source file is reached and there are no insns left to be processed.  */
  if (num_insns_saved == 0)
    return;

  /* Check some of the attributes of the first insn.  */
  insn0iscopro = MEP_INSN_COP_P (saved_insns[0].insn);
  insn0length = CGEN_FIELDS_BITSIZE (& saved_insns[0].fields);

  if (num_insns_saved == 2)
    {
      /* Check some of the attributes of the first insn. */
      insn1iscopro = MEP_INSN_COP_P (saved_insns[1].insn);
      insn1length = CGEN_FIELDS_BITSIZE (& saved_insns[1].fields);

      if ((insn0iscopro && !insn1iscopro)
	  || (insn1iscopro && !insn0iscopro))
	{
	  /* We have one core and one copro insn.  If their sizes
	     add up to 64, then the combination is valid.  */
	  if (insn0length + insn1length == 64)
            return;
	  else
            as_bad ("core and copro insn lengths must total 64 bits.");
	}
      else
        as_bad ("vliw group must consist of 1 core and 1 copro insn.");
    }
  else
    {
      /* If we arrive here, we have one saved instruction.  There are a
	 number of possible cases:

         1.  The instruction is a 64 bit coprocessor insn and can be
             executed by itself.  Valid.

         2.  The instrucion is a core instruction for which a cop nop
             exists.  In this case, insert the cop nop into the saved
             insn array after the core insn and return.  Valid.

         3.  The instruction is a coprocessor insn for which a core nop
             exists.  In this case, move the coprocessor insn to the
             second element of the array and put the nop in the first
             element then return.  Valid.

         4.  The instruction is a core or coprocessor instruction for
             which there is no matching coprocessor or core nop to use
             to form a valid vliw insn combination.  In this case, we
	     we have to abort.  */

      /* If the insn is 64 bits long, it can run alone.  The size check
	 is done indepependantly of whether the insn is core or copro
	 in case 64 bit coprocessor insns are added later.  */
      if (insn0length == 64)
        return;

      /* Insn is smaller than datapath.  If there are no matching
	 nops for this insn, then terminate assembly.  */
      if (CGEN_INSN_ATTR_VALUE (saved_insns[0].insn,
				CGEN_INSN_VLIW64_NO_MATCHING_NOP))
	as_fatal ("No valid nop.");

      if (insn0iscopro)
	{
	  char *errmsg;
	  mep_insn insn;

          /* Initialize the insn buffer.  */
	  memset (insn.buffer, 0, sizeof(insn.buffer));

	  /* We have a coprocessor insn.  At this point in time there
	     are is 32-bit core nop.  There is only a 16-bit core
	     nop.  The idea is to allow for a relatively arbitrary
	     coprocessor to be specified.  We aren't looking at
	     trying to cover future changes in the core at this time
	     since it is assumed that the core will remain fairly
	     static.  If there ever are 32 or 48 bit core nops added,
	     they will require entries below.  */

	  if (insn0length == 48)
	    {
	      /* Move the insn and fixups to the second element of the
		 arrays then assemble and insert a 16 bit core nop.  */
	      insn.insn = mep_cgen_assemble_insn (gas_cgen_cpu_desc, "nop",
						  & insn.fields, insn.buffer,
						  & errmsg);
	    }
          else
            {
              /* If this is reached, then we have a single coprocessor
                 insn that is not 48 bits long, but for which the assembler
                 thinks there is a matching core nop.  If a 32-bit core
                 nop has been added, then make the necessary changes and
                 handle its assembly and insertion here.  Otherwise,
                 go figure out why either:
              
                 1. The assembler thinks that there is a 32-bit core nop
                    to match a 32-bit coprocessor insn, or
                 2. The assembler thinks that there is a 48-bit core nop
                    to match a 16-bit coprocessor insn.  */

              as_fatal ("Assembler expects a non-existent core nop.");
            }

	 if (!insn.insn)
	   {
	     as_bad ("%s", errmsg);
	     return;
	   }

         /* Move the insn in element 0 to element 1 and insert the
            nop into element 0.  Move the fixups in element 0 to
            element 1 and save the current fixups to element 0. 
	    Really there aren't any fixups at this point because we're
	    inserting a nop but we might as well be general so that
	    if there's ever a need to insert a general insn, we'll
	    have an example. */

         saved_insns[1] = saved_insns[0];
         saved_insns[0] = insn;
         num_insns_saved++;
         gas_cgen_swap_fixups(0);
         gas_cgen_save_fixups(1);

	}
      else
	{
	  char * errmsg;
	  mep_insn insn;

          /* Initialize the insn buffer */
	  memset (insn.buffer, 0, sizeof(insn.buffer));

	  /* We have a core insn.  We have to handle all possible nop
	     lengths.  If a coprocessor doesn't have a nop of a certain
	     length but there exists core insns that when combined with
	      a nop of that length would fill the datapath, those core
	      insns will be flagged with the VLIW_NO_CORRESPONDING_NOP
	      attribute.  That will ensure that when used in a way that
	      requires a nop to be inserted, assembly will terminate
	      before reaching this section of code.  This guarantees
	      that cases below which would result in the attempted
	      insertion of nop that doesn't exist will never be entered.  */
	  if (insn0length == 16)
	    {
	      /* Insert 48 bit coprocessor nop.          */
	      /* Assemble it and put it into the arrays. */
	      insn.insn = mep_cgen_assemble_insn (gas_cgen_cpu_desc, "cpnop48",
						  &insn.fields, insn.buffer,
						  &errmsg);
	    }
	  else if (insn0length == 32)
	    {
	      /* Insert 32 bit coprocessor nop. */
	      insn.insn = mep_cgen_assemble_insn (gas_cgen_cpu_desc, "cpnop32",
						  &insn.fields, insn.buffer,
						  &errmsg);
	    }
	  else if (insn0length == 48)
	    {
	      /* Insert 16 bit coprocessor nop. */
	      insn.insn = mep_cgen_assemble_insn (gas_cgen_cpu_desc, "cpnop16",
						  &insn.fields, insn.buffer,
						  &errmsg);
	    }
	  else
	    /* Core insn has an invalid length.  Something has gone wrong. */
	    as_fatal ("Core insn has invalid length!  Something is wrong!");

	  if (!insn.insn)
	    {
	      as_bad ("%s", errmsg);
	      return;
	    }

	  /* Now put the insn and fixups into the arrays.  */
	  mep_save_insn (insn);
	}
    }
}

#ifdef MEP_IVC2_SUPPORTED

/* IVC2 packing is different than other VLIW coprocessors.  Many of
   the COP insns can be placed in any of three different types of
   slots, and each bundle can hold up to three insns - zero or one
   core insns and one or two IVC2 insns.  The insns in CGEN are tagged
   with which slots they're allowed in, and we have to decide based on
   that whether or not the user had given us a possible bundling.  */

static int
slot_ok (int idx, int slot)
{
  const CGEN_INSN *insn = saved_insns[idx].insn;
  return CGEN_ATTR_CGEN_INSN_SLOTS_VALUE (CGEN_INSN_ATTRS (insn)) & (1 << slot);
}

static void
mep_check_ivc2_scheduling (void)
{
  /* VLIW modes:

     V1 [-----core-----][--------p0s-------][------------p1------------]
     V2 [-------------core-------------]xxxx[------------p1------------]
     V3 1111[--p0--]0111[--------p0--------][------------p1------------]
  */

  int slots[5]; /* Indexed off the SLOTS_ATTR enum.  */
  int corelength;
  int i;
  bfd_byte temp[4];
  bfd_byte *f;
  int e = target_big_endian ? 0 : 1;

  /* If there are no insns saved, that's ok.  Just return.  This will
     happen when mep_process_saved_insns is called when the end of the
     source file is reached and there are no insns left to be processed.  */
  if (num_insns_saved == 0)
    return;

  for (i=0; i<5; i++)
    slots[i] = -1;

  if (slot_ok (0, SLOTS_CORE))
    {
      slots[SLOTS_CORE] = 0;
      corelength = CGEN_FIELDS_BITSIZE (& saved_insns[0].fields);
    }
  else
    corelength = 0;

  if (corelength == 16)
    {
      /* V1 mode: we need a P0S slot and a P1 slot.  */
      switch (num_insns_saved)
	{
	case 1:
	  /* No other insns, fill with NOPs. */
	  break;

	case 2:
	  if (slot_ok (1, SLOTS_P1))
	    slots[SLOTS_P1] = 1;
	  else if (slot_ok (1, SLOTS_P0S))
	    slots[SLOTS_P0S] = 1;
	  else
	    as_bad ("cannot pack %s with a 16-bit insn",
		    CGEN_INSN_NAME (saved_insns[1].insn));
	  break;

	case 3:
	  if (slot_ok (1, SLOTS_P0S)
	      && slot_ok (2, SLOTS_P1))
	    {
	      slots[SLOTS_P0S] = 1;
	      slots[SLOTS_P1] = 2;
	    }
	  else if (slot_ok (1, SLOTS_P1)
	      && slot_ok (2, SLOTS_P0S))
	    {
	      slots[SLOTS_P1] = 1;
	      slots[SLOTS_P0S] = 2;
	    }
	  else
	    as_bad ("cannot pack %s and %s together with a 16-bit insn",
		    CGEN_INSN_NAME (saved_insns[1].insn),
		    CGEN_INSN_NAME (saved_insns[2].insn));
	  break;

	default:
	  as_bad ("too many IVC2 insns to pack with a 16-bit core insn");
	  break;
	}
    }
  else if (corelength == 32)
    {
      /* V2 mode: we need a P1 slot.  */
      switch (num_insns_saved)
	{
	case 1:
	  /* No other insns, fill with NOPs. */
	  break;
	case 2:
	  /* The other insn must allow P1.  */
	  if (!slot_ok (1, SLOTS_P1))
	    as_bad ("cannot pack %s into slot P1",
		    CGEN_INSN_NAME (saved_insns[1].insn));
	  else
	    slots[SLOTS_P1] = 1;
	  break;
	default:
	  as_bad ("too many IVC2 insns to pack with a 32-bit core insn");
	  break;
	}
    }
  else if (corelength == 0)
    {
      /* V3 mode: we need a P0 slot and a P1 slot, or a P0S+P1 with a
	 core NOP.  */
      switch (num_insns_saved)
	{
	case 1:
	  if (slot_ok (0, SLOTS_P0))
	    slots[SLOTS_P0] = 0;
	  else if (slot_ok (0, SLOTS_P1))
	    slots[SLOTS_P1] = 0;
	  else if (slot_ok (0, SLOTS_P0S))
	    slots[SLOTS_P0S] = 0;
	  else
	    as_bad ("unable to pack %s by itself?",
		    CGEN_INSN_NAME (saved_insns[0].insn));
	  break;

	case 2:
	  if (slot_ok (0, SLOTS_P0)
	      && slot_ok (1, SLOTS_P1))
	    {
	      slots[SLOTS_P0] = 0;
	      slots[SLOTS_P1] = 1;
	    }
	  else if (slot_ok (0, SLOTS_P1)
	      && slot_ok (1, SLOTS_P0))
	    {
	      slots[SLOTS_P1] = 0;
	      slots[SLOTS_P0] = 1;
	    }
	  else if (slot_ok (0, SLOTS_P0S)
	      && slot_ok (1, SLOTS_P1))
	    {
	      slots[SLOTS_P0S] = 0;
	      slots[SLOTS_P1] = 1;
	    }
	  else if (slot_ok (0, SLOTS_P1)
	      && slot_ok (1, SLOTS_P0S))
	    {
	      slots[SLOTS_P1] = 0;
	      slots[SLOTS_P0S] = 1;
	    }
	  else
	    as_bad ("cannot pack %s and %s together",
		    CGEN_INSN_NAME (saved_insns[0].insn),
		    CGEN_INSN_NAME (saved_insns[1].insn));
	  break;

	default:
	  as_bad ("too many IVC2 insns to pack together");
	  break;
	}
    }

  /* The core insn needs to be done normally so that fixups,
     relaxation, etc are done.  Other IVC2 insns need only be resolved
     to bit patterns; there are no relocations for them.  */
  if (slots[SLOTS_CORE] != -1)
    {
      gas_cgen_restore_fixups (0);
      gas_cgen_finish_insn (saved_insns[0].insn, saved_insns[0].buffer,
			    CGEN_FIELDS_BITSIZE (& saved_insns[0].fields),
			    1, NULL);
    }

  /* Allocate whatever bytes remain in our insn word.  Adjust the
     pointer to point (as if it were) to the beginning of the whole
     word, so that we don't have to adjust for it elsewhere.  */
  f = (bfd_byte *) frag_more (8 - corelength / 8);
  /* Unused slots are filled with NOPs, which happen to be all zeros.  */
  memset (f, 0, 8 - corelength / 8);
  f -= corelength / 8;

  for (i=1; i<5; i++)
    {
      mep_insn *m;

      if (slots[i] == -1)
	continue;

      m = & saved_insns[slots[i]];

#if CGEN_INT_INSN_P
      cgen_put_insn_value (gas_cgen_cpu_desc, (unsigned char *) temp, 32,
			   m->buffer[0]);
#else
      memcpy (temp, m->buffer, byte_len);
#endif

      switch (i)
	{
	case SLOTS_P0S:
	  f[2^e] = temp[1^e];
	  f[3^e] = temp[2^e];
	  f[4^e] |= temp[3^e] & 0xf0;
	  break;
	case SLOTS_P0:
	  f[0^e] = 0xf0 | temp[0^e] >> 4;
	  f[1^e] = temp[0^e] << 4 | 0x07;
	  f[2^e] = temp[1^e];
	  f[3^e] = temp[2^e];
	  f[4^e] |= temp[3^e] & 0xf0;
	  break;
	case SLOTS_P1:
	  f[4^e] |= temp[0^e] >> 4;
	  f[5^e] = temp[0^e] << 4 | temp[1^e] >> 4;
	  f[6^e] = temp[1^e] << 4 | temp[2^e] >> 4;
	  f[7^e] = temp[2^e] << 4 | temp[3^e] >> 4;
	  break;
	default:
	  break;
	}
    }
}

#endif /* MEP_IVC2_SUPPORTED */

/* The scheduling functions are just filters for invalid combinations.
   If there is a violation, they terminate assembly.  Otherise they
   just fall through.  Succesful combinations cause no side effects
   other than valid nop insertion.  */

static void
mep_check_parallel_scheduling (void)
{
  /* This is where we will eventually read the config information
     and choose which scheduling checking function to call.  */   
#ifdef MEP_IVC2_SUPPORTED
  if (mep_cop == EF_MEP_COP_IVC2)
    mep_check_ivc2_scheduling ();
  else
#endif /* MEP_IVC2_SUPPORTED */
    if (MEP_VLIW64)
    mep_check_parallel64_scheduling ();
  else
    mep_check_parallel32_scheduling ();
}

static void
mep_process_saved_insns (void)
{
  int i;

  gas_cgen_save_fixups (MAX_SAVED_FIXUP_CHAINS - 1);

  /* We have to check for valid scheduling here. */
  mep_check_parallel_scheduling ();

  /* IVC2 has to pack instructions in a funny way, so it does it
     itself.  */
  if (mep_cop != EF_MEP_COP_IVC2)
    {
      /* If the last call didn't cause assembly to terminate, we have
	 a valid vliw insn/insn pair saved. Restore this instructions'
	 fixups and process the insns. */
      for (i = 0;i<num_insns_saved;i++)
	{
	  gas_cgen_restore_fixups (i);
	  gas_cgen_finish_insn (saved_insns[i].insn, saved_insns[i].buffer,
				CGEN_FIELDS_BITSIZE (& saved_insns[i].fields),
				1, NULL);
	}
    }
  gas_cgen_restore_fixups (MAX_SAVED_FIXUP_CHAINS - 1);

  /* Clear the fixups and reset the number insn saved to 0. */
  gas_cgen_initialize_saved_fixups_array ();
  num_insns_saved = 0;
  listing_prev_line ();
}

void
md_assemble (char * str)
{
  static CGEN_BITSET* isas = NULL;
  char * errmsg;

  /* Initialize GAS's cgen interface for a new instruction.  */
  gas_cgen_init_parse ();

  /* There are two possible modes: core and vliw.  We have to assemble
     differently for each.

     Core Mode:  We assemble normally.  All instructions are on a
                 single line and are made up of one mnemonic and one
                 set of operands.
     VLIW Mode:  Vliw combinations are indicated as follows:

		       core insn
		     + copro insn

                 We want to handle the general case where more than
                 one instruction can be preceeded by a +.  This will
                 happen later if we add support for internally parallel
                 coprocessors.  We'll make the parsing nice and general
                 so that it can handle an arbitrary number of insns
                 with leading +'s.  The actual checking for valid
                 combinations is done elsewhere.  */

  /* Initialize the isa to refer to the core.  */
  if (isas == NULL)
    isas = cgen_bitset_copy (& MEP_CORE_ISA);
  else
    {
      cgen_bitset_clear (isas);
      cgen_bitset_union (isas, & MEP_CORE_ISA, isas);
    }
  gas_cgen_cpu_desc->isas = isas;

  if (mode == VLIW)
    {
      /* VLIW mode.  */

      int thisInsnIsCopro = 0;
      mep_insn insn;
      int i;
      
      /* Initialize the insn buffer */
	
      if (! CGEN_INT_INSN_P)
         for (i=0; i < CGEN_MAX_INSN_SIZE; i++)
            insn.buffer[i]='\0';


      /* IVC2 has two sets of coprocessor opcodes, one for CORE mode
	 and one for VLIW mode.  They have the same names.  To specify
	 which one we want, we use the COP isas - the 32 bit ISA is
	 for the core instructions (which are always 32 bits), and the
	 other ISAs are for the VLIW ones (which always pack into 64
	 bit insns).  We use other attributes to determine slotting
	 later.  */
      if (mep_cop == EF_MEP_COP_IVC2)
	{
	  cgen_bitset_union (isas, & MEP_COP16_ISA, isas);
	  cgen_bitset_union (isas, & MEP_COP48_ISA, isas);
	  cgen_bitset_union (isas, & MEP_COP64_ISA, isas);
	}
      else
	{
	  /* Can't tell core / copro insns apart at parse time! */
	  cgen_bitset_union (isas, & MEP_COP_ISA, isas);
	}

      /* Assemble the insn so we can examine its attributes. */
      insn.insn = mep_cgen_assemble_insn (gas_cgen_cpu_desc, str,
					  &insn.fields, insn.buffer,
					  &errmsg);
      if (!insn.insn)
	{
	  as_bad ("%s", errmsg);
	  return;
	}
      mep_check_for_disabled_registers (&insn);

      /* Check to see if it's a coprocessor instruction. */
      thisInsnIsCopro = MEP_INSN_COP_P (insn.insn);

      if (!thisInsnIsCopro)
	{
	  insn.insn = mep_cgen_assemble_cop_insn (gas_cgen_cpu_desc, str,
						  &insn.fields, insn.buffer,
						  insn.insn);
	  thisInsnIsCopro = MEP_INSN_COP_P (insn.insn);
	  mep_check_for_disabled_registers (&insn);
	}

      if (pluspresent)
	{
	  /* A plus was present. */
	  /* Check for a + with a core insn and abort if found. */
	  if (!thisInsnIsCopro)
	    {
	      as_fatal("A core insn cannot be preceeded by a +.\n");
	      return;
	    }

	  if (num_insns_saved > 0)
	    {
	      /* There are insns in the queue. Add this one. */
	      mep_save_insn (insn);
	    }
	  else
	    {
	      /* There are no insns in the queue and a plus is present.
		 This is a syntax error.  Let's not tolerate this.
		 We can relax this later if necessary.  */
	      as_bad (_("Invalid use of parallelization operator."));
	      return;
	    }
	}
      else
	{
	  /* No plus was present. */
	  if (num_insns_saved > 0)
	    {
	      /* There are insns saved and we came across an insn without a
		 leading +.  That's the signal to process the saved insns
		 before proceeding then treat the current insn as the first
		 in a new vliw group.  */
	      mep_process_saved_insns ();
	      num_insns_saved = 0;
	      /* mep_save_insn (insn); */
	    }
	  mep_save_insn (insn);
#if 0
	  else
	    {

              /* Core Insn. Add it to the beginning of the queue. */
              mep_save_insn (insn);
	      /* gas_cgen_save_fixups(num_insns_saved); */
	    }
#endif
	}

      pluspresent = 0;
    }
  else
    {
      /* Core mode.  */

      /* Only single instructions are assembled in core mode. */
      mep_insn insn;

      /* See comment in the VLIW clause above about this.  */
      if (mep_cop & EF_MEP_COP_IVC2)
	cgen_bitset_union (isas, & MEP_COP32_ISA, isas);

      /* If a leading '+' was present, issue an error.
	 That's not allowed in core mode. */
      if (pluspresent)
	{
	  as_bad (_("Leading plus sign not allowed in core mode"));
	  return;
	}

      insn.insn = mep_cgen_assemble_insn
	(gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);

      if (!insn.insn)
	{
	  as_bad ("%s", errmsg);
	  return;
	}
      gas_cgen_finish_insn (insn.insn, insn.buffer,
			    CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
      mep_check_for_disabled_registers (&insn);
    }
}

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


symbolS *
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
{
  return 0;
}

/* Interface to relax_segment.  */


const relax_typeS md_relax_table[] =
{
  /* The fields are:
     1) most positive reach of this state,
     2) most negative reach of this state,
     3) how many bytes this mode will have in the variable part of the frag
     4) which index into the table to try if we can't fit into this one.  */
  /* Note that we use "beq" because "jmp" has a peculiarity - it cannot
     jump to addresses with any bits 27..24 set.  So, we use beq as a
     17-bit pc-relative branch to avoid using jmp, just in case.  */

  /* 0 */ {     0,      0, 0, 0 }, /* unused */
  /* 1 */ {     0,      0, 0, 0 }, /* marker for "don't know yet" */

  /* 2 */ {  2047,  -2048, 0, 3 }, /* bsr12 */
  /* 3 */ {     0,      0, 2, 0 }, /* bsr16 */

  /* 4 */ {  2047,  -2048, 0, 5 }, /* bra */
  /* 5 */ { 65535, -65536, 2, 6 }, /* beq $0,$0 */
  /* 6 */ {     0,      0, 2, 0 }, /* jmp24 */

  /* 7 */ { 65535, -65536, 0, 8 }, /* beqi */
  /* 8 */ {     0,      0, 4, 0 }, /* bnei/jmp */

  /* 9 */  {   127,   -128, 0, 10 }, /* beqz */
  /* 10 */ { 65535, -65536, 2, 11 }, /* beqi */
  /* 11 */ {     0,      0, 4,  0 }, /* bnei/jmp */

  /* 12 */ { 65535, -65536, 0, 13 }, /* bnei */
  /* 13 */ {     0,      0, 4,  0 }, /* beqi/jmp */

  /* 14 */ {   127,   -128, 0, 15 }, /* bnez */
  /* 15 */ { 65535, -65536, 2, 16 }, /* bnei */
  /* 16 */ {     0,      0, 4,  0 },  /* beqi/jmp */

  /* 17 */ { 65535, -65536, 0, 13 }, /* bgei */
  /* 18 */ {     0,      0, 4,  0 },
  /* 19 */ { 65535, -65536, 0, 13 }, /* blti */
  /* 20 */ {     0,      0, 4,  0 },
  /* 19 */ { 65535, -65536, 0, 13 }, /* bcpeq */
  /* 20 */ {     0,      0, 4,  0 },
  /* 19 */ { 65535, -65536, 0, 13 }, /* bcpne */
  /* 20 */ {     0,      0, 4,  0 },
  /* 19 */ { 65535, -65536, 0, 13 }, /* bcpat */
  /* 20 */ {     0,      0, 4,  0 },
  /* 19 */ { 65535, -65536, 0, 13 }, /* bcpaf */
  /* 20 */ {     0,      0, 4,  0 }
};

/* Pseudo-values for 64 bit "insns" which are combinations of two 32
   bit insns.  */
typedef enum {
  MEP_PSEUDO64_NONE,
  MEP_PSEUDO64_16BITCC,
  MEP_PSEUDO64_32BITCC,
} MepPseudo64Values;

static struct {
  int insn;
  int growth;
  int insn_for_extern;
} subtype_mappings[] = {
  { 0, 0, 0 },
  { 0, 0, 0 },
  { MEP_INSN_BSR12, 0, MEP_INSN_BSR24 },
  { MEP_INSN_BSR24, 2, MEP_INSN_BSR24 },
  { MEP_INSN_BRA,   0, MEP_INSN_BRA   },
  { MEP_INSN_BEQ,   2, MEP_INSN_BEQ   },
  { MEP_INSN_JMP,   2, MEP_INSN_JMP   },
  { MEP_INSN_BEQI,  0, MEP_INSN_BEQI  },
  { -1,             4, MEP_PSEUDO64_32BITCC },
  { MEP_INSN_BEQZ,  0, MEP_INSN_BEQZ  },
  { MEP_INSN_BEQI,  2, MEP_INSN_BEQI  },
  { -1,             4, MEP_PSEUDO64_16BITCC },
  { MEP_INSN_BNEI,  0, MEP_INSN_BNEI  },
  { -1,             4, MEP_PSEUDO64_32BITCC },
  { MEP_INSN_BNEZ,  0, MEP_INSN_BNEZ  },
  { MEP_INSN_BNEI,  2, MEP_INSN_BNEI  },
  { -1,             4, MEP_PSEUDO64_16BITCC },
  { MEP_INSN_BGEI,  0, MEP_INSN_BGEI  },
  { -1,             4, MEP_PSEUDO64_32BITCC },
  { MEP_INSN_BLTI,  0, MEP_INSN_BLTI  },
  { -1,             4, MEP_PSEUDO64_32BITCC },
  { MEP_INSN_BCPEQ, 0, MEP_INSN_BCPEQ  },
  { -1,             4, MEP_PSEUDO64_32BITCC },
  { MEP_INSN_BCPNE, 0, MEP_INSN_BCPNE  },
  { -1,             4, MEP_PSEUDO64_32BITCC },
  { MEP_INSN_BCPAT, 0, MEP_INSN_BCPAT  },
  { -1,             4, MEP_PSEUDO64_32BITCC },
  { MEP_INSN_BCPAF, 0, MEP_INSN_BCPAF  },
  { -1,             4, MEP_PSEUDO64_32BITCC }
};
#define NUM_MAPPINGS (sizeof (subtype_mappings) / sizeof (subtype_mappings[0]))

void
mep_prepare_relax_scan (fragS *fragP, offsetT *aim, relax_substateT this_state)
{
  symbolS *symbolP = fragP->fr_symbol;
  if (symbolP && !S_IS_DEFINED (symbolP))
    *aim = 0;
  /* Adjust for MeP pcrel not being relative to the next opcode.  */
  *aim += 2 + md_relax_table[this_state].rlx_length;
}

static int
insn_to_subtype (int insn)
{
  unsigned int i;
  for (i=0; i<NUM_MAPPINGS; i++)
    if (insn == subtype_mappings[i].insn)
      return i;
  abort ();
}

/* 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
   and 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, segT segment)
{
  if (fragP->fr_subtype == 1)
    fragP->fr_subtype = insn_to_subtype (fragP->fr_cgen.insn->base->num);

  if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
    {
      int new_insn;

      new_insn = subtype_mappings[fragP->fr_subtype].insn_for_extern;
      fragP->fr_subtype = insn_to_subtype (new_insn);
    }

  if (MEP_VLIW && ! MEP_VLIW64
      && (bfd_get_section_flags (stdoutput, segment) & SEC_MEP_VLIW))
    {
      /* Use 32 bit branches for vliw32 so the vliw word is not split.  */
      switch (fragP->fr_cgen.insn->base->num)
	{
	case MEP_INSN_BSR12:
	  fragP->fr_subtype = insn_to_subtype 
	    (subtype_mappings[fragP->fr_subtype].insn_for_extern);
	  break;
	case MEP_INSN_BEQZ:
	  fragP->fr_subtype ++;
	  break;
	case MEP_INSN_BNEZ:
	  fragP->fr_subtype ++;
	  break;
	}
    }

  if (fragP->fr_cgen.insn->base
      && fragP->fr_cgen.insn->base->num
         != subtype_mappings[fragP->fr_subtype].insn)
    {
      int new_insn= subtype_mappings[fragP->fr_subtype].insn;
      if (new_insn != -1)
	{
	  fragP->fr_cgen.insn = (fragP->fr_cgen.insn
				 - fragP->fr_cgen.insn->base->num
				 + new_insn);
	}
    }

  return subtype_mappings[fragP->fr_subtype].growth;
}

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

static int
target_address_for (fragS *frag)
{
  int rv = frag->fr_offset;
  symbolS *sym = frag->fr_symbol;

  if (sym)
    rv += S_GET_VALUE (sym);

  return rv;
}

void
md_convert_frag (bfd *abfd  ATTRIBUTE_UNUSED, 
		 segT sec ATTRIBUTE_UNUSED,
		 fragS *fragP)
{
  int addend, rn, bit = 0;
  int operand;
  int where = fragP->fr_opcode - fragP->fr_literal;
  int e = target_big_endian ? 0 : 1;

  addend = target_address_for (fragP) - (fragP->fr_address + where);

  if (subtype_mappings[fragP->fr_subtype].insn == -1)
    {
      fragP->fr_fix += subtype_mappings[fragP->fr_subtype].growth;
      switch (subtype_mappings[fragP->fr_subtype].insn_for_extern)
	{
	case MEP_PSEUDO64_16BITCC:
	  fragP->fr_opcode[1^e] = ((fragP->fr_opcode[1^e] & 1) ^ 1) | 0x06;
	  fragP->fr_opcode[2^e] = 0xd8;
	  fragP->fr_opcode[3^e] = 0x08;
	  fragP->fr_opcode[4^e] = 0;
	  fragP->fr_opcode[5^e] = 0;
	  where += 2;
	  break;
	case MEP_PSEUDO64_32BITCC:
	  if (fragP->fr_opcode[0^e] & 0x10)
	    fragP->fr_opcode[1^e] ^= 0x01;
	  else
	    fragP->fr_opcode[1^e] ^= 0x04;
	  fragP->fr_opcode[2^e] = 0;
	  fragP->fr_opcode[3^e] = 4;
	  fragP->fr_opcode[4^e] = 0xd8;
	  fragP->fr_opcode[5^e] = 0x08;
	  fragP->fr_opcode[6^e] = 0;
	  fragP->fr_opcode[7^e] = 0;
	  where += 4;
	  break;
	default:
	  abort ();
	}
      fragP->fr_cgen.insn = (fragP->fr_cgen.insn
			     - fragP->fr_cgen.insn->base->num
			     + MEP_INSN_JMP);
      operand = MEP_OPERAND_PCABS24A2;
    }
  else
    switch (fragP->fr_cgen.insn->base->num)
      {
      case MEP_INSN_BSR12:
	fragP->fr_opcode[0^e] = 0xb0 | ((addend >> 8) & 0x0f);
	fragP->fr_opcode[1^e] = 0x01 | (addend & 0xfe);
	operand = MEP_OPERAND_PCREL12A2;
	break;

      case MEP_INSN_BSR24:
	fragP->fr_fix += 2;
	fragP->fr_opcode[0^e] = 0xd8 | ((addend >> 5) & 0x07);
	fragP->fr_opcode[1^e] = 0x09 | ((addend << 3) & 0xf0);
	fragP->fr_opcode[2^e] = 0x00 | ((addend >>16) & 0xff);
	fragP->fr_opcode[3^e] = 0x00 | ((addend >> 8) & 0xff);
	operand = MEP_OPERAND_PCREL24A2;
	break;

      case MEP_INSN_BRA:
	fragP->fr_opcode[0^e] = 0xb0 | ((addend >> 8) & 0x0f);
	fragP->fr_opcode[1^e] = 0x00 | (addend & 0xfe);
	operand = MEP_OPERAND_PCREL12A2;
	break;

      case MEP_INSN_BEQ:
	/* The default relax_frag doesn't change the state if there is no
	   growth, so we must manually handle converting out-of-range BEQ
	   instructions to JMP.  */
	if (addend <= 65535 && addend >= -65536)
	  {
	    fragP->fr_fix += 2;
	    fragP->fr_opcode[0^e] = 0xe0;
	    fragP->fr_opcode[1^e] = 0x01;
	    fragP->fr_opcode[2^e] = 0x00 | ((addend >> 9) & 0xff);
	    fragP->fr_opcode[3^e] = 0x00 | ((addend >> 1) & 0xff);
	    operand = MEP_OPERAND_PCREL17A2;
	    break;
	  }
	/* ...FALLTHROUGH... */

      case MEP_INSN_JMP:
	addend = target_address_for (fragP);
	fragP->fr_fix += 2;
	fragP->fr_opcode[0^e] = 0xd8 | ((addend >> 5) & 0x07);
	fragP->fr_opcode[1^e] = 0x08 | ((addend << 3) & 0xf0);
	fragP->fr_opcode[2^e] = 0x00 | ((addend >>16) & 0xff);
	fragP->fr_opcode[3^e] = 0x00 | ((addend >> 8) & 0xff);
	operand = MEP_OPERAND_PCABS24A2;
	break;

      case MEP_INSN_BNEZ:
	bit = 1;
      case MEP_INSN_BEQZ:
	fragP->fr_opcode[1^e] = bit | (addend & 0xfe);
	operand = MEP_OPERAND_PCREL8A2;
	break;

      case MEP_INSN_BNEI:
	bit = 4;
      case MEP_INSN_BEQI:
	if (subtype_mappings[fragP->fr_subtype].growth)
	  {
	    fragP->fr_fix += subtype_mappings[fragP->fr_subtype].growth;
	    rn = fragP->fr_opcode[0^e] & 0x0f;
	    fragP->fr_opcode[0^e] = 0xe0 | rn;
	    fragP->fr_opcode[1^e] = bit;
	  }
	fragP->fr_opcode[2^e] = 0x00 | ((addend >> 9) & 0xff);
	fragP->fr_opcode[3^e] = 0x00 | ((addend >> 1) & 0xff);
	operand = MEP_OPERAND_PCREL17A2;
	break;

      case MEP_INSN_BLTI:
      case MEP_INSN_BGEI:
      case MEP_INSN_BCPEQ:
      case MEP_INSN_BCPNE:
      case MEP_INSN_BCPAT:
      case MEP_INSN_BCPAF:
	/* No opcode change needed, just operand.  */
	fragP->fr_opcode[2^e] = (addend >> 9) & 0xff;
	fragP->fr_opcode[3^e] = (addend >> 1) & 0xff;
	operand = MEP_OPERAND_PCREL17A2;
	break;

      default:
	abort ();
      }

  if (S_GET_SEGMENT (fragP->fr_symbol) != sec
      || operand == MEP_OPERAND_PCABS24A2)
    {
      assert (fragP->fr_cgen.insn != 0);
      gas_cgen_record_fixup (fragP,
			     where,
			     fragP->fr_cgen.insn,
			     (fragP->fr_fix - where) * 8,
			     cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
							 operand),
			     fragP->fr_cgen.opinfo,
			     fragP->fr_symbol, fragP->fr_offset);
    }
}


/* Functions concerning relocs.  */

void
mep_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
{
  /* If we already know the fixup value, adjust it in the same
     way that the linker would have done.  */
  if (fixP->fx_addsy == 0)
    switch (fixP->fx_cgen.opinfo)
      {
      case BFD_RELOC_MEP_LOW16:
	*valP = ((long)(*valP & 0xffff)) << 16 >> 16;
	break;
      case BFD_RELOC_MEP_HI16U:
	*valP >>= 16;
	break;
      case BFD_RELOC_MEP_HI16S:
	*valP = (*valP + 0x8000) >> 16;
	break;
      }

  /* Now call cgen's md_aply_fix.  */
  gas_cgen_md_apply_fix (fixP, valP, seg);
}

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))
    /* The symbol is undefined (or is defined but not in this section).
       Let the linker figure it out.  */
    return 0;

  /* Return the address of the opcode - cgen adjusts for opcode size
     itself, to be consistent with the disassembler, which must do
     so.  */
  return fixP->fx_where + fixP->fx_frag->fr_address;
}

/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
   Returns BFD_RELOC_NONE if no reloc type can be found.
   *FIXP may be modified if desired.  */

#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define MAP(n) case MEP_OPERAND_##n: return BFD_RELOC_MEP_##n;
#else
#define MAP(n) case MEP_OPERAND_/**/n: return BFD_RELOC_MEP_/**/n;
#endif

bfd_reloc_code_real_type
md_cgen_lookup_reloc (const CGEN_INSN *insn ATTRIBUTE_UNUSED,
		      const CGEN_OPERAND *operand,
		      fixS *fixP)
{
  enum bfd_reloc_code_real reloc = fixP->fx_cgen.opinfo;
  static char printed[MEP_OPERAND_MAX] = { 0 };

  /* If there's a reloc here, it's because the parser saw a %foo() and
     is giving us the correct reloc to use, or because we converted to
     a different size reloc below and want to avoid "converting" more
     than once.  */
  if (reloc && reloc != BFD_RELOC_NONE)
    return reloc;

  switch (operand->type)
    {
      MAP (PCREL8A2);	/* beqz */
      MAP (PCREL12A2);	/* bsr16 */
      MAP (PCREL17A2);	/* beqi */
      MAP (PCREL24A2);	/* bsr24 */
      MAP (PCABS24A2);	/* jmp */
      MAP (UIMM24);	/* mov */
      MAP (ADDR24A4);	/* sw/lw */

    /* The rest of the relocs should be generated by the parser,
       for things such as %tprel(), etc. */
    case MEP_OPERAND_SIMM16:
#ifdef OBJ_COMPLEX_RELC
      /* coalescing this into RELOC_MEP_16 is actually a bug,
	 since it's a signed operand. let the relc code handle it. */
      return BFD_RELOC_RELC; 
#endif

    case MEP_OPERAND_UIMM16:
    case MEP_OPERAND_SDISP16:
    case MEP_OPERAND_CODE16:
      fixP->fx_where += 2;
      /* to avoid doing the above add twice */
      fixP->fx_cgen.opinfo = BFD_RELOC_MEP_16;
      return BFD_RELOC_MEP_16;

    default:
#ifdef OBJ_COMPLEX_RELC
      /* this is not an error, yet. 
	 pass it to the linker. */
      return BFD_RELOC_RELC;
#endif
      if (printed[operand->type])
	return BFD_RELOC_NONE;
      printed[operand->type] = 1;

      as_bad_where (fixP->fx_file, fixP->fx_line,
		    _("Don't know how to relocate plain operands of type %s"),
		    operand->name);

      /* Print some helpful hints for the user.  */
      switch (operand->type)
	{
	case MEP_OPERAND_UDISP7:
	case MEP_OPERAND_UDISP7A2:
	case MEP_OPERAND_UDISP7A4:
	  as_bad_where (fixP->fx_file, fixP->fx_line,
			_("Perhaps you are missing %%tpoff()?"));
	  break;
	default:
	  break;
	}
      return BFD_RELOC_NONE;
    }
}

/* Called while parsing an instruction to create a fixup.
   We need to check for HI16 relocs and queue them up for later sorting.  */

fixS *
mep_cgen_record_fixup_exp (fragS *frag,
			   int where,
			   const CGEN_INSN *insn,
			   int length,
			   const CGEN_OPERAND *operand,
			   int opinfo,
			   expressionS *exp)
{
  fixS * fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
					   operand, opinfo, exp);
  return fixP;
}

/* Return BFD reloc type from opinfo field in a fixS.
   It's tricky using fx_r_type in mep_frob_file because the values
   are BFD_RELOC_UNUSED + operand number.  */
#define FX_OPINFO_R_TYPE(f) ((f)->fx_cgen.opinfo)

/* Sort any unmatched HI16 relocs so that they immediately precede
   the corresponding LO16 reloc.  This is called before md_apply_fix and
   tc_gen_reloc.  */

void
mep_frob_file ()
{
  struct mep_hi_fixup * l;

  for (l = mep_hi_fixup_list; l != NULL; l = l->next)
    {
      segment_info_type * seginfo;
      int pass;

      assert (FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_HI16
	      || FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_LO16);

      /* Check quickly whether the next fixup happens to be a matching low.  */
      if (l->fixp->fx_next != NULL
	  && FX_OPINFO_R_TYPE (l->fixp->fx_next) == BFD_RELOC_LO16
	  && l->fixp->fx_addsy == l->fixp->fx_next->fx_addsy
	  && l->fixp->fx_offset == l->fixp->fx_next->fx_offset)
	continue;

      /* Look through the fixups for this segment for a matching
         `low'.  When we find one, move the high just in front of it.
         We do this in two passes.  In the first pass, we try to find
         a unique `low'.  In the second pass, we permit multiple
         high's relocs for a single `low'.  */
      seginfo = seg_info (l->seg);
      for (pass = 0; pass < 2; pass++)
	{
	  fixS * f;
	  fixS * prev;

	  prev = NULL;
	  for (f = seginfo->fix_root; f != NULL; f = f->fx_next)
	    {
	      /* Check whether this is a `low' fixup which matches l->fixp.  */
	      if (FX_OPINFO_R_TYPE (f) == BFD_RELOC_LO16
		  && f->fx_addsy == l->fixp->fx_addsy
		  && f->fx_offset == l->fixp->fx_offset
		  && (pass == 1
		      || prev == NULL
		      || (FX_OPINFO_R_TYPE (prev) != BFD_RELOC_HI16)
		      || prev->fx_addsy != f->fx_addsy
		      || prev->fx_offset !=  f->fx_offset))
		{
		  fixS ** pf;

		  /* Move l->fixp before f.  */
		  for (pf = &seginfo->fix_root;
		       * pf != l->fixp;
		       pf = & (* pf)->fx_next)
		    assert (* pf != NULL);

		  * pf = l->fixp->fx_next;

		  l->fixp->fx_next = f;
		  if (prev == NULL)
		    seginfo->fix_root = l->fixp;
		  else
		    prev->fx_next = l->fixp;

		  break;
		}

	      prev = f;
	    }

	  if (f != NULL)
	    break;

	  if (pass == 1)
	    as_warn_where (l->fixp->fx_file, l->fixp->fx_line,
			   _("Unmatched high relocation"));
	}
    }
}

/* See whether we need to force a relocation into the output file. */

int
mep_force_relocation (fixS *fixp)
{
  if (   fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
	 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
    return 1;

  /* Allow branches to global symbols to be resolved at assembly time.
     This is consistent with way relaxable branches are handled, since
     branches to both global and local symbols are relaxed.  It also
     corresponds to the assumptions made in md_pcrel_from_section.  */
  return S_FORCE_RELOC (fixp->fx_addsy, !fixp->fx_pcrel);
}

/* Write a value out to the object file, using the appropriate endianness.  */

void
md_number_to_chars (char *buf, valueT val, int n)
{
  if (target_big_endian)
    number_to_chars_bigendian (buf, val, n);
  else
    number_to_chars_littleendian (buf, val, n);
}

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

bfd_boolean
mep_fix_adjustable (fixS *fixP)
{
  bfd_reloc_code_real_type reloc_type;

  if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
    {
      const CGEN_INSN *insn = NULL;
      int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
      const CGEN_OPERAND *operand
	= cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);
      reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
    }
  else
    reloc_type = fixP->fx_r_type;

  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;

  /* We need the symbol name for the VTABLE entries */
  if (reloc_type == BFD_RELOC_VTABLE_INHERIT
      || reloc_type == BFD_RELOC_VTABLE_ENTRY)
    return 0;

  return 1;
}

bfd_vma
mep_elf_section_letter (int letter, char **ptrmsg)
{
  if (letter == 'v')
    return SHF_MEP_VLIW;

  *ptrmsg = _("Bad .section directive: want a,v,w,x,M,S in string");
  return 0;
}

flagword
mep_elf_section_flags (flagword flags, bfd_vma attr, int type ATTRIBUTE_UNUSED)
{
  if (attr & SHF_MEP_VLIW)
    flags |= SEC_MEP_VLIW;
  return flags;
}

/* In vliw mode, the default section is .vtext.  We have to be able
   to switch into .vtext using only the .vtext directive.  */

static segT
mep_vtext_section (void)
{
  static segT vtext_section;

  if (! vtext_section)
    {
      flagword applicable = bfd_applicable_section_flags (stdoutput);
      vtext_section = subseg_new (VTEXT_SECTION_NAME, 0);
      bfd_set_section_flags (stdoutput, vtext_section,
			     applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
					   | SEC_CODE | SEC_READONLY
					   | SEC_MEP_VLIW));
    }

  return vtext_section;
}

static void
mep_s_vtext (int ignore ATTRIBUTE_UNUSED)
{
  int temp;

  /* Record previous_section and previous_subsection.  */
  obj_elf_section_change_hook ();

  temp = get_absolute_expression ();
  subseg_set (mep_vtext_section (), (subsegT) temp);
  demand_empty_rest_of_line ();
}

static void
mep_switch_to_core_mode (int dummy ATTRIBUTE_UNUSED)
{
  mep_process_saved_insns ();
  pluspresent = 0;
  mode = CORE;
}

static void
mep_switch_to_vliw_mode (int dummy ATTRIBUTE_UNUSED)
{
  if (! MEP_VLIW)
    as_bad (_(".vliw unavailable when VLIW is disabled."));
  mode = VLIW;
  /* Switch into .vtext here too. */
  /* mep_s_vtext(); */
}

/* This is an undocumented pseudo-op used to disable gas's
   "disabled_registers" check.  Used for code which checks for those
   registers at runtime.  */
static void
mep_noregerr (int i ATTRIBUTE_UNUSED)
{
  allow_disabled_registers = 1;
}

/* mep_unrecognized_line: This is called when a line that can't be parsed
   is encountered.  We use it to check for a leading '+' sign which indicates
   that the current instruction is a coprocessor instruction that is to be
   parallelized with a previous core insn.  This function accepts the '+' and
   rejects all other characters that might indicate garbage at the beginning
   of the line.  The '+' character gets lost as the calling loop continues,
   so we need to indicate that we saw it.  */

int
mep_unrecognized_line (int ch)
{
  switch (ch)
    {
    case '+':
      pluspresent = 1;
      return 1; /* '+' indicates an instruction to be parallelized. */
    default:
      return 0; /* If it's not a '+', the line can't be parsed. */
    }
}

void
mep_cleanup (void)
{
  /* Take care of any insns left to be parallelized when the file ends.
     This is mainly here to handle the case where the file ends with an
     insn preceeded by a + or the file ends unexpectedly.  */
  if (mode == VLIW)
    mep_process_saved_insns ();
}

int
mep_flush_pending_output (void)
{
  if (mode == VLIW)
    {
      mep_process_saved_insns ();
      pluspresent = 0;
    }

  return 1; 
}
