/* ARC opcode support.  -*- C -*-
   Copyright 1998, 1999, 2000, 2001, 2004, 2005, 2007, 2008
   Free Software Foundation, Inc.
   This file is part of CGEN.

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

/* This file is an addendum to arc.cpu.  Heavy use of C code isn't
   appropriate in .cpu files, so it resides here.  This especially applies
   to assembly/disassembly where parsing/printing can be quite involved.
   Such things aren't really part of the specification of the cpu, per se,
   so .cpu files provide the general framework and .opc files handle the
   nitty-gritty details as necessary.

   Each section is delimited with start and end markers.

   <arch>-opc.h additions use: "-- opc.h"
   <arch>-opc.c additions use: "-- opc.c"
   <arch>-asm.c additions use: "-- asm.c"
   <arch>-dis.c additions use: "-- dis.c"
   <arch>-ibd.h additions use: "-- ibd.h"  */

   /* Copyright (C) 2000, 2001, 2004, 2005 Red Hat, Inc. */
/* -- opc.h */

#undef  CGEN_DIS_HASH_SIZE
#define CGEN_DIS_HASH_SIZE 1024
#undef  CGEN_DIS_HASH
#define CGEN_DIS_HASH(buffer, value, big_p) \
  arc_cgen_dis_hash (buffer, big_p)
extern unsigned int arc_cgen_dis_hash (const char *, int);
/* Override CGEN_INSN_BITSIZE for sim/common/cgen-trace.c .
   insn extraction for simulation is fine with 32 bits, since we fetch long
   immediates as part of the semantics if required, but for disassembly
   we must make sure we read all the bits while we have the information how
   to read them.  */
#define CGEN_INSN_DISASM_BITSIZE(insn) 64
extern char limm_str[];

/* cgen can't generate correct decoders for variable-length insns,
   so we have it generate a decoder that assumes all insns are 32 bit.
   And even if the decoder generator bug were fixed, having the decoder
   understand long immediates would be messy.
   The simulator calculates instruction sizes as part of the semantics.
   For disassembly, we redefine CGEN_EXTRACT_FN so that we can correct
   the calculated instruction length.  */
#undef CGEN_EXTRACT_FN
#define CGEN_EXTRACT_FN(cd, insn) ARC_CGEN_EXTRACT_FN
extern int arc_insn_length (unsigned long insn_value, const CGEN_INSN *insn,
			   CGEN_EXTRACT_INFO *info, bfd_vma pc);
static inline int
ARC_CGEN_EXTRACT_FN (CGEN_CPU_DESC cd, const CGEN_INSN *insn,
		     CGEN_EXTRACT_INFO *info, CGEN_INSN_INT insn_value,
		     CGEN_FIELDS *fields, bfd_vma pc)
{
  static int initialized = 0;
  /* ??? There is no suitable hook for one-time initialization.  */
  if (!initialized)
    {
      static CGEN_KEYWORD_ENTRY arc_cgen_opval_limm_entry0 =
	{ limm_str, 62, {0, {{{0, 0}}}}, 0, 0 };
      static CGEN_KEYWORD_ENTRY arc_cgen_opval_limm_entry1 =
	{ limm_str, 62, {0, {{{0, 0}}}}, 0, 0 };

      cgen_keyword_add (&arc_cgen_opval_cr_names, &arc_cgen_opval_limm_entry0);
      cgen_keyword_add (&arc_cgen_opval_h_noilink, &arc_cgen_opval_limm_entry1);
      initialized = 1;
    }
  /* ??? sim/common/cgen-trace.c:sim_cgen_disassemble_insn uses its own
     home-brewn instruction target-to-host conversion, which gets the
     endianness wrong for ARC.  */
  if (cd->endian == CGEN_ENDIAN_LITTLE)
    insn_value = ((insn_value >> 16) & 0xffff) | (insn_value << 16);

  /* First, do the normal extract handler call, but ignore its value.  */
  ((cd)->extract_handlers[(insn)->opcode->handlers.extract]
    (cd, insn, info, insn_value, fields, pc));
  /* Now calculate the actual insn length, and extract any long immediate
     if present.  */
  return arc_insn_length (insn_value, insn, info, pc);
}

/* -- */

/* -- opc.c */
unsigned int
arc_cgen_dis_hash (const char * buf, int big_p)
{
  const unsigned char *ubuf = (unsigned const char *) buf;
  int b0 = ubuf[0], b1 = ubuf[1], w;

  if (big_p)
    w = (b0 << 8) + b1;
  else
    w = (b1 << 8) + b0;

  switch (w >> 11)
    {
    case 0x01: /* branches */
      return ((w >> 6) | w);
    case 0x04: /* general operations */
    case 0x05: case 0x06: case 0x07: /* 32 bit extension instructions */
      return ((w >> 3) & 768) | (w & 255);
    case 0x0c: /* .s load/add register-register */
    case 0x0d: /* .s add/sub/shift register-immediate */
    case 0x0e: /* .s mov/cmp/add with high register */
      return ((w >> 6) & 992) | (w & 24);
    case 0x0f: /* 16 bit general operations */
      return ((w >> 6) & 992) | (w & 31);
    case 0x17: /* .s shift/subtract/bit immediate */
    case 0x18: /* .s stack-pointer based */
      return ((w >> 6) & 992) | ((w >> 5) & 7);
    case 0x19: /* load/add GP-relative */
    case 0x1e: /* branch conditionally */
      return ((w >> 6) & (992 | 24));
    case 0x1c: /* add/cmp immediate */
    case 0x1d: /* branch on compare register with zero */
      return ((w >> 6) & (992 | 2));
    default:
      return ((w >> 6) & 992);
    }
}

/* -- */

/* -- asm.c */
#if 0
static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");

/* Handle '#' prefixes (i.e. skip over them).  */

static const char *
parse_hash (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
	    const char **strp,
	    int opindex ATTRIBUTE_UNUSED,
	    long *valuep ATTRIBUTE_UNUSED)
{
  if (**strp == '#')
    ++*strp;
  return NULL;
}

/* Handle shigh(), high().  */

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

  if (**strp == '#')
    ++*strp;

  if (strncasecmp (*strp, "high(", 5) == 0)
    {
      *strp += 5;
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_HI16_ULO,
				   & result_type, & value);
      if (**strp != ')')
	return MISSING_CLOSING_PARENTHESIS;
      ++*strp;
      if (errmsg == NULL
  	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
	{
	  value >>= 16;
	  value &= 0xffff;
	}
      *valuep = value;
      return errmsg;
    }
  else if (strncasecmp (*strp, "shigh(", 6) == 0)
    {
      *strp += 6;
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_HI16_SLO,
 				   & result_type, & value);
      if (**strp != ')')
	return MISSING_CLOSING_PARENTHESIS;
      ++*strp;
      if (errmsg == NULL
	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
        {
          value += 0x8000;
          value >>= 16;
	  value &= 0xffff;
        }
      *valuep = value;
      return errmsg;
    }

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

/* Handle low() in a signed context.  Also handle sda().
   The signedness of the value doesn't matter to low(), but this also
   handles the case where low() isn't present.  */

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

  if (**strp == '#')
    ++*strp;

  if (strncasecmp (*strp, "low(", 4) == 0)
    {
      *strp += 4;
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_LO16,
				   & result_type, & value);
      if (**strp != ')')
	return MISSING_CLOSING_PARENTHESIS;
      ++*strp;
      if (errmsg == NULL
	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
	value = ((value & 0xffff) ^ 0x8000) - 0x8000;
      *valuep = value;
      return errmsg;
    }

  if (strncasecmp (*strp, "sda(", 4) == 0)
    {
      *strp += 4;
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_SDA16,
				   NULL, & value);
      if (**strp != ')')
	return MISSING_CLOSING_PARENTHESIS;
      ++*strp;
      *valuep = value;
      return errmsg;
    }

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

/* Handle low() in an unsigned context.
   The signedness of the value doesn't matter to low(), but this also
   handles the case where low() isn't present.  */

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

  if (**strp == '#')
    ++*strp;

  if (strncasecmp (*strp, "low(", 4) == 0)
    {
      *strp += 4;
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_LO16,
				   & result_type, & value);
      if (**strp != ')')
	return MISSING_CLOSING_PARENTHESIS;
      ++*strp;
      if (errmsg == NULL
	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
	value &= 0xffff;
      *valuep = value;
      return errmsg;
    }

  return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
}
#endif

/* -- */

/* -- dis.c */
char limm_str[11] = "0x";

/* Read a long immediate and write it hexadecimally into limm_str.  */
static void
read_limm (CGEN_EXTRACT_INFO *ex_info, bfd_vma pc)
{
  unsigned char buf[2];
  int i;
  char *limmp = limm_str + 2;
  disassemble_info *dis_info = (disassemble_info *) ex_info->dis_info;

  for (i = 0; i < 2; i++, limmp +=4, pc += 2)
    {
      int status = (*dis_info->read_memory_func) (pc, buf, 2, dis_info);

      if (status != 0)
        (*dis_info->memory_error_func) (status, pc, dis_info);
      sprintf (limmp, "%.4x",
	       (unsigned) bfd_get_bits (buf, 16,
					dis_info->endian == BFD_ENDIAN_BIG));
    }
}

/* Return the actual instruction length, in bits, which depends on the size
   of the opcode - 2 or 4 bytes - and the absence or presence of a (4 byte)
   long immediate.
   Also, if a long immediate is present, put its hexadecimal representation
   into limm_str.
   ??? cgen-opc.c:cgen_lookup_insn has a 'sanity' check of the length
   that will fail if its input length differs from the result of
   CGEN_EXTRACT_FN.  Need to check when this could trigger.  */
int
arc_insn_length (unsigned long insn_value, const CGEN_INSN *insn,
		 CGEN_EXTRACT_INFO *info, bfd_vma pc)
{
  switch (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_LIMM))
    {
    case LIMM_NONE:
      return CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_SHORT_P) ? 16 : 32;
    case LIMM_H:
      {
	/* This is a short insn; extract the actual opcode.  */
	unsigned high = insn_value >> 16;

        if ((high & 0xe7) != 0xc7)
	  return 16;
	read_limm (info, pc+2);
	return 48;
      }
    case LIMM_B:
      if ((insn_value & 0x07007000) != 0x06007000)
	return 32;
      break;
    case LIMM_BC:
      if ((insn_value & 0x07007000) == 0x06007000)
	break;
      /* Fall through.  */
    case LIMM_C:
      if ((insn_value & 0x00000fc0) != 0x00000f80)
	return 32;
      break;
    default:
      abort ();
    }
  read_limm (info, pc+4);
  return 64;
}

/* -- */
