/* MeP opcode support.  -*- C -*-
   Copyright 2011 Free Software Foundation, Inc.

   Contributed by Red Hat Inc;

   This file is part of the GNU Binutils.

   This program 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 of the License, or
   (at your option) any later version.

   This program 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 this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

/* -- opc.h */

#undef  CGEN_DIS_HASH_SIZE
#define CGEN_DIS_HASH_SIZE 1

#undef  CGEN_DIS_HASH
#define CGEN_DIS_HASH(buffer, insn) 0

#define CGEN_VERBOSE_ASSEMBLER_ERRORS

typedef struct
{
  char * name;
  int    config_enum;
  unsigned cpu_flag;
  int    big_endian;
  int    vliw_bits;
  CGEN_ATTR_VALUE_BITSET_TYPE cop16_isa;
  CGEN_ATTR_VALUE_BITSET_TYPE cop32_isa;
  CGEN_ATTR_VALUE_BITSET_TYPE cop48_isa;
  CGEN_ATTR_VALUE_BITSET_TYPE cop64_isa;
  CGEN_ATTR_VALUE_BITSET_TYPE cop_isa;
  CGEN_ATTR_VALUE_BITSET_TYPE core_isa;
  unsigned int option_mask;
} mep_config_map_struct;

extern mep_config_map_struct mep_config_map[];
extern int mep_config_index;

extern void init_mep_all_core_isas_mask (void);
extern void init_mep_all_cop_isas_mask  (void);
extern CGEN_ATTR_VALUE_BITSET_TYPE mep_cop_isa  (void);

#define MEP_CONFIG     (mep_config_map[mep_config_index].config_enum)
#define MEP_CPU        (mep_config_map[mep_config_index].cpu_flag)
#define MEP_OMASK      (mep_config_map[mep_config_index].option_mask)
#define MEP_VLIW       (mep_config_map[mep_config_index].vliw_bits > 0)
#define MEP_VLIW32     (mep_config_map[mep_config_index].vliw_bits == 32)
#define MEP_VLIW64     (mep_config_map[mep_config_index].vliw_bits == 64)
#define MEP_COP16_ISA  (mep_config_map[mep_config_index].cop16_isa)
#define MEP_COP32_ISA  (mep_config_map[mep_config_index].cop32_isa)
#define MEP_COP48_ISA  (mep_config_map[mep_config_index].cop48_isa)
#define MEP_COP64_ISA  (mep_config_map[mep_config_index].cop64_isa)
#define MEP_COP_ISA    (mep_config_map[mep_config_index].cop_isa)
#define MEP_CORE_ISA   (mep_config_map[mep_config_index].core_isa)

/* begin-cop-ip-supported-defines */
#define MEP_IVC2_SUPPORTED 1
/* end-cop-ip-supported-defines */

extern int mep_insn_supported_by_isa (const CGEN_INSN *, CGEN_ATTR_VALUE_BITSET_TYPE *);

/* A mask for all ISAs executed by the core.  */
#define MEP_ALL_CORE_ISAS_MASK mep_all_core_isas_mask
extern CGEN_ATTR_VALUE_BITSET_TYPE mep_all_core_isas_mask;

#define MEP_INSN_CORE_P(insn) ( \
  init_mep_all_core_isas_mask (), \
  mep_insn_supported_by_isa (insn, & MEP_ALL_CORE_ISAS_MASK) \
)

/* A mask for all ISAs executed by a VLIW coprocessor.  */
#define MEP_ALL_COP_ISAS_MASK mep_all_cop_isas_mask 
extern CGEN_ATTR_VALUE_BITSET_TYPE mep_all_cop_isas_mask;

#define MEP_INSN_COP_P(insn) ( \
  init_mep_all_cop_isas_mask (), \
  mep_insn_supported_by_isa (insn, & MEP_ALL_COP_ISAS_MASK) \
)

extern int mep_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
extern int mep_cgen_insn_supported_asm (CGEN_CPU_DESC, const CGEN_INSN *);

/* -- asm.c */

#include "elf/mep.h"

#define CGEN_VALIDATE_INSN_SUPPORTED
#define mep_cgen_insn_supported mep_cgen_insn_supported_asm

       const char * parse_csrn       (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
       const char * parse_tpreg      (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
       const char * parse_spreg      (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
       const char * parse_mep_align  (CGEN_CPU_DESC, const char **, enum cgen_operand_type, long *);
       const char * parse_mep_alignu (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
static const char * parse_signed16   (CGEN_CPU_DESC, const char **, int, long *);
static const char * parse_signed16_range   (CGEN_CPU_DESC, const char **, int, long *) ATTRIBUTE_UNUSED;
static const char * parse_unsigned16 (CGEN_CPU_DESC, const char **, int, unsigned long *);
static const char * parse_unsigned16_range (CGEN_CPU_DESC, const char **, int, unsigned long *) ATTRIBUTE_UNUSED;
static const char * parse_lo16       (CGEN_CPU_DESC, const char **, int, long *, long);
static const char * parse_unsigned7  (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
static const char * parse_zero       (CGEN_CPU_DESC, const char **, int, long *);

const char *
parse_csrn (CGEN_CPU_DESC cd, const char **strp,
	    CGEN_KEYWORD *keyword_table, long *field)
{
  const char *err;
  unsigned long value;

  err = cgen_parse_keyword (cd, strp, keyword_table, field);
  if (!err)
    return NULL;

  err = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, & value);
  if (err)
    return err;
  *field = value;
  return NULL;
}

/* begin-cop-ip-parse-handlers */
static const char *
parse_ivc2_cr (CGEN_CPU_DESC,
	const char **,
	CGEN_KEYWORD *,
	long *) ATTRIBUTE_UNUSED;
static const char *
parse_ivc2_cr (CGEN_CPU_DESC cd,
	const char **strp,
	CGEN_KEYWORD *keyword_table  ATTRIBUTE_UNUSED,
	long *field)
{
  return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr_ivc2, field);
}
static const char *
parse_ivc2_ccr (CGEN_CPU_DESC,
	const char **,
	CGEN_KEYWORD *,
	long *) ATTRIBUTE_UNUSED;
static const char *
parse_ivc2_ccr (CGEN_CPU_DESC cd,
	const char **strp,
	CGEN_KEYWORD *keyword_table  ATTRIBUTE_UNUSED,
	long *field)
{
  return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, field);
}
/* end-cop-ip-parse-handlers */

const char *
parse_tpreg (CGEN_CPU_DESC cd, const char ** strp,
	     CGEN_KEYWORD *keyword_table, long *field)
{
  const char *err;

  err = cgen_parse_keyword (cd, strp, keyword_table, field);
  if (err)
    return err;
  if (*field != 13)
    return _("Only $tp or $13 allowed for this opcode");
  return NULL;
}

const char *
parse_spreg (CGEN_CPU_DESC cd, const char ** strp,
	     CGEN_KEYWORD *keyword_table, long *field)
{
  const char *err;

  err = cgen_parse_keyword (cd, strp, keyword_table, field);
  if (err)
    return err;
  if (*field != 15)
    return _("Only $sp or $15 allowed for this opcode");
  return NULL;
}

const char *
parse_mep_align (CGEN_CPU_DESC cd, const char ** strp,
		 enum cgen_operand_type type, long *field)
{
  long lsbs = 0;
  const char *err;

  switch (type)
    {
    case MEP_OPERAND_PCREL8A2:
    case MEP_OPERAND_PCREL12A2:
    case MEP_OPERAND_PCREL17A2:
    case MEP_OPERAND_PCREL24A2:
      err = cgen_parse_signed_integer   (cd, strp, type, field);
      break;
    case MEP_OPERAND_PCABS24A2:
    case MEP_OPERAND_UDISP7:
    case MEP_OPERAND_UDISP7A2:
    case MEP_OPERAND_UDISP7A4:
    case MEP_OPERAND_UIMM7A4:
    case MEP_OPERAND_ADDR24A4:
      err = cgen_parse_unsigned_integer (cd, strp, type, (unsigned long *) field);
      break;
    default:
      abort();
    }
  if (err)
    return err;
  switch (type)
    {
    case MEP_OPERAND_UDISP7:
      lsbs = 0;
      break;
    case MEP_OPERAND_PCREL8A2:
    case MEP_OPERAND_PCREL12A2:
    case MEP_OPERAND_PCREL17A2:
    case MEP_OPERAND_PCREL24A2:
    case MEP_OPERAND_PCABS24A2:
    case MEP_OPERAND_UDISP7A2:
      lsbs = *field & 1;
      break;
    case MEP_OPERAND_UDISP7A4:
    case MEP_OPERAND_UIMM7A4:
    case MEP_OPERAND_ADDR24A4:
      lsbs = *field & 3;
      break;
      lsbs = *field & 7;
      break;
    default:
      /* Safe assumption?  */
      abort ();
    }
  if (lsbs)
    return "Value is not aligned enough";
  return NULL;
}

const char *
parse_mep_alignu (CGEN_CPU_DESC cd, const char ** strp,
		 enum cgen_operand_type type, unsigned long *field)
{
  return parse_mep_align (cd, strp, type, (long *) field);
}


/* Handle %lo(), %tpoff(), %sdaoff(), %hi(), and other signed
   constants in a signed context.  */

static const char *
parse_signed16 (CGEN_CPU_DESC cd,
		const char **strp,
		int opindex,
		long *valuep)
{
  return parse_lo16 (cd, strp, opindex, valuep, 1);
}

static const char *
parse_lo16 (CGEN_CPU_DESC cd,
	    const char **strp,
	    int opindex,
	    long *valuep,
	    long signedp)
{
  const char *errmsg;
  enum cgen_parse_operand_result result_type;
  bfd_vma value;

  if (strncasecmp (*strp, "%lo(", 4) == 0)
    {
      *strp += 4;
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
				   & result_type, & value);
      if (**strp != ')')
	return _("missing `)'");
      ++*strp;
      if (errmsg == NULL
	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
	value &= 0xffff;
      if (signedp)
	*valuep = (long)(short) value;
      else
	*valuep = value;
      return errmsg;
    }

  if (strncasecmp (*strp, "%hi(", 4) == 0)
    {
      *strp += 4;
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
				   & result_type, & value);
      if (**strp != ')')
	return _("missing `)'");
      ++*strp;
      if (errmsg == NULL
	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
	value = (value + 0x8000) >> 16;
      *valuep = value;
      return errmsg;
    }

  if (strncasecmp (*strp, "%uhi(", 5) == 0)
    {
      *strp += 5;
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
				   & result_type, & value);
      if (**strp != ')')
	return _("missing `)'");
      ++*strp;
      if (errmsg == NULL
	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
	value = value >> 16;
      *valuep = value;
      return errmsg;
    }

  if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
    {
      *strp += 8;
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
				   NULL, & value);
      if (**strp != ')')
	return _("missing `)'");
      ++*strp;
      *valuep = value;
      return errmsg;
    }

  if (strncasecmp (*strp, "%tpoff(", 7) == 0)
    {
      *strp += 7;
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
				   NULL, & value);
      if (**strp != ')')
	return _("missing `)'");
      ++*strp;
      *valuep = value;
      return errmsg;
    }

  if (**strp == '%')
    return _("invalid %function() here");

  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
}

static const char *
parse_unsigned16 (CGEN_CPU_DESC cd,
		  const char **strp,
		  int opindex,
		  unsigned long *valuep)
{
  return parse_lo16 (cd, strp, opindex, (long *) valuep, 0);
}

static const char *
parse_signed16_range (CGEN_CPU_DESC cd,
		      const char **strp,
		      int opindex,
		      signed long *valuep)
{
  const char *errmsg = 0;
  signed long value;

  errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
  if (errmsg)
    return errmsg;

  if (value < -32768 || value > 32767)
    return _("Immediate is out of range -32768 to 32767");

  *valuep = value;
  return 0;
}

static const char *
parse_unsigned16_range (CGEN_CPU_DESC cd,
			const char **strp,
			int opindex,
			unsigned long *valuep)
{
  const char *errmsg = 0;
  unsigned long value;

  errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
  if (errmsg)
    return errmsg;

  if (value > 65535)
    return _("Immediate is out of range 0 to 65535");

  *valuep = value;
  return 0;
}

/* A special case of parse_signed16 which accepts only the value zero.  */

static const char *
parse_zero (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
{
  const char *errmsg;
  enum cgen_parse_operand_result result_type;
  bfd_vma value;

  /*fprintf(stderr, "dj: signed parse opindex `%s'\n", *strp);*/

  /* Prevent ($ry) from being attempted as an expression on 'sw $rx,($ry)'.
     It will fail and cause ry to be listed as an undefined symbol in the
     listing.  */
  if (strncmp (*strp, "($", 2) == 0)
    return "not zero"; /* any string will do -- will never be seen.  */

  if (strncasecmp (*strp, "%lo(", 4) == 0)
    {
      *strp += 4;
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
				   &result_type, &value);
      if (**strp != ')')
	return "missing `)'";
      ++*strp;
      if (errmsg == NULL
	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
	return "not zero"; /* any string will do -- will never be seen.  */
      *valuep = value;
      return errmsg;
    }

  if (strncasecmp (*strp, "%hi(", 4) == 0)
    {
      *strp += 4;
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
				   &result_type, &value);
      if (**strp != ')')
	return "missing `)'";
      ++*strp;
      if (errmsg == NULL
	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
	return "not zero"; /* any string will do -- will never be seen.  */
      *valuep = value;
      return errmsg;
    }

  if (strncasecmp (*strp, "%uhi(", 5) == 0)
    {
      *strp += 5;
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
				   &result_type, &value);
      if (**strp != ')')
	return "missing `)'";
      ++*strp;
      if (errmsg == NULL
	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
	return "not zero"; /* any string will do -- will never be seen.  */
      *valuep = value;
      return errmsg;
    }

  if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
    {
      *strp += 8;
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
				   &result_type, &value);
      if (**strp != ')')
	return "missing `)'";
      ++*strp;
      if (errmsg == NULL
	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
	return "not zero"; /* any string will do -- will never be seen.  */
      *valuep = value;
      return errmsg;
    }

  if (strncasecmp (*strp, "%tpoff(", 7) == 0)
    {
      *strp += 7;
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
				   &result_type, &value);
      if (**strp != ')')
	return "missing `)'";
      ++*strp;
      if (errmsg == NULL
	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
	return "not zero"; /* any string will do -- will never be seen.  */
      *valuep = value;
      return errmsg;
    }

  if (**strp == '%')
    return "invalid %function() here";

  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_NONE,
			       &result_type, &value);
  if (errmsg == NULL
      && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
    return "not zero"; /* any string will do -- will never be seen.  */

  return errmsg;
}

static const char *
parse_unsigned7 (CGEN_CPU_DESC cd, const char **strp,
		 enum cgen_operand_type opindex, unsigned long *valuep)
{
  const char *errmsg;
  bfd_vma value;

  /* fprintf(stderr, "dj: unsigned7 parse `%s'\n", *strp); */

  if (strncasecmp (*strp, "%tpoff(", 7) == 0)
    {
      int reloc;
      *strp += 7;
      switch (opindex)
	{
	case MEP_OPERAND_UDISP7:
	  reloc = BFD_RELOC_MEP_TPREL7;
	  break;
	case MEP_OPERAND_UDISP7A2:
	  reloc = BFD_RELOC_MEP_TPREL7A2;
	  break;
	case MEP_OPERAND_UDISP7A4:
	  reloc = BFD_RELOC_MEP_TPREL7A4;
	  break;
	default:
	  /* Safe assumption?  */
	  abort (); 
	}
      errmsg = cgen_parse_address (cd, strp, opindex, reloc,
				   NULL, &value);
      if (**strp != ')')
	return "missing `)'";
      ++*strp;
      *valuep = value;
      return errmsg;
    }

  if (**strp == '%')
    return _("invalid %function() here");

  return parse_mep_alignu (cd, strp, opindex, valuep);
}

static ATTRIBUTE_UNUSED const char *
parse_cdisp10 (CGEN_CPU_DESC cd,
	       const char **strp,
	       int opindex,
	       long *valuep)
{
  const char *errmsg = 0;
  signed long value;
  long have_zero = 0;
  int wide = 0;
  int alignment;

  switch (opindex)
    {
    case MEP_OPERAND_CDISP10A4:
      alignment = 2;
      break;
    case MEP_OPERAND_CDISP10A2:
      alignment = 1;
      break;
    case MEP_OPERAND_CDISP10:
    default:
      alignment = 0;
      break;
    }

  if ((MEP_CPU & EF_MEP_CPU_MASK) == EF_MEP_CPU_C5)
    wide = 1;

  if (strncmp (*strp, "0x0", 3) == 0 
      || (**strp == '0' && *(*strp + 1) != 'x'))
    have_zero = 1;

  errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
  if (errmsg)
    return errmsg;

  if (wide)
    {
      if (value < -512 || value > 511)
	return _("Immediate is out of range -512 to 511");
    }
  else
    {
      if (value < -128 || value > 127)
	return _("Immediate is out of range -128 to 127");
    }

  if (value & ((1<<alignment)-1))
    return _("Value is not aligned enough");

  /* If this field may require a relocation then use larger dsp16.  */
  if (! have_zero && value == 0)
    return (wide ? _("Immediate is out of range -512 to 511")
	    : _("Immediate is out of range -128 to 127"));

  *valuep = value;
  return 0;
}

/* BEGIN LIGHTWEIGHT MACRO PROCESSOR.  */

#define MAXARGS 9

typedef struct
{
  char *name;
  char *expansion;
}  macro;

typedef struct
{
  const char *start;
  int len;
} arg;

static macro const macros[] =
{
  { "sizeof", "(`1.end + (- `1))"},
  { "startof", "(`1 | 0)" },
  { "align4", "(`1&(~3))"},
/*{ "hi", "(((`1+0x8000)>>16) & 0xffff)" },  */
/*{ "lo", "(`1 & 0xffff)" },  */
/*{ "sdaoff", "((`1-__sdabase) & 0x7f)"},  */
/*{ "tpoff", "((`1-__tpbase) & 0x7f)"},  */
  { 0,0 }
};

static char  * expand_string    (const char *, int);

static const char *
mep_cgen_expand_macros_and_parse_operand
  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);

static char *
str_append (char *dest, const char *input, int len)
{  
  char *new_dest;
  int oldlen;

  if (len == 0)
    return dest;
  /* printf("str_append: <<%s>>, <<%s>>, %d\n", dest, input, len); */
  oldlen = (dest ? strlen(dest) : 0);
  new_dest = realloc (dest, oldlen + len + 1);
  memset (new_dest + oldlen, 0, len + 1);
  return strncat (new_dest, input, len);
}

static const macro *
lookup_macro (const char *name)
{
  const macro *m;

  for (m = macros; m->name; ++m)
    if (strncmp (m->name, name, strlen(m->name)) == 0)
      return m;

  return 0;
}

static char *
expand_macro (arg *args, int narg, const macro *mac)
{
  char *result = 0, *rescanned_result = 0;
  char *e = mac->expansion;
  char *mark = e;
  int mac_arg = 0;

  /*  printf("expanding macro %s with %d args\n", mac->name, narg + 1); */
  while (*e)
    {
      if (*e == '`' && 
	  (*e+1) && 
	  ((*(e + 1) - '1') <= MAXARGS) &&
	  ((*(e + 1) - '1') <= narg))
	{
	  result = str_append (result, mark, e - mark);
	  mac_arg = (*(e + 1) - '1');
	  /* printf("replacing `%d with %s\n", mac_arg+1, args[mac_arg].start); */
	  result = str_append (result, args[mac_arg].start, args[mac_arg].len);
	  ++e;
	  mark = e+1;
	}
      ++e;
    }

  if (mark != e)
    result = str_append (result, mark, e - mark);

  if (result)
    {
      rescanned_result = expand_string (result, 0);
      free (result);
      return rescanned_result;
    }
  else 
    return result;
}

#define IN_TEXT 0
#define IN_ARGS 1

static char *
expand_string (const char *in, int first_only)
{
  int num_expansions = 0;
  int depth = 0;
  int narg = -1;
  arg args[MAXARGS];
  int state = IN_TEXT;
  const char *mark = in;
  const macro *pmacro = NULL;
  char *expansion = 0;
  char *result = 0;

  while (*in)
    {
      switch (state)
	{
	case IN_TEXT:
	  if (*in == '%' && *(in + 1) && (!first_only || num_expansions == 0)) 
	    {	      
	      pmacro = lookup_macro (in + 1);
	      if (pmacro)
		{
		  /* printf("entering state %d at '%s'...\n", state, in); */
		  result = str_append (result, mark, in - mark);
		  mark = in;
		  in += 1 + strlen (pmacro->name);
		  while (*in == ' ') ++in;
		  if (*in != '(')
		    {
		      state = IN_TEXT;		      
		      pmacro = NULL;
		    }
		  else
		    {
		      state = IN_ARGS;
		      narg = 0;
		      args[narg].start = in + 1;
		      args[narg].len = 0;
		      mark = in + 1;	      		      
		    }
		}
	    }
	  break;
	case IN_ARGS:
	  if (depth == 0)
	    {
	      switch (*in)
		{
		case ',':
		  narg++;
		  args[narg].start = (in + 1);
		  args[narg].len = 0;
		  break;
		case ')':
		  state = IN_TEXT;
		  /* printf("entering state %d at '%s'...\n", state, in); */
		  if (pmacro)
		    {
		      expansion = 0;
		      expansion = expand_macro (args, narg, pmacro);
		      num_expansions++;
		      if (expansion)
			{
			  result = str_append (result, expansion, strlen (expansion));
			  free (expansion);
			}
		    }
		  else
		    {
		      result = str_append (result, mark, in - mark);
		    }
		  pmacro = NULL;
		  mark = in + 1;
		  break;
		case '(':
		  depth++;
		  /* Fall through.  */
		default:
		  args[narg].len++;
		  break;		  
		}
	    } 
	  else
	    {
	      if (*in == ')')
		depth--;
	      if (narg > -1)
		args[narg].len++;
	    }
	  
	}
      ++in;
    }
  
  if (mark != in)
    result = str_append (result, mark, in - mark);
  
  return result;
}

#undef IN_ARGS
#undef IN_TEXT
#undef MAXARGS


/* END LIGHTWEIGHT MACRO PROCESSOR.  */

const char * mep_cgen_parse_operand
  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);

const char *
mep_cgen_expand_macros_and_parse_operand (CGEN_CPU_DESC cd, int opindex,
					  const char ** strp_in, CGEN_FIELDS * fields)
{
  const char * errmsg = NULL;
  char *str = 0, *hold = 0;
  const char **strp = 0;

  /* Set up a new pointer to macro-expanded string.  */
  str = expand_string (*strp_in, 1);
  /* fprintf (stderr, " expanded <<%s>> to <<%s>>\n", *strp_in, str); */

  hold = str;
  strp = (const char **)(&str);

  errmsg = mep_cgen_parse_operand (cd, opindex, strp, fields);

  /* Now work out the advance.  */
  if (strlen (str) == 0)
    *strp_in += strlen (*strp_in);

  else
    {
      if (strstr (*strp_in, str))
	/* A macro-expansion was pulled off the front.  */
	*strp_in = strstr (*strp_in, str);  
      else
	/* A non-macro-expansion was pulled off the front.  */
	*strp_in += (str - hold); 
    }

  free (hold);

  return errmsg;
}

#define CGEN_ASM_INIT_HOOK (cd->parse_operand = mep_cgen_expand_macros_and_parse_operand); 

/* -- dis.c */

#include "elf/mep.h"
#include "elf-bfd.h"

#define CGEN_VALIDATE_INSN_SUPPORTED

static void print_tpreg (CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int);
static void print_spreg (CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int);

static void
print_tpreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, PTR dis_info,
	     CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
	     unsigned int flags ATTRIBUTE_UNUSED)
{
  disassemble_info *info = (disassemble_info *) dis_info;

  (*info->fprintf_func) (info->stream, "$tp");
}

static void
print_spreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, PTR dis_info, 
	     CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
	     unsigned int flags ATTRIBUTE_UNUSED)
{
  disassemble_info *info = (disassemble_info *) dis_info;

  (*info->fprintf_func) (info->stream, "$sp");
}

/* begin-cop-ip-print-handlers */
static void
print_ivc2_cr (CGEN_CPU_DESC,
	void *,
	CGEN_KEYWORD *,
	long,
	unsigned int) ATTRIBUTE_UNUSED;
static void
print_ivc2_cr (CGEN_CPU_DESC cd,
	void *dis_info,
	CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
	long value,
	unsigned int attrs)
{
  print_keyword (cd, dis_info, & mep_cgen_opval_h_cr_ivc2, value, attrs);
}
static void
print_ivc2_ccr (CGEN_CPU_DESC,
	void *,
	CGEN_KEYWORD *,
	long,
	unsigned int) ATTRIBUTE_UNUSED;
static void
print_ivc2_ccr (CGEN_CPU_DESC cd,
	void *dis_info,
	CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
	long value,
	unsigned int attrs)
{
  print_keyword (cd, dis_info, & mep_cgen_opval_h_ccr_ivc2, value, attrs);
}
/* end-cop-ip-print-handlers */

/************************************************************\
*********************** Experimental *************************
\************************************************************/

#undef  CGEN_PRINT_INSN
#define CGEN_PRINT_INSN mep_print_insn

static int
mep_print_vliw_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info,
		      bfd_byte *buf, int corelength, int copro1length,
		      int copro2length ATTRIBUTE_UNUSED)
{
  int i;
  int status = 0;
  /* char insnbuf[CGEN_MAX_INSN_SIZE]; */
  bfd_byte insnbuf[64];

  /* If corelength > 0 then there is a core insn present. It
     will be at the beginning of the buffer.  After printing
     the core insn, we need to print the + on the next line.  */
  if (corelength > 0)
    {
      int my_status = 0;
	 
      for (i = 0; i < corelength; i++ )
	insnbuf[i] = buf[i];
      cd->isas = & MEP_CORE_ISA;
	 
      my_status = print_insn (cd, pc, info, insnbuf, corelength);
      if (my_status != corelength)
	{
	  (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
	  my_status = corelength;
	}
      status += my_status;

      /* Print the + to indicate that the following copro insn is   */
      /* part of a vliw group.                                      */
      if (copro1length > 0)
	(*info->fprintf_func) (info->stream, " + "); 
    }

  /* Now all that is left to be processed is the coprocessor insns
     In vliw mode, there will always be one.  Its positioning will
     be from byte corelength to byte corelength+copro1length -1.
     No need to check for existence.   Also, the first vliw insn,
     will, as spec'd, always be at least as long as the core insn
     so we don't need to flush the buffer.  */
  if (copro1length > 0)
    {
      int my_status = 0;
	 
      for (i = corelength; i < corelength + copro1length; i++ )
	insnbuf[i - corelength] = buf[i];

      switch (copro1length)
	{
	case 0:
	  break;
	case 2:
	  cd->isas = & MEP_COP16_ISA;
	  break;
	case 4:
	  cd->isas = & MEP_COP32_ISA;
	  break;
	case 6:
	  cd->isas = & MEP_COP48_ISA;
	  break;
	case 8:
	  cd->isas = & MEP_COP64_ISA;
	  break; 
	default:
	  /* Shouldn't be anything but 16,32,48,64.  */
	  break;
	}

      my_status = print_insn (cd, pc, info, insnbuf, copro1length);

      if (my_status != copro1length)
	{
	  (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
	  my_status = copro1length;
	}
      status += my_status;
    }

#if 0
  /* Now we need to process the second copro insn if it exists. We
     have no guarantee that the second copro insn will be longer
     than the first, so we have to flush the buffer if we are have
     a second copro insn to process.  If present, this insn will
     be in the position from byte corelength+copro1length to byte
     corelength+copro1length+copro2length-1 (which better equal 8
     or else we're in big trouble.  */
  if (copro2length > 0)
    {
      int my_status = 0;

      for (i = 0; i < 64 ; i++)
	insnbuf[i] = 0;

      for (i = corelength + copro1length; i < 64; i++)
	insnbuf[i - (corelength + copro1length)] = buf[i];
      
      switch (copro2length)
	{
	case 2:
	  cd->isas = 1 << ISA_EXT_COP1_16;
	  break;
	case 4:
	  cd->isas = 1 << ISA_EXT_COP1_32;
	  break;
	case 6:
	  cd->isas = 1 << ISA_EXT_COP1_48;
	  break;
	case 8:
	  cd->isas = 1 << ISA_EXT_COP1_64; 
	  break;
	default:
	  /* Shouldn't be anything but 16,32,48,64.  */
	  break;
	}

      my_status = print_insn (cd, pc, info, insnbuf, copro2length);

      if (my_status != copro2length)
	{
	  (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
	  my_status = copro2length;
	}

      status += my_status;
    }
#endif

  /* Status should now be the number of bytes that were printed
     which should be 4 for VLIW32 mode and 64 for VLIW64 mode.  */

  if ((!MEP_VLIW64 && (status != 4)) || (MEP_VLIW64 && (status != 8)))
    return -1;
  else
    return status;
}

/* The two functions mep_examine_vliw[32,64]_insns are used find out 
   which vliw combinaion (16 bit core with 48 bit copro, 32 bit core 
   with 32 bit copro, etc.) is present.  Later on, when internally   
   parallel coprocessors are handled, only these functions should    
   need to be changed.                                               

   At this time only the following combinations are supported: 
   
   VLIW32 Mode:
   16 bit core insn (core) and 16 bit coprocessor insn (cop1)
   32 bit core insn (core)
   32 bit coprocessor insn (cop1)
   Note: As of this time, I do not believe we have enough information
         to distinguish a 32 bit core insn from a 32 bit cop insn. Also,
         no 16 bit coprocessor insns have been specified.  

   VLIW64 Mode:
   16 bit core insn (core) and 48 bit coprocessor insn (cop1)
   32 bit core insn (core) and 32 bit coprocessor insn (cop1)
   64 bit coprocessor insn (cop1)
  
   The framework for an internally parallel coprocessor is also
   present (2nd coprocessor insn is cop2), but at this time it 
   is not used.  This only appears to be valid in VLIW64 mode.  */

static int
mep_examine_vliw32_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
{
  int status;
  int buflength;
  int corebuflength;
  int cop1buflength;
  int cop2buflength;
  bfd_byte buf[CGEN_MAX_INSN_SIZE];  
  char indicator16[1];
  char indicatorcop32[2]; 

  /* At this time we're not supporting internally parallel coprocessors,
     so cop2buflength will always be 0.  */
  cop2buflength = 0;

  /* Read in 32 bits.  */
  buflength = 4; /* VLIW insn spans 4 bytes.  */
  status = (*info->read_memory_func) (pc, buf, buflength, info);

  if (status != 0)
    {
      (*info->memory_error_func) (status, pc, info);
      return -1;
    }

  /* Put the big endian representation of the bytes to be examined
     in the temporary buffers for examination.  */

  if (info->endian == BFD_ENDIAN_BIG)
    {
      indicator16[0] = buf[0];
      indicatorcop32[0] = buf[0];
      indicatorcop32[1] = buf[1];
    }
  else
    {
      indicator16[0] = buf[1];
      indicatorcop32[0] = buf[1];
      indicatorcop32[1] = buf[0];
    }

  /* If the two high order bits are 00, 01 or 10, we have a 16 bit
     core insn and a 48 bit copro insn.  */

  if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
    {
      if ((indicatorcop32[0] & 0xf0) == 0xf0 && (indicatorcop32[1] & 0x07) == 0x07)
	{
          /* We have a 32 bit copro insn.  */
          corebuflength = 0;
	  /* All 4 4ytes are one copro insn. */
          cop1buflength = 4;
	}
      else
	{
          /* We have a 32 bit core.  */
          corebuflength = 4;
          cop1buflength = 0;
	}
    }
  else
    {
      /* We have a 16 bit core insn and a 16 bit copro insn.  */
      corebuflength = 2;
      cop1buflength = 2;
    }

  /* Now we have the distrubution set.  Print them out.  */
  status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
				 cop1buflength, cop2buflength);

  return status;
}

static int
mep_examine_vliw64_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
{
  int status;
  int buflength;
  int corebuflength;
  int cop1buflength;
  int cop2buflength;
  bfd_byte buf[CGEN_MAX_INSN_SIZE];
  char indicator16[1];
  char indicator64[4];

  /* At this time we're not supporting internally parallel
     coprocessors, so cop2buflength will always be 0.  */
  cop2buflength = 0;

  /* Read in 64 bits.  */
  buflength = 8; /* VLIW insn spans 8 bytes.  */
  status = (*info->read_memory_func) (pc, buf, buflength, info);

  if (status != 0)
    {
      (*info->memory_error_func) (status, pc, info);
      return -1;
    }

  /* We have all 64 bits in the buffer now.  We have to figure out
     what combination of instruction sizes are present.  The two
     high order bits will indicate whether or not we have a 16 bit
     core insn or not.  If not, then we have to look at the 7,8th
     bytes to tell whether we have 64 bit copro insn or a 32 bit
     core insn with a 32 bit copro insn.  Endianness will make a
     difference here.  */

  /* Put the big endian representation of the bytes to be examined
     in the temporary buffers for examination.  */

  /* indicator16[0] = buf[0];  */
  if (info->endian == BFD_ENDIAN_BIG)
    {
      indicator16[0] = buf[0];
      indicator64[0] = buf[0];
      indicator64[1] = buf[1];
      indicator64[2] = buf[2];
      indicator64[3] = buf[3];
    }
  else
    {
      indicator16[0] = buf[1];
      indicator64[0] = buf[1];
      indicator64[1] = buf[0];
      indicator64[2] = buf[3];
      indicator64[3] = buf[2];
    }

  /* If the two high order bits are 00, 01 or 10, we have a 16 bit
     core insn and a 48 bit copro insn.  */

  if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
    {
      if ((indicator64[0] & 0xf0) == 0xf0 && (indicator64[1] & 0x07) == 0x07
	  && ((indicator64[2] & 0xfe) != 0xf0 || (indicator64[3] & 0xf4) != 0))
	{
          /* We have a 64 bit copro insn.  */
          corebuflength = 0;
	  /* All 8 bytes are one copro insn.  */
          cop1buflength = 8;
	}
      else
	{
          /* We have a 32 bit core insn and a 32 bit copro insn.  */
          corebuflength = 4;
          cop1buflength = 4;
	}
    }
  else
    {
      /* We have a 16 bit core insn and a 48 bit copro insn.  */
      corebuflength = 2;
      cop1buflength = 6;
    }

  /* Now we have the distrubution set.  Print them out. */
  status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
				 cop1buflength, cop2buflength);

  return status;
}

#ifdef MEP_IVC2_SUPPORTED

static int
print_slot_insn (CGEN_CPU_DESC cd,
		 bfd_vma pc,
		 disassemble_info *info,
		 SLOTS_ATTR slot,
		 bfd_byte *buf)
{
  const CGEN_INSN_LIST *insn_list;
  CGEN_INSN_INT insn_value;
  CGEN_EXTRACT_INFO ex_info;

  insn_value = cgen_get_insn_value (cd, buf, 32, cd->insn_endian);

  /* Fill in ex_info fields like read_insn would.  Don't actually call
     read_insn, since the incoming buffer is already read (and possibly
     modified a la m32r).  */
  ex_info.valid = (1 << 8) - 1;
  ex_info.dis_info = info;
  ex_info.insn_bytes = buf;

  /* The instructions are stored in hash lists.
     Pick the first one and keep trying until we find the right one.  */

  insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
  while (insn_list != NULL)
    {
      const CGEN_INSN *insn = insn_list->insn;
      CGEN_FIELDS fields;
      int length;

      if ((CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_CONFIG)
	   && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_CONFIG) != MEP_CONFIG)
	  || ! (CGEN_ATTR_CGEN_INSN_SLOTS_VALUE (CGEN_INSN_ATTRS (insn)) & (1 << slot)))
        {
          insn_list = CGEN_DIS_NEXT_INSN (insn_list);
	  continue;
        }

      if ((insn_value & CGEN_INSN_BASE_MASK (insn))
	  == CGEN_INSN_BASE_VALUE (insn))
	{
	  /* Printing is handled in two passes.  The first pass parses the
	     machine insn and extracts the fields.  The second pass prints
	     them.  */

	  length = CGEN_EXTRACT_FN (cd, insn)
	    (cd, insn, &ex_info, insn_value, &fields, pc);

	  /* Length < 0 -> error.  */
	  if (length < 0)
	    return length;
	  if (length > 0)
	    {
	      CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
	      /* Length is in bits, result is in bytes.  */
	      return length / 8;
	    }
	}

      insn_list = CGEN_DIS_NEXT_INSN (insn_list);
    }

  if (slot == SLOTS_P0S)
    (*info->fprintf_func) (info->stream, "*unknown-p0s*");
  else if (slot == SLOTS_P0)
    (*info->fprintf_func) (info->stream, "*unknown-p0*");
  else if (slot == SLOTS_P1)
    (*info->fprintf_func) (info->stream, "*unknown-p1*");
  else if (slot == SLOTS_C3)
    (*info->fprintf_func) (info->stream, "*unknown-c3*");
  return 0;
}

static int
mep_examine_ivc2_insns (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, bfd_vma pc ATTRIBUTE_UNUSED, disassemble_info *info ATTRIBUTE_UNUSED)
{
  int status;
  int buflength;
  bfd_byte buf[8];
  bfd_byte insn[8];
  int e;

  /* Read in 64 bits.  */
  buflength = 8; /* VLIW insn spans 8 bytes.  */
  status = (*info->read_memory_func) (pc, buf, buflength, info);

  if (status != 0)
    {
      (*info->memory_error_func) (status, pc, info);
      return -1;
    }

  if (info->endian == BFD_ENDIAN_LITTLE)
    e = 1;
  else
    e = 0;

  if (((unsigned char)buf[0^e] & 0xf0) < 0xc0)
    {
      /*      <--00--><--11--><--22--><--33--><--44--><--55--><--66--><--77--> */
      /* V1   [-----core-----][--------p0s-------][------------p1------------] */

      print_insn (cd, pc, info, buf, 2);

      insn[0^e] = 0;
      insn[1^e] = buf[2^e];
      insn[2^e] = buf[3^e];
      insn[3^e] = buf[4^e] & 0xf0;
      (*info->fprintf_func) (info->stream, " + ");
      print_slot_insn (cd, pc, info, SLOTS_P0S, insn);

      insn[0^e] = buf[4^e] << 4 | buf[5^e] >> 4;
      insn[1^e] = buf[5^e] << 4 | buf[6^e] >> 4;
      insn[2^e] = buf[6^e] << 4 | buf[7^e] >> 4;
      insn[3^e] = buf[7^e] << 4;
      (*info->fprintf_func) (info->stream, " + ");
      print_slot_insn (cd, pc, info, SLOTS_P1, insn);
    }
  else if ((buf[0^e] & 0xf0) == 0xf0 && (buf[1^e] & 0x0f) == 0x07)
    {
      /*      <--00--><--11--><--22--><--33--><--44--><--55--><--66--><--77--> */
      /* V3   1111[--p0--]0111[--------p0--------][------------p1------------] */
      /*                                          00000000111111112222222233333333 */

      insn[0^e] = buf[0^e] << 4 | buf[1^e] >> 4;
      insn[1^e] = buf[2^e];
      insn[2^e] = buf[3^e];
      insn[3^e] = buf[4^e] & 0xf0;
      print_slot_insn (cd, pc, info, SLOTS_P0, insn);

      insn[0^e] = buf[4^e] << 4 | buf[5^e] >> 4;
      insn[1^e] = buf[5^e] << 4 | buf[6^e] >> 4;
      insn[2^e] = buf[6^e] << 4 | buf[7^e] >> 4;
      insn[3^e] = buf[7^e] << 4;
      (*info->fprintf_func) (info->stream, " + ");
      print_slot_insn (cd, pc, info, SLOTS_P1, insn);
    }
  else
    {
      /*      <--00--><--11--><--22--><--33--><--44--><--55--><--66--><--77--> */
      /* V2   [-------------core-------------]xxxx[------------p1------------] */
      print_insn (cd, pc, info, buf, 4);

      insn[0^e] = buf[4^e] << 4 | buf[5^e] >> 4;
      insn[1^e] = buf[5^e] << 4 | buf[6^e] >> 4;
      insn[2^e] = buf[6^e] << 4 | buf[7^e] >> 4;
      insn[3^e] = buf[7^e] << 4;
      (*info->fprintf_func) (info->stream, " + ");
      print_slot_insn (cd, pc, info, SLOTS_P1, insn);
    }

  return 8;
}

#endif /* MEP_IVC2_SUPPORTED */

/* This is a hack.  SID calls this to update the disassembler as the
   CPU changes modes.  */
static int mep_ivc2_disassemble_p = 0;
static int mep_ivc2_vliw_disassemble_p = 0;

void
mep_print_insn_set_ivc2_mode (int ivc2_p, int vliw_p, int cfg_idx);
void
mep_print_insn_set_ivc2_mode (int ivc2_p, int vliw_p, int cfg_idx)
{
  mep_ivc2_disassemble_p = ivc2_p;
  mep_ivc2_vliw_disassemble_p = vliw_p;
  mep_config_index = cfg_idx;
}

static int
mep_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
{
  int status;
  int cop_type;
  int ivc2 = 0;
  static CGEN_ATTR_VALUE_BITSET_TYPE *ivc2_core_isa = NULL;

  if (ivc2_core_isa == NULL)
    {
      /* IVC2 has some core-only coprocessor instructions.  We
	 use COP32 to flag those, and COP64 for the VLIW ones,
	 since they have the same names.  */
      ivc2_core_isa = cgen_bitset_create (MAX_ISAS);
    }

  /* Extract and adapt to configuration number, if available. */
  if (info->section && info->section->owner)
    {
      bfd *abfd = info->section->owner;
      mep_config_index = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_INDEX_MASK;
      /* This instantly redefines MEP_CONFIG, MEP_OMASK, .... MEP_VLIW64 */

      cop_type = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_COP_MASK;
      if (cop_type == EF_MEP_COP_IVC2)
	ivc2 = 1;
    }

  /* Picking the right ISA bitmask for the current context is tricky.  */
  if (info->section)
    {
      if (info->section->flags & SEC_MEP_VLIW)
	{
#ifdef MEP_IVC2_SUPPORTED
	  if (ivc2)
	    {
	      /* ivc2 has its own way of selecting its functions.  */
	      cd->isas = & MEP_CORE_ISA;
	      status = mep_examine_ivc2_insns (cd, pc, info);
	    }
	  else
#endif
	    /* Are we in 32 or 64 bit vliw mode?  */
	    if (MEP_VLIW64)
	      status = mep_examine_vliw64_insns (cd, pc, info);
	    else
	      status = mep_examine_vliw32_insns (cd, pc, info);
	  /* Both the above branches set their own isa bitmasks.  */
	}
      else
	{
	  if (ivc2)
	    {
	      cgen_bitset_clear (ivc2_core_isa);
	      cgen_bitset_union (ivc2_core_isa, &MEP_CORE_ISA, ivc2_core_isa);
	      cgen_bitset_union (ivc2_core_isa, &MEP_COP32_ISA, ivc2_core_isa);
	      cd->isas = ivc2_core_isa;
	    }
	  else
	    cd->isas = & MEP_CORE_ISA;
	  status = default_print_insn (cd, pc, info);
	}
    }
  else /* sid or gdb */
    {
#ifdef MEP_IVC2_SUPPORTED
      if (mep_ivc2_disassemble_p)
	{
	  if (mep_ivc2_vliw_disassemble_p)
	    {
	      cd->isas = & MEP_CORE_ISA;
	      status = mep_examine_ivc2_insns (cd, pc, info);
	      return status;
	    }
	  else
	    {
	      if (ivc2)
		cd->isas = ivc2_core_isa;
	    }
	}
#endif

      status = default_print_insn (cd, pc, info);
    }

  return status;
}


/* -- opc.c */
#include "elf/mep.h"

/* A mask for all ISAs executed by the core. */
CGEN_ATTR_VALUE_BITSET_TYPE mep_all_core_isas_mask = {0, 0};

void
init_mep_all_core_isas_mask (void)
{
  if (mep_all_core_isas_mask.length != 0)
    return;
  cgen_bitset_init (& mep_all_core_isas_mask, ISA_MAX);
  cgen_bitset_set (& mep_all_core_isas_mask, ISA_MEP);
  /* begin-all-core-isas */
  cgen_bitset_add (& mep_all_core_isas_mask, ISA_EXT_CORE1);
  /* end-all-core-isas */
}

CGEN_ATTR_VALUE_BITSET_TYPE mep_all_cop_isas_mask = {0, 0};

void
init_mep_all_cop_isas_mask (void)
{
  if (mep_all_cop_isas_mask.length != 0)
    return;
  cgen_bitset_init (& mep_all_cop_isas_mask, ISA_MAX);
  /* begin-all-cop-isas */
  cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP1_16);
  cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP1_32);
  cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP1_48);
  cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP1_64);
  /* end-all-cop-isas */
}

int
mep_insn_supported_by_isa (const CGEN_INSN *insn, CGEN_ATTR_VALUE_BITSET_TYPE *isa_mask)
{
  CGEN_BITSET insn_isas = CGEN_INSN_BITSET_ATTR_VALUE (insn, CGEN_INSN_ISA);
  return cgen_bitset_intersect_p (& insn_isas, isa_mask);
}

#define OPTION_MASK \
	( (1 << CGEN_INSN_OPTIONAL_BIT_INSN) \
	| (1 << CGEN_INSN_OPTIONAL_MUL_INSN) \
	| (1 << CGEN_INSN_OPTIONAL_DIV_INSN) \
	| (1 << CGEN_INSN_OPTIONAL_DEBUG_INSN) \
	| (1 << CGEN_INSN_OPTIONAL_LDZ_INSN) \
	| (1 << CGEN_INSN_OPTIONAL_ABS_INSN) \
	| (1 << CGEN_INSN_OPTIONAL_AVE_INSN) \
	| (1 << CGEN_INSN_OPTIONAL_MINMAX_INSN) \
	| (1 << CGEN_INSN_OPTIONAL_CLIP_INSN) \
	| (1 << CGEN_INSN_OPTIONAL_SAT_INSN) \
	| (1 << CGEN_INSN_OPTIONAL_UCI_INSN) \
	| (1 << CGEN_INSN_OPTIONAL_DSP_INSN) \
	| (1 << CGEN_INSN_OPTIONAL_CP_INSN) \
	| (1 << CGEN_INSN_OPTIONAL_CP64_INSN) )


mep_config_map_struct mep_config_map[] =
{
  /* config-map-start */
  /* Default entry: first module, with all options enabled. */
  { "", 0,  EF_MEP_COP_IVC2 | EF_MEP_CPU_C5,0, 64, { 1, "\x20" }, { 1, "\x10" }, { 1, "\x8" }, { 1, "\x4" }, { 1, "\x3c" }, { 1, "\xc0" }, OPTION_MASK | (1 << CGEN_INSN_OPTIONAL_DSP_INSN) | (1 << CGEN_INSN_OPTIONAL_UCI_INSN) },
  { "default", CONFIG_DEFAULT, EF_MEP_COP_IVC2 | EF_MEP_CPU_C5, 0, 64, { 1, "\x20" }, { 1, "\x10" }, { 1, "\x8" }, { 1, "\x4" }, { 1, "\x3c" }, { 1, "\xc0" },
	  0
	| (1 << CGEN_INSN_OPTIONAL_CP_INSN)
	| (1 << CGEN_INSN_OPTIONAL_CP64_INSN)
	| (1 << CGEN_INSN_OPTIONAL_MUL_INSN)
	| (1 << CGEN_INSN_OPTIONAL_DIV_INSN)
	| (1 << CGEN_INSN_OPTIONAL_BIT_INSN)
	| (1 << CGEN_INSN_OPTIONAL_LDZ_INSN)
	| (1 << CGEN_INSN_OPTIONAL_ABS_INSN)
	| (1 << CGEN_INSN_OPTIONAL_AVE_INSN)
	| (1 << CGEN_INSN_OPTIONAL_MINMAX_INSN)
	| (1 << CGEN_INSN_OPTIONAL_CLIP_INSN)
	| (1 << CGEN_INSN_OPTIONAL_SAT_INSN) },
  /* config-map-end */
  { 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0 }
};

int mep_config_index = 0;

static int
check_configured_mach (int machs)
{
  /* All base insns are supported.  */
  int mach = 1 << MACH_BASE;
  switch (MEP_CPU & EF_MEP_CPU_MASK)
    {
    case EF_MEP_CPU_C2:
    case EF_MEP_CPU_C3:
      mach |= (1 << MACH_MEP);
      break;
    case EF_MEP_CPU_H1:
      mach |= (1 << MACH_H1);
      break;
    case EF_MEP_CPU_C5:
      mach |= (1 << MACH_MEP);
      mach |= (1 << MACH_C5);
      break;
    default:
      break;
    }
  return machs & mach;
}

int
mep_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
{
  int iconfig = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_CONFIG);
  int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
  CGEN_BITSET isas = CGEN_INSN_BITSET_ATTR_VALUE (insn, CGEN_INSN_ISA);
  int ok1;
  int ok2;
  int ok3;

  /* If the insn has an option bit set that we don't want,
     reject it.  */
  if (CGEN_INSN_ATTRS (insn)->bool_ & OPTION_MASK & ~MEP_OMASK)
    return 0;

  /* If attributes are absent, assume no restriction. */
  if (machs == 0)
    machs = ~0;

  ok1 = ((machs & cd->machs) && cgen_bitset_intersect_p (& isas, cd->isas));
  /* If the insn is config-specific, make sure it matches.  */
  ok2 =  (iconfig == 0 || iconfig == MEP_CONFIG);
  /* Make sure the insn is supported by the configured mach  */
  ok3 = check_configured_mach (machs);

  return (ok1 && ok2 && ok3);
}

int
mep_cgen_insn_supported_asm (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
{
#ifdef MEP_IVC2_SUPPORTED
  /* If we're assembling VLIW packets, ignore the 12-bit BSR as we
     can't relax that.  The 24-bit BSR is matched instead.  */
  if (insn->base->num == MEP_INSN_BSR12
      && cgen_bitset_contains (cd->isas, ISA_EXT_COP1_64))
    return 0;
#endif

  return mep_cgen_insn_supported (cd, insn);
}
