/* Disassemble SH64 instructions.
   Copyright 2000, 2001, 2002, 2003, 2005, 2007 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 <stdio.h>

#include "dis-asm.h"
#include "sysdep.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)
    {
      int i;

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