/* Disassemble MN10300 instructions.
   Copyright (C) 1996-2019 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/mn10300.h"
#include "disassemble.h"
#include "opintl.h"

#define HAVE_AM33_2 (info->mach == AM33_2)
#define HAVE_AM33   (info->mach == AM33 || HAVE_AM33_2)
#define HAVE_AM30   (info->mach == AM30)

static void
disassemble (bfd_vma memaddr,
	     struct disassemble_info *info,
	     unsigned long insn,
	     unsigned int size)
{
  struct mn10300_opcode *op = (struct mn10300_opcode *) mn10300_opcodes;
  const struct mn10300_operand *operand;
  bfd_byte buffer[4];
  unsigned long extension = 0;
  int status, match = 0;

  /* Find the opcode.  */
  while (op->name)
    {
      int mysize, extra_shift;

      if (op->format == FMT_S0)
	mysize = 1;
      else if (op->format == FMT_S1
	       || op->format == FMT_D0)
	mysize = 2;
      else if (op->format == FMT_S2
	       || op->format == FMT_D1)
	mysize = 3;
      else if (op->format == FMT_S4)
	mysize = 5;
      else if (op->format == FMT_D2)
	mysize = 4;
      else if (op->format == FMT_D3)
	mysize = 5;
      else if (op->format == FMT_D4)
	mysize = 6;
      else if (op->format == FMT_D6)
	mysize = 3;
      else if (op->format == FMT_D7 || op->format == FMT_D10)
	mysize = 4;
      else if (op->format == FMT_D8)
	mysize = 6;
      else if (op->format == FMT_D9)
	mysize = 7;
      else
	mysize = 7;

      if ((op->mask & insn) == op->opcode
	  && size == (unsigned int) mysize
	  && (op->machine == 0
	      || (op->machine == AM33_2 && HAVE_AM33_2)
	      || (op->machine == AM33 && HAVE_AM33)
	      || (op->machine == AM30 && HAVE_AM30)))
	{
	  const unsigned char *opindex_ptr;
	  unsigned int nocomma;
	  int paren = 0;

	  if (op->format == FMT_D1 || op->format == FMT_S1)
	    extra_shift = 8;
	  else if (op->format == FMT_D2 || op->format == FMT_D4
		   || op->format == FMT_S2 || op->format == FMT_S4
		   || op->format == FMT_S6 || op->format == FMT_D5)
	    extra_shift = 16;
	  else if (op->format == FMT_D7
		   || op->format == FMT_D8
		   || op->format == FMT_D9)
	    extra_shift = 8;
	  else
	    extra_shift = 0;

	  if (size == 1 || size == 2)
	    extension = 0;

	  else if (size == 3
		   && (op->format == FMT_D1
		       || op->opcode == 0xdf0000
		       || op->opcode == 0xde0000))
	    extension = 0;

	  else if (size == 3
		   && op->format == FMT_D6)
	    extension = 0;

	  else if (size == 3)
	    {
	      insn &= 0xff0000;
	      status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
	      if (status != 0)
		{
		  (*info->memory_error_func) (status, memaddr, info);
		  return;
		}

	      insn |= bfd_getl16 (buffer);
	      extension = 0;
	    }
	  else if (size == 4
		   && (op->opcode == 0xfaf80000
		       || op->opcode == 0xfaf00000
		       || op->opcode == 0xfaf40000))
	    extension = 0;

	  else if (size == 4
		   && (op->format == FMT_D7
		       || op->format == FMT_D10))
	    extension = 0;

	  else if (size == 4)
	    {
	      insn &= 0xffff0000;
	      status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
	      if (status != 0)
		{
		  (*info->memory_error_func) (status, memaddr, info);
		  return;
		}

	      insn |= bfd_getl16 (buffer);
	      extension = 0;
	    }
	  else if (size == 5 && op->opcode == 0xdc000000)
	    {
	      unsigned long temp = 0;

	      status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
	      if (status != 0)
		{
		  (*info->memory_error_func) (status, memaddr, info);
		  return;
		}
	      temp |= bfd_getl32 (buffer);

	      insn &= 0xff000000;
	      insn |= (temp & 0xffffff00) >> 8;
	      extension = temp & 0xff;
	    }
	  else if (size == 5 && op->format == FMT_D3)
	    {
	      status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
	      if (status != 0)
		{
		  (*info->memory_error_func) (status, memaddr, info);
		  return;
		}
	      insn &= 0xffff0000;
	      insn |= bfd_getl16 (buffer);

	      status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
	      if (status != 0)
		{
		  (*info->memory_error_func) (status, memaddr, info);
		  return;
		}
	      extension = *(unsigned char *) buffer;
	    }
	  else if (size == 5)
	    {
	      unsigned long temp = 0;

	      status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
	      if (status != 0)
		{
		  (*info->memory_error_func) (status, memaddr, info);
		  return;
		}
	      temp |= bfd_getl16 (buffer);

	      insn &= 0xff0000ff;
	      insn |= temp << 8;

	      status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
	      if (status != 0)
		{
		  (*info->memory_error_func) (status, memaddr, info);
		  return;
		}
	      extension = *(unsigned char *) buffer;
	    }
	  else if (size == 6 && op->format == FMT_D8)
	    {
	      insn &= 0xffffff00;
	      status = (*info->read_memory_func) (memaddr + 5, buffer, 1, info);
	      if (status != 0)
		{
		  (*info->memory_error_func) (status, memaddr, info);
		  return;
		}
	      insn |= *(unsigned char *) buffer;

	      status = (*info->read_memory_func) (memaddr + 3, buffer, 2, info);
	      if (status != 0)
		{
		  (*info->memory_error_func) (status, memaddr, info);
		  return;
		}
	      extension = bfd_getl16 (buffer);
	    }
	  else if (size == 6)
	    {
	      unsigned long temp = 0;

	      status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
	      if (status != 0)
		{
		  (*info->memory_error_func) (status, memaddr, info);
		  return;
		}
	      temp |= bfd_getl32 (buffer);

	      insn &= 0xffff0000;
	      insn |= (temp >> 16) & 0xffff;
	      extension = temp & 0xffff;
	    }
	  else if (size == 7 && op->format == FMT_D9)
	    {
	      insn &= 0xffffff00;
	      status = (*info->read_memory_func) (memaddr + 3, buffer, 4, info);
	      if (status != 0)
		{
		  (*info->memory_error_func) (status, memaddr, info);
		  return;
		}
	      extension = bfd_getl32 (buffer);
	      insn |= (extension & 0xff000000) >> 24;
	      extension &= 0xffffff;
	    }
	  else if (size == 7 && op->opcode == 0xdd000000)
	    {
	      unsigned long temp = 0;

	      status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
	      if (status != 0)
		{
		  (*info->memory_error_func) (status, memaddr, info);
		  return;
		}
	      temp |= bfd_getl32 (buffer);

	      insn &= 0xff000000;
	      insn |= (temp >> 8) & 0xffffff;
	      extension = (temp & 0xff) << 16;

	      status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info);
	      if (status != 0)
		{
		  (*info->memory_error_func) (status, memaddr, info);
		  return;
		}
	      extension |= bfd_getb16 (buffer);
	    }
	  else if (size == 7)
	    {
	      unsigned long temp = 0;

	      status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
	      if (status != 0)
		{
		  (*info->memory_error_func) (status, memaddr, info);
		  return;
		}
	      temp |= bfd_getl32 (buffer);

	      insn &= 0xffff0000;
	      insn |= (temp >> 16) & 0xffff;
	      extension = (temp & 0xffff) << 8;

	      status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info);
	      if (status != 0)
		{
		  (*info->memory_error_func) (status, memaddr, info);
		  return;
		}
	      extension |= *(unsigned char *) buffer;
	    }

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

	  /* Now print the operands.  */
	  for (opindex_ptr = op->operands, nocomma = 1;
	       *opindex_ptr != 0;
	       opindex_ptr++)
	    {
	      unsigned long value;

	      operand = &mn10300_operands[*opindex_ptr];

	      /* If this operand is a PLUS (autoincrement), then do not emit
		 a comma before emitting the plus.  */
	      if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
		nocomma = 1;

	      if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
		{
		  unsigned long temp;

		  value = insn & ((1 << operand->bits) - 1);
		  value <<= (32 - operand->bits);
		  temp = extension >> operand->shift;
		  temp &= ((1 << (32 - operand->bits)) - 1);
		  value |= temp;
		  value = ((value ^ (((unsigned long) 1) << 31))
			   - (((unsigned long) 1) << 31));
		}
	      else if ((operand->flags & MN10300_OPERAND_24BIT) != 0)
		{
		  unsigned long temp;

		  value = insn & ((1 << operand->bits) - 1);
		  value <<= (24 - operand->bits);
		  temp = extension >> operand->shift;
		  temp &= ((1 << (24 - operand->bits)) - 1);
		  value |= temp;
		  if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
		    value = ((value & 0xffffff) ^ 0x800000) - 0x800000;
		}
	      else if ((operand->flags & (MN10300_OPERAND_FSREG
					  | MN10300_OPERAND_FDREG)))
		{
		  /* See m10300-opc.c just before #define FSM0 for an
		     explanation of these variables.  Note that
		     FMT-implied shifts are not taken into account for
		     FP registers.  */
		  unsigned long mask_low, mask_high;
		  int shl_low, shr_high, shl_high;

		  switch (operand->bits)
		    {
		    case 5:
		      /* Handle regular FP registers.  */
		      if (operand->shift >= 0)
			{
			  /* This is an `m' register.  */
			  shl_low = operand->shift;
			  shl_high = 8 + (8 & shl_low) + (shl_low & 4) / 4;
			}
		      else
			{
			  /* This is an `n' register.  */
			  shl_low = -operand->shift;
			  shl_high = shl_low / 4;
			}
		      mask_low = 0x0f;
		      mask_high = 0x10;
		      shr_high = 4;
		      break;

		    case 3:
		      /* Handle accumulators.  */
		      shl_low = -operand->shift;
		      shl_high = 0;
		      mask_low = 0x03;
		      mask_high = 0x04;
		      shr_high = 2;
		      break;

		    default:
		      abort ();
		    }
		  value = ((((insn >> shl_high) << shr_high) & mask_high)
			   | ((insn >> shl_low) & mask_low));
		}
	      else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
		value = ((extension >> (operand->shift))
			 & ((1 << operand->bits) - 1));

	      else
		value = ((insn >> (operand->shift))
			 & ((1 << operand->bits) - 1));

	      if ((operand->flags & MN10300_OPERAND_SIGNED) != 0
		  /* These are properly extended by the code above.  */
		  && ((operand->flags & MN10300_OPERAND_24BIT) == 0))
		value = ((value ^ (((unsigned long) 1) << (operand->bits - 1)))
			 - (((unsigned long) 1) << (operand->bits - 1)));

	      if (!nocomma
		  && (!paren
		      || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
		(*info->fprintf_func) (info->stream, ",");

	      nocomma = 0;

	      if ((operand->flags & MN10300_OPERAND_DREG) != 0)
		{
		  value = ((insn >> (operand->shift + extra_shift))
			   & ((1 << operand->bits) - 1));
		  (*info->fprintf_func) (info->stream, "d%d", (int) value);
		}

	      else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
		{
		  value = ((insn >> (operand->shift + extra_shift))
			   & ((1 << operand->bits) - 1));
		  (*info->fprintf_func) (info->stream, "a%d", (int) value);
		}

	      else if ((operand->flags & MN10300_OPERAND_SP) != 0)
		(*info->fprintf_func) (info->stream, "sp");

	      else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
		(*info->fprintf_func) (info->stream, "psw");

	      else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
		(*info->fprintf_func) (info->stream, "mdr");

	      else if ((operand->flags & MN10300_OPERAND_RREG) != 0)
		{
		  value = ((insn >> (operand->shift + extra_shift))
			   & ((1 << operand->bits) - 1));
		  if (value < 8)
		    (*info->fprintf_func) (info->stream, "r%d", (int) value);
		  else if (value < 12)
		    (*info->fprintf_func) (info->stream, "a%d", (int) value - 8);
		  else
		    (*info->fprintf_func) (info->stream, "d%d", (int) value - 12);
		}

	      else if ((operand->flags & MN10300_OPERAND_XRREG) != 0)
		{
		  value = ((insn >> (operand->shift + extra_shift))
			   & ((1 << operand->bits) - 1));
		  if (value == 0)
		    (*info->fprintf_func) (info->stream, "sp");
		  else
		    (*info->fprintf_func) (info->stream, "xr%d", (int) value);
		}

	      else if ((operand->flags & MN10300_OPERAND_FSREG) != 0)
		(*info->fprintf_func) (info->stream, "fs%d", (int) value);

	      else if ((operand->flags & MN10300_OPERAND_FDREG) != 0)
		(*info->fprintf_func) (info->stream, "fd%d", (int) value);

	      else if ((operand->flags & MN10300_OPERAND_FPCR) != 0)
		(*info->fprintf_func) (info->stream, "fpcr");

	      else if ((operand->flags & MN10300_OPERAND_USP) != 0)
		(*info->fprintf_func) (info->stream, "usp");

	      else if ((operand->flags & MN10300_OPERAND_SSP) != 0)
		(*info->fprintf_func) (info->stream, "ssp");

	      else if ((operand->flags & MN10300_OPERAND_MSP) != 0)
		(*info->fprintf_func) (info->stream, "msp");

	      else if ((operand->flags & MN10300_OPERAND_PC) != 0)
		(*info->fprintf_func) (info->stream, "pc");

	      else if ((operand->flags & MN10300_OPERAND_EPSW) != 0)
		(*info->fprintf_func) (info->stream, "epsw");

	      else if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
		(*info->fprintf_func) (info->stream, "+");

	      else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
		{
		  if (paren)
		    (*info->fprintf_func) (info->stream, ")");
		  else
		    {
		      (*info->fprintf_func) (info->stream, "(");
		      nocomma = 1;
		    }
		  paren = !paren;
		}

	      else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
		(*info->print_address_func) ((long) value + memaddr, info);

	      else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
		(*info->print_address_func) (value, info);

	      else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
		{
		  int comma = 0;

		  (*info->fprintf_func) (info->stream, "[");
		  if (value & 0x80)
		    {
		      (*info->fprintf_func) (info->stream, "d2");
		      comma = 1;
		    }

		  if (value & 0x40)
		    {
		      if (comma)
			(*info->fprintf_func) (info->stream, ",");
		      (*info->fprintf_func) (info->stream, "d3");
		      comma = 1;
		    }

		  if (value & 0x20)
		    {
		      if (comma)
			(*info->fprintf_func) (info->stream, ",");
		      (*info->fprintf_func) (info->stream, "a2");
		      comma = 1;
		    }

		  if (value & 0x10)
		    {
		      if (comma)
			(*info->fprintf_func) (info->stream, ",");
		      (*info->fprintf_func) (info->stream, "a3");
		      comma = 1;
		    }

		  if (value & 0x08)
		    {
		      if (comma)
			(*info->fprintf_func) (info->stream, ",");
		      (*info->fprintf_func) (info->stream, "other");
		      comma = 1;
		    }

		  if (value & 0x04)
		    {
		      if (comma)
			(*info->fprintf_func) (info->stream, ",");
		      (*info->fprintf_func) (info->stream, "exreg0");
		      comma = 1;
		    }
		  if (value & 0x02)
		    {
		      if (comma)
			(*info->fprintf_func) (info->stream, ",");
		      (*info->fprintf_func) (info->stream, "exreg1");
		      comma = 1;
		    }
		  if (value & 0x01)
		    {
		      if (comma)
			(*info->fprintf_func) (info->stream, ",");
		      (*info->fprintf_func) (info->stream, "exother");
		      comma = 1;
		    }
		  (*info->fprintf_func) (info->stream, "]");
		}

	      else
		(*info->fprintf_func) (info->stream, "%ld", (long) value);
	    }
	  /* All done. */
	  break;
	}
      op++;
    }

  if (!match)
    /* xgettext:c-format */
    (*info->fprintf_func) (info->stream, _("unknown\t0x%04lx"), insn);
}

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

  /* First figure out how big the opcode is.  */
  status = (*info->read_memory_func) (memaddr, buffer, 1, info);
  if (status != 0)
    {
      (*info->memory_error_func) (status, memaddr, info);
      return -1;
    }
  insn = *(unsigned char *) buffer;

  /* These are one byte insns.  */
  if ((insn & 0xf3) == 0x00
      || (insn & 0xf0) == 0x10
      || (insn & 0xfc) == 0x3c
      || (insn & 0xf3) == 0x41
      || (insn & 0xf3) == 0x40
      || (insn & 0xfc) == 0x50
      || (insn & 0xfc) == 0x54
      || (insn & 0xf0) == 0x60
      || (insn & 0xf0) == 0x70
      || ((insn & 0xf0) == 0x80
	  && (insn & 0x0c) >> 2 != (insn & 0x03))
      || ((insn & 0xf0) == 0x90
	  && (insn & 0x0c) >> 2 != (insn & 0x03))
      || ((insn & 0xf0) == 0xa0
	  && (insn & 0x0c) >> 2 != (insn & 0x03))
      || ((insn & 0xf0) == 0xb0
	  && (insn & 0x0c) >> 2 != (insn & 0x03))
      || (insn & 0xff) == 0xcb
      || (insn & 0xfc) == 0xd0
      || (insn & 0xfc) == 0xd4
      || (insn & 0xfc) == 0xd8
      || (insn & 0xf0) == 0xe0
      || (insn & 0xff) == 0xff)
    {
      consume = 1;
    }

  /* These are two byte insns.  */
  else if ((insn & 0xf0) == 0x80
	   || (insn & 0xf0) == 0x90
	   || (insn & 0xf0) == 0xa0
	   || (insn & 0xf0) == 0xb0
	   || (insn & 0xfc) == 0x20
	   || (insn & 0xfc) == 0x28
	   || (insn & 0xf3) == 0x43
	   || (insn & 0xf3) == 0x42
	   || (insn & 0xfc) == 0x58
	   || (insn & 0xfc) == 0x5c
	   || ((insn & 0xf0) == 0xc0
	       && (insn & 0xff) != 0xcb
	       && (insn & 0xff) != 0xcc
	       && (insn & 0xff) != 0xcd)
	   || (insn & 0xff) == 0xf0
	   || (insn & 0xff) == 0xf1
	   || (insn & 0xff) == 0xf2
	   || (insn & 0xff) == 0xf3
	   || (insn & 0xff) == 0xf4
	   || (insn & 0xff) == 0xf5
	   || (insn & 0xff) == 0xf6)
    {
      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
      if (status != 0)
	{
	  (*info->memory_error_func) (status, memaddr, info);
	  return -1;
	}
      insn = bfd_getb16 (buffer);
      consume = 2;
    }

  /* These are three byte insns.  */
  else if ((insn & 0xff) == 0xf8
	   || (insn & 0xff) == 0xcc
	   || (insn & 0xff) == 0xf9
	   || (insn & 0xf3) == 0x01
	   || (insn & 0xf3) == 0x02
	   || (insn & 0xf3) == 0x03
	   || (insn & 0xfc) == 0x24
	   || (insn & 0xfc) == 0x2c
	   || (insn & 0xfc) == 0x30
	   || (insn & 0xfc) == 0x34
	   || (insn & 0xfc) == 0x38
	   || (insn & 0xff) == 0xde
	   || (insn & 0xff) == 0xdf
	   || (insn & 0xff) == 0xf9
	   || (insn & 0xff) == 0xcc)
    {
      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
      if (status != 0)
	{
	  (*info->memory_error_func) (status, memaddr, info);
	  return -1;
	}
      insn = bfd_getb16 (buffer);
      insn <<= 8;
      status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
      if (status != 0)
	{
	  (*info->memory_error_func) (status, memaddr, info);
	  return -1;
	}
      insn |= *(unsigned char *) buffer;
      consume = 3;
    }

  /* These are four byte insns.  */
  else if ((insn & 0xff) == 0xfa
	   || (insn & 0xff) == 0xf7
	   || (insn & 0xff) == 0xfb)
    {
      status = (*info->read_memory_func) (memaddr, buffer, 4, info);
      if (status != 0)
	{
	  (*info->memory_error_func) (status, memaddr, info);
	  return -1;
	}
      insn = bfd_getb32 (buffer);
      consume = 4;
    }

  /* These are five byte insns.  */
  else if ((insn & 0xff) == 0xcd
	   || (insn & 0xff) == 0xdc)
    {
      status = (*info->read_memory_func) (memaddr, buffer, 4, info);
      if (status != 0)
	{
	  (*info->memory_error_func) (status, memaddr, info);
	  return -1;
	}
      insn = bfd_getb32 (buffer);
      consume = 5;
    }

  /* These are six byte insns.  */
  else if ((insn & 0xff) == 0xfd
	   || (insn & 0xff) == 0xfc)
    {
      status = (*info->read_memory_func) (memaddr, buffer, 4, info);
      if (status != 0)
	{
	  (*info->memory_error_func) (status, memaddr, info);
	  return -1;
	}

      insn = bfd_getb32 (buffer);
      consume = 6;
    }

  /* Else its a seven byte insns (in theory).  */
  else
    {
      status = (*info->read_memory_func) (memaddr, buffer, 4, info);
      if (status != 0)
	{
	  (*info->memory_error_func) (status, memaddr, info);
	  return -1;
	}

      insn = bfd_getb32 (buffer);
      consume = 7;
      /* Handle the 5-byte extended instruction codes.  */
      if ((insn & 0xfff80000) == 0xfe800000)
	consume = 5;
    }

  disassemble (memaddr, info, insn, consume);

  return consume;
}
