/* NDS32-specific support for 32-bit ELF.
   Copyright (C) 2012-2021 Free Software Foundation, Inc.
   Contributed by Andes Technology Corporation.

   This file is part of BFD, the Binary File Descriptor library.

   This program 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 of the License, or
   (at your option) any later version.

   This program 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 "ansidecl.h"
#include "disassemble.h"
#include "bfd.h"
#include "symcat.h"
#include "libiberty.h"
#include "opintl.h"
#include <stdint.h>
#include "hashtab.h"
#include "nds32-asm.h"
#include "opcode/nds32.h"

/* Get fields macro define.  */
#define MASK_OP(insn, mask)	((insn) & (0x3f << 25 | (mask)))

/* For mapping symbol.  */
enum map_type
{
  MAP_DATA0,
  MAP_DATA1,
  MAP_DATA2,
  MAP_DATA3,
  MAP_DATA4,
  MAP_CODE,
};

struct nds32_private_data
{
  /* Whether any mapping symbols are present in the provided symbol
     table.  -1 if we do not know yet, otherwise 0 or 1.  */
  int has_mapping_symbols;

  /* Track the last type (although this doesn't seem to be useful).  */
  enum map_type last_mapping_type;

  /* Tracking symbol table information.  */
  int last_symbol_index;
  bfd_vma last_addr;
};

/* Default text to print if an instruction isn't recognized.  */
#define UNKNOWN_INSN_MSG _("*unknown*")
#define NDS32_PARSE_INSN16      0x01
#define NDS32_PARSE_INSN32      0x02

static uint32_t nds32_mask_opcode (uint32_t);
static void nds32_special_opcode (uint32_t, struct nds32_opcode **);
static int get_mapping_symbol_type (struct disassemble_info *, int,
				    enum map_type *);
static int is_mapping_symbol (struct disassemble_info *, int,
			      enum map_type *);

/* Hash function for disassemble.  */

static htab_t opcode_htab;

/* Find the value map register name.  */

static const keyword_t *
nds32_find_reg_keyword (const keyword_t *reg, int value)
{
  if (!reg)
    return NULL;

  while (reg->name != NULL && reg->value != value)
    {
      reg++;
    }
  if (reg->name == NULL)
    return NULL;
  return reg;
}

static void
nds32_parse_audio_ext (const field_t *pfd,
		       disassemble_info *info, uint32_t insn)
{
  fprintf_ftype func = info->fprintf_func;
  void *stream = info->stream;
  const keyword_t *psys_reg;
  int int_value, new_value;

  if (pfd->hw_res == HW_INT || pfd->hw_res == HW_UINT)
    {
      if (pfd->hw_res == HW_INT)
	int_value = (unsigned) N32_IMMS (insn >> pfd->bitpos,
					 pfd->bitsize) << pfd->shift;
      else
	int_value = __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;

      if (int_value < 10)
	func (stream, "#%d", int_value);
      else
	func (stream, "#0x%x", int_value);
      return;
    }
  int_value =
    __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
  new_value = int_value;
  psys_reg = (keyword_t*) nds32_keywords[pfd->hw_res];

  /* p = bit[4].bit[1:0], r = bit[4].bit[3:2].  */
  if (strcmp (pfd->name, "im5_i") == 0)
    {
      new_value = int_value & 0x03;
      new_value |= ((int_value & 0x10) >> 2);
    }
  else if (strcmp (pfd->name, "im5_m") == 0)
    {
      new_value = ((int_value & 0x1C) >> 2);
    }
  /* p = 0.bit[1:0], r = 0.bit[3:2].  */
  /* q = 1.bit[1:0], s = 1.bit[5:4].  */
  else if (strcmp (pfd->name, "im6_iq") == 0)
    {
      new_value |= 0x04;
    }
  else if (strcmp (pfd->name, "im6_ms") == 0)
    {
      new_value |= 0x04;
    }
  /*  Rt CONCAT(c, t21, t0).  */
  else if (strcmp (pfd->name, "a_rt21") == 0)
    {
      new_value = (insn & 0x00000020) >> 5;
      new_value |= (insn & 0x00000C00) >> 9;
      new_value |= (insn & 0x00008000) >> 12;
    }
  else if (strcmp (pfd->name, "a_rte") == 0)
    {
      new_value = (insn & 0x00000C00) >> 9;
      new_value |= (insn & 0x00008000) >> 12;
    }
  else if (strcmp (pfd->name, "a_rte1") == 0)
    {
      new_value = (insn & 0x00000C00) >> 9;
      new_value |= (insn & 0x00008000) >> 12;
      new_value |= 0x01;
    }
  else if (strcmp (pfd->name, "a_rte69") == 0)
    {
      new_value = int_value << 1;
    }
  else if (strcmp (pfd->name, "a_rte69_1") == 0)
    {
      new_value = int_value << 1;
      new_value |= 0x01;
    }

  psys_reg = nds32_find_reg_keyword (psys_reg, new_value);
  if (!psys_reg)
    func (stream, "???");
  else
    func (stream, "$%s", psys_reg->name);
}

/* Match instruction opcode with keyword table.  */

static field_t *
match_field (char *name)
{
  field_t *pfd;
  int k;

  for (k = 0; k < NDS32_CORE_COUNT; k++)
    {
      pfd = (field_t *) nds32_field_table[k];
      while (1)
	{
	  if (pfd->name == NULL)
	    break;
	  if (strcmp (name, pfd->name) == 0)
	    return pfd;
	  pfd++;
	}
    }

  return NULL;
}

/* Dump instruction.  If the opcode is unknown, return FALSE.  */

static void
nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
		    disassemble_info *info, uint32_t insn,
		    uint32_t parse_mode)
{
  int op = 0;
  fprintf_ftype func = info->fprintf_func;
  void *stream = info->stream;
  const char *pstr_src;
  char *pstr_tmp;
  char tmp_string[16];
  unsigned int push25gpr = 0, lsmwRb, lsmwRe, lsmwEnb4, checkbit, i;
  int int_value, ifthe1st = 1;
  const field_t *pfd;
  const keyword_t *psys_reg;

  if (opc == NULL)
    {
      func (stream, UNKNOWN_INSN_MSG);
      return;
    }

  pstr_src = opc->instruction;
  if (*pstr_src == 0)
    {
      func (stream, "%s", opc->opcode);
      return;
    }
  /* NDS32_PARSE_INSN16.  */
  if (parse_mode & NDS32_PARSE_INSN16)
    {
      func (stream, "%s ", opc->opcode);
    }

  /* NDS32_PARSE_INSN32.  */
  else
    {
      op = N32_OP6 (insn);
      if (op == N32_OP6_LSMW)
	func (stream, "%s.", opc->opcode);
      else if (strstr (opc->instruction, "tito"))
	func (stream, "%s", opc->opcode);
      else
	func (stream, "%s\t", opc->opcode);
    }

  while (*pstr_src)
    {
      switch (*pstr_src)
	{
	case '%':
	case '=':
	case '&':
	  pstr_src++;
	  /* Compare with nds32_operand_fields[].name.  */
	  pstr_tmp = &tmp_string[0];
	  while (*pstr_src)
	    {
	      if ((*pstr_src == ',') || (*pstr_src == ' ')
		  || (*pstr_src == '{') || (*pstr_src == '}')
		  || (*pstr_src == '[') || (*pstr_src == ']')
		  || (*pstr_src == '(') || (*pstr_src == ')')
		  || (*pstr_src == '+') || (*pstr_src == '<'))
		break;
	      *pstr_tmp++ = *pstr_src++;
	    }
	  *pstr_tmp = 0;

	  if ((pfd = match_field (&tmp_string[0])) == NULL)
	    return;

	  /* For insn-16.  */
	  if (parse_mode & NDS32_PARSE_INSN16)
	    {
	      if (pfd->hw_res == HW_GPR)
		{
		  int_value =
		    __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
		  /* push25/pop25.  */
		  if ((opc->value == 0xfc00) || (opc->value == 0xfc80))
		    {
		      if (int_value == 0)
			int_value = 6;
		      else
			int_value = (6 + (0x01 << int_value));
		      push25gpr = int_value;
		    }
		  else if (strcmp (pfd->name, "rt4") == 0)
		    {
		      int_value = nds32_r45map[int_value];
		    }
		  func (stream, "$%s", nds32_keyword_gpr[int_value].name);
		}
	      else if ((pfd->hw_res == HW_INT) || (pfd->hw_res == HW_UINT))
		{
		  if (pfd->hw_res == HW_INT)
		    int_value
		      = (unsigned) N32_IMMS (insn >> pfd->bitpos,
					     pfd->bitsize) << pfd->shift;
		  else
		    int_value =
		      __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;

		  /* movpi45.  */
		  if (opc->value == 0xfa00)
		    {
		      int_value += 16;
		      func (stream, "#0x%x", int_value);
		    }
		  /* lwi45.fe.  */
		  else if (opc->value == 0xb200)
		    {
		      int_value = 0 - (128 - int_value);
		      func (stream, "#%d", int_value);
		    }
		  /* beqz38/bnez38/beqs38/bnes38/j8/beqzs8/bnezs8.  */
		  else if ((opc->value == 0xc000) || (opc->value == 0xc800)
			   || (opc->value == 0xd000) || (opc->value == 0xd800)
			   || (opc->value == 0xd500) || (opc->value == 0xe800)
			   || (opc->value == 0xe900))
		    {
		      info->print_address_func (int_value + pc, info);
		    }
		  /* push25/pop25.  */
		  else if ((opc->value == 0xfc00) || (opc->value == 0xfc80))
		    {
		      func (stream, "#%d    ! {$r6", int_value);
		      if (push25gpr != 6)
			func (stream, "~$%s", nds32_keyword_gpr[push25gpr].name);
		      func (stream, ", $fp, $gp, $lp}");
		    }
		  else if (pfd->hw_res == HW_INT)
		    {
		      if (int_value < 10)
			func (stream, "#%d", int_value);
		      else
			func (stream, "#0x%x", int_value);
		    }
		  else /* if (pfd->hw_res == HW_UINT).  */
		    {
		      if (int_value < 10)
			func (stream, "#%u", int_value);
		      else
			func (stream, "#0x%x", int_value);
		    }
		}

	    }
	  /* for audio-ext.  */
	  else if (op == N32_OP6_AEXT)
	    {
	      nds32_parse_audio_ext (pfd, info, insn);
	    }
	  /* for insn-32.  */
	  else if (pfd->hw_res < HW_INT)
	    {
	      int_value =
		__GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;

	      psys_reg = *(nds32_keyword_table[pfd->hw_res >> 8]
			   + (pfd->hw_res & 0xff));

	      psys_reg = nds32_find_reg_keyword (psys_reg, int_value);
	      /* For HW_SR, dump the index when it can't
		 map the register name.  */
	      if (!psys_reg && pfd->hw_res == HW_SR)
		func (stream, "%d", int_value);
	      else if (!psys_reg)
		func (stream, "???");
	      else
		{
		  if (pfd->hw_res == HW_GPR || pfd->hw_res == HW_CPR
		      || pfd->hw_res == HW_FDR || pfd->hw_res == HW_FSR
		      || pfd->hw_res == HW_DXR || pfd->hw_res == HW_SR
		      || pfd->hw_res == HW_USR)
		    func (stream, "$%s", psys_reg->name);
		  else if (pfd->hw_res == HW_DTITON
			   || pfd->hw_res == HW_DTITOFF)
		    func (stream, ".%s", psys_reg->name);
		  else
		    func (stream, "%s", psys_reg->name);
		}
	    }
	  else if ((pfd->hw_res == HW_INT) || (pfd->hw_res == HW_UINT))
	    {
	      if (pfd->hw_res == HW_INT)
		int_value = (unsigned) N32_IMMS (insn >> pfd->bitpos,
						 pfd->bitsize) << pfd->shift;
	      else
		int_value =
		  __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;

	      if ((op == N32_OP6_BR1) || (op == N32_OP6_BR2))
		{
		  info->print_address_func (int_value + pc, info);
		}
	      else if ((op == N32_OP6_BR3) && (pfd->bitpos == 0))
		{
		  info->print_address_func (int_value + pc, info);
		}
	      else if (op == N32_OP6_JI)
		{
		  /* FIXME: Handle relocation.  */
		  if (info->flags & INSN_HAS_RELOC)
		    pc = 0;
		  info->print_address_func (int_value + pc, info);
		}
	      else if (op == N32_OP6_LSMW)
		{
		  /* lmw.adm/smw.adm.  */
		  func (stream, "#0x%x    ! {", int_value);
		  lsmwEnb4 = int_value;
		  lsmwRb = ((insn >> 20) & 0x1F);
		  lsmwRe = ((insn >> 10) & 0x1F);

		  /* If [Rb, Re] specifies at least one register,
		     Rb(4,0) <= Re(4,0) and 0 <= Rb(4,0), Re(4,0) < 28.
		     Disassembling does not consider this currently because of
		     the convience comparing with bsp320.  */
		  if (lsmwRb != 31 || lsmwRe != 31)
		    {
		      func (stream, "$%s", nds32_keyword_gpr[lsmwRb].name);
		      if (lsmwRb != lsmwRe)
			func (stream, "~$%s", nds32_keyword_gpr[lsmwRe].name);
		      ifthe1st = 0;
		    }
		  if (lsmwEnb4 != 0)
		    {
		      /* $fp, $gp, $lp, $sp.  */
		      checkbit = 0x08;
		      for (i = 0; i < 4; i++)
			{
			  if (lsmwEnb4 & checkbit)
			    {
			      if (ifthe1st == 1)
				{
				  ifthe1st = 0;
				  func (stream, "$%s", nds32_keyword_gpr[28 + i].name);
				}
			      else
				func (stream, ", $%s", nds32_keyword_gpr[28 + i].name);
			    }
			  checkbit >>= 1;
			}
		    }
		  func (stream, "}");
		}
	      else if (pfd->hw_res == HW_INT)
		{
		  if (int_value < 10)
		    func (stream, "#%d", int_value);
		  else
		    func (stream, "#0x%x", int_value);
		}
	      else /* if (pfd->hw_res == HW_UINT).  */
		{
		  if (int_value < 10)
		    func (stream, "#%u", int_value);
		  else
		    func (stream, "#0x%x", int_value);
		}
	    }
	  break;

	case '{':
	case '}':
	  pstr_src++;
	  break;

	case ',':
	  func (stream, ", ");
	  pstr_src++;
	  break;
	  
	case '+':
	  func (stream, " + ");
	  pstr_src++;
	  break;
	  
	case '<':
	  if (pstr_src[1] == '<')
	    {
	      func (stream, " << ");
	      pstr_src += 2;
	    }
	  else
	    {
	      func (stream, " <");
	      pstr_src++;
	    }
	  break;
	  
	default:
	  func (stream, "%c", *pstr_src++);
	  break;
	}
    }
}

/* Filter instructions with some bits must be fixed.  */

static void
nds32_filter_unknown_insn (uint32_t insn, struct nds32_opcode **opc)
{
  if (!(*opc))
    return;

  switch ((*opc)->value)
    {
    case JREG (JR):
    case JREG (JRNEZ):
      /* jr jr.xtoff */
      if (__GF (insn, 6, 2) != 0 || __GF (insn, 15, 10) != 0)
        *opc = NULL;
      break;
    case MISC (STANDBY):
      if (__GF (insn, 7, 18) != 0)
        *opc = NULL;
      break;
    case SIMD (PBSAD):
    case SIMD (PBSADA):
      if (__GF (insn, 5, 5) != 0)
        *opc = NULL;
      break;
    case BR2 (SOP0):
      if (__GF (insn, 20, 5) != 0)
        *opc = NULL;
      break;
    case JREG (JRAL):
      if (__GF (insn, 5, 3) != 0 || __GF (insn, 15, 5) != 0)
        *opc = NULL;
      break;
    case ALU1 (NOR):
    case ALU1 (SLT):
    case ALU1 (SLTS):
    case ALU1 (SLLI):
    case ALU1 (SRLI):
    case ALU1 (SRAI):
    case ALU1 (ROTRI):
    case ALU1 (SLL):
    case ALU1 (SRL):
    case ALU1 (SRA):
    case ALU1 (ROTR):
    case ALU1 (SEB):
    case ALU1 (SEH):
    case ALU1 (ZEH):
    case ALU1 (WSBH):
    case ALU1 (SVA):
    case ALU1 (SVS):
    case ALU1 (CMOVZ):
    case ALU1 (CMOVN):
      if (__GF (insn, 5, 5) != 0)
        *opc = NULL;
      break;
    case MISC (IRET):
    case MISC (ISB):
    case MISC (DSB):
      if (__GF (insn, 5, 20) != 0)
        *opc = NULL;
      break;
    }
}

static void
print_insn32 (bfd_vma pc, disassemble_info *info, uint32_t insn,
	      uint32_t parse_mode)
{
  /* Get the final correct opcode and parse.  */
  struct nds32_opcode *opc;
  uint32_t opcode = nds32_mask_opcode (insn);
  opc = (struct nds32_opcode *) htab_find (opcode_htab, &opcode);

  nds32_special_opcode (insn, &opc);
  nds32_filter_unknown_insn (insn, &opc);
  nds32_parse_opcode (opc, pc, info, insn, parse_mode);
}

static void
print_insn16 (bfd_vma pc, disassemble_info *info,
	      uint32_t insn, uint32_t parse_mode)
{
  struct nds32_opcode *opc;
  uint32_t opcode;

  /* Get highest 7 bit in default.  */
  unsigned int mask = 0xfe00;

  /* Classify 16-bit instruction to 4 sets by bit 13 and 14.  */
  switch (__GF (insn, 13, 2))
    {
    case 0x0:
      /* mov55 movi55 */
      if (__GF (insn, 11, 2) == 0)
	{
	  mask = 0xfc00;
	  /* ifret16 = mov55 $sp, $sp*/
	  if (__GF (insn, 0, 11) == 0x3ff)
	    mask = 0xffff;
	}
      else if (__GF (insn, 9, 4) == 0xb)
	mask = 0xfe07;
      break;
    case 0x1:
      /* lwi37 swi37 */
      if (__GF (insn, 11, 2) == 0x3)
	mask = 0xf880;
      break;
    case 0x2:
      mask = 0xf800;
      /* Exclude beqz38, bnez38, beqs38, and bnes38.  */
      if (__GF (insn, 12, 1) == 0x1
	  && __GF (insn, 8, 3) == 0x5)
	{
	  if (__GF (insn, 11, 1) == 0x0)
	    mask = 0xff00;
	  else
	    mask = 0xffe0;
	}
      break;
    case 0x3:
      switch (__GF (insn, 11, 2))
	{
	case 0x1:
	  /* beqzs8 bnezs8 */
	  if (__GF (insn, 9, 2) == 0x0)
	    mask = 0xff00;
	  /* addi10s */
	  else if (__GF(insn, 10, 1) == 0x1)
	    mask = 0xfc00;
	  break;
	case 0x2:
	  /* lwi37.sp swi37.sp */
	  mask = 0xf880;
	  break;
	case 0x3:
	  if (__GF (insn, 8, 3) == 0x5)
	    mask = 0xff00;
	  else if (__GF (insn, 8, 3) == 0x4)
	    mask = 0xff80;
	  else if (__GF (insn, 9 , 2) == 0x3)
	    mask = 0xfe07;
	  break;
	}
      break;
    }
  opcode = insn & mask;
  opc = (struct nds32_opcode *) htab_find (opcode_htab, &opcode);

  nds32_special_opcode (insn, &opc);
  /* Get the final correct opcode and parse it.  */
  nds32_parse_opcode (opc, pc, info, insn, parse_mode);
}

static hashval_t
htab_hash_hash (const void *p)
{
  return (*(unsigned int *) p) % 49;
}

static int
htab_hash_eq (const void *p, const void *q)
{
  uint32_t pinsn = ((struct nds32_opcode *) p)->value;
  uint32_t qinsn = *((uint32_t *) q);

  return (pinsn == qinsn);
}

/* Get the format of instruction.  */

static uint32_t
nds32_mask_opcode (uint32_t insn)
{
  uint32_t opcode = N32_OP6 (insn);
  switch (opcode)
    {
    case N32_OP6_LBI:
    case N32_OP6_LHI:
    case N32_OP6_LWI:
    case N32_OP6_LDI:
    case N32_OP6_LBI_BI:
    case N32_OP6_LHI_BI:
    case N32_OP6_LWI_BI:
    case N32_OP6_LDI_BI:
    case N32_OP6_SBI:
    case N32_OP6_SHI:
    case N32_OP6_SWI:
    case N32_OP6_SDI:
    case N32_OP6_SBI_BI:
    case N32_OP6_SHI_BI:
    case N32_OP6_SWI_BI:
    case N32_OP6_SDI_BI:
    case N32_OP6_LBSI:
    case N32_OP6_LHSI:
    case N32_OP6_LWSI:
    case N32_OP6_LBSI_BI:
    case N32_OP6_LHSI_BI:
    case N32_OP6_LWSI_BI:
    case N32_OP6_MOVI:
    case N32_OP6_SETHI:
    case N32_OP6_ADDI:
    case N32_OP6_SUBRI:
    case N32_OP6_ANDI:
    case N32_OP6_XORI:
    case N32_OP6_ORI:
    case N32_OP6_SLTI:
    case N32_OP6_SLTSI:
    case N32_OP6_CEXT:
    case N32_OP6_BITCI:
      return MASK_OP (insn, 0);
    case N32_OP6_ALU2:
      /* FFBI */
      if (__GF (insn, 0, 7) == (N32_ALU2_FFBI | N32_BIT (6)))
	return MASK_OP (insn, 0x7f);
      else if (__GF (insn, 0, 7) == (N32_ALU2_MFUSR | N32_BIT (6))
	       || __GF (insn, 0, 7) == (N32_ALU2_MTUSR | N32_BIT (6)))
	/* RDOV CLROV */
	return MASK_OP (insn, 0xf81ff);
      else if (__GF (insn, 0, 10) == (N32_ALU2_ONEOP | N32_BIT (7)))
	{
	  /* INSB */
	  if (__GF (insn, 12, 3) == 4)
	    return MASK_OP (insn, 0x73ff);
	  return MASK_OP (insn, 0x7fff);
	}
      return MASK_OP (insn, 0x3ff);
    case N32_OP6_ALU1:
    case N32_OP6_SIMD:
      return MASK_OP (insn, 0x1f);
    case N32_OP6_MEM:
      return MASK_OP (insn, 0xff);
    case N32_OP6_JREG:
      return MASK_OP (insn, 0x7f);
    case N32_OP6_LSMW:
      return MASK_OP (insn, 0x23);
    case N32_OP6_SBGP:
    case N32_OP6_LBGP:
      return MASK_OP (insn, 0x1 << 19);
    case N32_OP6_HWGP:
      if (__GF (insn, 18, 2) == 0x3)
	return MASK_OP (insn, 0x7 << 17);
      return MASK_OP (insn, 0x3 << 18);
    case N32_OP6_DPREFI:
      return MASK_OP (insn, 0x1 << 24);
    case N32_OP6_LWC:
    case N32_OP6_SWC:
    case N32_OP6_LDC:
    case N32_OP6_SDC:
      return MASK_OP (insn, 0x1 << 12);
    case N32_OP6_JI:
      return MASK_OP (insn, 0x1 << 24);
    case N32_OP6_BR1:
      return MASK_OP (insn, 0x1 << 14);
    case N32_OP6_BR2:
      if (__GF (insn, 16, 4) == 0)
	return MASK_OP (insn, 0x1ff << 16);
      else
	return MASK_OP (insn, 0xf << 16);
    case N32_OP6_BR3:
      return MASK_OP (insn, 0x1 << 19);
    case N32_OP6_MISC:
      switch (__GF (insn, 0, 5))
	{
	case N32_MISC_MTSR:
	  /* SETGIE and SETEND  */
	  if (__GF (insn, 5, 5) == 0x1 || __GF (insn, 5, 5) == 0x2)
	    return MASK_OP (insn, 0x1fffff);
	  return MASK_OP (insn, 0x1f);
	case N32_MISC_TLBOP:
	  if (__GF (insn, 5, 5) == 5 || __GF (insn, 5, 5) == 7)
	    /* PB FLUA  */
	    return MASK_OP (insn, 0x3ff);
	  return MASK_OP (insn, 0x1f);
	default:
	  return MASK_OP (insn, 0x1f);
	}
    case N32_OP6_COP:
      if (__GF (insn, 4, 2) == 0)
	{
	  /* FPU */
	  switch (__GF (insn, 0, 4))
	    {
	    case 0x0:
	    case 0x8:
	      /* FS1/F2OP FD1/F2OP */
	      if (__GF (insn, 6, 4) == 0xf)
		return MASK_OP (insn, 0x7fff);
	      /* FS1 FD1 */
	      return MASK_OP (insn, 0x3ff);
	    case 0x4:
	    case 0xc:
	      /* FS2 */
	      return MASK_OP (insn, 0x3ff);
	    case 0x1:
	    case 0x9:
	      /* XR */
	      if (__GF (insn, 6, 4) == 0xc)
		return MASK_OP (insn, 0x7fff);
	      /* MFCP MTCP */
	      return MASK_OP (insn, 0x3ff);
	    default:
	      return MASK_OP (insn, 0xff);
	    }
	}
      else if  (__GF (insn, 0, 2) == 0)
	return MASK_OP (insn, 0xf);
      return MASK_OP (insn, 0xcf);
    case N32_OP6_AEXT:
      /* AUDIO */
      switch (__GF (insn, 23, 2))
	{
	case 0x0:
	  if (__GF (insn, 5, 4) == 0)
	    /* AMxxx AMAyyS AMyyS AMAWzS AMWzS */
	    return MASK_OP (insn, (0x1f << 20) | 0x1ff);
	  else if (__GF (insn, 5, 4) == 1)
	    /* ALR ASR ALA ASA AUPI */
	    return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
	  else if (__GF (insn, 20, 3) == 0 && __GF (insn, 6, 3) == 1)
	    /* ALR2 */
	    return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
	  else if (__GF (insn, 20 ,3) == 2 && __GF (insn, 6, 3) == 1)
	    /* AWEXT ASATS48 */
	    return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
	  else if (__GF (insn, 20 ,3) == 3 && __GF (insn, 6, 3) == 1)
	    /* AMTAR AMTAR2 AMFAR AMFAR2 */
	    return MASK_OP (insn, (0x1f << 20) | (0x1f << 5));
	  else if (__GF (insn, 7, 2) == 3)
	    /* AMxxxSA */
	    return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
	  else if (__GF (insn, 6, 3) == 2)
	    /* AMxxxL.S  */
	    return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
	  else
	    /* AmxxxL.l AmxxxL2.S AMxxxL2.L  */
	    return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
	case 0x1:
	  if (__GF (insn, 20, 3) == 0)
	    /* AADDL ASUBL */
	    return MASK_OP (insn, (0x1f << 20) | (0x1 << 5));
	  else if (__GF (insn, 20, 3) == 1)
	    /* AMTARI Ix AMTARI Mx */
	    return MASK_OP (insn, (0x1f << 20));
	  else if (__GF (insn, 6, 3) == 2)
	    /* AMAWzSl.S AMWzSl.S */
	    return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
	  else if (__GF (insn, 7, 2) == 3)
	    /* AMAWzSSA AMWzSSA */
	    return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
	  else
	    /* AMAWzSL.L AMAWzSL2.S AMAWzSL2.L
	       AMWzSL.L AMWzSL.L AMWzSL2.S */
	    return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
	case 0x2:
	  if (__GF (insn, 6, 3) == 2)
	    /* AMAyySl.S AMWyySl.S */
	    return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
	  else if (__GF (insn, 7, 2) == 3)
	    /* AMAWyySSA AMWyySSA */
	    return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
	  else
	    /* AMAWyySL.L AMAWyySL2.S AMAWyySL2.L
	       AMWyySL.L AMWyySL.L AMWyySL2.S */
	    return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
	}
      return MASK_OP (insn, 0x1f << 20);
    default:
      return 1u << 31;
    }
}

/* Define cctl subtype.  */
static char *cctl_subtype [] =
{
  /* 0x0 */
  "st0", "st0", "st0", "st2", "st2", "st3", "st3", "st4",
  "st1", "st1", "st1", "st0", "st0", NULL, NULL, "st5",
  /* 0x10 */
  "st0", NULL, NULL, "st2", "st2", "st3", "st3", NULL,
  "st1", NULL, NULL, "st0", "st0", NULL, NULL, NULL
};

/* Check the subset of opcode.  */

static void
nds32_special_opcode (uint32_t insn, struct nds32_opcode **opc)
{
  char *string = NULL;
  uint32_t op;

  if (!(*opc))
    return;

  /* Check if special case.  */
  switch ((*opc)->value)
    {
    case OP6 (LWC):
    case OP6 (SWC):
    case OP6 (LDC):
    case OP6 (SDC):
    case FPU_RA_IMMBI (LWC):
    case FPU_RA_IMMBI (SWC):
    case FPU_RA_IMMBI (LDC):
    case FPU_RA_IMMBI (SDC):
      /* Check if cp0 => FPU.  */
      if (__GF (insn, 13, 2) == 0)
      {
	while (!((*opc)->attr & ATTR (FPU)) && (*opc)->next)
	  *opc = (*opc)->next;
      }
      break;
    case ALU1 (ADD):
    case ALU1 (SUB):
    case ALU1 (AND):
    case ALU1 (XOR):
    case ALU1 (OR):
      /* Check if (add/add_slli) (sub/sub_slli) (and/and_slli).  */
      if (N32_SH5(insn) != 0)
        string = "sh";
      break;
    case ALU1 (SRLI):
      /* Check if nop.  */
      if (__GF (insn, 10, 15) == 0)
        string = "nop";
      break;
    case MISC (CCTL):
      string = cctl_subtype [__GF (insn, 5, 5)];
      break;
    case JREG (JR):
    case JREG (JRAL):
    case JREG (JR) | JREG_RET:
      if (__GF (insn, 8, 2) != 0)
	string = "tit";
      break;
    case N32_OP6_COP:
      break;
    case 0x9200:
      /* nop16 */
      if (__GF (insn, 0, 9) == 0)
	string = "nop16";
      break;
    }

  if (string)
    {
      while (strstr ((*opc)->opcode, string) == NULL
	     && strstr ((*opc)->instruction, string) == NULL && (*opc)->next)
	*opc = (*opc)->next;
      return;
    }

  /* Classify instruction is COP or FPU.  */
  op = N32_OP6 (insn);
  if (op == N32_OP6_COP && __GF (insn, 4, 2) != 0)
    {
      while (((*opc)->attr & ATTR (FPU)) != 0 && (*opc)->next)
	*opc = (*opc)->next;
    }
}

int
print_insn_nds32 (bfd_vma pc, disassemble_info *info)
{
  int status;
  bfd_byte buf[4];
  bfd_byte buf_data[16];
  uint64_t given;
  uint64_t given1;
  uint32_t insn;
  int n;
  int last_symbol_index = -1;
  bfd_vma addr;
  int is_data = false;
  bool found = false;
  struct nds32_private_data *private_data;
  unsigned int size;
  enum map_type mapping_type = MAP_CODE;

  if (info->private_data == NULL)
    {
      /* Note: remain lifecycle throughout whole execution.  */
      static struct nds32_private_data private;
      private.has_mapping_symbols = -1;	/* unknown yet.  */
      private.last_symbol_index = -1;
      private.last_addr = 0;
      info->private_data = &private;
    }
  private_data = info->private_data;

  if (info->symtab_size != 0)
    {
      int start;
      if (pc == 0)
	start = 0;
      else
	{
	  start = info->symtab_pos;
	  if (start < private_data->last_symbol_index)
	    start = private_data->last_symbol_index;
	}

      if (0 > start)
	start = 0;

      if (private_data->has_mapping_symbols != 0
	  && ((strncmp (".text", info->section->name, 5) == 0)))
	{
	  for (n = start; n < info->symtab_size; n++)
	    {
	      addr = bfd_asymbol_value (info->symtab[n]);
	      if (addr > pc)
		break;
	      if (get_mapping_symbol_type (info, n, &mapping_type))
		{
		  last_symbol_index = n;
		  found = true;
		}
	    }

	  if (found)
	    private_data->has_mapping_symbols = 1;
	  else if (!found && private_data->has_mapping_symbols == -1)
	    {
	      /* Make sure there are no any mapping symbol.  */
	      for (n = 0; n < info->symtab_size; n++)
		{
		  if (is_mapping_symbol (info, n, &mapping_type))
		    {
		      private_data->has_mapping_symbols = -1;
		      break;
		    }
		}
	      if (private_data->has_mapping_symbols == -1)
		private_data->has_mapping_symbols = 0;
	    }

	  private_data->last_symbol_index = last_symbol_index;
	  private_data->last_mapping_type = mapping_type;
	  is_data = (private_data->last_mapping_type == MAP_DATA0
		     || private_data->last_mapping_type == MAP_DATA1
		     || private_data->last_mapping_type == MAP_DATA2
		     || private_data->last_mapping_type == MAP_DATA3
		     || private_data->last_mapping_type == MAP_DATA4);
	}
    }

  /* Wonder data or instruction.  */
  if (is_data)
    {
      unsigned int i1;

      /* Fix corner case: there is no next mapping symbol,
	 let mapping type decides size */
      size = 16;
      if (last_symbol_index + 1 >= info->symtab_size)
	{
	  if (mapping_type == MAP_DATA0)
	    size = 1;
	  if (mapping_type == MAP_DATA1)
	    size = 2;
	  if (mapping_type == MAP_DATA2)
	    size = 4;
	  if (mapping_type == MAP_DATA3)
	    size = 8;
	  if (mapping_type == MAP_DATA4)
	    size = 16;
	}
      for (n = last_symbol_index + 1; n < info->symtab_size; n++)
	{
	  addr = bfd_asymbol_value (info->symtab[n]);

	  enum map_type fake_mapping_type;
	  if (get_mapping_symbol_type (info, n, &fake_mapping_type)
	      && (addr > pc
		  && ((info->section == NULL)
		      || (info->section == info->symtab[n]->section)))
	      && (addr - pc < size))
	    {
	      size = addr - pc;
	      break;
	    }
	}

      if (size == 3)
	size = (pc & 1) ? 1 : 2;

      /* Read bytes from BFD.  */
      info->read_memory_func (pc, buf_data, size, info);
      given = 0;
      given1 = 0;
      /* Start assembling data.  */
      /* Little endian of data.  */
      if (info->endian == BFD_ENDIAN_LITTLE)
	{
	  for (i1 = size - 1;; i1--)
	    {
	      if (i1 >= 8)
		given1 = buf_data[i1] | (given1 << 8);
	      else
		given = buf_data[i1] | (given << 8);

	      if (i1 == 0)
		break;
	    }
	}
      else
	{
	  /* Big endian of data.  */
	  for (i1 = 0; i1 < size; i1++)
	    {
	      if (i1 <= 7)
		given = buf_data[i1] | (given << 8);
	      else
		given1 = buf_data[i1] | (given1 << 8);
	    }
	}

      info->bytes_per_line = 4;

      if (size == 16)
	info->fprintf_func (info->stream, ".qword\t0x%016" PRIx64 "%016" PRIx64,
			    given, given1);
      else if (size == 8)
	info->fprintf_func (info->stream, ".dword\t0x%016" PRIx64, given);
      else if (size == 4)
	info->fprintf_func (info->stream, ".word\t0x%08" PRIx64, given);
      else if (size == 2)
	{
	  /* short */
	  if (mapping_type == MAP_DATA0)
	    info->fprintf_func (info->stream, ".byte\t0x%02" PRIx64,
				given & 0xFF);
	  else
	    info->fprintf_func (info->stream, ".short\t0x%04" PRIx64, given);
	}
      else
	{
	  /* byte */
	  info->fprintf_func (info->stream, ".byte\t0x%02" PRIx64, given);
	}

      return size;
    }

  size = 4;
  status = info->read_memory_func (pc, buf, 4, info);
  if (status)
    {
      /* For the last 16-bit instruction.  */
      size = 2;
      status = info->read_memory_func (pc, buf, 2, info);
      if (status)
	{
	  (*info->memory_error_func) (status, pc, info);
	  return -1;
	}
      buf[2] = 0;
      buf[3] = 0;
    }

  insn = bfd_getb32 (buf);
  /* 16-bit instruction.  */
  if (insn & 0x80000000)
    {
      print_insn16 (pc, info, (insn >> 16), NDS32_PARSE_INSN16);
      return 2;
    }

  /* 32-bit instructions.  */
  if (size == 4)
    print_insn32 (pc, info, insn, NDS32_PARSE_INSN32);
  else
    info->fprintf_func (info->stream,
			_("insufficient data to decode instruction"));
  return 4;
}

/* Ignore disassembling unnecessary name.  */

static bool
nds32_symbol_is_valid (asymbol *sym,
		       struct disassemble_info *info ATTRIBUTE_UNUSED)
{
  const char *name;

  if (sym == NULL)
    return false;

  name = bfd_asymbol_name (sym);

  /* Mapping symbol is invalid.  */
  if (name[0] == '$')
    return false;
  return true;
}

static void
nds32_add_opcode_hash_table (unsigned indx)
{
  opcode_t *opc;

  opc = nds32_opcode_table[indx];
  if (opc == NULL)
    return;

  while (opc->opcode != NULL)
    {
      opcode_t **slot;

      slot = (opcode_t **) htab_find_slot
	(opcode_htab, &opc->value, INSERT);
      if (*slot == NULL)
	{
	  /* This is the new one.  */
	  *slot = opc;
	}
      else
	{
	  opcode_t *tmp;

	  /* Already exists.  Append to the list.  */
	  tmp = *slot;
	  while (tmp->next)
	    tmp = tmp->next;
	  tmp->next = opc;
	  opc->next = NULL;
	}
      opc++;
    }
}

void
disassemble_init_nds32 (struct disassemble_info *info)
{
  static unsigned init_done = 0;
  unsigned k;

  /* Set up symbol checking function.  */
  info->symbol_is_valid = nds32_symbol_is_valid;

  /* Only need to initialize once:
     High level will call this function for every object file.
     For example, when disassemble all members of a library.  */
  if (init_done)
    return;

  /* Setup main core.  */
  nds32_keyword_table[NDS32_MAIN_CORE] = &nds32_keywords[0];
  nds32_opcode_table[NDS32_MAIN_CORE] = &nds32_opcodes[0];
  nds32_field_table[NDS32_MAIN_CORE] = &nds32_operand_fields[0];

  /* Build opcode table.  */
  opcode_htab = htab_create_alloc (1024, htab_hash_hash, htab_hash_eq,
				   NULL, xcalloc, free);

  for (k = 0; k < NDS32_CORE_COUNT; k++)
    {
      /* Add op-codes.  */
      nds32_add_opcode_hash_table (k);
    }

  init_done = 1;
}

static int
is_mapping_symbol (struct disassemble_info *info, int n,
		   enum map_type *map_type)
{
  const char *name = NULL;

  /* Get symbol name.  */
  name = bfd_asymbol_name (info->symtab[n]);

  if (name[1] == 'c')
    {
      *map_type = MAP_CODE;
      return true;
    }
  else if (name[1] == 'd' && name[2] == '0')
    {
      *map_type = MAP_DATA0;
      return true;
    }
  else if (name[1] == 'd' && name[2] == '1')
    {
      *map_type = MAP_DATA1;
      return true;
    }
  else if (name[1] == 'd' && name[2] == '2')
    {
      *map_type = MAP_DATA2;
      return true;
    }
  else if (name[1] == 'd' && name[2] == '3')
    {
      *map_type = MAP_DATA3;
      return true;
    }
  else if (name[1] == 'd' && name[2] == '4')
    {
      *map_type = MAP_DATA4;
      return true;
    }

  return false;
}

static int
get_mapping_symbol_type (struct disassemble_info *info, int n,
			 enum map_type *map_type)
{
  /* If the symbol is in a different section, ignore it.  */
  if (info->section != NULL
      && info->section != info->symtab[n]->section)
    return false;

  return is_mapping_symbol (info, n, map_type);
}
