/* Disassemble SH64 instructions.
   Copyright (C) 2000-2018 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 "disassemble.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;
}
