/* Disassemble SH64 instructions.
   Copyright 2000, 2001, 2002, 2003, 2005, 2007, 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 file; see the file COPYING.  If not, write to the
   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "sysdep.h"
#include <stdio.h>
#include "dis-asm.h"
#include "sh64-opc.h"
#include "libiberty.h"
/* We need to refer to the ELF header structure.  */
#include "elf-bfd.h"
#include "elf/sh.h"
#include "elf32-sh64.h"

#define ELF_MODE32_CODE_LABEL_P(SYM) \
 (((elf_symbol_type *) (SYM))->internal_elf_sym.st_other & STO_SH5_ISA32)

#define SAVED_MOVI_R(INFO) \
 (((struct sh64_disassemble_info *) ((INFO)->private_data))->address_reg)

#define SAVED_MOVI_IMM(INFO) \
 (((struct sh64_disassemble_info *) ((INFO)->private_data))->built_address)

struct sh64_disassemble_info
 {
   /* When we see a MOVI, we save the register and the value, and merge a
      subsequent SHORI and display the address, if there is one.  */
   unsigned int address_reg;
   bfd_signed_vma built_address;

   /* This is the range decriptor for the current address.  It is kept
      around for the next call.  */
   sh64_elf_crange crange;
 };

/* Each item in the table is a mask to indicate which bits to be set
   to determine an instruction's operator.
   The index is as same as the instruction in the opcode table.
   Note that some archs have this as a field in the opcode table.  */
static unsigned long *shmedia_opcode_mask_table;

/* Initialize the SH64 opcode mask table for each instruction in SHmedia
   mode.  */

static void
initialize_shmedia_opcode_mask_table (void)
{
  int n_opc;
  int n;

  /* Calculate number of opcodes.  */
  for (n_opc = 0; shmedia_table[n_opc].name != NULL; n_opc++)
    ;

  shmedia_opcode_mask_table
    = xmalloc (sizeof (shmedia_opcode_mask_table[0]) * n_opc);

  for (n = 0; n < n_opc; n++)
    {
      int i;

      unsigned long mask = 0;

      for (i = 0; shmedia_table[n].arg[i] != A_NONE; i++)
	{
	  int offset = shmedia_table[n].nibbles[i];
	  int length;

	  switch (shmedia_table[n].arg[i])
	    {
	    case A_GREG_M:
	    case A_GREG_N:
	    case A_GREG_D:
	    case A_CREG_K:
	    case A_CREG_J:
	    case A_FREG_G:
	    case A_FREG_H:
	    case A_FREG_F:
	    case A_DREG_G:
	    case A_DREG_H:
	    case A_DREG_F:
	    case A_FMREG_G:
	    case A_FMREG_H:
	    case A_FMREG_F:
	    case A_FPREG_G:
	    case A_FPREG_H:
	    case A_FPREG_F:
	    case A_FVREG_G:
	    case A_FVREG_H:
	    case A_FVREG_F:
	    case A_REUSE_PREV:
	      length = 6;
	      break;

	    case A_TREG_A:
	    case A_TREG_B:
	      length = 3;
	      break;

	    case A_IMMM:
	      abort ();
	      break;

	    case A_IMMU5:
	      length = 5;
	      break;

	    case A_IMMS6:
	    case A_IMMU6:
	    case A_IMMS6BY32:
	      length = 6;
	      break;

	    case A_IMMS10:
	    case A_IMMS10BY1:
	    case A_IMMS10BY2:
	    case A_IMMS10BY4:
	    case A_IMMS10BY8:
	      length = 10;
	      break;

	    case A_IMMU16:
	    case A_IMMS16:
	    case A_PCIMMS16BY4:
	    case A_PCIMMS16BY4_PT:
	      length = 16;
	      break;

	    default:
	      abort ();
	      length = 0;
	      break;
	    }

	  if (length != 0)
	    mask |= (0xffffffff >> (32 - length)) << offset;
	}
      shmedia_opcode_mask_table[n] = 0xffffffff & ~mask;
    }
}

/* Get a predefined control-register-name, or return NULL.  */

static const char *
creg_name (int cregno)
{
  const shmedia_creg_info *cregp;

  /* If control register usage is common enough, change this to search a
     hash-table.  */
  for (cregp = shmedia_creg_table; cregp->name != NULL; cregp++)
    if (cregp->cregno == cregno)
      return cregp->name;

  return NULL;
}

/* Main function to disassemble SHmedia instructions.  */

static int
print_insn_shmedia (bfd_vma memaddr, struct disassemble_info *info)
{
  fprintf_ftype fprintf_fn = info->fprintf_func;
  void *stream = info->stream;
  unsigned char insn[4];
  unsigned long instruction;
  int status;
  int n;
  const shmedia_opcode_info *op;
  int i;
  unsigned int r = 0;
  long imm = 0;
  bfd_vma disp_pc_addr;

  status = info->read_memory_func (memaddr, insn, 4, info);

  /* If we can't read four bytes, something is wrong.  Display any data we
     can get as .byte:s.  */
  if (status != 0)
    {
      for (i = 0; i < 3; i++)
	{
	  status = info->read_memory_func (memaddr + i, insn, 1, info);
	  if (status != 0)
	    break;
	  (*fprintf_fn) (stream, "%s0x%02x",
			 i == 0 ? ".byte " : ", ",
			 insn[0]);
	}

      return i ? i : -1;
    }

  /* Rearrange the bytes to make up an instruction.  */
  if (info->endian == BFD_ENDIAN_LITTLE)
    instruction = bfd_getl32 (insn);
  else
    instruction = bfd_getb32 (insn);

  /* FIXME: Searching could be implemented using a hash on relevant
     fields.  */
  for (n = 0, op = shmedia_table;
       op->name != NULL
       && ((instruction & shmedia_opcode_mask_table[n]) != op->opcode_base);
       n++, op++)
    ;

  /* FIXME: We should also check register number constraints.  */
  if (op->name == NULL)
    {
      fprintf_fn (stream, ".long 0x%08lx", instruction);
      return 4;
    }

  fprintf_fn (stream, "%s\t", op->name);

  for (i = 0; i < 3 && op->arg[i] != A_NONE; i++)
    {
      unsigned long temp = instruction >> op->nibbles[i];
      int by_number = 0;

      if (i > 0 && op->arg[i] != A_REUSE_PREV)
	fprintf_fn (stream, ",");

      switch (op->arg[i])
	{
	case A_REUSE_PREV:
	  continue;

	case A_GREG_M:
	case A_GREG_N:
	case A_GREG_D:
	  r = temp & 0x3f;
	  fprintf_fn (stream, "r%d", r);
	  break;

	case A_FVREG_F:
	case A_FVREG_G:
	case A_FVREG_H:
	  r = temp & 0x3f;
	  fprintf_fn (stream, "fv%d", r);
	  break;

	case A_FPREG_F:
	case A_FPREG_G:
	case A_FPREG_H:
	  r = temp & 0x3f;
	  fprintf_fn (stream, "fp%d", r);
	  break;

	case A_FMREG_F:
	case A_FMREG_G:
	case A_FMREG_H:
	  r = temp & 0x3f;
	  fprintf_fn (stream, "mtrx%d", r);
	  break;

	case A_CREG_K:
	case A_CREG_J:
	  {
	    const char *name;

	    r = temp & 0x3f;

	    name = creg_name (r);

	    if (name != NULL)
	      fprintf_fn (stream, "%s", name);
	    else
	      fprintf_fn (stream, "cr%d", r);
	  }
	  break;

	case A_FREG_G:
	case A_FREG_H:
	case A_FREG_F:
	  r = temp & 0x3f;
	  fprintf_fn (stream, "fr%d", r);
	  break;

	case A_DREG_G:
	case A_DREG_H:
	case A_DREG_F:
	  r = temp & 0x3f;
	  fprintf_fn (stream, "dr%d", r);
	  break;

	case A_TREG_A:
	case A_TREG_B:
	  r = temp & 0x7;
	  fprintf_fn (stream, "tr%d", r);
	  break;

	  /* A signed 6-bit number.  */
	case A_IMMS6:
	  imm = temp & 0x3f;
	  if (imm & (unsigned long) 0x20)
	    imm |= ~(unsigned long) 0x3f;
	  fprintf_fn (stream, "%ld", imm);
	  break;

	  /* A signed 6-bit number, multiplied by 32 when used.  */
	case A_IMMS6BY32:
	  imm = temp & 0x3f;
	  if (imm & (unsigned long) 0x20)
	    imm |= ~(unsigned long) 0x3f;
	  fprintf_fn (stream, "%ld", imm * 32);
	  break;

	  /* A signed 10-bit number, multiplied by 8 when used.  */
	case A_IMMS10BY8:
	  by_number++;
	  /* Fall through.  */

	  /* A signed 10-bit number, multiplied by 4 when used.  */
	case A_IMMS10BY4:
	  by_number++;
	  /* Fall through.  */

	  /* A signed 10-bit number, multiplied by 2 when used.  */
	case A_IMMS10BY2:
	  by_number++;
	  /* Fall through.  */

	  /* A signed 10-bit number.  */
	case A_IMMS10:
	case A_IMMS10BY1:
	  imm = temp & 0x3ff;
	  if (imm & (unsigned long) 0x200)
	    imm |= ~(unsigned long) 0x3ff;
	  imm <<= by_number;
	  fprintf_fn (stream, "%ld", imm);
	  break;

	  /* A signed 16-bit number.  */
	case A_IMMS16:
	  imm = temp & 0xffff;
	  if (imm & (unsigned long) 0x8000)
	    imm |= ~((unsigned long) 0xffff);
	  fprintf_fn (stream, "%ld", imm);
	  break;

	  /* A PC-relative signed 16-bit number, multiplied by 4 when
	     used.  */
	case A_PCIMMS16BY4:
	  imm = temp & 0xffff;	/* 16 bits */
	  if (imm & (unsigned long) 0x8000)
	    imm |= ~(unsigned long) 0xffff;
	  imm <<= 2;
	  disp_pc_addr = (bfd_vma) imm + memaddr;
	  (*info->print_address_func) (disp_pc_addr, info);
	  break;

	  /* An unsigned 5-bit number.  */
	case A_IMMU5:
	  imm = temp & 0x1f;
	  fprintf_fn (stream, "%ld", imm);
	  break;

	  /* An unsigned 6-bit number.  */
	case A_IMMU6:
	  imm = temp & 0x3f;
	  fprintf_fn (stream, "%ld", imm);
	  break;

	  /* An unsigned 16-bit number.  */
	case A_IMMU16:
	  imm = temp & 0xffff;
	  fprintf_fn (stream, "%ld", imm);
	  break;

	default:
	  abort ();
	  break;
	}
    }

  /* FIXME: Looks like 32-bit values only are handled.
     FIXME: PC-relative numbers aren't handled correctly.  */
  if (op->opcode_base == (unsigned long) SHMEDIA_SHORI_OPC
      && SAVED_MOVI_R (info) == r)
    {
      asection *section = info->section;

      /* Most callers do not set the section field correctly yet.  Revert
	 to getting the section from symbols, if any. */
      if (section == NULL
	  && info->symbols != NULL
	  && bfd_asymbol_flavour (info->symbols[0]) == bfd_target_elf_flavour
	  && ! bfd_is_und_section (bfd_get_section (info->symbols[0]))
	  && ! bfd_is_abs_section (bfd_get_section (info->symbols[0])))
	section = bfd_get_section (info->symbols[0]);

      /* Only guess addresses when the contents of this section is fully
	 relocated.  Otherwise, the value will be zero or perhaps even
	 bogus.  */
      if (section == NULL
	  || section->owner == NULL
	  || elf_elfheader (section->owner)->e_type == ET_EXEC)
	{
	  bfd_signed_vma shori_addr;

	  shori_addr = SAVED_MOVI_IMM (info) << 16;
	  shori_addr |= imm;

	  fprintf_fn (stream, "\t! 0x");
	  (*info->print_address_func) (shori_addr, info);
	}
    }

  if (op->opcode_base == SHMEDIA_MOVI_OPC)
    {
      SAVED_MOVI_IMM (info) = imm;
      SAVED_MOVI_R (info) = r;
    }
  else
    {
      SAVED_MOVI_IMM (info) = 0;
      SAVED_MOVI_R (info) = 255;
    }

  return 4;
}

/* Check the type of contents about to be disassembled.  This is like
   sh64_get_contents_type (which may be called from here), except that it
   takes the same arguments as print_insn_* and does what can be done if
   no section is available.  */

static enum sh64_elf_cr_type
sh64_get_contents_type_disasm (bfd_vma memaddr, struct disassemble_info *info)
{
  struct sh64_disassemble_info *sh64_infop = info->private_data;

  /* Perhaps we have a region from a previous probe and it still counts
     for this address?  */
  if (sh64_infop->crange.cr_type != CRT_NONE
      && memaddr >= sh64_infop->crange.cr_addr
      && memaddr < sh64_infop->crange.cr_addr + sh64_infop->crange.cr_size)
    return sh64_infop->crange.cr_type;

  /* If we have a section, try and use it.  */
  if (info->section
      && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour)
    {
      enum sh64_elf_cr_type cr_type
	= sh64_get_contents_type (info->section, memaddr,
				  &sh64_infop->crange);

      if (cr_type != CRT_NONE)
	return cr_type;
    }

  /* If we have symbols, we can try and get at a section from *that*.  */
  if (info->symbols != NULL
      && bfd_asymbol_flavour (info->symbols[0]) == bfd_target_elf_flavour
      && ! bfd_is_und_section (bfd_get_section (info->symbols[0]))
      && ! bfd_is_abs_section (bfd_get_section (info->symbols[0])))
    {
      enum sh64_elf_cr_type cr_type
	= sh64_get_contents_type (bfd_get_section (info->symbols[0]),
				  memaddr, &sh64_infop->crange);

      if (cr_type != CRT_NONE)
	return cr_type;
    }

  /* We can make a reasonable guess based on the st_other field of a
     symbol; for a BranchTarget this is marked as STO_SH5_ISA32 and then
     it's most probably code there.  */
  if (info->symbols
      && bfd_asymbol_flavour (info->symbols[0]) == bfd_target_elf_flavour
      && elf_symbol_from (bfd_asymbol_bfd (info->symbols[0]),
			  info->symbols[0])->internal_elf_sym.st_other
      == STO_SH5_ISA32)
    return CRT_SH5_ISA32;

  /* If all else fails, guess this is code and guess on the low bit set.  */
  return (memaddr & 1) == 1 ? CRT_SH5_ISA32 : CRT_SH5_ISA16;
}

/* Initialize static and dynamic disassembly state.  */

static bfd_boolean
init_sh64_disasm_info (struct disassemble_info *info)
{
  struct sh64_disassemble_info *sh64_infop
    = calloc (sizeof (*sh64_infop), 1);

  if (sh64_infop == NULL)
    return FALSE;

  info->private_data = sh64_infop;

  SAVED_MOVI_IMM (info) = 0;
  SAVED_MOVI_R (info) = 255;

  if (shmedia_opcode_mask_table == NULL)
    initialize_shmedia_opcode_mask_table ();

  return TRUE;
}

/* Main entry to disassemble SHmedia instructions, given an endian set in
   INFO.  Note that the simulator uses this as the main entry and does not
   use any of the functions further below.  */

int
print_insn_sh64x_media (bfd_vma memaddr, struct disassemble_info *info)
{
  if (info->private_data == NULL && ! init_sh64_disasm_info (info))
    return -1;

  /* Make reasonable output.  */
  info->bytes_per_line = 4;
  info->bytes_per_chunk = 4;

  return print_insn_shmedia (memaddr, info);
}

/* Main entry to disassemble SHmedia insns.
   If we see an SHcompact instruction, return -2.  */

int
print_insn_sh64 (bfd_vma memaddr, struct disassemble_info *info)
{
  enum bfd_endian endian = info->endian;
  enum sh64_elf_cr_type cr_type;

  if (info->private_data == NULL && ! init_sh64_disasm_info (info))
    return -1;

  cr_type = sh64_get_contents_type_disasm (memaddr, info);
  if (cr_type != CRT_SH5_ISA16)
    {
      int length = 4 - (memaddr % 4);
      info->display_endian = endian;

      /* If we got an uneven address to indicate SHmedia, adjust it.  */
      if (cr_type == CRT_SH5_ISA32 && length == 3)
	memaddr--, length = 4;

      /* Only disassemble on four-byte boundaries.  Addresses that are not
	 a multiple of four can happen after a data region.  */
      if (cr_type == CRT_SH5_ISA32 && length == 4)
	return print_insn_sh64x_media (memaddr, info);

      /* We get CRT_DATA *only* for data regions in a mixed-contents
	 section.  For sections with data only, we get indication of one
	 of the ISA:s.  You may think that we shouldn't disassemble
	 section with only data if we can figure that out.  However, the
	 disassembly function is by default not called for data-only
	 sections, so if the user explicitly specified disassembly of a
	 data section, that's what we should do.  */
      if (cr_type == CRT_DATA || length != 4)
	{
	  int status;
	  unsigned char data[4];
	  struct sh64_disassemble_info *sh64_infop = info->private_data;

	  if (length == 4
	      && sh64_infop->crange.cr_type != CRT_NONE
	      && memaddr >= sh64_infop->crange.cr_addr
	      && memaddr < (sh64_infop->crange.cr_addr
			    + sh64_infop->crange.cr_size))
	    length
	      = (sh64_infop->crange.cr_addr
		 + sh64_infop->crange.cr_size - memaddr);

	  status
	    = (*info->read_memory_func) (memaddr, data,
					 length >= 4 ? 4 : length, info);

	  if (status == 0 && length >= 4)
	    {
	      (*info->fprintf_func) (info->stream, ".long 0x%08lx",
				     endian == BFD_ENDIAN_BIG
				     ? (long) (bfd_getb32 (data))
				     : (long) (bfd_getl32 (data)));
	      return 4;
	    }
	  else
	    {
	      int i;

	      for (i = 0; i < length; i++)
		{
		  status = info->read_memory_func (memaddr + i, data, 1, info);
		  if (status != 0)
		    break;
		  (*info->fprintf_func) (info->stream, "%s0x%02x",
					 i == 0 ? ".byte " : ", ",
					 data[0]);
		}

	      return i ? i : -1;
	    }
	}
    }

  /* SH1 .. SH4 instruction, let caller handle it.  */
  return -2;
}
