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

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


#include <stdio.h>

#include "sysdep.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", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
  "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
  "ctpc", "ctpsw", "dbpc", "dbpsw", "ctbp", "sr21", "sr22", "sr23",
  "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
  "sr16", "sr17", "sr18", "sr19", "sr20", "sr21", "sr22", "sr23",
  "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31" };

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 int
disassemble (bfd_vma memaddr,
	     struct disassemble_info * info,
	     unsigned long insn)
{
  struct v850_opcode * op = (struct v850_opcode *) v850_opcodes;
  const struct v850_operand * operand;
  int match = 0;
  int short_op = ((insn & 0x0600) != 0x0600);
  int bytes_read;
  int target_processor;

  /* Special case: 32 bit MOV.  */
  if ((insn & 0xffe0) == 0x0620)
    short_op = 1;

  bytes_read = short_op ? 2 : 4;

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

  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_V850E1;
      break;
    }

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

	  match = 1;
	  (*info->fprintf_func) (info->stream, "%s\t", op->name);

	  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++)
	    {
	      long value;
	      int flag;
	      int status;
	      bfd_byte buffer[4];

	      operand = &v850_operands[*opindex_ptr];

	      if (operand->extract)
		value = (operand->extract) (insn, 0);
	      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 << (32 - operand->bits))
			     >> (32 - operand->bits));
		}

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

	           if (memop && opnum == memop + 1)
		     info->fprintf_func (info->stream, "[");
		   else if (memop && opnum == memop + 2)
		     info->fprintf_func (info->stream, "],");
		   else if (memop == 1 && opnum == 1
			    && (operand->flags & V850_OPERAND_REG))
		     info->fprintf_func (info->stream, "[");
		   else if (opnum > 1)
		     info->fprintf_func (info->stream, ", ");

	      /* Extract the flags, ignorng ones which
		 do not effect disassembly output. */
	      flag = operand->flags;
	      flag &= ~ V850_OPERAND_SIGNED;
	      flag &= ~ V850_OPERAND_RELAX;
	      flag &= - flag;

	      switch (flag)
		{
		case V850_OPERAND_REG:
		  info->fprintf_func (info->stream, "%s", v850_reg_names[value]);
		  break;
		case V850_OPERAND_SRG:
		  info->fprintf_func (info->stream, "%s", v850_sreg_names[value]);
		  break;
		case V850_OPERAND_CC:
		  info->fprintf_func (info->stream, "%s", v850_cc_names[value]);
		  break;
		case V850_OPERAND_EP:
		  info->fprintf_func (info->stream, "ep");
		  break;
		default:
		  info->fprintf_func (info->stream, "%ld", value);
		  break;
		case V850_OPERAND_DISP:
		  {
		    bfd_vma addr = value + memaddr;

		    /* On the v850 the top 8 bits of an address are used by an
		       overlay manager.  Thus it may happen that when we are
		       looking for a symbol to match against an address with
		       some of its top bits set, the search fails to turn up an
		       exact match.  In this case we try to find an exact match
		       against a symbol in the lower address space, and if we
		       find one, we use that address.   We only do this for
		       JARL instructions however, as we do not want to
		       misinterpret branch instructions.  */
		    if (operand->bits == 22)
		      {
			if ( ! info->symbol_at_address_func (addr, info)
			    && ((addr & 0xFF000000) != 0)
			    && info->symbol_at_address_func (addr & 0x00FFFFFF, info))
			  addr &= 0x00FFFFFF;
		      }
		    info->print_address_func (addr, info);
		    break;
		  }

		case V850E_PUSH_POP:
		  {
		    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 };
		    static int list18_h_regs[32] = { 19, 18, 17, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 30, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
		    static int list18_l_regs[32] = {  3,  2,  1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 14, 15, 13, 12,  7,  6,  5,  4, 11, 10,  9,  8 };
		    int *regs;
		    int i;
		    unsigned long int mask = 0;
		    int pc = 0;
		    int sr = 0;

		    switch (operand->shift)
		      {
		      case 0xffe00001: regs = list12_regs; break;
		      case 0xfff8000f: regs = list18_h_regs; break;
		      case 0xfff8001f:
			regs = list18_l_regs;
			value &= ~0x10;  /* Do not include magic bit.  */
			  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 pop reg: %d\n"), i );
				abort ();
			      case -1: pc = 1; break;
			      case -2: sr = 1; break;
			      }
			  }
		      }

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

		    if (mask || pc || sr)
		      {
			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 ? ", " : "");
			if (sr)
			  info->fprintf_func (info->stream, "%sSR", (mask || pc) ? ", " : "");
		      }

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

		case V850E_IMMEDIATE16:
		  status = info->read_memory_func (memaddr + bytes_read,
						   buffer, 2, info);
		  if (status == 0)
		    {
		      bytes_read += 2;
		      value = bfd_getl16 (buffer);

		      /* If this is a DISPOSE instruction with ff
			 set to 0x10, then shift value up by 16.  */
		      if ((insn & 0x001fffc0) == 0x00130780)
			value <<= 16;

		      info->fprintf_func (info->stream, "0x%lx", value);
		    }
		  else
		    info->memory_error_func (status, memaddr + bytes_read,
					     info);
		  break;

		case V850E_IMMEDIATE32:
		  status = info->read_memory_func (memaddr + bytes_read,
						   buffer, 4, info);
		  if (status == 0)
		    {
		      bytes_read += 4;
		      value = bfd_getl32 (buffer);
		      info->fprintf_func (info->stream, "0x%lx", value);
		    }
		  else
		    info->memory_error_func (status, memaddr + bytes_read,
					     info);
		  break;
		}

	      /* Handle jmp correctly.  */
	      if (memop == 1 && opnum == 1
		  && ((operand->flags & V850_OPERAND_REG) != 0))
		(*info->fprintf_func) (info->stream, "]");
	    }

	  /* Close any square bracket we left open.  */
	  if (memop && opnum == memop + 2)
	    (*info->fprintf_func) (info->stream, "]");

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

  if (!match)
    {
      if (short_op)
	info->fprintf_func (info->stream, ".short\t0x%04lx", insn);
      else
	info->fprintf_func (info->stream, ".long\t0x%08lx", insn);
    }

  return bytes_read;
}

int
print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info)
{
  int status;
  bfd_byte buffer[4];
  unsigned long insn = 0;

  /* First figure out how big the opcode is.  */
  status = info->read_memory_func (memaddr, buffer, 2, info);
  if (status == 0)
    {
      insn = bfd_getl16 (buffer);

      if (   (insn & 0x0600) == 0x0600
	  && (insn & 0xffe0) != 0x0620)
	{
	  /* If this is a 4 byte insn, read 4 bytes of stuff.  */
	  status = info->read_memory_func (memaddr, buffer, 4, info);

	  if (status == 0)
	    insn = bfd_getl32 (buffer);
	}
    }

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

  /* Make sure we tell our caller how many bytes we consumed.  */
  return disassemble (memaddr, info, insn);
}
