/* Target-dependent code for the NDS32 architecture, for GDB.

   Copyright (C) 2013-2016 Free Software Foundation, Inc.
   Contributed by Andes Technology Corporation.

   This file is part of GDB.

   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, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "frame.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "gdbcore.h"
#include "value.h"
#include "reggroups.h"
#include "inferior.h"
#include "osabi.h"
#include "arch-utils.h"
#include "regcache.h"
#include "dis-asm.h"
#include "user-regs.h"
#include "elf-bfd.h"
#include "dwarf2-frame.h"
#include "remote.h"
#include "target-descriptions.h"

#include "nds32-tdep.h"
#include "elf/nds32.h"
#include "opcode/nds32.h"
#include "features/nds32.c"

/* Simple macros for instruction analysis.  */
#define CHOP_BITS(insn, n)	(insn & ~__MASK (n))
#define N32_LSMW_ENABLE4(insn)	(((insn) >> 6) & 0xf)
#define N32_SMW_ADM \
	N32_TYPE4 (LSMW, 0, 0, 0, 1, (N32_LSMW_ADM << 2) | N32_LSMW_LSMW)
#define N32_LMW_BIM \
	N32_TYPE4 (LSMW, 0, 0, 0, 0, (N32_LSMW_BIM << 2) | N32_LSMW_LSMW)
#define N32_FLDI_SP \
	N32_TYPE2 (LDC, 0, REG_SP, 0)

extern void _initialize_nds32_tdep (void);

/* Use an invalid address value as 'not available' marker.  */
enum { REG_UNAVAIL = (CORE_ADDR) -1 };

/* Use an impossible value as invalid offset.  */
enum { INVALID_OFFSET = (CORE_ADDR) -1 };

/* Instruction groups for NDS32 epilogue analysis.  */
enum
{
  /* Instructions used everywhere, not only in epilogue.  */
  INSN_NORMAL,
  /* Instructions used to reset sp for local vars, arguments, etc.  */
  INSN_RESET_SP,
  /* Instructions used to recover saved regs and to recover padding.  */
  INSN_RECOVER,
  /* Instructions used to return to the caller.  */
  INSN_RETURN,
  /* Instructions used to recover saved regs and to return to the caller.  */
  INSN_RECOVER_RETURN,
};

static const char *const nds32_register_names[] =
{
  /* 32 GPRs.  */
  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
  "r24", "r25", "r26", "r27", "fp", "gp", "lp", "sp",
  /* PC.  */
  "pc",
};

static const char *const nds32_fdr_register_names[] =
{
  "fd0", "fd1", "fd2", "fd3", "fd4", "fd5", "fd6", "fd7",
  "fd8", "fd9", "fd10", "fd11", "fd12", "fd13", "fd14", "fd15",
  "fd16", "fd17", "fd18", "fd19", "fd20", "fd21", "fd22", "fd23",
  "fd24", "fd25", "fd26", "fd27", "fd28", "fd29", "fd30", "fd31"
};

static const char *const nds32_fsr_register_names[] =
{
  "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
  "fs8", "fs9", "fs10", "fs11", "fs12", "fs13", "fs14", "fs15",
  "fs16", "fs17", "fs18", "fs19", "fs20", "fs21", "fs22", "fs23",
  "fs24", "fs25", "fs26", "fs27", "fs28", "fs29", "fs30", "fs31"
};

/* The number of registers for four FPU configuration options.  */
const int num_fdr_map[] = { 4, 8, 16, 32 };
const int num_fsr_map[] = { 8, 16, 32, 32 };

/* Aliases for registers.  */
static const struct
{
  const char *name;
  const char *alias;
} nds32_register_aliases[] =
{
  {"r15", "ta"},
  {"r26", "p0"},
  {"r27", "p1"},
  {"fp", "r28"},
  {"gp", "r29"},
  {"lp", "r30"},
  {"sp", "r31"},

  {"cr0", "cpu_ver"},
  {"cr1", "icm_cfg"},
  {"cr2", "dcm_cfg"},
  {"cr3", "mmu_cfg"},
  {"cr4", "msc_cfg"},
  {"cr5", "core_id"},
  {"cr6", "fucop_exist"},
  {"cr7", "msc_cfg2"},

  {"ir0", "psw"},
  {"ir1", "ipsw"},
  {"ir2", "p_psw"},
  {"ir3", "ivb"},
  {"ir4", "eva"},
  {"ir5", "p_eva"},
  {"ir6", "itype"},
  {"ir7", "p_itype"},
  {"ir8", "merr"},
  {"ir9", "ipc"},
  {"ir10", "p_ipc"},
  {"ir11", "oipc"},
  {"ir12", "p_p0"},
  {"ir13", "p_p1"},
  {"ir14", "int_mask"},
  {"ir15", "int_pend"},
  {"ir16", "sp_usr"},
  {"ir17", "sp_priv"},
  {"ir18", "int_pri"},
  {"ir19", "int_ctrl"},
  {"ir20", "sp_usr1"},
  {"ir21", "sp_priv1"},
  {"ir22", "sp_usr2"},
  {"ir23", "sp_priv2"},
  {"ir24", "sp_usr3"},
  {"ir25", "sp_priv3"},
  {"ir26", "int_mask2"},
  {"ir27", "int_pend2"},
  {"ir28", "int_pri2"},
  {"ir29", "int_trigger"},

  {"mr0", "mmu_ctl"},
  {"mr1", "l1_pptb"},
  {"mr2", "tlb_vpn"},
  {"mr3", "tlb_data"},
  {"mr4", "tlb_misc"},
  {"mr5", "vlpt_idx"},
  {"mr6", "ilmb"},
  {"mr7", "dlmb"},
  {"mr8", "cache_ctl"},
  {"mr9", "hsmp_saddr"},
  {"mr10", "hsmp_eaddr"},
  {"mr11", "bg_region"},

  {"dr0", "bpc0"},
  {"dr1", "bpc1"},
  {"dr2", "bpc2"},
  {"dr3", "bpc3"},
  {"dr4", "bpc4"},
  {"dr5", "bpc5"},
  {"dr6", "bpc6"},
  {"dr7", "bpc7"},
  {"dr8", "bpa0"},
  {"dr9", "bpa1"},
  {"dr10", "bpa2"},
  {"dr11", "bpa3"},
  {"dr12", "bpa4"},
  {"dr13", "bpa5"},
  {"dr14", "bpa6"},
  {"dr15", "bpa7"},
  {"dr16", "bpam0"},
  {"dr17", "bpam1"},
  {"dr18", "bpam2"},
  {"dr19", "bpam3"},
  {"dr20", "bpam4"},
  {"dr21", "bpam5"},
  {"dr22", "bpam6"},
  {"dr23", "bpam7"},
  {"dr24", "bpv0"},
  {"dr25", "bpv1"},
  {"dr26", "bpv2"},
  {"dr27", "bpv3"},
  {"dr28", "bpv4"},
  {"dr29", "bpv5"},
  {"dr30", "bpv6"},
  {"dr31", "bpv7"},
  {"dr32", "bpcid0"},
  {"dr33", "bpcid1"},
  {"dr34", "bpcid2"},
  {"dr35", "bpcid3"},
  {"dr36", "bpcid4"},
  {"dr37", "bpcid5"},
  {"dr38", "bpcid6"},
  {"dr39", "bpcid7"},
  {"dr40", "edm_cfg"},
  {"dr41", "edmsw"},
  {"dr42", "edm_ctl"},
  {"dr43", "edm_dtr"},
  {"dr44", "bpmtc"},
  {"dr45", "dimbr"},
  {"dr46", "tecr0"},
  {"dr47", "tecr1"},

  {"hspr0", "hsp_ctl"},
  {"hspr1", "sp_bound"},
  {"hspr2", "sp_bound_priv"},

  {"pfr0", "pfmc0"},
  {"pfr1", "pfmc1"},
  {"pfr2", "pfmc2"},
  {"pfr3", "pfm_ctl"},
  {"pfr4", "pft_ctl"},

  {"dmar0", "dma_cfg"},
  {"dmar1", "dma_gcsw"},
  {"dmar2", "dma_chnsel"},
  {"dmar3", "dma_act"},
  {"dmar4", "dma_setup"},
  {"dmar5", "dma_isaddr"},
  {"dmar6", "dma_esaddr"},
  {"dmar7", "dma_tcnt"},
  {"dmar8", "dma_status"},
  {"dmar9", "dma_2dset"},
  {"dmar10", "dma_2dsctl"},
  {"dmar11", "dma_rcnt"},
  {"dmar12", "dma_hstatus"},

  {"racr0", "prusr_acc_ctl"},
  {"fucpr", "fucop_ctl"},

  {"idr0", "sdz_ctl"},
  {"idr1", "misc_ctl"},
  {"idr2", "ecc_misc"},

  {"secur0", "sfcr"},
  {"secur1", "sign"},
  {"secur2", "isign"},
  {"secur3", "p_isign"},
};

/* Value of a register alias.  BATON is the regnum of the corresponding
   register.  */

static struct value *
value_of_nds32_reg (struct frame_info *frame, const void *baton)
{
  return value_of_register ((int) (intptr_t) baton, frame);
}

/* Implement the "frame_align" gdbarch method.  */

static CORE_ADDR
nds32_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
{
  /* 8-byte aligned.  */
  return align_down (sp, 8);
}

/* Implement the "breakpoint_from_pc" gdbarch method.

   Use the program counter to determine the contents and size of a
   breakpoint instruction.  Return a pointer to a string of bytes that
   encode a breakpoint instruction, store the length of the string in
   *LENPTR and optionally adjust *PCPTR to point to the correct memory
   location for inserting the breakpoint.  */

static const gdb_byte *
nds32_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
			  int *lenptr)
{
  /* The same insn machine code is used for little-endian and big-endian.  */
  static const gdb_byte break_insn[] = { 0xEA, 0x00 };

  *lenptr = sizeof (break_insn);
  return break_insn;
}

/* Implement the "dwarf2_reg_to_regnum" gdbarch method.  */

static int
nds32_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  const int FSR = 38;
  const int FDR = FSR + 32;

  if (num >= 0 && num < 32)
    {
      /* General-purpose registers (R0 - R31).  */
      return num;
    }
  else if (num >= FSR && num < FSR + 32)
    {
      /* Single precision floating-point registers (FS0 - FS31).  */
      return num - FSR + tdep->fs0_regnum;
    }
  else if (num >= FDR && num < FDR + 32)
    {
      /* Double precision floating-point registers (FD0 - FD31).  */
      return num - FDR + NDS32_FD0_REGNUM;
    }

  /* No match, return a inaccessible register number.  */
  return -1;
}

/* NDS32 register groups.  */
static struct reggroup *nds32_cr_reggroup;
static struct reggroup *nds32_ir_reggroup;
static struct reggroup *nds32_mr_reggroup;
static struct reggroup *nds32_dr_reggroup;
static struct reggroup *nds32_pfr_reggroup;
static struct reggroup *nds32_hspr_reggroup;
static struct reggroup *nds32_dmar_reggroup;
static struct reggroup *nds32_racr_reggroup;
static struct reggroup *nds32_idr_reggroup;
static struct reggroup *nds32_secur_reggroup;

static void
nds32_init_reggroups (void)
{
  nds32_cr_reggroup = reggroup_new ("cr", USER_REGGROUP);
  nds32_ir_reggroup = reggroup_new ("ir", USER_REGGROUP);
  nds32_mr_reggroup = reggroup_new ("mr", USER_REGGROUP);
  nds32_dr_reggroup = reggroup_new ("dr", USER_REGGROUP);
  nds32_pfr_reggroup = reggroup_new ("pfr", USER_REGGROUP);
  nds32_hspr_reggroup = reggroup_new ("hspr", USER_REGGROUP);
  nds32_dmar_reggroup = reggroup_new ("dmar", USER_REGGROUP);
  nds32_racr_reggroup = reggroup_new ("racr", USER_REGGROUP);
  nds32_idr_reggroup = reggroup_new ("idr", USER_REGGROUP);
  nds32_secur_reggroup = reggroup_new ("secur", USER_REGGROUP);
}

static void
nds32_add_reggroups (struct gdbarch *gdbarch)
{
  /* Add pre-defined register groups.  */
  reggroup_add (gdbarch, general_reggroup);
  reggroup_add (gdbarch, float_reggroup);
  reggroup_add (gdbarch, system_reggroup);
  reggroup_add (gdbarch, all_reggroup);
  reggroup_add (gdbarch, save_reggroup);
  reggroup_add (gdbarch, restore_reggroup);

  /* Add NDS32 register groups.  */
  reggroup_add (gdbarch, nds32_cr_reggroup);
  reggroup_add (gdbarch, nds32_ir_reggroup);
  reggroup_add (gdbarch, nds32_mr_reggroup);
  reggroup_add (gdbarch, nds32_dr_reggroup);
  reggroup_add (gdbarch, nds32_pfr_reggroup);
  reggroup_add (gdbarch, nds32_hspr_reggroup);
  reggroup_add (gdbarch, nds32_dmar_reggroup);
  reggroup_add (gdbarch, nds32_racr_reggroup);
  reggroup_add (gdbarch, nds32_idr_reggroup);
  reggroup_add (gdbarch, nds32_secur_reggroup);
}

/* Implement the "register_reggroup_p" gdbarch method.  */

static int
nds32_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
			   struct reggroup *reggroup)
{
  const char *reg_name;
  const char *group_name;
  int ret;

  if (reggroup == all_reggroup)
    return 1;

  /* General reggroup contains only GPRs and PC.  */
  if (reggroup == general_reggroup)
    return regnum <= NDS32_PC_REGNUM;

  if (reggroup == float_reggroup || reggroup == save_reggroup
      || reggroup == restore_reggroup)
    {
      ret = tdesc_register_in_reggroup_p (gdbarch, regnum, reggroup);
      if (ret != -1)
	return ret;

      return default_register_reggroup_p (gdbarch, regnum, reggroup);
    }

  if (reggroup == system_reggroup)
    return (regnum > NDS32_PC_REGNUM)
	    && !nds32_register_reggroup_p (gdbarch, regnum, float_reggroup);

  /* The NDS32 reggroup contains registers whose name is prefixed
     by reggroup name.  */
  reg_name = gdbarch_register_name (gdbarch, regnum);
  group_name = reggroup_name (reggroup);
  return !strncmp (reg_name, group_name, strlen (group_name));
}

/* Implement the "pseudo_register_type" tdesc_arch_data method.  */

static struct type *
nds32_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
{
  regnum -= gdbarch_num_regs (gdbarch);

  /* Currently, only FSRs could be defined as pseudo registers.  */
  if (regnum < gdbarch_num_pseudo_regs (gdbarch))
    return arch_float_type (gdbarch, -1, "builtin_type_ieee_single",
			    floatformats_ieee_single);

  warning (_("Unknown nds32 pseudo register %d."), regnum);
  return NULL;
}

/* Implement the "pseudo_register_name" tdesc_arch_data method.  */

static const char *
nds32_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
{
  regnum -= gdbarch_num_regs (gdbarch);

  /* Currently, only FSRs could be defined as pseudo registers.  */
  if (regnum < gdbarch_num_pseudo_regs (gdbarch))
    return nds32_fsr_register_names[regnum];

  warning (_("Unknown nds32 pseudo register %d."), regnum);
  return NULL;
}

/* Implement the "pseudo_register_read" gdbarch method.  */

static enum register_status
nds32_pseudo_register_read (struct gdbarch *gdbarch,
			    struct regcache *regcache, int regnum,
			    gdb_byte *buf)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  gdb_byte reg_buf[8];
  int offset, fdr_regnum;
  enum register_status status = REG_UNKNOWN;

  /* Sanity check.  */
  if (tdep->fpu_freg == -1 || tdep->use_pseudo_fsrs == 0)
    return status;

  regnum -= gdbarch_num_regs (gdbarch);

  /* Currently, only FSRs could be defined as pseudo registers.  */
  if (regnum < gdbarch_num_pseudo_regs (gdbarch))
    {
      /* fs0 is always the most significant half of fd0.  */
      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	offset = (regnum & 1) ? 4 : 0;
      else
	offset = (regnum & 1) ? 0 : 4;

      fdr_regnum = NDS32_FD0_REGNUM + (regnum >> 1);
      status = regcache_raw_read (regcache, fdr_regnum, reg_buf);
      if (status == REG_VALID)
	memcpy (buf, reg_buf + offset, 4);
    }

  return status;
}

/* Implement the "pseudo_register_write" gdbarch method.  */

static void
nds32_pseudo_register_write (struct gdbarch *gdbarch,
			     struct regcache *regcache, int regnum,
			     const gdb_byte *buf)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  gdb_byte reg_buf[8];
  int offset, fdr_regnum;

  /* Sanity check.  */
  if (tdep->fpu_freg == -1 || tdep->use_pseudo_fsrs == 0)
    return;

  regnum -= gdbarch_num_regs (gdbarch);

  /* Currently, only FSRs could be defined as pseudo registers.  */
  if (regnum < gdbarch_num_pseudo_regs (gdbarch))
    {
      /* fs0 is always the most significant half of fd0.  */
      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	offset = (regnum & 1) ? 4 : 0;
      else
	offset = (regnum & 1) ? 0 : 4;

      fdr_regnum = NDS32_FD0_REGNUM + (regnum >> 1);
      regcache_raw_read (regcache, fdr_regnum, reg_buf);
      memcpy (reg_buf + offset, buf, 4);
      regcache_raw_write (regcache, fdr_regnum, reg_buf);
    }
}

/* Helper function for NDS32 ABI.  Return true if FPRs can be used
   to pass function arguments and return value.  */

static int
nds32_abi_use_fpr (int elf_abi)
{
  return elf_abi == E_NDS_ABI_V2FP_PLUS;
}

/* Helper function for NDS32 ABI.  Return true if GPRs and stack
   can be used together to pass an argument.  */

static int
nds32_abi_split (int elf_abi)
{
  return elf_abi == E_NDS_ABI_AABI;
}

#define NDS32_NUM_SAVED_REGS (NDS32_LP_REGNUM + 1)

struct nds32_frame_cache
{
  /* The previous frame's inner most stack address.  Used as this
     frame ID's stack_addr.  */
  CORE_ADDR prev_sp;

  /* The frame's base, optionally used by the high-level debug info.  */
  CORE_ADDR base;

  /* During prologue analysis, keep how far the SP and FP have been offset
     from the start of the stack frame (as defined by the previous frame's
     stack pointer).
     During epilogue analysis, keep how far the SP has been offset from the
     current stack pointer.  */
  CORE_ADDR sp_offset;
  CORE_ADDR fp_offset;

  /* The address of the first instruction in this function.  */
  CORE_ADDR pc;

  /* Saved registers.  */
  CORE_ADDR saved_regs[NDS32_NUM_SAVED_REGS];
};

/* Allocate and initialize a frame cache.  */

static struct nds32_frame_cache *
nds32_alloc_frame_cache (void)
{
  struct nds32_frame_cache *cache;
  int i;

  cache = FRAME_OBSTACK_ZALLOC (struct nds32_frame_cache);

  /* Initialize fp_offset to check if FP is set in prologue.  */
  cache->fp_offset = INVALID_OFFSET;

  /* Saved registers.  We initialize these to -1 since zero is a valid
     offset.  */
  for (i = 0; i < NDS32_NUM_SAVED_REGS; i++)
    cache->saved_regs[i] = REG_UNAVAIL;

  return cache;
}

/* Helper function for instructions used to push multiple words.  */

static void
nds32_push_multiple_words (struct nds32_frame_cache *cache, int rb, int re,
			   int enable4)
{
  CORE_ADDR sp_offset = cache->sp_offset;
  int i;

  /* Check LP, GP, FP in enable4.  */
  for (i = 1; i <= 3; i++)
    {
      if ((enable4 >> i) & 0x1)
	{
	  sp_offset += 4;
	  cache->saved_regs[NDS32_SP_REGNUM - i] = sp_offset;
	}
    }

  /* Skip case where re == rb == sp.  */
  if ((rb < REG_FP) && (re < REG_FP))
    {
      for (i = re; i >= rb; i--)
	{
	  sp_offset += 4;
	  cache->saved_regs[i] = sp_offset;
	}
    }

  /* For sp, update the offset.  */
  cache->sp_offset = sp_offset;
}

/* Analyze the instructions within the given address range.  If CACHE
   is non-NULL, fill it in.  Return the first address beyond the given
   address range.  If CACHE is NULL, return the first address not
   recognized as a prologue instruction.  */

static CORE_ADDR
nds32_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
			CORE_ADDR limit_pc, struct nds32_frame_cache *cache)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  int abi_use_fpr = nds32_abi_use_fpr (tdep->elf_abi);
  /* Current scanning status.  */
  int in_prologue_bb = 0;
  int val_ta = 0;
  uint32_t insn, insn_len;

  for (; pc < limit_pc; pc += insn_len)
    {
      insn = read_memory_unsigned_integer (pc, 4, BFD_ENDIAN_BIG);

      if ((insn & 0x80000000) == 0)
	{
	  /* 32-bit instruction */
	  insn_len = 4;

	  if (CHOP_BITS (insn, 15) == N32_TYPE2 (ADDI, REG_SP, REG_SP, 0))
	    {
	      /* addi $sp, $sp, imm15s */
	      int imm15s = N32_IMM15S (insn);

	      if (imm15s < 0)
		{
		  if (cache != NULL)
		    cache->sp_offset += -imm15s;

		  in_prologue_bb = 1;
		  continue;
		}
	    }
	  else if (CHOP_BITS (insn, 15) == N32_TYPE2 (ADDI, REG_FP, REG_SP, 0))
	    {
	      /* addi $fp, $sp, imm15s */
	      int imm15s = N32_IMM15S (insn);

	      if (imm15s > 0)
		{
		  if (cache != NULL)
		    cache->fp_offset = cache->sp_offset - imm15s;

		  in_prologue_bb = 1;
		  continue;
		}
	    }
	  else if ((insn & ~(__MASK (19) << 6)) == N32_SMW_ADM
		   && N32_RA5 (insn) == REG_SP)
	    {
	      /* smw.adm Rb, [$sp], Re, enable4 */
	      if (cache != NULL)
		nds32_push_multiple_words (cache, N32_RT5 (insn),
					   N32_RB5 (insn),
					   N32_LSMW_ENABLE4 (insn));
	      in_prologue_bb = 1;
	      continue;
	    }
	  else if (insn == N32_ALU1 (ADD, REG_SP, REG_SP, REG_TA)
		   || insn == N32_ALU1 (ADD, REG_SP, REG_TA, REG_SP))
	    {
	      /* add $sp, $sp, $ta */
	      /* add $sp, $ta, $sp */
	      if (val_ta < 0)
		{
		  if (cache != NULL)
		    cache->sp_offset += -val_ta;

		  in_prologue_bb = 1;
		  continue;
		}
	    }
	  else if (CHOP_BITS (insn, 20) == N32_TYPE1 (MOVI, REG_TA, 0))
	    {
	      /* movi $ta, imm20s */
	      if (cache != NULL)
		val_ta = N32_IMM20S (insn);

	      continue;
	    }
	  else if (CHOP_BITS (insn, 20) == N32_TYPE1 (SETHI, REG_TA, 0))
	    {
	      /* sethi $ta, imm20u */
	      if (cache != NULL)
		val_ta = N32_IMM20U (insn) << 12;

	      continue;
	    }
	  else if (CHOP_BITS (insn, 15) == N32_TYPE2 (ORI, REG_TA, REG_TA, 0))
	    {
	      /* ori $ta, $ta, imm15u */
	      if (cache != NULL)
		val_ta |= N32_IMM15U (insn);

	      continue;
	    }
	  else if (CHOP_BITS (insn, 15) == N32_TYPE2 (ADDI, REG_TA, REG_TA, 0))
	    {
	      /* addi $ta, $ta, imm15s */
	      if (cache != NULL)
		val_ta += N32_IMM15S (insn);

	      continue;
	    }
	  if (insn == N32_ALU1 (ADD, REG_GP, REG_TA, REG_GP)
	      || insn == N32_ALU1 (ADD, REG_GP, REG_GP, REG_TA))
	    {
	      /* add $gp, $ta, $gp */
	      /* add $gp, $gp, $ta */
	      in_prologue_bb = 1;
	      continue;
	    }
	  else if (CHOP_BITS (insn, 20) == N32_TYPE1 (MOVI, REG_GP, 0))
	    {
	      /* movi $gp, imm20s */
	      in_prologue_bb = 1;
	      continue;
	    }
	  else if (CHOP_BITS (insn, 20) == N32_TYPE1 (SETHI, REG_GP, 0))
	    {
	      /* sethi $gp, imm20u */
	      in_prologue_bb = 1;
	      continue;
	    }
	  else if (CHOP_BITS (insn, 15) == N32_TYPE2 (ORI, REG_GP, REG_GP, 0))
	    {
	      /* ori $gp, $gp, imm15u */
	      in_prologue_bb = 1;
	      continue;
	    }
	  else
	    {
	      /* Jump/Branch insns never appear in prologue basic block.
		 The loop can be escaped early when these insns are met.  */
	      if (in_prologue_bb == 1)
		{
		  int op = N32_OP6 (insn);

		  if (op == N32_OP6_JI
		      || op == N32_OP6_JREG
		      || op == N32_OP6_BR1
		      || op == N32_OP6_BR2
		      || op == N32_OP6_BR3)
		    break;
		}
	    }

	  if (abi_use_fpr && N32_OP6 (insn) == N32_OP6_SDC
	      && __GF (insn, 12, 3) == 0)
	    {
	      /* For FPU insns, CP (bit [13:14]) should be CP0,  and only
		 normal form (bit [12] == 0) is used.  */

	      /* fsdi FDt, [$sp + (imm12s << 2)] */
	      if (N32_RA5 (insn) == REG_SP)
		continue;
	    }

	  /* The optimizer might shove anything into the prologue, if
	     we build up cache (cache != NULL) from analyzing prologue,
	     we just skip what we don't recognize and analyze further to
	     make cache as complete as possible.  However, if we skip
	     prologue, we'll stop immediately on unrecognized
	     instruction.  */
	  if (cache == NULL)
	    break;
	}
      else
	{
	  /* 16-bit instruction */
	  insn_len = 2;

	  insn >>= 16;

	  if (CHOP_BITS (insn, 10) == N16_TYPE10 (ADDI10S, 0))
	    {
	      /* addi10s.sp */
	      int imm10s = N16_IMM10S (insn);

	      if (imm10s < 0)
		{
		  if (cache != NULL)
		    cache->sp_offset += -imm10s;

		  in_prologue_bb = 1;
		  continue;
		}
	    }
	  else if (__GF (insn, 7, 8) == N16_T25_PUSH25)
	    {
	      /* push25 */
	      if (cache != NULL)
		{
		  int imm8u = (insn & 0x1f) << 3;
		  int re = (insn >> 5) & 0x3;
		  const int reg_map[] = { 6, 8, 10, 14 };

		  /* Operation 1 -- smw.adm R6, [$sp], Re, #0xe */
		  nds32_push_multiple_words (cache, 6, reg_map[re], 0xe);

		  /* Operation 2 -- sp = sp - (imm5u << 3) */
		  cache->sp_offset += imm8u;
		}

	      in_prologue_bb = 1;
	      continue;
	    }
	  else if (insn == N16_TYPE5 (ADD5PC, REG_GP))
	    {
	      /* add5.pc $gp */
	      in_prologue_bb = 1;
	      continue;
	    }
	  else if (CHOP_BITS (insn, 5) == N16_TYPE55 (MOVI55, REG_GP, 0))
	    {
	      /* movi55 $gp, imm5s */
	      in_prologue_bb = 1;
	      continue;
	    }
	  else
	    {
	      /* Jump/Branch insns never appear in prologue basic block.
		 The loop can be escaped early when these insns are met.  */
	      if (in_prologue_bb == 1)
		{
		  uint32_t insn5 = CHOP_BITS (insn, 5);
		  uint32_t insn8 = CHOP_BITS (insn, 8);
		  uint32_t insn38 = CHOP_BITS (insn, 11);

		  if (insn5 == N16_TYPE5 (JR5, 0)
		      || insn5 == N16_TYPE5 (JRAL5, 0)
		      || insn5 == N16_TYPE5 (RET5, 0)
		      || insn8 == N16_TYPE8 (J8, 0)
		      || insn8 == N16_TYPE8 (BEQZS8, 0)
		      || insn8 == N16_TYPE8 (BNEZS8, 0)
		      || insn38 == N16_TYPE38 (BEQZ38, 0, 0)
		      || insn38 == N16_TYPE38 (BNEZ38, 0, 0)
		      || insn38 == N16_TYPE38 (BEQS38, 0, 0)
		      || insn38 == N16_TYPE38 (BNES38, 0, 0))
		    break;
		}
	    }

	  /* The optimizer might shove anything into the prologue, if
	     we build up cache (cache != NULL) from analyzing prologue,
	     we just skip what we don't recognize and analyze further to
	     make cache as complete as possible.  However, if we skip
	     prologue, we'll stop immediately on unrecognized
	     instruction.  */
	  if (cache == NULL)
	    break;
	}
    }

  return pc;
}

/* Implement the "skip_prologue" gdbarch method.

   Find the end of function prologue.  */

static CORE_ADDR
nds32_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR func_addr, limit_pc;

  /* See if we can determine the end of the prologue via the symbol table.
     If so, then return either PC, or the PC after the prologue, whichever
     is greater.  */
  if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
    {
      CORE_ADDR post_prologue_pc
	= skip_prologue_using_sal (gdbarch, func_addr);
      if (post_prologue_pc != 0)
	return max (pc, post_prologue_pc);
    }

  /* Can't determine prologue from the symbol table, need to examine
     instructions.  */

  /* Find an upper limit on the function prologue using the debug
     information.  If the debug information could not be used to provide
     that bound, then use an arbitrary large number as the upper bound.  */
  limit_pc = skip_prologue_using_sal (gdbarch, pc);
  if (limit_pc == 0)
    limit_pc = pc + 128;	/* Magic.  */

  /* Find the end of prologue.  */
  return nds32_analyze_prologue (gdbarch, pc, limit_pc, NULL);
}

/* Allocate and fill in *THIS_CACHE with information about the prologue of
   *THIS_FRAME.  Do not do this if *THIS_CACHE was already allocated.  Return
   a pointer to the current nds32_frame_cache in *THIS_CACHE.  */

static struct nds32_frame_cache *
nds32_frame_cache (struct frame_info *this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct nds32_frame_cache *cache;
  CORE_ADDR current_pc;
  ULONGEST prev_sp;
  ULONGEST this_base;
  int i;

  if (*this_cache)
    return (struct nds32_frame_cache *) *this_cache;

  cache = nds32_alloc_frame_cache ();
  *this_cache = cache;

  cache->pc = get_frame_func (this_frame);
  current_pc = get_frame_pc (this_frame);
  nds32_analyze_prologue (gdbarch, cache->pc, current_pc, cache);

  /* Compute the previous frame's stack pointer (which is also the
     frame's ID's stack address), and this frame's base pointer.  */
  if (cache->fp_offset != INVALID_OFFSET)
    {
      /* FP is set in prologue, so it can be used to calculate other info.  */
      this_base = get_frame_register_unsigned (this_frame, NDS32_FP_REGNUM);
      prev_sp = this_base + cache->fp_offset;
    }
  else
    {
      this_base = get_frame_register_unsigned (this_frame, NDS32_SP_REGNUM);
      prev_sp = this_base + cache->sp_offset;
    }

  cache->prev_sp = prev_sp;
  cache->base = this_base;

  /* Adjust all the saved registers such that they contain addresses
     instead of offsets.  */
  for (i = 0; i < NDS32_NUM_SAVED_REGS; i++)
    if (cache->saved_regs[i] != REG_UNAVAIL)
      cache->saved_regs[i] = cache->prev_sp - cache->saved_regs[i];

  return cache;
}

/* Implement the "this_id" frame_unwind method.

   Our frame ID for a normal frame is the current function's starting
   PC and the caller's SP when we were called.  */

static void
nds32_frame_this_id (struct frame_info *this_frame,
		     void **this_cache, struct frame_id *this_id)
{
  struct nds32_frame_cache *cache = nds32_frame_cache (this_frame, this_cache);

  /* This marks the outermost frame.  */
  if (cache->prev_sp == 0)
    return;

  *this_id = frame_id_build (cache->prev_sp, cache->pc);
}

/* Implement the "prev_register" frame_unwind method.  */

static struct value *
nds32_frame_prev_register (struct frame_info *this_frame, void **this_cache,
			   int regnum)
{
  struct nds32_frame_cache *cache = nds32_frame_cache (this_frame, this_cache);

  if (regnum == NDS32_SP_REGNUM)
    return frame_unwind_got_constant (this_frame, regnum, cache->prev_sp);

  /* The PC of the previous frame is stored in the LP register of
     the current frame.  */
  if (regnum == NDS32_PC_REGNUM)
    regnum = NDS32_LP_REGNUM;

  if (regnum < NDS32_NUM_SAVED_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
    return frame_unwind_got_memory (this_frame, regnum,
				    cache->saved_regs[regnum]);

  return frame_unwind_got_register (this_frame, regnum, regnum);
}

static const struct frame_unwind nds32_frame_unwind =
{
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  nds32_frame_this_id,
  nds32_frame_prev_register,
  NULL,
  default_frame_sniffer,
};

/* Return the frame base address of *THIS_FRAME.  */

static CORE_ADDR
nds32_frame_base_address (struct frame_info *this_frame, void **this_cache)
{
  struct nds32_frame_cache *cache = nds32_frame_cache (this_frame, this_cache);

  return cache->base;
}

static const struct frame_base nds32_frame_base =
{
  &nds32_frame_unwind,
  nds32_frame_base_address,
  nds32_frame_base_address,
  nds32_frame_base_address
};

/* Helper function for instructions used to pop multiple words.  */

static void
nds32_pop_multiple_words (struct nds32_frame_cache *cache, int rb, int re,
			  int enable4)
{
  CORE_ADDR sp_offset = cache->sp_offset;
  int i;

  /* Skip case where re == rb == sp.  */
  if ((rb < REG_FP) && (re < REG_FP))
    {
      for (i = rb; i <= re; i++)
	{
	  cache->saved_regs[i] = sp_offset;
	  sp_offset += 4;
	}
    }

  /* Check FP, GP, LP in enable4.  */
  for (i = 3; i >= 1; i--)
    {
      if ((enable4 >> i) & 0x1)
	{
	  cache->saved_regs[NDS32_SP_REGNUM - i] = sp_offset;
	  sp_offset += 4;
	}
    }

  /* For sp, update the offset.  */
  cache->sp_offset = sp_offset;
}

/* The instruction sequences in NDS32 epilogue are

   INSN_RESET_SP  (optional)
		  (If exists, this must be the first instruction in epilogue
		   and the stack has not been destroyed.).
   INSN_RECOVER  (optional).
   INSN_RETURN/INSN_RECOVER_RETURN  (required).  */

/* Helper function for analyzing the given 32-bit INSN.  If CACHE is non-NULL,
   the necessary information will be recorded.  */

static inline int
nds32_analyze_epilogue_insn32 (int abi_use_fpr, uint32_t insn,
			       struct nds32_frame_cache *cache)
{
  if (CHOP_BITS (insn, 15) == N32_TYPE2 (ADDI, REG_SP, REG_SP, 0)
      && N32_IMM15S (insn) > 0)
    /* addi $sp, $sp, imm15s */
    return INSN_RESET_SP;
  else if (CHOP_BITS (insn, 15) == N32_TYPE2 (ADDI, REG_SP, REG_FP, 0)
	   && N32_IMM15S (insn) < 0)
    /* addi $sp, $fp, imm15s */
    return INSN_RESET_SP;
  else if ((insn & ~(__MASK (19) << 6)) == N32_LMW_BIM
	   && N32_RA5 (insn) == REG_SP)
    {
      /* lmw.bim Rb, [$sp], Re, enable4 */
      if (cache != NULL)
	nds32_pop_multiple_words (cache, N32_RT5 (insn),
				  N32_RB5 (insn), N32_LSMW_ENABLE4 (insn));

      return INSN_RECOVER;
    }
  else if (insn == N32_JREG (JR, 0, REG_LP, 0, 1))
    /* ret $lp */
    return INSN_RETURN;
  else if (insn == N32_ALU1 (ADD, REG_SP, REG_SP, REG_TA)
	   || insn == N32_ALU1 (ADD, REG_SP, REG_TA, REG_SP))
    /* add $sp, $sp, $ta */
    /* add $sp, $ta, $sp */
    return INSN_RESET_SP;
  else if (abi_use_fpr
	   && (insn & ~(__MASK (5) << 20 | __MASK (13))) == N32_FLDI_SP)
    {
      if (__GF (insn, 12, 1) == 0)
	/* fldi FDt, [$sp + (imm12s << 2)] */
	return INSN_RECOVER;
      else
	{
	  /* fldi.bi FDt, [$sp], (imm12s << 2) */
	  int offset = N32_IMM12S (insn) << 2;

	  if (offset == 8 || offset == 12)
	    {
	      if (cache != NULL)
		cache->sp_offset += offset;

	      return INSN_RECOVER;
	    }
	}
    }

  return INSN_NORMAL;
}

/* Helper function for analyzing the given 16-bit INSN.  If CACHE is non-NULL,
   the necessary information will be recorded.  */

static inline int
nds32_analyze_epilogue_insn16 (uint32_t insn, struct nds32_frame_cache *cache)
{
  if (insn == N16_TYPE5 (RET5, REG_LP))
    /* ret5 $lp */
    return INSN_RETURN;
  else if (CHOP_BITS (insn, 10) == N16_TYPE10 (ADDI10S, 0))
    {
      /* addi10s.sp */
      int imm10s = N16_IMM10S (insn);

      if (imm10s > 0)
	{
	  if (cache != NULL)
	    cache->sp_offset += imm10s;

	  return INSN_RECOVER;
	}
    }
  else if (__GF (insn, 7, 8) == N16_T25_POP25)
    {
      /* pop25 */
      if (cache != NULL)
	{
	  int imm8u = (insn & 0x1f) << 3;
	  int re = (insn >> 5) & 0x3;
	  const int reg_map[] = { 6, 8, 10, 14 };

	  /* Operation 1 -- sp = sp + (imm5u << 3) */
	  cache->sp_offset += imm8u;

	  /* Operation 2 -- lmw.bim R6, [$sp], Re, #0xe */
	  nds32_pop_multiple_words (cache, 6, reg_map[re], 0xe);
	}

      /* Operation 3 -- ret $lp */
      return INSN_RECOVER_RETURN;
    }

  return INSN_NORMAL;
}

/* Analyze a reasonable amount of instructions from the given PC to find
   the instruction used to return to the caller.  Return 1 if the 'return'
   instruction could be found, 0 otherwise.

   If CACHE is non-NULL, fill it in.  */

static int
nds32_analyze_epilogue (struct gdbarch *gdbarch, CORE_ADDR pc,
			struct nds32_frame_cache *cache)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  int abi_use_fpr = nds32_abi_use_fpr (tdep->elf_abi);
  CORE_ADDR limit_pc;
  uint32_t insn, insn_len;
  int insn_type = INSN_NORMAL;

  if (abi_use_fpr)
    limit_pc = pc + 48;
  else
    limit_pc = pc + 16;

  for (; pc < limit_pc; pc += insn_len)
    {
      insn = read_memory_unsigned_integer (pc, 4, BFD_ENDIAN_BIG);

      if ((insn & 0x80000000) == 0)
	{
	  /* 32-bit instruction */
	  insn_len = 4;

	  insn_type = nds32_analyze_epilogue_insn32 (abi_use_fpr, insn, cache);
	  if (insn_type == INSN_RETURN)
	    return 1;
	  else if (insn_type == INSN_RECOVER)
	    continue;
	}
      else
	{
	  /* 16-bit instruction */
	  insn_len = 2;

	  insn >>= 16;
	  insn_type = nds32_analyze_epilogue_insn16 (insn, cache);
	  if (insn_type == INSN_RETURN || insn_type == INSN_RECOVER_RETURN)
	    return 1;
	  else if (insn_type == INSN_RECOVER)
	    continue;
	}

      /* Stop the scan if this is an unexpected instruction.  */
      break;
    }

  return 0;
}

/* Implement the "stack_frame_destroyed_p" gdbarch method.  */

static int
nds32_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  int abi_use_fpr = nds32_abi_use_fpr (tdep->elf_abi);
  int insn_type = INSN_NORMAL;
  int ret_found = 0;
  uint32_t insn;

  insn = read_memory_unsigned_integer (addr, 4, BFD_ENDIAN_BIG);

  if ((insn & 0x80000000) == 0)
    {
      /* 32-bit instruction */

      insn_type = nds32_analyze_epilogue_insn32 (abi_use_fpr, insn, NULL);
    }
  else
    {
      /* 16-bit instruction */

      insn >>= 16;
      insn_type = nds32_analyze_epilogue_insn16 (insn, NULL);
    }

  if (insn_type == INSN_NORMAL || insn_type == INSN_RESET_SP)
    return 0;

  /* Search the required 'return' instruction within the following reasonable
     instructions.  */
  ret_found = nds32_analyze_epilogue (gdbarch, addr, NULL);
  if (ret_found == 0)
    return 0;

  /* Scan backwards to make sure that the last instruction has adjusted
     stack.  Both a 16-bit and a 32-bit instruction will be tried.  This is
     just a heuristic, so the false positives will be acceptable.  */
  insn = read_memory_unsigned_integer (addr - 2, 4, BFD_ENDIAN_BIG);

  /* Only 16-bit instructions are possible at addr - 2.  */
  if ((insn & 0x80000000) != 0)
    {
      /* This may be a 16-bit instruction or part of a 32-bit instruction.  */

      insn_type = nds32_analyze_epilogue_insn16 (insn >> 16, NULL);
      if (insn_type == INSN_RECOVER)
	return 1;
    }

  insn = read_memory_unsigned_integer (addr - 4, 4, BFD_ENDIAN_BIG);

  /* If this is a 16-bit instruction at addr - 4, then there must be another
     16-bit instruction at addr - 2, so only 32-bit instructions need to
     be analyzed here.  */
  if ((insn & 0x80000000) == 0)
    {
      /* This may be a 32-bit instruction or part of a 32-bit instruction.  */

      insn_type = nds32_analyze_epilogue_insn32 (abi_use_fpr, insn, NULL);
      if (insn_type == INSN_RECOVER || insn_type == INSN_RESET_SP)
	return 1;
    }

  return 0;
}

/* Implement the "sniffer" frame_unwind method.  */

static int
nds32_epilogue_frame_sniffer (const struct frame_unwind *self,
			      struct frame_info *this_frame, void **this_cache)
{
  if (frame_relative_level (this_frame) == 0)
    return nds32_stack_frame_destroyed_p (get_frame_arch (this_frame),
					  get_frame_pc (this_frame));
  else
    return 0;
}

/* Allocate and fill in *THIS_CACHE with information needed to unwind
   *THIS_FRAME within epilogue.  Do not do this if *THIS_CACHE was already
   allocated.  Return a pointer to the current nds32_frame_cache in
   *THIS_CACHE.  */

static struct nds32_frame_cache *
nds32_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct nds32_frame_cache *cache;
  CORE_ADDR current_pc, current_sp;
  int i;

  if (*this_cache)
    return (struct nds32_frame_cache *) *this_cache;

  cache = nds32_alloc_frame_cache ();
  *this_cache = cache;

  cache->pc = get_frame_func (this_frame);
  current_pc = get_frame_pc (this_frame);
  nds32_analyze_epilogue (gdbarch, current_pc, cache);

  current_sp = get_frame_register_unsigned (this_frame, NDS32_SP_REGNUM);
  cache->prev_sp = current_sp + cache->sp_offset;

  /* Adjust all the saved registers such that they contain addresses
     instead of offsets.  */
  for (i = 0; i < NDS32_NUM_SAVED_REGS; i++)
    if (cache->saved_regs[i] != REG_UNAVAIL)
      cache->saved_regs[i] = current_sp + cache->saved_regs[i];

  return cache;
}

/* Implement the "this_id" frame_unwind method.  */

static void
nds32_epilogue_frame_this_id (struct frame_info *this_frame,
			      void **this_cache, struct frame_id *this_id)
{
  struct nds32_frame_cache *cache
    = nds32_epilogue_frame_cache (this_frame, this_cache);

  /* This marks the outermost frame.  */
  if (cache->prev_sp == 0)
    return;

  *this_id = frame_id_build (cache->prev_sp, cache->pc);
}

/* Implement the "prev_register" frame_unwind method.  */

static struct value *
nds32_epilogue_frame_prev_register (struct frame_info *this_frame,
				    void **this_cache, int regnum)
{
  struct nds32_frame_cache *cache
    = nds32_epilogue_frame_cache (this_frame, this_cache);

  if (regnum == NDS32_SP_REGNUM)
    return frame_unwind_got_constant (this_frame, regnum, cache->prev_sp);

  /* The PC of the previous frame is stored in the LP register of
     the current frame.  */
  if (regnum == NDS32_PC_REGNUM)
    regnum = NDS32_LP_REGNUM;

  if (regnum < NDS32_NUM_SAVED_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
    return frame_unwind_got_memory (this_frame, regnum,
				    cache->saved_regs[regnum]);

  return frame_unwind_got_register (this_frame, regnum, regnum);
}

static const struct frame_unwind nds32_epilogue_frame_unwind =
{
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  nds32_epilogue_frame_this_id,
  nds32_epilogue_frame_prev_register,
  NULL,
  nds32_epilogue_frame_sniffer
};

/* Implement the "dummy_id" gdbarch method.  */

static struct frame_id
nds32_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
{
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, NDS32_SP_REGNUM);

  return frame_id_build (sp, get_frame_pc (this_frame));
}

/* Implement the "unwind_pc" gdbarch method.  */

static CORE_ADDR
nds32_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  return frame_unwind_register_unsigned (next_frame, NDS32_PC_REGNUM);
}

/* Implement the "unwind_sp" gdbarch method.  */

static CORE_ADDR
nds32_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  return frame_unwind_register_unsigned (next_frame, NDS32_SP_REGNUM);
}

/* Floating type and struct type that has only one floating type member
   can pass value using FPU registers (when FPU ABI is used).  */

static int
nds32_check_calling_use_fpr (struct type *type)
{
  struct type *t;
  enum type_code typecode;

  t = type;
  while (1)
    {
      t = check_typedef (t);
      typecode = TYPE_CODE (t);
      if (typecode != TYPE_CODE_STRUCT)
	break;
      else if (TYPE_NFIELDS (t) != 1)
	return 0;
      else
	t = TYPE_FIELD_TYPE (t, 0);
    }

  return typecode == TYPE_CODE_FLT;
}

/* Return the alignment (in bytes) of the given type.  */

static int
nds32_type_align (struct type *type)
{
  int n;
  int align;
  int falign;

  type = check_typedef (type);
  switch (TYPE_CODE (type))
    {
    default:
      /* Should never happen.  */
      internal_error (__FILE__, __LINE__, _("unknown type alignment"));
      return 4;

    case TYPE_CODE_PTR:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_INT:
    case TYPE_CODE_FLT:
    case TYPE_CODE_SET:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_REF:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_BOOL:
      return TYPE_LENGTH (type);

    case TYPE_CODE_ARRAY:
    case TYPE_CODE_COMPLEX:
      return nds32_type_align (TYPE_TARGET_TYPE (type));

    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
      align = 1;
      for (n = 0; n < TYPE_NFIELDS (type); n++)
	{
	  falign = nds32_type_align (TYPE_FIELD_TYPE (type, n));
	  if (falign > align)
	    align = falign;
	}
      return align;
    }
}

/* Implement the "push_dummy_call" gdbarch method.  */

static CORE_ADDR
nds32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
		       struct regcache *regcache, CORE_ADDR bp_addr,
		       int nargs, struct value **args, CORE_ADDR sp,
		       int struct_return, CORE_ADDR struct_addr)
{
  const int REND = 6;		/* End for register offset.  */
  int goff = 0;			/* Current gpr offset for argument.  */
  int foff = 0;			/* Current fpr offset for argument.  */
  int soff = 0;			/* Current stack offset for argument.  */
  int i;
  ULONGEST regval;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  struct type *func_type = value_type (function);
  int abi_use_fpr = nds32_abi_use_fpr (tdep->elf_abi);
  int abi_split = nds32_abi_split (tdep->elf_abi);

  /* Set the return address.  For the NDS32, the return breakpoint is
     always at BP_ADDR.  */
  regcache_cooked_write_unsigned (regcache, NDS32_LP_REGNUM, bp_addr);

  /* If STRUCT_RETURN is true, then the struct return address (in
     STRUCT_ADDR) will consume the first argument-passing register.
     Both adjust the register count and store that value.  */
  if (struct_return)
    {
      regcache_cooked_write_unsigned (regcache, NDS32_R0_REGNUM, struct_addr);
      goff++;
    }

  /* Now make sure there's space on the stack */
  for (i = 0; i < nargs; i++)
    {
      struct type *type = value_type (args[i]);
      int align = nds32_type_align (type);

      /* If align is zero, it may be an empty struct.
	 Just ignore the argument of empty struct.  */
      if (align == 0)
	continue;

      sp -= TYPE_LENGTH (type);
      sp = align_down (sp, align);
    }

  /* Stack must be 8-byte aligned.  */
  sp = align_down (sp, 8);

  soff = 0;
  for (i = 0; i < nargs; i++)
    {
      const gdb_byte *val;
      int align, len;
      struct type *type;
      int calling_use_fpr;
      int use_fpr = 0;

      type = value_type (args[i]);
      calling_use_fpr = nds32_check_calling_use_fpr (type);
      len = TYPE_LENGTH (type);
      align = nds32_type_align (type);
      val = value_contents (args[i]);

      /* The size of a composite type larger than 4 bytes will be rounded
	 up to the nearest multiple of 4.  */
      if (len > 4)
	len = align_up (len, 4);

      /* Variadic functions are handled differently between AABI and ABI2FP+.

	 For AABI, the caller pushes arguments in registers, callee stores
	 unnamed arguments in stack, and then va_arg fetch arguments in stack.
	 Therefore, we don't have to handle variadic functions specially.

	 For ABI2FP+, the caller pushes only named arguments in registers
	 and pushes all unnamed arguments in stack.  */

      if (abi_use_fpr && TYPE_VARARGS (func_type)
	  && i >= TYPE_NFIELDS (func_type))
	goto use_stack;

      /* Try to use FPRs to pass arguments only when
	 1. The program is built using toolchain with FPU support.
	 2. The type of this argument can use FPR to pass value.  */
      use_fpr = abi_use_fpr && calling_use_fpr;

      if (use_fpr)
	{
	  if (tdep->fpu_freg == -1)
	    goto error_no_fpr;

	  /* Adjust alignment.  */
	  if ((align >> 2) > 0)
	    foff = align_up (foff, align >> 2);

	  if (foff < REND)
	    {
	      switch (len)
		{
		case 4:
		  regcache_cooked_write (regcache,
					 tdep->fs0_regnum + foff, val);
		  foff++;
		  break;
		case 8:
		  regcache_cooked_write (regcache,
					 NDS32_FD0_REGNUM + (foff >> 1), val);
		  foff += 2;
		  break;
		default:
		  /* Long double?  */
		  internal_error (__FILE__, __LINE__,
				  "Do not know how to handle %d-byte double.\n",
				  len);
		  break;
		}
	      continue;
	    }
	}
      else
	{
	  /*
	     When passing arguments using GPRs,

	     * A composite type not larger than 4 bytes is passed in $rN.
	       The format is as if the value is loaded with load instruction
	       of corresponding size (e.g., LB, LH, LW).

	       For example,

		       r0
		       31      0
	       LITTLE: [x x b a]
		  BIG: [x x a b]

	     * Otherwise, a composite type is passed in consecutive registers.
	       The size is rounded up to the nearest multiple of 4.
	       The successive registers hold the parts of the argument as if
	       were loaded using lmw instructions.

	       For example,

		       r0	 r1
		       31      0 31      0
	       LITTLE: [d c b a] [x x x e]
		  BIG: [a b c d] [e x x x]
	   */

	  /* Adjust alignment.  */
	  if ((align >> 2) > 0)
	    goff = align_up (goff, align >> 2);

	  if (len <= (REND - goff) * 4)
	    {
	      /* This argument can be passed wholly via GPRs.  */
	      while (len > 0)
		{
		  regval = extract_unsigned_integer (val, (len > 4) ? 4 : len,
						     byte_order);
		  regcache_cooked_write_unsigned (regcache,
						  NDS32_R0_REGNUM + goff,
						  regval);
		  len -= 4;
		  val += 4;
		  goff++;
		}
	      continue;
	    }
	  else if (abi_split)
	    {
	      /* Some parts of this argument can be passed via GPRs.  */
	      while (goff < REND)
		{
		  regval = extract_unsigned_integer (val, (len > 4) ? 4 : len,
						     byte_order);
		  regcache_cooked_write_unsigned (regcache,
						  NDS32_R0_REGNUM + goff,
						  regval);
		  len -= 4;
		  val += 4;
		  goff++;
		}
	    }
	}

use_stack:
      /*
	 When pushing (split parts of) an argument into stack,

	 * A composite type not larger than 4 bytes is copied to different
	   base address.
	   In little-endian, the first byte of this argument is aligned
	   at the low address of the next free word.
	   In big-endian, the last byte of this argument is aligned
	   at the high address of the next free word.

	   For example,

	   sp [ - ]  [ c ] hi
	      [ c ]  [ b ]
	      [ b ]  [ a ]
	      [ a ]  [ - ] lo
	     LITTLE   BIG
       */

      /* Adjust alignment.  */
      soff = align_up (soff, align);

      while (len > 0)
	{
	  int rlen = (len > 4) ? 4 : len;

	  if (byte_order == BFD_ENDIAN_BIG)
	    write_memory (sp + soff + 4 - rlen, val, rlen);
	  else
	    write_memory (sp + soff, val, rlen);

	  len -= 4;
	  val += 4;
	  soff += 4;
	}
    }

  /* Finally, update the SP register.  */
  regcache_cooked_write_unsigned (regcache, NDS32_SP_REGNUM, sp);

  return sp;

error_no_fpr:
  /* If use_fpr, but no floating-point register exists,
     then it is an error.  */
  error (_("Fail to call. FPU registers are required."));
}

/* Read, for architecture GDBARCH, a function return value of TYPE
   from REGCACHE, and copy that into VALBUF.  */

static void
nds32_extract_return_value (struct gdbarch *gdbarch, struct type *type,
			    struct regcache *regcache, gdb_byte *valbuf)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  int abi_use_fpr = nds32_abi_use_fpr (tdep->elf_abi);
  int calling_use_fpr;
  int len;

  calling_use_fpr = nds32_check_calling_use_fpr (type);
  len = TYPE_LENGTH (type);

  if (abi_use_fpr && calling_use_fpr)
    {
      if (len == 4)
	regcache_cooked_read (regcache, tdep->fs0_regnum, valbuf);
      else if (len == 8)
	regcache_cooked_read (regcache, NDS32_FD0_REGNUM, valbuf);
      else
	internal_error (__FILE__, __LINE__,
			_("Cannot extract return value of %d bytes "
			  "long floating-point."), len);
    }
  else
    {
      /*
	 When returning result,

	 * A composite type not larger than 4 bytes is returned in $r0.
	   The format is as if the result is loaded with load instruction
	   of corresponding size (e.g., LB, LH, LW).

	   For example,

		   r0
		   31      0
	   LITTLE: [x x b a]
	      BIG: [x x a b]

	 * Otherwise, a composite type not larger than 8 bytes is returned
	   in $r0 and $r1.
	   In little-endian, the first word is loaded in $r0.
	   In big-endian, the last word is loaded in $r1.

	   For example,

		   r0	     r1
		   31      0 31      0
	   LITTLE: [d c b a] [x x x e]
	      BIG: [x x x a] [b c d e]
       */

      ULONGEST tmp;

      if (len < 4)
	{
	  /* By using store_unsigned_integer we avoid having to do
	     anything special for small big-endian values.  */
	  regcache_cooked_read_unsigned (regcache, NDS32_R0_REGNUM, &tmp);
	  store_unsigned_integer (valbuf, len, byte_order, tmp);
	}
      else if (len == 4)
	{
	  regcache_cooked_read (regcache, NDS32_R0_REGNUM, valbuf);
	}
      else if (len < 8)
	{
	  int len1, len2;

	  len1 = byte_order == BFD_ENDIAN_BIG ? len - 4 : 4;
	  len2 = len - len1;

	  regcache_cooked_read_unsigned (regcache, NDS32_R0_REGNUM, &tmp);
	  store_unsigned_integer (valbuf, len1, byte_order, tmp);

	  regcache_cooked_read_unsigned (regcache, NDS32_R0_REGNUM + 1, &tmp);
	  store_unsigned_integer (valbuf + len1, len2, byte_order, tmp);
	}
      else
	{
	  regcache_cooked_read (regcache, NDS32_R0_REGNUM, valbuf);
	  regcache_cooked_read (regcache, NDS32_R0_REGNUM + 1, valbuf + 4);
	}
    }
}

/* Write, for architecture GDBARCH, a function return value of TYPE
   from VALBUF into REGCACHE.  */

static void
nds32_store_return_value (struct gdbarch *gdbarch, struct type *type,
			  struct regcache *regcache, const gdb_byte *valbuf)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  int abi_use_fpr = nds32_abi_use_fpr (tdep->elf_abi);
  int calling_use_fpr;
  int len;

  calling_use_fpr = nds32_check_calling_use_fpr (type);
  len = TYPE_LENGTH (type);

  if (abi_use_fpr && calling_use_fpr)
    {
      if (len == 4)
	regcache_cooked_write (regcache, tdep->fs0_regnum, valbuf);
      else if (len == 8)
	regcache_cooked_write (regcache, NDS32_FD0_REGNUM, valbuf);
      else
	internal_error (__FILE__, __LINE__,
			_("Cannot store return value of %d bytes "
			  "long floating-point."), len);
    }
  else
    {
      ULONGEST regval;

      if (len < 4)
	{
	  regval = extract_unsigned_integer (valbuf, len, byte_order);
	  regcache_cooked_write_unsigned (regcache, NDS32_R0_REGNUM, regval);
	}
      else if (len == 4)
	{
	  regcache_cooked_write (regcache, NDS32_R0_REGNUM, valbuf);
	}
      else if (len < 8)
	{
	  int len1, len2;

	  len1 = byte_order == BFD_ENDIAN_BIG ? len - 4 : 4;
	  len2 = len - len1;

	  regval = extract_unsigned_integer (valbuf, len1, byte_order);
	  regcache_cooked_write_unsigned (regcache, NDS32_R0_REGNUM, regval);

	  regval = extract_unsigned_integer (valbuf + len1, len2, byte_order);
	  regcache_cooked_write_unsigned (regcache, NDS32_R0_REGNUM + 1,
					  regval);
	}
      else
	{
	  regcache_cooked_write (regcache, NDS32_R0_REGNUM, valbuf);
	  regcache_cooked_write (regcache, NDS32_R0_REGNUM + 1, valbuf + 4);
	}
    }
}

/* Implement the "return_value" gdbarch method.

   Determine, for architecture GDBARCH, how a return value of TYPE
   should be returned.  If it is supposed to be returned in registers,
   and READBUF is non-zero, read the appropriate value from REGCACHE,
   and copy it into READBUF.  If WRITEBUF is non-zero, write the value
   from WRITEBUF into REGCACHE.  */

static enum return_value_convention
nds32_return_value (struct gdbarch *gdbarch, struct value *func_type,
		    struct type *type, struct regcache *regcache,
		    gdb_byte *readbuf, const gdb_byte *writebuf)
{
  if (TYPE_LENGTH (type) > 8)
    {
      return RETURN_VALUE_STRUCT_CONVENTION;
    }
  else
    {
      if (readbuf != NULL)
	nds32_extract_return_value (gdbarch, type, regcache, readbuf);
      if (writebuf != NULL)
	nds32_store_return_value (gdbarch, type, regcache, writebuf);

      return RETURN_VALUE_REGISTER_CONVENTION;
    }
}

/* Implement the "get_longjmp_target" gdbarch method.  */

static int
nds32_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
{
  gdb_byte buf[4];
  CORE_ADDR jb_addr;
  struct gdbarch *gdbarch = get_frame_arch (frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  jb_addr = get_frame_register_unsigned (frame, NDS32_R0_REGNUM);

  if (target_read_memory (jb_addr + 11 * 4, buf, 4))
    return 0;

  *pc = extract_unsigned_integer (buf, 4, byte_order);
  return 1;
}

/* Validate the given TDESC, and fixed-number some registers in it.
   Return 0 if the given TDESC does not contain the required feature
   or not contain required registers.  */

static int
nds32_validate_tdesc_p (const struct target_desc *tdesc,
			struct tdesc_arch_data *tdesc_data,
			int *fpu_freg, int *use_pseudo_fsrs)
{
  const struct tdesc_feature *feature;
  int i, valid_p;

  feature = tdesc_find_feature (tdesc, "org.gnu.gdb.nds32.core");
  if (feature == NULL)
    return 0;

  valid_p = 1;
  /* Validate and fixed-number R0-R10.  */
  for (i = NDS32_R0_REGNUM; i <= NDS32_R0_REGNUM + 10; i++)
    valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
					nds32_register_names[i]);

  /* Validate R15.  */
  valid_p &= tdesc_unnumbered_register (feature,
					nds32_register_names[NDS32_TA_REGNUM]);

  /* Validate and fixed-number FP, GP, LP, SP, PC.  */
  for (i = NDS32_FP_REGNUM; i <= NDS32_PC_REGNUM; i++)
    valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
					nds32_register_names[i]);

  if (!valid_p)
    return 0;

  /* Fixed-number R11-R27.  */
  for (i = NDS32_R0_REGNUM + 11; i <= NDS32_R0_REGNUM + 27; i++)
    tdesc_numbered_register (feature, tdesc_data, i, nds32_register_names[i]);

  feature = tdesc_find_feature (tdesc, "org.gnu.gdb.nds32.fpu");
  if (feature != NULL)
    {
      int num_fdr_regs, num_fsr_regs, fs0_regnum, num_listed_fsr;
      int freg = -1;

      /* Guess FPU configuration via listed registers.  */
      if (tdesc_unnumbered_register (feature, "fd31"))
	freg = 3;
      else if (tdesc_unnumbered_register (feature, "fd15"))
	freg = 2;
      else if (tdesc_unnumbered_register (feature, "fd7"))
	freg = 1;
      else if (tdesc_unnumbered_register (feature, "fd3"))
	freg = 0;

      if (freg == -1)
	/* Required FDR is not found.  */
	return 0;
      else
	*fpu_freg = freg;

      /* Validate and fixed-number required FDRs.  */
      num_fdr_regs = num_fdr_map[freg];
      for (i = 0; i < num_fdr_regs; i++)
	valid_p &= tdesc_numbered_register (feature, tdesc_data,
					    NDS32_FD0_REGNUM + i,
					    nds32_fdr_register_names[i]);
      if (!valid_p)
	return 0;

      /* Count the number of listed FSRs, and fixed-number them if present.  */
      num_fsr_regs = num_fsr_map[freg];
      fs0_regnum = NDS32_FD0_REGNUM + num_fdr_regs;
      num_listed_fsr = 0;
      for (i = 0; i < num_fsr_regs; i++)
	num_listed_fsr += tdesc_numbered_register (feature, tdesc_data,
						   fs0_regnum + i,
						   nds32_fsr_register_names[i]);

      if (num_listed_fsr == 0)
	/* No required FSRs are listed explicitly,  make them pseudo registers
	   of FDRs.  */
	*use_pseudo_fsrs = 1;
      else if (num_listed_fsr == num_fsr_regs)
	/* All required FSRs are listed explicitly.  */
	*use_pseudo_fsrs = 0;
      else
	/* Some required FSRs are missing.  */
	return 0;
    }

  return 1;
}

/* Initialize the current architecture based on INFO.  If possible,
   re-use an architecture from ARCHES, which is a list of
   architectures already created during this debugging session.

   Called e.g. at program startup, when reading a core file, and when
   reading a binary file.  */

static struct gdbarch *
nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch *gdbarch;
  struct gdbarch_tdep *tdep;
  struct gdbarch_list *best_arch;
  struct tdesc_arch_data *tdesc_data = NULL;
  const struct target_desc *tdesc = info.target_desc;
  int elf_abi = E_NDS_ABI_AABI;
  int fpu_freg = -1;
  int use_pseudo_fsrs = 0;
  int i, num_regs, maxregs;

  /* Extract the elf_flags if available.  */
  if (info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
    elf_abi = elf_elfheader (info.abfd)->e_flags & EF_NDS_ABI;

  /* If there is already a candidate, use it.  */
  for (best_arch = gdbarch_list_lookup_by_info (arches, &info);
       best_arch != NULL;
       best_arch = gdbarch_list_lookup_by_info (best_arch->next, &info))
    {
      struct gdbarch_tdep *idep = gdbarch_tdep (best_arch->gdbarch);

      if (idep->elf_abi != elf_abi)
	continue;

      /* Found a match.  */
      break;
    }

  if (best_arch != NULL)
    return best_arch->gdbarch;

  if (!tdesc_has_registers (tdesc))
    tdesc = tdesc_nds32;

  tdesc_data = tdesc_data_alloc ();

  if (!nds32_validate_tdesc_p (tdesc, tdesc_data, &fpu_freg, &use_pseudo_fsrs))
    {
      tdesc_data_cleanup (tdesc_data);
      return NULL;
    }

  /* Allocate space for the new architecture.  */
  tdep = XCNEW (struct gdbarch_tdep);
  tdep->fpu_freg = fpu_freg;
  tdep->use_pseudo_fsrs = use_pseudo_fsrs;
  tdep->fs0_regnum = -1;
  tdep->elf_abi = elf_abi;

  gdbarch = gdbarch_alloc (&info, tdep);

  if (fpu_freg == -1)
    num_regs = NDS32_NUM_REGS;
  else if (use_pseudo_fsrs == 1)
    {
      set_gdbarch_pseudo_register_read (gdbarch, nds32_pseudo_register_read);
      set_gdbarch_pseudo_register_write (gdbarch, nds32_pseudo_register_write);
      set_tdesc_pseudo_register_name (gdbarch, nds32_pseudo_register_name);
      set_tdesc_pseudo_register_type (gdbarch, nds32_pseudo_register_type);
      set_gdbarch_num_pseudo_regs (gdbarch, num_fsr_map[fpu_freg]);

      num_regs = NDS32_NUM_REGS + num_fdr_map[fpu_freg];
    }
  else
    num_regs = NDS32_NUM_REGS + num_fdr_map[fpu_freg] + num_fsr_map[fpu_freg];

  set_gdbarch_num_regs (gdbarch, num_regs);
  tdesc_use_registers (gdbarch, tdesc, tdesc_data);

  /* Cache the register number of fs0.  */
  if (fpu_freg != -1)
    tdep->fs0_regnum = user_reg_map_name_to_regnum (gdbarch, "fs0", -1);

  /* Add NDS32 register aliases.  To avoid search in user register name space,
     user_reg_map_name_to_regnum is not used.  */
  maxregs = (gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch));
  for (i = 0; i < ARRAY_SIZE (nds32_register_aliases); i++)
    {
      int regnum, j;

      regnum = -1;
      /* Search register name space.  */
      for (j = 0; j < maxregs; j++)
	{
	  const char *regname = gdbarch_register_name (gdbarch, j);

	  if (regname != NULL
	      && strcmp (regname, nds32_register_aliases[i].name) == 0)
	    {
	      regnum = j;
	      break;
	    }
	}

      /* Try next alias entry if the given name can not be found in register
	 name space.  */
      if (regnum == -1)
	continue;

      user_reg_add (gdbarch, nds32_register_aliases[i].alias,
		    value_of_nds32_reg, (const void *) (intptr_t) regnum);
    }

  nds32_add_reggroups (gdbarch);

  /* Hook in ABI-specific overrides, if they have been registered.  */
  info.tdep_info = (void *) tdesc_data;
  gdbarch_init_osabi (info, gdbarch);

  /* Override tdesc_register callbacks for system registers.  */
  set_gdbarch_register_reggroup_p (gdbarch, nds32_register_reggroup_p);

  set_gdbarch_sp_regnum (gdbarch, NDS32_SP_REGNUM);
  set_gdbarch_pc_regnum (gdbarch, NDS32_PC_REGNUM);
  set_gdbarch_unwind_sp (gdbarch, nds32_unwind_sp);
  set_gdbarch_unwind_pc (gdbarch, nds32_unwind_pc);
  set_gdbarch_stack_frame_destroyed_p (gdbarch, nds32_stack_frame_destroyed_p);
  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, nds32_dwarf2_reg_to_regnum);

  set_gdbarch_push_dummy_call (gdbarch, nds32_push_dummy_call);
  set_gdbarch_return_value (gdbarch, nds32_return_value);
  set_gdbarch_dummy_id (gdbarch, nds32_dummy_id);

  set_gdbarch_skip_prologue (gdbarch, nds32_skip_prologue);
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  set_gdbarch_breakpoint_from_pc (gdbarch, nds32_breakpoint_from_pc);

  set_gdbarch_frame_align (gdbarch, nds32_frame_align);
  frame_base_set_default (gdbarch, &nds32_frame_base);

  set_gdbarch_print_insn (gdbarch, print_insn_nds32);

  /* Handle longjmp.  */
  set_gdbarch_get_longjmp_target (gdbarch, nds32_get_longjmp_target);

  /* The order of appending is the order it check frame.  */
  dwarf2_append_unwinders (gdbarch);
  frame_unwind_append_unwinder (gdbarch, &nds32_epilogue_frame_unwind);
  frame_unwind_append_unwinder (gdbarch, &nds32_frame_unwind);

  return gdbarch;
}

void
_initialize_nds32_tdep (void)
{
  /* Initialize gdbarch.  */
  register_gdbarch_init (bfd_arch_nds32, nds32_gdbarch_init);

  initialize_tdesc_nds32 ();
  nds32_init_reggroups ();
}
