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

   Copyright (C) 2013-2025 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 "extract-store-integer.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 <algorithm>

#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)

/* 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 (const frame_info_ptr &frame, const void *baton)
{
  return value_of_register ((int) (intptr_t) baton,
			    get_next_frame_sentinel_okay (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);
}

/* The same insn machine code is used for little-endian and big-endian.  */
constexpr gdb_byte nds32_break_insn[] = { 0xEA, 0x00 };

typedef BP_MANIPULATION (nds32_break_insn) nds32_breakpoint;

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

static int
nds32_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num)
{
  nds32_gdbarch_tdep *tdep = gdbarch_tdep<nds32_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 const reggroup *nds32_cr_reggroup;
static const reggroup *nds32_ir_reggroup;
static const reggroup *nds32_mr_reggroup;
static const reggroup *nds32_dr_reggroup;
static const reggroup *nds32_pfr_reggroup;
static const reggroup *nds32_hspr_reggroup;
static const reggroup *nds32_dmar_reggroup;
static const reggroup *nds32_racr_reggroup;
static const reggroup *nds32_idr_reggroup;
static const 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 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,
			   const 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 ();
  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))
    {
      type_allocator alloc (gdbarch);
      return init_float_type (alloc, -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.  */
  gdb_assert (regnum < gdbarch_num_pseudo_regs (gdbarch));
  return nds32_fsr_register_names[regnum];
}

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

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

  /* This function is registered in nds32_gdbarch_init only after these are
     set.  */
  gdb_assert (tdep->fpu_freg != -1);
  gdb_assert (tdep->use_pseudo_fsrs != 0);

  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 (fdr_regnum, reg_buf);
      if (status == REG_VALID)
	memcpy (buf, reg_buf + offset, 4);

      return status;
    }

  gdb_assert_not_reached ("invalid pseudo register number");
}

/* 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)
{
  nds32_gdbarch_tdep *tdep = gdbarch_tdep<nds32_gdbarch_tdep> (gdbarch);
  gdb_byte reg_buf[8];
  int offset, fdr_regnum;

  /* This function is registered in nds32_gdbarch_init only after these are
     set.  */
  gdb_assert (tdep->fpu_freg != -1);
  gdb_assert (tdep->use_pseudo_fsrs != 0);

  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 (fdr_regnum, reg_buf);
      memcpy (reg_buf + offset, buf, 4);
      regcache->raw_write (fdr_regnum, reg_buf);
      return;
    }

  gdb_assert_not_reached ("invalid pseudo register number");
}

/* 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)
{
  nds32_gdbarch_tdep *tdep = gdbarch_tdep<nds32_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 std::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 (const frame_info_ptr &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 (const frame_info_ptr &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 (const frame_info_ptr &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_legacy nds32_frame_unwind (
  "nds32 prologue",
  NORMAL_FRAME,
  FRAME_UNWIND_ARCH,
  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 (const frame_info_ptr &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)
{
  nds32_gdbarch_tdep *tdep = gdbarch_tdep<nds32_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)
{
  nds32_gdbarch_tdep *tdep = gdbarch_tdep<nds32_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,
			      const frame_info_ptr &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 (const frame_info_ptr &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 (const frame_info_ptr &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 (const frame_info_ptr &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_legacy nds32_epilogue_frame_unwind (
  "nds32 epilogue",
  NORMAL_FRAME,
  FRAME_UNWIND_ARCH,
  default_frame_unwind_stop_reason,
  nds32_epilogue_frame_this_id,
  nds32_epilogue_frame_prev_register,
  NULL,
  nds32_epilogue_frame_sniffer
);


/* 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 = t->code ();
      if (typecode != TYPE_CODE_STRUCT)
	break;
      else if (t->num_fields () != 1)
	return 0;
      else
	t = t->field (0).type ();
    }

  return typecode == TYPE_CODE_FLT;
}

/* 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,
		       function_call_return_method return_method,
		       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);
  nds32_gdbarch_tdep *tdep = gdbarch_tdep<nds32_gdbarch_tdep> (gdbarch);
  struct type *func_type = function->type ();
  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 (return_method == return_method_struct)
    {
      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 = args[i]->type ();
      int align = 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 ();
      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 = args[i]->type ();
      calling_use_fpr = nds32_check_calling_use_fpr (type);
      len = type->length ();
      align = type_align (type);
      val = args[i]->contents ().data ();

      /* 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 && func_type->has_varargs ()
	  && i >= func_type->num_fields ())
	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 (tdep->fs0_regnum + foff, val);
		  foff++;
		  break;
		case 8:
		  regcache->cooked_write (NDS32_FD0_REGNUM + (foff >> 1), val);
		  foff += 2;
		  break;
		default:
		  /* Long double?  */
		  internal_error ("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);
  nds32_gdbarch_tdep *tdep = gdbarch_tdep<nds32_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 ();

  if (abi_use_fpr && calling_use_fpr)
    {
      if (len == 4)
	regcache->cooked_read (tdep->fs0_regnum, valbuf);
      else if (len == 8)
	regcache->cooked_read (NDS32_FD0_REGNUM, valbuf);
      else
	internal_error (_("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 (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 (NDS32_R0_REGNUM, valbuf);
	  regcache->cooked_read (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);
  nds32_gdbarch_tdep *tdep = gdbarch_tdep<nds32_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 ();

  if (abi_use_fpr && calling_use_fpr)
    {
      if (len == 4)
	regcache->cooked_write (tdep->fs0_regnum, valbuf);
      else if (len == 8)
	regcache->cooked_write (NDS32_FD0_REGNUM, valbuf);
      else
	internal_error (_("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 (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 (NDS32_R0_REGNUM, valbuf);
	  regcache->cooked_write (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 () > 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 (const frame_info_ptr &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,
   reuse 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_list *best_arch;
  tdesc_arch_data_up tdesc_data;
  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))
    {
      nds32_gdbarch_tdep *idep
	= gdbarch_tdep<nds32_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.get (), &fpu_freg,
			       &use_pseudo_fsrs))
    return NULL;

  /* Allocate space for the new architecture.  */
  gdbarch *gdbarch
    = gdbarch_alloc (&info, gdbarch_tdep_up (new nds32_gdbarch_tdep));
  nds32_gdbarch_tdep *tdep = gdbarch_tdep<nds32_gdbarch_tdep> (gdbarch);

  tdep->fpu_freg = fpu_freg;
  tdep->use_pseudo_fsrs = use_pseudo_fsrs;
  tdep->fs0_regnum = -1;
  tdep->elf_abi = elf_abi;

  set_gdbarch_wchar_bit (gdbarch, 16);
  set_gdbarch_wchar_signed (gdbarch, 0);

  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_deprecated_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, std::move (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_cooked_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 (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.tdesc_data = tdesc_data.get ();
  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_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_skip_prologue (gdbarch, nds32_skip_prologue);
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  set_gdbarch_breakpoint_kind_from_pc (gdbarch,
				       nds32_breakpoint::kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch,
				       nds32_breakpoint::bp_from_kind);

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

  /* 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_nds32_tdep ()
{
  /* Initialize gdbarch.  */
  gdbarch_register (bfd_arch_nds32, nds32_gdbarch_init);

  initialize_tdesc_nds32 ();
  nds32_init_reggroups ();
}
