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

/* This file is an addendum to fr30.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".  */

/* -- opc.h */

/* ??? This can be improved upon.  */
#undef  CGEN_DIS_HASH_SIZE
#define CGEN_DIS_HASH_SIZE 16
#undef  CGEN_DIS_HASH
#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 4)

/* -- */

/* -- asm.c */
/* Handle register lists for LDMx and STMx.  */

static int
parse_register_number (const char **strp)
{
  int regno;

  if (**strp < '0' || **strp > '9')
    return -1; /* Error.  */
  regno = **strp - '0';
  ++*strp;

  if (**strp >= '0' && **strp <= '9')
    {
      regno = regno * 10 + (**strp - '0');
      ++*strp;
    }

  return regno;
}

static const char *
parse_register_list (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
		     const char **strp,
		     int opindex ATTRIBUTE_UNUSED,
		     unsigned long *valuep,
		     int high_low,   /* 0 == high, 1 == low.  */
		     int load_store) /* 0 == load, 1 == store.  */
{
  *valuep = 0;
  while (**strp && **strp != ')')
    {
      int regno;

      if (**strp != 'R' && **strp != 'r')
	break;
      ++*strp;

      regno = parse_register_number (strp);
      if (regno == -1)
	return _("Register number is not valid");
      if (regno > 7 && !high_low)
	return _("Register must be between r0 and r7");
      if (regno < 8 && high_low)
	return _("Register must be between r8 and r15");

      if (high_low)
	regno -= 8;

      if (load_store) /* Mask is reversed for store.  */
	*valuep |= 0x80 >> regno;
      else
	*valuep |= 1 << regno;

      if (**strp == ',')
	{
	  if (*(*strp + 1) == ')')
	    break;
	  ++*strp;
	}
    }

  if (!*strp || **strp != ')')
    return _("Register list is not valid");

  return NULL;
}

static const char *
parse_low_register_list_ld (CGEN_CPU_DESC cd,
			    const char **strp,
			    int opindex,
			    unsigned long *valuep)
{
  return parse_register_list (cd, strp, opindex, valuep,
			      0 /* Low.  */, 0 /* Load.  */);
}

static const char *
parse_hi_register_list_ld (CGEN_CPU_DESC cd,
			   const char **strp,
			   int opindex,
			   unsigned long *valuep)
{
  return parse_register_list (cd, strp, opindex, valuep,
			      1 /* High.  */, 0 /* Load.  */);
}

static const char *
parse_low_register_list_st (CGEN_CPU_DESC cd,
			    const char **strp,
			    int opindex,
			    unsigned long *valuep)
{
  return parse_register_list (cd, strp, opindex, valuep,
			      0 /* Low.  */, 1 /* Store.  */);
}

static const char *
parse_hi_register_list_st (CGEN_CPU_DESC cd,
			   const char **strp,
			   int opindex,
			   unsigned long *valuep)
{
  return parse_register_list (cd, strp, opindex, valuep,
			      1 /* High.  */, 1 /* Store.  */);
}

/* -- */

/* -- dis.c */
static void
print_register_list (void * dis_info,
		     long value,
		     long offset,
		     int load_store) /* 0 == load, 1 == store.  */
{
  disassemble_info *info = dis_info;
  int mask;
  int reg_index = 0;
  char * comma = "";

  if (load_store)
    mask = 0x80;
  else
    mask = 1;

  if (value & mask)
    {
      (*info->fprintf_func) (info->stream, "r%li", reg_index + offset);
      comma = ",";
    }
    
  for (reg_index = 1; reg_index <= 7; ++reg_index)
    {
      if (load_store)
	mask >>= 1;
      else
	mask <<= 1;

      if (value & mask)
	{
	  (*info->fprintf_func) (info->stream, "%sr%li", comma, reg_index + offset);
	  comma = ",";
	}
    }
}

static void
print_hi_register_list_ld (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)
{
  print_register_list (dis_info, value, 8, 0 /* Load.  */);
}

static void
print_low_register_list_ld (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)
{
  print_register_list (dis_info, value, 0, 0 /* Load.  */);
}

static void
print_hi_register_list_st (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)
{
  print_register_list (dis_info, value, 8, 1 /* Store.  */);
}

static void
print_low_register_list_st (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)
{
  print_register_list (dis_info, value, 0, 1 /* Store.  */);
}

static void
print_m4 (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);
}
/* -- */
