/* IP2K opcode support.  -*- C -*-
   Copyright 2002, 2005, 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.  */

/*
   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".  */

/* -- opc.h */

/* Check applicability of instructions against machines.  */
#define CGEN_VALIDATE_INSN_SUPPORTED

/* Allows reason codes to be output when assembler errors occur.  */
#define CGEN_VERBOSE_ASSEMBLER_ERRORS

/* Override disassembly hashing - there are variable bits in the top
   byte of these instructions.  */
#define CGEN_DIS_HASH_SIZE 8
#define CGEN_DIS_HASH(buf, value) \
  (((* (unsigned char*) (buf)) >> 5) % CGEN_DIS_HASH_SIZE)

#define CGEN_ASM_HASH_SIZE 127
#define CGEN_ASM_HASH(insn) ip2k_asm_hash (insn)

extern unsigned int ip2k_asm_hash (const char *);
extern int ip2k_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);

/* -- opc.c */

#include "safe-ctype.h"

/* A better hash function for instruction mnemonics.  */
unsigned int
ip2k_asm_hash (const char* insn)
{
  unsigned int hash;
  const char* m = insn;

  for (hash = 0; *m && ! ISSPACE (*m); m++)
    hash = (hash * 23) ^ (0x1F & TOLOWER (*m));

  /* printf ("%s %d\n", insn, (hash % CGEN_ASM_HASH_SIZE)); */

  return hash % CGEN_ASM_HASH_SIZE;
}


/* Special check to ensure that instruction exists for given machine.  */

int
ip2k_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
{
  int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);

  /* No mach attribute?  Assume it's supported for all machs.  */
  if (machs == 0)
    return 1;
  
  return (machs & cd->machs) != 0;
}


/* -- asm.c */

static const char *
parse_fr (CGEN_CPU_DESC cd,
	  const char **strp,
	  int opindex,
	  unsigned long *valuep)
{
  const char *errmsg;
  const char *old_strp;
  char *afteroffset; 
  enum cgen_parse_operand_result result_type;
  bfd_vma value;
  extern CGEN_KEYWORD ip2k_cgen_opval_register_names;
  bfd_vma tempvalue;

  old_strp = *strp;
  afteroffset = NULL;

  /* Check here to see if you're about to try parsing a w as the first arg
     and return an error if you are.  */
  if ((strncmp (*strp, "w", 1) == 0) || (strncmp (*strp, "W", 1) == 0))
    {
      (*strp)++;

      if ((strncmp (*strp, ",", 1) == 0) || ISSPACE (**strp))
	{
	  /* We've been passed a w.  Return with an error message so that
	     cgen will try the next parsing option.  */
	  errmsg = _("W keyword invalid in FR operand slot.");
	  return errmsg;
	}
      *strp = old_strp;
    }

  /* Attempt parse as register keyword. */
  errmsg = cgen_parse_keyword (cd, strp, & ip2k_cgen_opval_register_names,
			       (long *) valuep);
  if (*strp != NULL
      && errmsg == NULL)
    return errmsg;

  /* Attempt to parse for "(IP)".  */
  afteroffset = strstr (*strp, "(IP)");

  if (afteroffset == NULL)
    /* Make sure it's not in lower case.  */
    afteroffset = strstr (*strp, "(ip)");

  if (afteroffset != NULL)
    {
      if (afteroffset != *strp)
	{
	  /* Invalid offset present.  */
	  errmsg = _("offset(IP) is not a valid form");
	  return errmsg;
	}
      else
	{
	  *strp += 4; 
	  *valuep = 0;
	  errmsg = NULL;
	  return errmsg;
	}
    }

  /* Attempt to parse for DP. ex: mov w, offset(DP)
                                  mov offset(DP),w   */

  /* Try parsing it as an address and see what comes back.  */
  afteroffset = strstr (*strp, "(DP)");

  if (afteroffset == NULL)
    /* Maybe it's in lower case.  */
    afteroffset = strstr (*strp, "(dp)");

  if (afteroffset != NULL)
    {
      if (afteroffset == *strp)
	{
	  /* No offset present. Use 0 by default.  */
	  tempvalue = 0;
	  errmsg = NULL;
	}
      else
	errmsg = cgen_parse_address (cd, strp, opindex,
				     BFD_RELOC_IP2K_FR_OFFSET,
				     & result_type, & tempvalue);

      if (errmsg == NULL)
	{
	  if (tempvalue <= 127)
	    {
	      /* Value is ok.  Fix up the first 2 bits and return.  */
	      *valuep = 0x0100 | tempvalue;
	      *strp += 4; /* Skip over the (DP) in *strp.  */
	      return errmsg;
	    }
	  else
	    {
	      /* Found something there in front of (DP) but it's out
		 of range.  */
	      errmsg = _("(DP) offset out of range.");
	      return errmsg;
	    }
	}
    }


  /* Attempt to parse for SP. ex: mov w, offset(SP)
                                  mov offset(SP), w.  */
  afteroffset = strstr (*strp, "(SP)");

  if (afteroffset == NULL)
    /* Maybe it's in lower case.  */
    afteroffset = strstr (*strp, "(sp)");

  if (afteroffset != NULL)
    {
      if (afteroffset == *strp)
	{
	  /* No offset present. Use 0 by default.  */
	  tempvalue = 0;
	  errmsg = NULL;
	}
      else
	errmsg = cgen_parse_address (cd, strp, opindex,
				     BFD_RELOC_IP2K_FR_OFFSET,
				     & result_type, & tempvalue);

      if (errmsg == NULL)
	{
	  if (tempvalue <= 127)
	    {
	      /* Value is ok.  Fix up the first 2 bits and return.  */
	      *valuep = 0x0180 | tempvalue;
	      *strp += 4; /* Skip over the (SP) in *strp.  */
	      return errmsg;
	    }
	  else
	    {
	      /* Found something there in front of (SP) but it's out
		 of range.  */
	      errmsg = _("(SP) offset out of range.");
	      return errmsg;
	    }
	}
    }

  /* Attempt to parse as an address.  */
  *strp = old_strp;
  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IP2K_FR9,
			       & result_type, & value);
  if (errmsg == NULL)
    {
      *valuep = value;

      /* If a parenthesis is found, warn about invalid form.  */
      if (**strp == '(')
	errmsg = _("illegal use of parentheses");

      /* If a numeric value is specified, ensure that it is between
	 1 and 255.  */
      else if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
	{
	  if (value < 0x1 || value > 0xff)
	    errmsg = _("operand out of range (not between 1 and 255)");
	}
    }
  return errmsg;
}

static const char *
parse_addr16 (CGEN_CPU_DESC cd,
	      const char **strp,
	      int opindex,
	      unsigned long *valuep)
{
  const char *errmsg;
  enum cgen_parse_operand_result result_type;
  bfd_reloc_code_real_type code = BFD_RELOC_NONE;
  bfd_vma value;

  if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16H)
    code = BFD_RELOC_IP2K_HI8DATA;
  else if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16L)
    code = BFD_RELOC_IP2K_LO8DATA;
  else
    {
      /* Something is very wrong. opindex has to be one of the above.  */
      errmsg = _("parse_addr16: invalid opindex.");
      return errmsg;
    }
  
  errmsg = cgen_parse_address (cd, strp, opindex, code,
			       & result_type, & value);
  if (errmsg == NULL)
    {
      /* We either have a relocation or a number now.  */
      if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
	{
	  /* We got a number back.  */
	  if (code == BFD_RELOC_IP2K_HI8DATA)
            value >>= 8;
	  else
	    /* code = BFD_RELOC_IP2K_LOW8DATA.  */
	    value &= 0x00FF;
	}   
      *valuep = value;
    }

  return errmsg;
}

static const char *
parse_addr16_cjp (CGEN_CPU_DESC cd,
		  const char **strp,
		  int opindex,
		  unsigned long *valuep)
{
  const char *errmsg;
  enum cgen_parse_operand_result result_type;
  bfd_reloc_code_real_type code = BFD_RELOC_NONE;
  bfd_vma value;
 
  if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16CJP)
    code = BFD_RELOC_IP2K_ADDR16CJP;
  else if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16P)
    code = BFD_RELOC_IP2K_PAGE3;

  errmsg = cgen_parse_address (cd, strp, opindex, code,
			       & result_type, & value);
  if (errmsg == NULL)
    {
      if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
	{
	  if ((value & 0x1) == 0)  /* If the address is even .... */
	    {
	      if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16CJP)
                *valuep = (value >> 1) & 0x1FFF;  /* Should mask be 1FFF?  */
	      else if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16P)
                *valuep = (value >> 14) & 0x7;
	    }
          else
 	    errmsg = _("Byte address required. - must be even.");
	}
      else if (result_type == CGEN_PARSE_OPERAND_RESULT_QUEUED)
	{
	  /* This will happen for things like (s2-s1) where s2 and s1
	     are labels.  */
	  *valuep = value;
	}
      else 
        errmsg = _("cgen_parse_address returned a symbol. Literal required.");
    }
  return errmsg; 
}

static const char *
parse_lit8 (CGEN_CPU_DESC cd,
	    const char **strp,
	    int opindex,
	    long *valuep)
{
  const char *errmsg;
  enum cgen_parse_operand_result result_type;
  bfd_reloc_code_real_type code = BFD_RELOC_NONE;
  bfd_vma value;

  /* Parse %OP relocating operators.  */
  if (strncmp (*strp, "%bank", 5) == 0)
    {
      *strp += 5;
      code = BFD_RELOC_IP2K_BANK;
    }
  else if (strncmp (*strp, "%lo8data", 8) == 0)
    {
      *strp += 8;
      code = BFD_RELOC_IP2K_LO8DATA;
    }
  else if (strncmp (*strp, "%hi8data", 8) == 0)
    {
      *strp += 8;
      code = BFD_RELOC_IP2K_HI8DATA;
    }
  else if (strncmp (*strp, "%ex8data", 8) == 0)
    {
      *strp += 8;
      code = BFD_RELOC_IP2K_EX8DATA;
    }
  else if (strncmp (*strp, "%lo8insn", 8) == 0)
    {
      *strp += 8;
      code = BFD_RELOC_IP2K_LO8INSN;
    }
  else if (strncmp (*strp, "%hi8insn", 8) == 0)
    {
      *strp += 8;
      code = BFD_RELOC_IP2K_HI8INSN;
    }

  /* Parse %op operand.  */
  if (code != BFD_RELOC_NONE)
    {
      errmsg = cgen_parse_address (cd, strp, opindex, code, 
				   & result_type, & value);
      if ((errmsg == NULL) &&
	  (result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED))
	errmsg = _("percent-operator operand is not a symbol");

      *valuep = value;
    }
  /* Parse as a number.  */
  else
    {
      errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);

      /* Truncate to eight bits to accept both signed and unsigned input.  */
      if (errmsg == NULL)
	*valuep &= 0xFF;
    }

  return errmsg;
}

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

  if (strncmp (*strp, "%bit", 4) == 0)
    {
      *strp += 4;
      mode = 1;
    }
  else if (strncmp (*strp, "%msbbit", 7) == 0)
    {
      *strp += 7;
      mode = 1;
    }
  else if (strncmp (*strp, "%lsbbit", 7) == 0)
    {
      *strp += 7;
      mode = 2;
    }

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

  if (mode)
    {
      value = * valuep;
      if (value == 0)
	{
	  errmsg = _("Attempt to find bit index of 0");
	  return errmsg;
	}
    
      if (mode == 1)
	{
	  count = 31;
	  while ((value & 0x80000000) == 0)
	    {
	      count--;
	      value <<= 1;
	    }
	}
      else if (mode == 2)
	{
	  count = 0;
	  while ((value & 0x00000001) == 0)
	    {
	      count++;
	      value >>= 1;
	    }
	}
    
      *valuep = count;
    }

  return errmsg;
}

/* -- dis.c */

static void
print_fr (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
	  void * dis_info,
	  long value,
	  unsigned int attrs ATTRIBUTE_UNUSED,
	  bfd_vma pc ATTRIBUTE_UNUSED,
	  int length ATTRIBUTE_UNUSED)
{
  disassemble_info *info = (disassemble_info *) dis_info;
  const CGEN_KEYWORD_ENTRY *ke;
  extern CGEN_KEYWORD ip2k_cgen_opval_register_names;
  long offsettest;
  long offsetvalue;

  if (value == 0) /* This is (IP).  */
    {
      (*info->fprintf_func) (info->stream, "%s", "(IP)");
      return;
    }

  offsettest = value >> 7;
  offsetvalue = value & 0x7F;

  /* Check to see if first two bits are 10 -> (DP).  */
  if (offsettest == 2)
    {
      if (offsetvalue == 0)
	(*info->fprintf_func) (info->stream, "%s","(DP)");
      else
	(*info->fprintf_func) (info->stream, "$%lx%s", offsetvalue, "(DP)");
      return;
    }

  /* Check to see if first two bits are 11 -> (SP).  */
  if (offsettest == 3)
    {
      if (offsetvalue == 0)
	(*info->fprintf_func) (info->stream, "%s", "(SP)");
      else
	(*info->fprintf_func) (info->stream, "$%lx%s", offsetvalue,"(SP)");
      return;
    }

  /* Attempt to print as a register keyword.  */
  ke = cgen_keyword_lookup_value (& ip2k_cgen_opval_register_names, value);

  if (ke != NULL)
    (*info->fprintf_func) (info->stream, "%s", ke->name);
  else
    /* Print as an address literal.  */
    (*info->fprintf_func) (info->stream, "$%02lx", value);
}

static void
print_dollarhex (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
		 void * dis_info,
		 long value,
		 unsigned int attrs ATTRIBUTE_UNUSED,
		 bfd_vma pc ATTRIBUTE_UNUSED,
		 int length ATTRIBUTE_UNUSED)
{
  disassemble_info *info = (disassemble_info *) dis_info;

  (*info->fprintf_func) (info->stream, "$%lx", value);
}

static void
print_dollarhex8 (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
		  void * dis_info,
		  long value,
		  unsigned int attrs ATTRIBUTE_UNUSED,
		  bfd_vma pc ATTRIBUTE_UNUSED,
		  int length ATTRIBUTE_UNUSED)
{
  disassemble_info *info = (disassemble_info *) dis_info;

  (*info->fprintf_func) (info->stream, "$%02lx", value);
}

static void
print_dollarhex_addr16h (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
			 void * dis_info,
			 long value,
			 unsigned int attrs ATTRIBUTE_UNUSED,
			 bfd_vma pc ATTRIBUTE_UNUSED,
			 int length ATTRIBUTE_UNUSED)
{
  disassemble_info *info = (disassemble_info *) dis_info;

  /* This is a loadh instruction. Shift the value to the left
     by 8 bits so that disassembled code will reassemble properly.  */
  value = ((value << 8) & 0xFF00);

  (*info->fprintf_func) (info->stream, "$%04lx", value);
}

static void
print_dollarhex_addr16l (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
			 void * dis_info,
			 long value,
			 unsigned int attrs ATTRIBUTE_UNUSED,
			 bfd_vma pc ATTRIBUTE_UNUSED,
			 int length ATTRIBUTE_UNUSED)
{
  disassemble_info *info = (disassemble_info *) dis_info;

  (*info->fprintf_func) (info->stream, "$%04lx", value);
}

static void
print_dollarhex_p (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
		   void * dis_info,
		   long value,
		   unsigned int attrs ATTRIBUTE_UNUSED,
		   bfd_vma pc ATTRIBUTE_UNUSED,
		   int length ATTRIBUTE_UNUSED)
{
  disassemble_info *info = (disassemble_info *) dis_info;

  value = ((value << 14) & 0x1C000);
  ;value = (value  & 0x1FFFF);
  (*info->fprintf_func) (info->stream, "$%05lx", value);
}

static void
print_dollarhex_cj (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
		    void * dis_info,
		    long value,
		    unsigned int attrs ATTRIBUTE_UNUSED,
		    bfd_vma pc ATTRIBUTE_UNUSED,
		    int length ATTRIBUTE_UNUSED)
{
  disassemble_info *info = (disassemble_info *) dis_info;

  value = ((value << 1) & 0x1FFFF);
  (*info->fprintf_func) (info->stream, "$%05lx", value);
}

static void
print_decimal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
	       void * dis_info,
	       long value,
	       unsigned int attrs ATTRIBUTE_UNUSED,
	       bfd_vma pc ATTRIBUTE_UNUSED,
	       int length ATTRIBUTE_UNUSED)
{
  disassemble_info *info = (disassemble_info *) dis_info;

  (*info->fprintf_func) (info->stream, "%ld", value);
}



/* -- */

