/* Altera Nios II disassemble routines
   Copyright (C) 2012-2014 Free Software Foundation, Inc.
   Contributed by Nigel Gray (ngray@altera.com).
   Contributed by Mentor Graphics, 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 "dis-asm.h"
#include "opcode/nios2.h"
#include "libiberty.h"
#include <string.h>
#include <assert.h>

/* No symbol table is available when this code runs out in an embedded
   system as when it is used for disassembler support in a monitor.  */
#if !defined(EMBEDDED_ENV)
#define SYMTAB_AVAILABLE 1
#include "elf-bfd.h"
#include "elf/nios2.h"
#endif

/* Length of Nios II instruction in bytes.  */
#define INSNLEN 4

/* Data structures used by the opcode hash table.  */
typedef struct _nios2_opcode_hash
{
  const struct nios2_opcode *opcode;
  struct _nios2_opcode_hash *next;
} nios2_opcode_hash;

static bfd_boolean nios2_hash_init = 0;
static nios2_opcode_hash *nios2_hash[(OP_MASK_OP) + 1];

/* Separate hash table for pseudo-ops.  */
static nios2_opcode_hash *nios2_ps_hash[(OP_MASK_OP) + 1];

/* Function to initialize the opcode hash table.  */
static void
nios2_init_opcode_hash (void)
{
  unsigned int i;
  register const struct nios2_opcode *op;

  for (i = 0; i <= OP_MASK_OP; ++i)
    nios2_hash[0] = NULL;
  for (i = 0; i <= OP_MASK_OP; i++)
    for (op = nios2_opcodes; op < &nios2_opcodes[NUMOPCODES]; op++)
      {
	nios2_opcode_hash *new_hash;
	nios2_opcode_hash **bucket = NULL;

	if ((op->pinfo & NIOS2_INSN_MACRO) == NIOS2_INSN_MACRO)
	  {
	    if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP)
		&& (op->pinfo & (NIOS2_INSN_MACRO_MOV | NIOS2_INSN_MACRO_MOVI)
		    & 0x7fffffff))
	      bucket = &(nios2_ps_hash[i]);
	  }
	else if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
	  bucket = &(nios2_hash[i]);

	if (bucket)
	  {
	    new_hash =
	      (nios2_opcode_hash *) malloc (sizeof (nios2_opcode_hash));
	    if (new_hash == NULL)
	      {
		fprintf (stderr,
			 "error allocating memory...broken disassembler\n");
		abort ();
	      }
	    new_hash->opcode = op;
	    new_hash->next = NULL;
	    while (*bucket)
	      bucket = &((*bucket)->next);
	    *bucket = new_hash;
	  }
      }
  nios2_hash_init = 1;
#ifdef DEBUG_HASHTABLE
  for (i = 0; i <= OP_MASK_OP; ++i)
    {
      nios2_opcode_hash *tmp_hash = nios2_hash[i];
      printf ("index: 0x%02X	ops: ", i);
      while (tmp_hash != NULL)
	{
	  printf ("%s ", tmp_hash->opcode->name);
	  tmp_hash = tmp_hash->next;
	}
      printf ("\n");
    }

  for (i = 0; i <= OP_MASK_OP; ++i)
    {
      nios2_opcode_hash *tmp_hash = nios2_ps_hash[i];
      printf ("index: 0x%02X	ops: ", i);
      while (tmp_hash != NULL)
	{
	  printf ("%s ", tmp_hash->opcode->name);
	  tmp_hash = tmp_hash->next;
	}
      printf ("\n");
    }
#endif /* DEBUG_HASHTABLE */
}

/* Return a pointer to an nios2_opcode struct for a given instruction
   opcode, or NULL if there is an error.  */
const struct nios2_opcode *
nios2_find_opcode_hash (unsigned long opcode)
{
  nios2_opcode_hash *entry;

  /* Build a hash table to shorten the search time.  */
  if (!nios2_hash_init)
    nios2_init_opcode_hash ();

  /* First look in the pseudo-op hashtable.  */
  for (entry = nios2_ps_hash[(opcode >> OP_SH_OP) & OP_MASK_OP];
       entry; entry = entry->next)
    if (entry->opcode->match == (opcode & entry->opcode->mask))
      return entry->opcode;

  /* Otherwise look in the main hashtable.  */
  for (entry = nios2_hash[(opcode >> OP_SH_OP) & OP_MASK_OP];
       entry; entry = entry->next)
    if (entry->opcode->match == (opcode & entry->opcode->mask))
      return entry->opcode;

  return NULL;
}

/* There are 32 regular registers, 32 coprocessor registers,
   and 32 control registers.  */
#define NUMREGNAMES 32

/* Return a pointer to the base of the coprocessor register name array.  */
static struct nios2_reg *
nios2_coprocessor_regs (void)
{
  static struct nios2_reg *cached = NULL;
  
  if (!cached)
    {
      int i;
      for (i = NUMREGNAMES; i < nios2_num_regs; i++)
	if (!strcmp (nios2_regs[i].name, "c0"))
	  {
	    cached = nios2_regs + i;
	    break;
	  }
      assert (cached);
    }
  return cached;
}

/* Return a pointer to the base of the control register name array.  */
static struct nios2_reg *
nios2_control_regs (void)
{
  static struct nios2_reg *cached = NULL;
  
  if (!cached)
    {
      int i;
      for (i = NUMREGNAMES; i < nios2_num_regs; i++)
	if (!strcmp (nios2_regs[i].name, "status"))
	  {
	    cached = nios2_regs + i;
	    break;
	  }
      assert (cached);
    }
  return cached;
}

/* The function nios2_print_insn_arg uses the character pointed
   to by ARGPTR to determine how it print the next token or separator
   character in the arguments to an instruction.  */
static int
nios2_print_insn_arg (const char *argptr,
		      unsigned long opcode, bfd_vma address,
		      disassemble_info *info)
{
  unsigned long i = 0;
  struct nios2_reg *reg_base;

  switch (*argptr)
    {
    case ',':
    case '(':
    case ')':
      (*info->fprintf_func) (info->stream, "%c", *argptr);
      break;
    case 'd':
      i = GET_INSN_FIELD (RRD, opcode);

      if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
	  && GET_INSN_FIELD (CUSTOM_C, opcode) == 0)
	reg_base = nios2_coprocessor_regs ();
      else
	reg_base = nios2_regs;

      if (i < NUMREGNAMES)
	(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
      else
	(*info->fprintf_func) (info->stream, "unknown");
      break;
    case 's':
      i = GET_INSN_FIELD (RRS, opcode);

      if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
	  && GET_INSN_FIELD (CUSTOM_A, opcode) == 0)
	reg_base = nios2_coprocessor_regs ();
      else
	reg_base = nios2_regs;

      if (i < NUMREGNAMES)
	(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
      else
	(*info->fprintf_func) (info->stream, "unknown");
      break;
    case 't':
      i = GET_INSN_FIELD (RRT, opcode);

      if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
	  && GET_INSN_FIELD (CUSTOM_B, opcode) == 0)
	reg_base = nios2_coprocessor_regs ();
      else
	reg_base = nios2_regs;

      if (i < NUMREGNAMES)
	(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
      else
	(*info->fprintf_func) (info->stream, "unknown");
      break;
    case 'i':
      /* 16-bit signed immediate.  */
      i = (signed) (GET_INSN_FIELD (IMM16, opcode) << 16) >> 16;
      (*info->fprintf_func) (info->stream, "%ld", i);
      break;
    case 'u':
      /* 16-bit unsigned immediate.  */
      i = GET_INSN_FIELD (IMM16, opcode);
      (*info->fprintf_func) (info->stream, "%ld", i);
      break;
    case 'o':
      /* 16-bit signed immediate address offset.  */
      i = (signed) (GET_INSN_FIELD (IMM16, opcode) << 16) >> 16;
      address = address + 4 + i;
      (*info->print_address_func) (address, info);
      break;
    case 'p':
      /* 5-bit unsigned immediate.  */
      i = GET_INSN_FIELD (CACHE_OPX, opcode);
      (*info->fprintf_func) (info->stream, "%ld", i);
      break;
    case 'j':
      /* 5-bit unsigned immediate.  */
      i = GET_INSN_FIELD (IMM5, opcode);
      (*info->fprintf_func) (info->stream, "%ld", i);
      break;
    case 'l':
      /* 8-bit unsigned immediate.  */
      /* FIXME - not yet implemented */
      i = GET_INSN_FIELD (CUSTOM_N, opcode);
      (*info->fprintf_func) (info->stream, "%lu", i);
      break;
    case 'm':
      /* 26-bit unsigned immediate.  */
      i = GET_INSN_FIELD (IMM26, opcode);
      /* This translates to an address because it's only used in call
	 instructions.  */
      address = (address & 0xf0000000) | (i << 2);
      (*info->print_address_func) (address, info);
      break;
    case 'c':
      /* Control register index.  */
      i = GET_INSN_FIELD (IMM5, opcode);
      reg_base = nios2_control_regs ();
      (*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
      break;
    case 'b':
      i = GET_INSN_FIELD (IMM5, opcode);
      (*info->fprintf_func) (info->stream, "%ld", i);
      break;
    default:
      (*info->fprintf_func) (info->stream, "unknown");
      break;
    }
  return 0;
}

/* nios2_disassemble does all the work of disassembling a Nios II
   instruction opcode.  */
static int
nios2_disassemble (bfd_vma address, unsigned long opcode,
		   disassemble_info *info)
{
  const struct nios2_opcode *op;

  info->bytes_per_line = INSNLEN;
  info->bytes_per_chunk = INSNLEN;
  info->display_endian = info->endian;
  info->insn_info_valid = 1;
  info->branch_delay_insns = 0;
  info->data_size = 0;
  info->insn_type = dis_nonbranch;
  info->target = 0;
  info->target2 = 0;

  /* Find the major opcode and use this to disassemble
     the instruction and its arguments.  */
  op = nios2_find_opcode_hash (opcode);

  if (op != NULL)
    {
      bfd_boolean is_nop = FALSE;
      if (op->pinfo == NIOS2_INSN_MACRO_MOV)
	{
	  /* Check for mov r0, r0 and change to nop.  */
	  int dst, src;
	  dst = GET_INSN_FIELD (RRD, opcode);
	  src = GET_INSN_FIELD (RRS, opcode);
	  if (dst == 0 && src == 0)
	    {
	      (*info->fprintf_func) (info->stream, "nop");
	      is_nop = TRUE;
	    }
	  else
	    (*info->fprintf_func) (info->stream, "%s", op->name);
	}
      else
	(*info->fprintf_func) (info->stream, "%s", op->name);

      if (!is_nop)
	{
	  const char *argstr = op->args;
	  if (argstr != NULL && *argstr != '\0')
	    {
	      (*info->fprintf_func) (info->stream, "\t");
	      while (*argstr != '\0')
		{
		  nios2_print_insn_arg (argstr, opcode, address, info);
		  ++argstr;
		}
	    }
	}
    }
  else
    {
      /* Handle undefined instructions.  */
      info->insn_type = dis_noninsn;
      (*info->fprintf_func) (info->stream, "0x%lx", opcode);
    }
  /* Tell the caller how far to advance the program counter.  */
  return INSNLEN;
}


/* print_insn_nios2 is the main disassemble function for Nios II.
   The function diassembler(abfd) (source in disassemble.c) returns a
   pointer to this either print_insn_big_nios2 or
   print_insn_little_nios2, which in turn call this function when the
   bfd machine type is Nios II. print_insn_nios2 reads the
   instruction word at the address given, and prints the disassembled
   instruction on the stream info->stream using info->fprintf_func. */

static int
print_insn_nios2 (bfd_vma address, disassemble_info *info,
		  enum bfd_endian endianness)
{
  bfd_byte buffer[INSNLEN];
  int status;

  status = (*info->read_memory_func) (address, buffer, INSNLEN, info);
  if (status == 0)
    {
      unsigned long insn;
      if (endianness == BFD_ENDIAN_BIG)
	insn = (unsigned long) bfd_getb32 (buffer);
      else
	insn = (unsigned long) bfd_getl32 (buffer);
      status = nios2_disassemble (address, insn, info);
    }
  else
    {
      (*info->memory_error_func) (status, address, info);
      status = -1;
    }
  return status;
}

/* These two functions are the main entry points, accessed from
   disassemble.c.  */
int
print_insn_big_nios2 (bfd_vma address, disassemble_info *info)
{
  return print_insn_nios2 (address, info, BFD_ENDIAN_BIG);
}

int
print_insn_little_nios2 (bfd_vma address, disassemble_info *info)
{
  return print_insn_nios2 (address, info, BFD_ENDIAN_LITTLE);
}
