/* Disassemble V850 instructions.
   Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007, 2010,
   2012  Free Software Foundation, Inc.

   This file is part of the GNU opcodes library.

   This library 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.

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


#include "sysdep.h"
#include <stdio.h>
#include "opcode/v850.h"
#include "dis-asm.h"
#include "opintl.h"

static const char *const v850_reg_names[] =
{
  "r0", "r1", "r2", "sp", "gp", "r5", "r6", "r7",
  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
  "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp"
};

static const char *const v850_sreg_names[] =
{
  "eipc/vip/mpm", "eipsw/mpc", "fepc/tid", "fepsw/ppa", "ecr/vmecr", "psw/vmtid",
  "sr6/fpsr/vmadr/dcc", "sr7/fpepc/dc0",
  "sr8/fpst/vpecr/dcv1", "sr9/fpcc/vptid", "sr10/fpcfg/vpadr/spal", "sr11/spau",
  "sr12/vdecr/ipa0l", "eiic/vdtid/ipa0u", "feic/ipa1l", "dbic/ipa1u",
  "ctpc/ipa2l", "ctpsw/ipa2u", "dbpc/ipa3l", "dbpsw/ipa3u", "ctbp/dpa0l",
  "dir/dpa0u", "bpc/dpa0u", "asid/dpa1l",
  "bpav/dpa1u", "bpam/dpa2l", "bpdv/dpa2u", "bpdm/dpa3l", "eiwr/dpa3u",
  "fewr", "dbwr", "bsel"
};

static const char *const v850_cc_names[] =
{
  "v", "c/l", "z", "nh", "s/n", "t", "lt", "le",
  "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt"
};

static const char *const v850_float_cc_names[] =
{
  "f/t", "un/or", "eq/neq", "ueq/ogl", "olt/uge", "ult/oge", "ole/ugt", "ule/ogt",
  "sf/st", "ngle/gle", "seq/sne", "ngl/gl", "lt/nlt", "nge/ge", "le/nle", "ngt/gt"
};


static void
print_value (int flags, bfd_vma memaddr, struct disassemble_info *info, long value)
{
  if (flags & V850_PCREL)
    {
      bfd_vma addr = value + memaddr;
      info->print_address_func (addr, info);
    }
  else if (flags & V850_OPERAND_DISP)
    {
      if (flags & V850_OPERAND_SIGNED)
        {
          info->fprintf_func (info->stream, "%ld", value);
        }
      else
        {
          info->fprintf_func (info->stream, "%lu", value);
        }
    }
  else if (flags & V850E_IMMEDIATE32)
    {
      info->fprintf_func (info->stream, "0x%lx", value);
    }
  else
    {
      if (flags & V850_OPERAND_SIGNED)
	{
	  info->fprintf_func (info->stream, "%ld", value);
	}
      else
	{
	  info->fprintf_func (info->stream, "%lu", value);
	}
    }
}

static long
get_operand_value (const struct v850_operand *operand,
		   unsigned long insn,
		   int bytes_read,
		   bfd_vma memaddr,
		   struct disassemble_info * info,
		   bfd_boolean noerror,
		   int *invalid)
{
  long value;
  bfd_byte buffer[4];

  if ((operand->flags & V850E_IMMEDIATE16)
      || (operand->flags & V850E_IMMEDIATE16HI))
    {
      int status = info->read_memory_func (memaddr + bytes_read, buffer, 2, info);

      if (status == 0)
	{
	  value = bfd_getl16 (buffer);

	  if (operand->flags & V850E_IMMEDIATE16HI)
	    value <<= 16;

	  return value;
	}

      if (!noerror)
	info->memory_error_func (status, memaddr + bytes_read, info);

      return 0;
    }

  if (operand->flags & V850E_IMMEDIATE23)
    {
      int status = info->read_memory_func (memaddr + 2, buffer, 4, info);

      if (status == 0)
	{
	  value = bfd_getl32 (buffer);

	  value = (operand->extract) (value, invalid);

	  return value;
	}

      if (!noerror)
	info->memory_error_func (status, memaddr + bytes_read, info);

      return 0;
    }

  if (operand->flags & V850E_IMMEDIATE32)
    {
      int status = info->read_memory_func (memaddr + bytes_read, buffer, 4, info);

      if (status == 0)
	{
	  bytes_read += 4;
	  value = bfd_getl32 (buffer);

	  return value;
	}

      if (!noerror)
	info->memory_error_func (status, memaddr + bytes_read, info);

      return 0;
    }

  if (operand->extract)
    value = (operand->extract) (insn, invalid);
  else
    {
      if (operand->bits == -1)
	value = (insn & operand->shift);
      else
	value = (insn >> operand->shift) & ((1 << operand->bits) - 1);

      if (operand->flags & V850_OPERAND_SIGNED)
	value = ((long)(value << (sizeof (long)*8 - operand->bits))
		 >> (sizeof (long)*8 - operand->bits));
    }

  return value;
}


static int
disassemble (bfd_vma memaddr, struct disassemble_info *info, int bytes_read, unsigned long insn)
{
  struct v850_opcode *op = (struct v850_opcode *)v850_opcodes;
  const struct v850_operand *operand;
  int match = 0;
  int target_processor;

  switch (info->mach)
    {
    case 0:
    default:
      target_processor = PROCESSOR_V850;
      break;

    case bfd_mach_v850e:
      target_processor = PROCESSOR_V850E;
      break;

    case bfd_mach_v850e1:
      target_processor = PROCESSOR_V850E;
      break;

    case bfd_mach_v850e2:
      target_processor = PROCESSOR_V850E2;
      break;

    case bfd_mach_v850e2v3:
      target_processor = PROCESSOR_V850E2V3;
      break;
    }

  /* If this is a two byte insn, then mask off the high bits.  */
  if (bytes_read == 2)
    insn &= 0xffff;

  /* Find the opcode.  */
  while (op->name)
    {
      if ((op->mask & insn) == op->opcode
	  && (op->processors & target_processor)
	  && !(op->processors & PROCESSOR_OPTION_ALIAS))
	{
	  /* Code check start.  */
	  const unsigned char *opindex_ptr;
	  unsigned int opnum;
	  unsigned int memop;

	  for (opindex_ptr = op->operands, opnum = 1;
	       *opindex_ptr != 0;
	       opindex_ptr++, opnum++)
	    {
	      int invalid = 0;
	      long value;

	      operand = &v850_operands[*opindex_ptr];

	      value = get_operand_value (operand, insn, bytes_read, memaddr, info, 1, &invalid);

	      if (invalid)
		goto next_opcode;

              if ((operand->flags & V850_NOT_R0) && value == 0 && (op->memop) <=2)
		goto next_opcode;

	      if ((operand->flags & V850_NOT_SA) && value == 0xd)
		goto next_opcode;

	      if ((operand->flags & V850_NOT_IMM0) && value == 0)
		goto next_opcode;
	    }

	  /* Code check end.  */

	  match = 1;
	  (*info->fprintf_func) (info->stream, "%s\t", op->name);
#if 0
	  fprintf (stderr, "match: insn: %lx, mask: %lx, opcode: %lx, name: %s\n",
		   insn, op->mask, op->opcode, op->name );
#endif

	  memop = op->memop;
	  /* Now print the operands.

	     MEMOP is the operand number at which a memory
	     address specification starts, or zero if this
	     instruction has no memory addresses.

	     A memory address is always two arguments.

	     This information allows us to determine when to
	     insert commas into the output stream as well as
	     when to insert disp[reg] expressions onto the
	     output stream.  */

	  for (opindex_ptr = op->operands, opnum = 1;
	       *opindex_ptr != 0;
	       opindex_ptr++, opnum++)
	    {
	      bfd_boolean square = FALSE;
	      long value;
	      int flag;
	      char *prefix;

	      operand = &v850_operands[*opindex_ptr];

	      value = get_operand_value (operand, insn, bytes_read, memaddr, info, 0, 0);

	      /* The first operand is always output without any
		 special handling.

		 For the following arguments:

		   If memop && opnum == memop + 1, then we need '[' since
		   we're about to output the register used in a memory
		   reference.

		   If memop && opnum == memop + 2, then we need ']' since
		   we just finished the register in a memory reference.  We
		   also need a ',' before this operand.

		   Else we just need a comma.

		   We may need to output a trailing ']' if the last operand
		   in an instruction is the register for a memory address.

		   The exception (and there's always an exception) is the
		   "jmp" insn which needs square brackets around it's only
		   register argument.  */
	      prefix = "";
	      if (operand->flags & V850_OPERAND_BANG)
		{
		  prefix = "!";
		}
	      else if (operand->flags & V850_OPERAND_PERCENT)
		{
		  prefix = "%";
		}

	      if (opnum == 1 && opnum == memop)
		{
		  info->fprintf_func (info->stream, "%s[", prefix);
		  square = TRUE;
		}
	      else if (opnum > 1
		       && (v850_operands[*(opindex_ptr - 1)].flags & V850_OPERAND_DISP) != 0
		       && opnum == memop)
		{
		  info->fprintf_func (info->stream, "%s[", prefix);
		  square = TRUE;
		}
	      else if (opnum > 1)
		info->fprintf_func (info->stream, ", %s", prefix);

 	      /* Extract the flags, ignoring ones which do not effect disassembly output.  */
	      flag = operand->flags & (V850_OPERAND_REG
				       | V850_REG_EVEN
				       | V850_OPERAND_EP
				       | V850_OPERAND_SRG
				       | V850E_OPERAND_REG_LIST
				       | V850_OPERAND_CC
				       | V850_OPERAND_FLOAT_CC);

	      switch (flag)
		{
		case V850_OPERAND_REG:  info->fprintf_func (info->stream, "%s", v850_reg_names[value]); break;
		case (V850_OPERAND_REG|V850_REG_EVEN):  info->fprintf_func (info->stream, "%s", v850_reg_names[value*2]); break;
		case V850_OPERAND_EP:   info->fprintf_func (info->stream, "ep"); break;
		case V850_OPERAND_SRG:  info->fprintf_func (info->stream, "%s", v850_sreg_names[value]); break;

		case V850E_OPERAND_REG_LIST:
		  {
		    static int list12_regs[32]   = { 30, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
						     0,  0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
		    int *regs;
		    int i;
		    unsigned long int mask = 0;
		    int pc = 0;


		    switch (operand->shift)
		      {
		      case 0xffe00001: regs = list12_regs; break;
		      default:
			/* xgettext:c-format */
			fprintf (stderr, _("unknown operand shift: %x\n"), operand->shift );
			abort ();
		      }

		    for (i = 0; i < 32; i++)
		      {
			if (value & (1 << i))
			  {
			    switch (regs[ i ])
			      {
			      default: mask |= (1 << regs[ i ]); break;
				/* xgettext:c-format */
			      case 0:  fprintf (stderr, _("unknown reg: %d\n"), i ); abort ();
			      case -1: pc = 1; break;
			      }
			  }
		      }

		    info->fprintf_func (info->stream, "{");

		    if (mask || pc)
		      {
			if (mask)
			  {
			    unsigned int bit;
			    int shown_one = 0;

			    for (bit = 0; bit < 32; bit++)
			      if (mask & (1 << bit))
				{
				  unsigned long int first = bit;
				  unsigned long int last;

				  if (shown_one)
				    info->fprintf_func (info->stream, ", ");
				  else
				    shown_one = 1;

				  info->fprintf_func (info->stream, v850_reg_names[first]);

				  for (bit++; bit < 32; bit++)
				    if ((mask & (1 << bit)) == 0)
				      break;

				  last = bit;

				  if (last > first + 1)
				    {
				      info->fprintf_func (info->stream, " - %s", v850_reg_names[ last - 1 ]);
				    }
				}
			  }

			if (pc)
			  info->fprintf_func (info->stream, "%sPC", mask ? ", " : "");
		      }

		    info->fprintf_func (info->stream, "}");
		  }
		  break;

		case V850_OPERAND_CC:   info->fprintf_func (info->stream, "%s", v850_cc_names[value]); break;
		case V850_OPERAND_FLOAT_CC:   info->fprintf_func (info->stream, "%s", v850_float_cc_names[value]); break;

		default:
		  print_value (operand->flags, memaddr, info, value);
		  break;
		}

	      if (square)
		(*info->fprintf_func) (info->stream, "]");
	    }

	  /* All done. */
	  break;
	}
    next_opcode:
      op++;
    }

  return match;
}

int
print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info)
{
  int status, status2, match;
  bfd_byte buffer[8];
  int length = 0, code_length = 0;
  unsigned long insn = 0, insn2 = 0;
  int target_processor;

  switch (info->mach)
    {
    case 0:
    default:
      target_processor = PROCESSOR_V850;
      break;

    case bfd_mach_v850e:
      target_processor = PROCESSOR_V850E;
      break;

    case bfd_mach_v850e1:
      target_processor = PROCESSOR_V850E;
      break;

    case bfd_mach_v850e2:
      target_processor = PROCESSOR_V850E2;
      break;

    case bfd_mach_v850e2v3:
      target_processor = PROCESSOR_V850E2V3;
      break;
    }

  status = info->read_memory_func (memaddr, buffer, 2, info);

  if (status)
    {
      info->memory_error_func (status, memaddr, info);
      return -1;
    }

  insn = bfd_getl16 (buffer);

  status2 = info->read_memory_func (memaddr+2, buffer, 2 , info);

  if (!status2)
    {
      insn2 = bfd_getl16 (buffer);
      /* fprintf (stderr, "insn2 0x%08lx\n", insn2); */
    }

  /* Special case.  */
  if (length == 0
      && (target_processor == PROCESSOR_V850E2
	  || target_processor == PROCESSOR_V850E2V3))
    {
      if ((insn & 0xffff) == 0x02e0		/* jr 32bit */
	  && !status2 && (insn2 & 0x1) == 0)
	{
	  length = 2;
	  code_length = 6;
	}
      else if ((insn & 0xffe0) == 0x02e0	/* jarl 32bit */
	       && !status2 && (insn2 & 0x1) == 0)
	{
	  length = 2;
	  code_length = 6;
	}
      else if ((insn & 0xffe0) == 0x06e0	/* jmp 32bit */
	       && !status2 && (insn2 & 0x1) == 0)
	{
	  length = 2;
	  code_length = 6;
	}
    }

  if (length == 0
      && target_processor == PROCESSOR_V850E2V3)
    {
      if (((insn & 0xffe0) == 0x0780		/* ld.b 23bit */
	   && !status2 && (insn2 & 0x000f) == 0x0005)
	  || ((insn & 0xffe0) == 0x07a0		/* ld.bu 23bit */
	      && !status2 && (insn2 & 0x000f) == 0x0005)
	  || ((insn & 0xffe0) == 0x0780		/* ld.h 23bit */
	      && !status2 && (insn2 & 0x000f) == 0x0007)
	  || ((insn & 0xffe0) == 0x07a0		/* ld.hu 23bit */
	      && !status2 && (insn2 & 0x000f) == 0x0007)
	  || ((insn & 0xffe0) == 0x0780		/* ld.w 23bit */
	      && !status2 && (insn2 & 0x000f) == 0x0009))
	{
	  length = 4;
	  code_length = 6;
	}
      else if (((insn & 0xffe0) == 0x0780	/* st.b 23bit */
	       && !status2 && (insn2 & 0x000f) == 0x000d)
	      || ((insn & 0xffe0) == 0x07a0	/* st.h 23bit */
		  && !status2 && (insn2 & 0x000f) == 0x000d)
	      || ((insn & 0xffe0) == 0x0780	/* st.w 23bit */
		  && !status2 && (insn2 & 0x000f) == 0x000f))
	{
	  length = 4;
	  code_length = 6;
	}
    }

  if (length == 0
      && target_processor != PROCESSOR_V850)
    {
      if ((insn & 0xffe0) == 0x0620)		/* 32 bit MOV */
	{
	  length = 2;
	  code_length = 6;
	}
      else if ((insn & 0xffc0) == 0x0780	/* prepare {list}, imm5, imm16<<16 */
	       && !status2 && (insn2 & 0x001f) == 0x0013)
	{
	  length = 4;
	  code_length = 6;
	}
      else if ((insn & 0xffc0) == 0x0780	/* prepare {list}, imm5, imm16 */
	       && !status2 && (insn2 & 0x001f) == 0x000b)
	{
	  length = 4;
	  code_length = 6;
	}
      else if ((insn & 0xffc0) == 0x0780	/* prepare {list}, imm5, imm32 */
	       && !status2 && (insn2 & 0x001f) == 0x001b)
	{
	  length = 4;
	  code_length = 8;
	}
    }

  if (length == 4
      || (length == 0
	  && (insn & 0x0600) == 0x0600))
    {
      /* This is a 4 byte insn.  */
      status = info->read_memory_func (memaddr, buffer, 4, info);
      if (!status)
	{
	  insn = bfd_getl32 (buffer);

	  if (!length)
	    length = code_length = 4;
	}
    }

  if (code_length > length)
    {
      status = info->read_memory_func (memaddr + length, buffer, code_length - length, info);
      if (status)
	length = 0;
    }

  if (length == 0 && !status)
    length = code_length = 2;

  if (length == 2)
    insn &= 0xffff;

  match = disassemble (memaddr, info, length, insn);

  if (!match)
    {
      int l = 0;

      status = info->read_memory_func (memaddr, buffer, code_length, info);

      while (l < code_length)
	{
	  if (code_length - l == 2)
	    {
	      insn = bfd_getl16 (buffer + l) & 0xffff;
	      info->fprintf_func (info->stream, ".short\t0x%04lx", insn);
	      l += 2;
	    }
	  else
	    {
	      insn = bfd_getl32 (buffer + l);
	      info->fprintf_func (info->stream, ".long\t0x%08lx", insn);
	      l += 4;
	    }
	}
    }

  return code_length;
}
