/* 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)
{
  int i;

  auto *cache = frame_obstack_zalloc<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.get ();

  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;
}

INIT_GDB_FILE (nds32_tdep)
{
  /* Initialize gdbarch.  */
  gdbarch_register (bfd_arch_nds32, nds32_gdbarch_init);

  initialize_tdesc_nds32 ();
  nds32_init_reggroups ();
}
