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

   Copyright (C) 2022 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "arch-utils.h"
#include "dwarf2/frame.h"
#include "elf-bfd.h"
#include "frame-unwind.h"
#include "gdbcore.h"
#include "loongarch-tdep.h"
#include "target.h"
#include "target-descriptions.h"
#include "trad-frame.h"
#include "user-regs.h"

/* Fetch the instruction at PC.  */

static insn_t
loongarch_fetch_instruction (CORE_ADDR pc)
{
  size_t insn_len = loongarch_insn_length (0);
  gdb_byte buf[insn_len];
  int err;

  err = target_read_memory (pc, buf, insn_len);
  if (err)
    memory_error (TARGET_XFER_E_IO, pc);

  return extract_unsigned_integer (buf, insn_len, BFD_ENDIAN_LITTLE);
}

/* Return TRUE if INSN is a unconditional branch instruction, otherwise return FALSE.  */

static bool
loongarch_insn_is_uncond_branch (insn_t insn)
{
  if ((insn & 0xfc000000) == 0x4c000000		/* jirl  */
      || (insn & 0xfc000000) == 0x50000000	/* b     */
      || (insn & 0xfc000000) == 0x54000000)	/* bl    */
    return true;
  return false;
}

/* Return TRUE if INSN is a conditional branch instruction, otherwise return FALSE.  */

static bool
loongarch_insn_is_cond_branch (insn_t insn)
{
  if ((insn & 0xfc000000) == 0x58000000		/* beq   */
      || (insn & 0xfc000000) == 0x5c000000	/* bne   */
      || (insn & 0xfc000000) == 0x60000000	/* blt   */
      || (insn & 0xfc000000) == 0x64000000	/* bge	 */
      || (insn & 0xfc000000) == 0x68000000	/* bltu  */
      || (insn & 0xfc000000) == 0x6c000000	/* bgeu  */
      || (insn & 0xfc000000) == 0x40000000	/* beqz  */
      || (insn & 0xfc000000) == 0x44000000)	/* bnez  */
    return true;
  return false;
}

/* Return TRUE if INSN is a branch instruction, otherwise return FALSE.  */

static bool
loongarch_insn_is_branch (insn_t insn)
{
  bool is_uncond = loongarch_insn_is_uncond_branch (insn);
  bool is_cond = loongarch_insn_is_cond_branch (insn);

  return (is_uncond || is_cond);
}

/* Return TRUE if INSN is a Load Linked instruction, otherwise return FALSE.  */

static bool
loongarch_insn_is_ll (insn_t insn)
{
  if ((insn & 0xff000000) == 0x20000000		/* ll.w  */
      || (insn & 0xff000000) == 0x22000000)	/* ll.d  */
    return true;
  return false;
}

/* Return TRUE if INSN is a Store Conditional instruction, otherwise return FALSE.  */

static bool
loongarch_insn_is_sc (insn_t insn)
{
  if ((insn & 0xff000000) == 0x21000000		/* sc.w  */
      || (insn & 0xff000000) == 0x23000000)	/* sc.d  */
    return true;
  return false;
}

/* Analyze the function prologue from START_PC to LIMIT_PC.
   Return the address of the first instruction past the prologue.  */

static CORE_ADDR
loongarch_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc,
			 CORE_ADDR limit_pc, struct frame_info *this_frame,
			 struct trad_frame_cache *this_cache)
{
  CORE_ADDR cur_pc = start_pc, prologue_end = 0;
  int32_t sp = LOONGARCH_SP_REGNUM;
  int32_t fp = LOONGARCH_FP_REGNUM;
  int32_t reg_value[32] = {0};
  int32_t reg_used[32] = {1, 0};

  while (cur_pc < limit_pc)
    {
      insn_t insn = loongarch_fetch_instruction (cur_pc);
      size_t insn_len = loongarch_insn_length (insn);
      int32_t rd = loongarch_decode_imm ("0:5", insn, 0);
      int32_t rj = loongarch_decode_imm ("5:5", insn, 0);
      int32_t rk = loongarch_decode_imm ("10:5", insn, 0);
      int32_t si12 = loongarch_decode_imm ("10:12", insn, 1);
      int32_t si20 = loongarch_decode_imm ("5:20", insn, 1);

      if ((insn & 0xffc00000) == 0x02c00000	/* addi.d sp,sp,si12  */
	  && rd == sp && rj == sp && si12 < 0)
	{
	  prologue_end = cur_pc + insn_len;
	}
      else if ((insn & 0xffc00000) == 0x02c00000 /* addi.d fp,sp,si12  */
	       && rd == fp && rj == sp && si12 > 0)
	{
	  prologue_end = cur_pc + insn_len;
	}
      else if ((insn & 0xffc00000) == 0x29c00000 /* st.d rd,sp,si12  */
	       && rj == sp)
	{
	  prologue_end = cur_pc + insn_len;
	}
      else if ((insn & 0xff000000) == 0x27000000 /* stptr.d rd,sp,si14  */
	       && rj == sp)
	{
	  prologue_end = cur_pc + insn_len;
	}
      else if ((insn & 0xfe000000) == 0x14000000) /* lu12i.w rd,si20  */
	{
	  reg_value[rd] = si20 << 12;
	  reg_used[rd] = 1;
	}
      else if ((insn & 0xffc00000) == 0x03800000) /* ori rd,rj,si12  */
	{
	  if (reg_used[rj])
	    {
	      reg_value[rd] = reg_value[rj] | (si12 & 0xfff);
	      reg_used[rd] = 1;
	    }
	}
      else if ((insn & 0xffff8000) == 0x00108000 /* add.d sp,sp,rk  */
	       && rd == sp && rj == sp)
	{
	  if (reg_used[rk] == 1 && reg_value[rk] < 0)
	    {
	      prologue_end = cur_pc + insn_len;
	      break;
	    }
	}
      else if (loongarch_insn_is_branch (insn))
	{
	  break;
	}

      cur_pc += insn_len;
    }

  if (prologue_end == 0)
    prologue_end = cur_pc;

  return prologue_end;
}

/* Implement the loongarch_skip_prologue gdbarch method.  */

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

  /* 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, nullptr, &func_addr, nullptr))
    {
      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.  */
  CORE_ADDR limit_pc = skip_prologue_using_sal (gdbarch, pc);
  if (limit_pc == 0)
    limit_pc = pc + 100;	/* Arbitrary large number.  */

  return loongarch_scan_prologue (gdbarch, pc, limit_pc, nullptr, nullptr);
}

/* Decode the current instruction and determine the address of the
   next instruction.  */

static CORE_ADDR
loongarch_next_pc (struct regcache *regcache, CORE_ADDR cur_pc)
{
  struct gdbarch *gdbarch = regcache->arch ();
  loongarch_gdbarch_tdep *tdep = gdbarch_tdep<loongarch_gdbarch_tdep> (gdbarch);
  insn_t insn = loongarch_fetch_instruction (cur_pc);
  size_t insn_len = loongarch_insn_length (insn);
  CORE_ADDR next_pc = cur_pc + insn_len;

  if ((insn & 0xfc000000) == 0x4c000000)		/* jirl rd, rj, offs16  */
    {
      LONGEST rj = regcache_raw_get_signed (regcache,
		     loongarch_decode_imm ("5:5", insn, 0));
      next_pc = rj + loongarch_decode_imm ("10:16<<2", insn, 1);
    }
  else if ((insn & 0xfc000000) == 0x50000000		/* b    offs26  */
	   || (insn & 0xfc000000) == 0x54000000)	/* bl	offs26  */
    {
      next_pc = cur_pc + loongarch_decode_imm ("0:10|10:16<<2", insn, 1);
    }
  else if ((insn & 0xfc000000) == 0x58000000)		/* beq	rj, rd, offs16  */
    {
      LONGEST rj = regcache_raw_get_signed (regcache,
		     loongarch_decode_imm ("5:5", insn, 0));
      LONGEST rd = regcache_raw_get_signed (regcache,
		     loongarch_decode_imm ("0:5", insn, 0));
      if (rj == rd)
	next_pc = cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1);
    }
  else if ((insn & 0xfc000000) == 0x5c000000)		/* bne	rj, rd, offs16  */
    {
      LONGEST rj = regcache_raw_get_signed (regcache,
		     loongarch_decode_imm ("5:5", insn, 0));
      LONGEST rd = regcache_raw_get_signed (regcache,
		     loongarch_decode_imm ("0:5", insn, 0));
      if (rj != rd)
	next_pc = cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1);
    }
  else if ((insn & 0xfc000000) == 0x60000000)		/* blt	rj, rd, offs16  */
    {
      LONGEST rj = regcache_raw_get_signed (regcache,
		     loongarch_decode_imm ("5:5", insn, 0));
      LONGEST rd = regcache_raw_get_signed (regcache,
		     loongarch_decode_imm ("0:5", insn, 0));
      if (rj < rd)
	next_pc = cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1);
    }
  else if ((insn & 0xfc000000) == 0x64000000)		/* bge	rj, rd, offs16  */
    {
      LONGEST rj = regcache_raw_get_signed (regcache,
		     loongarch_decode_imm ("5:5", insn, 0));
      LONGEST rd = regcache_raw_get_signed (regcache,
		     loongarch_decode_imm ("0:5", insn, 0));
      if (rj >= rd)
	next_pc = cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1);
    }
  else if ((insn & 0xfc000000) == 0x68000000)		/* bltu	rj, rd, offs16  */
    {
      ULONGEST rj = regcache_raw_get_unsigned (regcache,
		      loongarch_decode_imm ("5:5", insn, 0));
      ULONGEST rd = regcache_raw_get_unsigned (regcache,
		      loongarch_decode_imm ("0:5", insn, 0));
      if (rj < rd)
	next_pc = cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1);
    }
  else if ((insn & 0xfc000000) == 0x6c000000)		/* bgeu	rj, rd, offs16  */
    {
      ULONGEST rj = regcache_raw_get_unsigned (regcache,
		      loongarch_decode_imm ("5:5", insn, 0));
      ULONGEST rd = regcache_raw_get_unsigned (regcache,
		      loongarch_decode_imm ("0:5", insn, 0));
      if (rj >= rd)
	next_pc = cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1);
    }
  else if ((insn & 0xfc000000) == 0x40000000)		/* beqz	rj, offs21  */
    {
      LONGEST rj = regcache_raw_get_signed (regcache,
		     loongarch_decode_imm ("5:5", insn, 0));
      if (rj == 0)
	next_pc = cur_pc + loongarch_decode_imm ("0:5|10:16<<2", insn, 1);
    }
  else if ((insn & 0xfc000000) == 0x44000000)		/* bnez	rj, offs21  */
    {
      LONGEST rj = regcache_raw_get_signed (regcache,
		     loongarch_decode_imm ("5:5", insn, 0));
      if (rj != 0)
	next_pc = cur_pc + loongarch_decode_imm ("0:5|10:16<<2", insn, 1);
    }
  else if ((insn & 0xffff8000) == 0x002b0000)		/* syscall  */
    {
      if (tdep->syscall_next_pc != nullptr)
	next_pc = tdep->syscall_next_pc (get_current_frame ());
    }

  return next_pc;
}

/* We can't put a breakpoint in the middle of a ll/sc atomic sequence,
   so look for the end of the sequence and put the breakpoint there.  */

static std::vector<CORE_ADDR>
loongarch_deal_with_atomic_sequence (struct regcache *regcache, CORE_ADDR cur_pc)
{
  CORE_ADDR next_pc;
  std::vector<CORE_ADDR> next_pcs;
  insn_t insn = loongarch_fetch_instruction (cur_pc);
  size_t insn_len = loongarch_insn_length (insn);
  const int atomic_sequence_length = 16;
  bool found_atomic_sequence_endpoint = false;

  /* Look for a Load Linked instruction which begins the atomic sequence.  */
  if (!loongarch_insn_is_ll (insn))
    return {};

  /* Assume that no atomic sequence is longer than "atomic_sequence_length" instructions.  */
  for (int insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
    {
      cur_pc += insn_len;
      insn = loongarch_fetch_instruction (cur_pc);

      /* Look for a unconditional branch instruction, fallback to the standard code.  */
      if (loongarch_insn_is_uncond_branch (insn))
	{
	  return {};
	}
      /* Look for a conditional branch instruction, put a breakpoint in its destination address.  */
      else if (loongarch_insn_is_cond_branch (insn))
	{
	  next_pc = loongarch_next_pc (regcache, cur_pc);
	  next_pcs.push_back (next_pc);
	}
      /* Look for a Store Conditional instruction which closes the atomic sequence.  */
      else if (loongarch_insn_is_sc (insn))
	{
	  found_atomic_sequence_endpoint = true;
	  next_pc = cur_pc + insn_len;
	  next_pcs.push_back (next_pc);
	  break;
	}
    }

  /* We didn't find a closing Store Conditional instruction, fallback to the standard code.  */
  if (!found_atomic_sequence_endpoint)
    return {};

  return next_pcs;
}

/* Implement the software_single_step gdbarch method  */

static std::vector<CORE_ADDR>
loongarch_software_single_step (struct regcache *regcache)
{
  CORE_ADDR cur_pc = regcache_read_pc (regcache);
  std::vector<CORE_ADDR> next_pcs
    = loongarch_deal_with_atomic_sequence (regcache, cur_pc);

  if (!next_pcs.empty ())
    return next_pcs;

  CORE_ADDR next_pc = loongarch_next_pc (regcache, cur_pc);

  return {next_pc};
}

/* Implement the frame_align gdbarch method.  */

static CORE_ADDR
loongarch_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return align_down (addr, 16);
}

/* Generate, or return the cached frame cache for frame unwinder.  */

static struct trad_frame_cache *
loongarch_frame_cache (struct frame_info *this_frame, void **this_cache)
{
  struct trad_frame_cache *cache;
  CORE_ADDR pc;

  if (*this_cache != nullptr)
    return (struct trad_frame_cache *) *this_cache;

  cache = trad_frame_cache_zalloc (this_frame);
  *this_cache = cache;

  trad_frame_set_reg_realreg (cache, LOONGARCH_PC_REGNUM, LOONGARCH_RA_REGNUM);

  pc = get_frame_address_in_block (this_frame);
  trad_frame_set_id (cache, frame_id_build_unavailable_stack (pc));

  return cache;
}

/* Implement the this_id callback for frame unwinder.  */

static void
loongarch_frame_this_id (struct frame_info *this_frame, void **prologue_cache,
			 struct frame_id *this_id)
{
  struct trad_frame_cache *info;

  info = loongarch_frame_cache (this_frame, prologue_cache);
  trad_frame_get_id (info, this_id);
}

/* Implement the prev_register callback for frame unwinder.  */

static struct value *
loongarch_frame_prev_register (struct frame_info *this_frame,
			       void **prologue_cache, int regnum)
{
  struct trad_frame_cache *info;

  info = loongarch_frame_cache (this_frame, prologue_cache);
  return trad_frame_get_register (info, this_frame, regnum);
}

static const struct frame_unwind loongarch_frame_unwind = {
  "loongarch prologue",
  /*.type	   =*/NORMAL_FRAME,
  /*.stop_reason   =*/default_frame_unwind_stop_reason,
  /*.this_id	   =*/loongarch_frame_this_id,
  /*.prev_register =*/loongarch_frame_prev_register,
  /*.unwind_data   =*/nullptr,
  /*.sniffer	   =*/default_frame_sniffer,
  /*.dealloc_cache =*/nullptr,
  /*.prev_arch	   =*/nullptr,
};

/* Write the contents of buffer VAL into the general-purpose argument
   register defined by GAR in REGCACHE.  GAR indicates the available
   general-purpose argument registers which should be a value in the
   range 1 to 8 (LOONGARCH_ARG_REGNUM), which correspond to registers
   a7 and a0 respectively, that is to say, regnum is a7 if GAR is 1,
   regnum is a6 if GAR is 2, regnum is a5 if GAR is 3, regnum is a4
   if GAR is 4, regnum is a3 if GAR is 5, regnum is a2 if GAR is 6,
   regnum is a1 if GAR is 7, regnum is a0 if GAR is 8.  */

static void
pass_in_gar (struct regcache *regcache, unsigned int gar, const gdb_byte *val)
{
  unsigned int regnum = LOONGARCH_ARG_REGNUM - gar + LOONGARCH_A0_REGNUM;
  regcache->cooked_write (regnum, val);
}

/* Write the contents of buffer VAL into the floating-point argument
   register defined by FAR in REGCACHE.  FAR indicates the available
   floating-point argument registers which should be a value in the
   range 1 to 8 (LOONGARCH_ARG_REGNUM), which correspond to registers
   f7 and f0 respectively, that is to say, regnum is f7 if FAR is 1,
   regnum is f6 if FAR is 2, regnum is f5 if FAR is 3, regnum is f4
   if FAR is 4, regnum is f3 if FAR is 5, regnum is f2 if FAR is 6,
   regnum is f1 if FAR is 7, regnum is f0 if FAR is 8.  */

static void
pass_in_far (struct regcache *regcache, unsigned int far, const gdb_byte *val)
{
  unsigned int regnum = LOONGARCH_ARG_REGNUM - far + LOONGARCH_FIRST_FP_REGNUM;
  regcache->cooked_write (regnum, val);
}

/* Pass a value on the stack.  */

static void
pass_on_stack (struct regcache *regcache, const gdb_byte *val,
	       size_t len, int align, gdb_byte **addr)
{
  align = align_up (align, 8);
  if (align > 16)
    align = 16;

  CORE_ADDR align_addr = (CORE_ADDR) (*addr);
  align_addr = align_up (align_addr, align);
  *addr = (gdb_byte *) align_addr;
  memcpy (*addr, val, len);
  *addr += len;
}

/* Compute the numbers of struct member.  */

static void
compute_struct_member (struct type *type,
		       unsigned int *fixed_point_members,
		       unsigned int *floating_point_members,
		       bool *first_member_is_fixed_point)
{
  for (int i = 0; i < type->num_fields (); i++)
    {
      struct type *field_type = check_typedef (type->field (i).type ());

      if (field_type->code () == TYPE_CODE_INT
	  || field_type->code () == TYPE_CODE_BOOL
	  || field_type->code () == TYPE_CODE_CHAR
	  || field_type->code () == TYPE_CODE_RANGE
	  || field_type->code () == TYPE_CODE_ENUM
	  || field_type->code () == TYPE_CODE_PTR)
      {
	(*fixed_point_members)++;

	if (*floating_point_members == 0)
	  *first_member_is_fixed_point = true;
      }
      else if (field_type->code () == TYPE_CODE_FLT)
	(*floating_point_members)++;
      else if (field_type->code () == TYPE_CODE_STRUCT)
	compute_struct_member (field_type,
			       fixed_point_members,
			       floating_point_members,
			       first_member_is_fixed_point);
      else if (field_type->code () == TYPE_CODE_COMPLEX)
	(*floating_point_members) += 2;
    }
}

/* Implement the push_dummy_call gdbarch method.  */

static CORE_ADDR
loongarch_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)
{
  int regsize = register_size (gdbarch, 0);
  unsigned int gar = LOONGARCH_ARG_REGNUM;
  unsigned int far = LOONGARCH_ARG_REGNUM;
  unsigned int fixed_point_members;
  unsigned int floating_point_members;
  bool first_member_is_fixed_point;
  gdb_byte buf[1024] = { 0 };
  gdb_byte *addr = buf;

  if (return_method != return_method_normal)
    pass_in_gar (regcache, gar--, (gdb_byte *) &struct_addr);

  for (int i = 0; i < nargs; i++)
    {
      struct value *arg = args[i];
      const gdb_byte *val = value_contents (arg).data ();
      struct type *type = check_typedef (value_type (arg));
      size_t len = TYPE_LENGTH (type);
      int align = type_align (type);
      enum type_code code = type->code ();

      switch (code)
	{
	case TYPE_CODE_INT:
	case TYPE_CODE_BOOL:
	case TYPE_CODE_CHAR:
	case TYPE_CODE_RANGE:
	case TYPE_CODE_ENUM:
	case TYPE_CODE_PTR:
	  {
	    /* integer or pointer type is passed in GAR.
	       If no GAR is available, it's passed on the stack.
	       When passed in registers or on the stack,
	       the unsigned integer scalars are zero-extended to GRLEN bits,
	       and the signed integer scalars are sign-extended.  */
	  if (type->is_unsigned ())
	    {
              ULONGEST data = extract_unsigned_integer (val, len, BFD_ENDIAN_LITTLE);
	      if (gar > 0)
		pass_in_gar (regcache, gar--, (gdb_byte *) &data);
	      else
		pass_on_stack (regcache, (gdb_byte *) &data, len, align, &addr);
            }
	  else
	    {
	      LONGEST data = extract_signed_integer (val, len, BFD_ENDIAN_LITTLE);
	      if (gar > 0)
		pass_in_gar (regcache, gar--, (gdb_byte *) &data);
	      else
		pass_on_stack (regcache, (gdb_byte *) &data, len, align, &addr);
            }
	  }
	  break;
	case TYPE_CODE_FLT:
	  if (len == 2 * regsize)
	    {
	      /* long double type is passed in a pair of GAR,
		 with the low-order GRLEN bits in the lower-numbered register
		 and the high-order GRLEN bits in the higher-numbered register.
		 If exactly one register is available,
		 the low-order GRLEN bits are passed in the register
		 and the high-order GRLEN bits are passed on the stack.
		 If no GAR is available, it's passed on the stack.  */
	      if (gar >= 2)
		{
		  pass_in_gar (regcache, gar--, val);
		  pass_in_gar (regcache, gar--, val + regsize);
		}
	      else if (gar == 1)
		{
		  pass_in_gar (regcache, gar--, val);
		  pass_on_stack (regcache, val + regsize, len - regsize, align, &addr);
		}
	      else
		{
		  pass_on_stack (regcache, val, len, align, &addr);
		}
	    }
	  else
	    {
	      /* The other floating-point type is passed in FAR.
		 If no FAR is available, it's passed in GAR.
		 If no GAR is available, it's passed on the stack.  */
	      if (far > 0)
		  pass_in_far (regcache, far--, val);
	      else if (gar > 0)
		  pass_in_gar (regcache, gar--, val);
	      else
		  pass_on_stack (regcache, val, len, align, &addr);
	    }
	  break;
	case TYPE_CODE_STRUCT:
	  {
	    fixed_point_members = 0;
	    floating_point_members = 0;
	    first_member_is_fixed_point = false;
	    compute_struct_member (type,
				   &fixed_point_members,
				   &floating_point_members,
				   &first_member_is_fixed_point);

	    if (len > 0 && len <= regsize)
	      {
		/* The structure has only fixed-point members.  */
		if (fixed_point_members > 0 && floating_point_members == 0)
		  {
		    /* If there is an available GAR,
		       the structure is passed through the GAR by value passing;
		       If no GAR is available, it's passed on the stack.  */
		    if (gar > 0)
		      pass_in_gar (regcache, gar--, val);
		    else
		      pass_on_stack (regcache, val, len, align, &addr);
		  }
		/* The structure has only floating-point members.  */
		else if (fixed_point_members == 0 && floating_point_members > 0)
		  {
		    /* The structure has one floating-point member.
		       The argument is passed in a FAR.
		       If no FAR is available, the value is passed in a GAR.
		       if no GAR is available, the value is passed on the stack.  */
		    if (floating_point_members == 1)
		      {
			if (far > 0)
			  pass_in_far (regcache, far--, val);
			else if (gar > 0)
			  pass_in_gar (regcache, gar--, val);
			else
			  pass_on_stack (regcache, val, len, align, &addr);
		      }
		    /* The structure has two floating-point members.
		       The argument is passed in a pair of available FAR,
		       with the low-order float member bits in the lower-numbered FAR
		       and the high-order float member bits in the higher-numbered FAR.
		       If the number of available FAR is less than 2, it's passed in a GAR,
		       and passed on the stack if no GAR is available.  */
		    else if (floating_point_members == 2)
		      {
			if (far >= 2)
			  {
			    pass_in_far (regcache, far--, val);
			    pass_in_far (regcache, far--, val + align);
			  }
			else if (gar > 0)
			  {
			    pass_in_gar (regcache, gar--, val);
			  }
			else
			  {
			    pass_on_stack (regcache, val, len, align, &addr);
			  }
		      }
		  }
		/* The structure has both fixed-point and floating-point members.  */
		else if (fixed_point_members > 0 && floating_point_members > 0)
		  {
		    /* The structure has one float member and multiple fixed-point members.
		       If there are available GAR, the structure is passed in a GAR,
		       and passed on the stack if no GAR is available.  */
		    if (floating_point_members == 1 && fixed_point_members > 1)
		      {
			if (gar > 0)
			  pass_in_gar (regcache, gar--, val);
			else
			  pass_on_stack (regcache, val, len, align, &addr);
		      }
		    /* The structure has one float member and one fixed-point member.
		       If one FAR and one GAR are available,
		       the floating-point member of the structure is passed in the FAR,
		       and the fixed-point member of the structure is passed in the GAR.
		       If no floating-point register but one GAR is available, it's passed in GAR;
		       If no GAR is available, it's passed on the stack.  */
		    else if (floating_point_members == 1 && fixed_point_members == 1)
		      {
			if (far > 0 && gar > 0)
			  {
			    if (first_member_is_fixed_point == false)
			      {
				pass_in_far (regcache, far--, val);
				pass_in_gar (regcache, gar--, val + align);
			      }
			    else
			      {
				pass_in_gar (regcache, gar--, val);
				pass_in_far (regcache, far--, val + align);
			      }
			  }
			else
			  {
			    if (gar > 0)
			      pass_in_gar (regcache, gar--, val);
			    else
			      pass_on_stack (regcache, val, len, align, &addr);
			  }
		      }
		  }
	      }
	    else if (len > regsize && len <= 2 * regsize)
	      {
		/* The structure has only fixed-point members.  */
		if (fixed_point_members > 0 && floating_point_members == 0)
		  {
		    /* The argument is passed in a pair of available GAR,
		       with the low-order bits in the lower-numbered GAR
		       and the high-order bits in the higher-numbered GAR.
		       If only one GAR is available,
		       the low-order bits are in the GAR
		       and the high-order bits are on the stack,
		       and passed on the stack if no GAR is available.  */
		    if (gar >= 2)
		      {
			pass_in_gar (regcache, gar--, val);
			pass_in_gar (regcache, gar--, val + regsize);
		      }
		    else if (gar == 1)
		      {
			pass_in_gar (regcache, gar--, val);
			pass_on_stack (regcache, val + regsize, len - regsize, align, &addr);
		      }
		    else
		      {
			pass_on_stack (regcache, val, len, align, &addr);
		      }
		  }
		/* The structure has only floating-point members.  */
		else if (fixed_point_members == 0 && floating_point_members > 0)
		  {
		    /* The structure has one long double member
		       or one double member and two adjacent float members
		       or 3-4 float members.
		       The argument is passed in a pair of available GAR,
		       with the low-order bits in the lower-numbered GAR
		       and the high-order bits in the higher-numbered GAR.
		       If only one GAR is available,
		       the low-order bits are in the GAR
		       and the high-order bits are on the stack,
		       and passed on the stack if no GAR is available.  */
		    if ((len == 16 && floating_point_members == 1)
			 || (len == 16 && floating_point_members == 3)
			 || (len == 12 && floating_point_members == 3)
			 || (len == 16 && floating_point_members == 4))
		      {
			if (gar >= 2)
			  {
			    pass_in_gar (regcache, gar--, val);
			    pass_in_gar (regcache, gar--, val + regsize);
			  }
			else if (gar == 1)
			  {
			    pass_in_gar (regcache, gar--, val);
			    pass_on_stack (regcache, val + regsize, len - regsize, align, &addr);
			  }
			else
			  {
			    pass_on_stack (regcache, val, len, align, &addr);
			  }
		      }
		    /* The structure has two double members
		       or one double member and one float member.
		       The argument is passed in a pair of available FAR,
		       with the low-order bits in the lower-numbered FAR
		       and the high-order bits in the higher-numbered FAR.
		       If no a pair of available FAR,
		       it's passed in a pair of available GAR,
		       with the low-order bits in the lower-numbered GAR
		       and the high-order bits in the higher-numbered GAR.
		       If only one GAR is available,
		       the low-order bits are in the GAR
		       and the high-order bits are on stack,
		       and passed on the stack if no GAR is available.  */
		    else if ((len == 16 && floating_point_members == 2)
			     || (len == 12 && floating_point_members == 2))
		      {
			if (far >= 2)
			  {
			    pass_in_far (regcache, far--, val);
			    pass_in_far (regcache, far--, val + regsize);
			  }
			else if (gar >= 2)
			  {
			    pass_in_gar (regcache, gar--, val);
			    pass_in_gar (regcache, gar--, val + regsize);
			  }
			else if (gar == 1)
			  {
			    pass_in_gar (regcache, gar--, val);
			    pass_on_stack (regcache, val + regsize, len - regsize, align, &addr);
			  }
			else
			  {
			    pass_on_stack (regcache, val, len, align, &addr);
			  }
		      }
		  }
		/* The structure has both fixed-point and floating-point members.  */
		else if (fixed_point_members > 0 && floating_point_members > 0)
		  {
		    /* The structure has one floating-point member and one fixed-point member.  */
		    if (floating_point_members == 1 && fixed_point_members == 1)
		      {
			/* If one FAR and one GAR are available,
			   the floating-point member of the structure is passed in the FAR,
			   and the fixed-point member of the structure is passed in the GAR;
			   If no floating-point registers but two GARs are available,
			   it's passed in the two GARs;
			   If only one GAR is available,
			   the low-order bits are in the GAR
			   and the high-order bits are on the stack;
			   And it's passed on the stack if no GAR is available.  */
			if (far > 0 && gar > 0)
			  {
			    if (first_member_is_fixed_point == false)
			      {
				pass_in_far (regcache, far--, val);
				pass_in_gar (regcache, gar--, val + regsize);
			      }
			    else
			      {
				pass_in_gar (regcache, gar--, val);
				pass_in_far (regcache, far--, val + regsize);
			      }
			  }
			else if (far == 0 && gar >= 2)
			  {
			    pass_in_gar (regcache, gar--, val);
			    pass_in_gar (regcache, gar--, val + regsize);
			  }
			else if (far == 0 && gar == 1)
			  {
			    pass_in_gar (regcache, gar--, val);
			    pass_on_stack (regcache, val + regsize, len - regsize, align, &addr);
			  }
			else if (far == 0 && gar == 0)
			  {
			    pass_on_stack (regcache, val, len, align, &addr);
			  }
		      }
		    else
		      {
			/* The argument is passed in a pair of available GAR,
			   with the low-order bits in the lower-numbered GAR
			   and the high-order bits in the higher-numbered GAR.
			   If only one GAR is available,
			   the low-order bits are in the GAR
			   and the high-order bits are on the stack,
			   and passed on the stack if no GAR is available.  */
			if (gar >= 2)
			  {
			    pass_in_gar (regcache, gar--, val);
			    pass_in_gar (regcache, gar--, val + regsize);
			  }
			else if (gar == 1)
			  {
			    pass_in_gar (regcache, gar--, val);
			    pass_on_stack (regcache, val + regsize, len - regsize, align, &addr);
			  }
			else
			  {
			    pass_on_stack (regcache, val, len, align, &addr);
			  }
		      }
		  }
	      }
	    else if (len > 2 * regsize)
	      {
	        /* It's passed by reference and are replaced in the argument list with the address.
		   If there is an available GAR, the reference is passed in the GAR,
		   and passed on the stack if no GAR is available.  */
		sp = align_down (sp - len, 16);
		write_memory (sp, val, len);

		if (gar > 0)
		  pass_in_gar (regcache, gar--, (const gdb_byte *) &sp);
		else
		  pass_on_stack (regcache, (const gdb_byte*) &sp, len, regsize, &addr);
	      }
	  }
	  break;
	case TYPE_CODE_UNION:
	  /* Union is passed in GAR or stack.  */
	  if (len > 0 && len <= regsize)
	    {
	      /* The argument is passed in a GAR,
		 or on the stack by value if no GAR is available.  */
	      if (gar > 0)
		pass_in_gar (regcache, gar--, val);
	      else
		pass_on_stack (regcache, val, len, align, &addr);
	    }
	  else if (len > regsize && len <= 2 * regsize)
	    {
	      /* The argument is passed in a pair of available GAR,
		 with the low-order bits in the lower-numbered GAR
		 and the high-order bits in the higher-numbered GAR.
		 If only one GAR is available,
		 the low-order bits are in the GAR
		 and the high-order bits are on the stack.
		 The arguments are passed on the stack when no GAR is available.  */
	      if (gar >= 2)
		{
		  pass_in_gar (regcache, gar--, val);
		  pass_in_gar (regcache, gar--, val + regsize);
		}
	      else if (gar == 1)
		{
		  pass_in_gar (regcache, gar--, val);
		  pass_on_stack (regcache, val + regsize, len - regsize, align, &addr);
		}
	      else
		{
		  pass_on_stack (regcache, val, len, align, &addr);
		}
	    }
	  else if (len > 2 * regsize)
	    {
	      /* It's passed by reference and are replaced in the argument list with the address.
		 If there is an available GAR, the reference is passed in the GAR,
		 and passed on the stack if no GAR is available.  */
	      sp = align_down (sp - len, 16);
	      write_memory (sp, val, len);

	      if (gar > 0)
		pass_in_gar (regcache, gar--, (const gdb_byte *) &sp);
	      else
		pass_on_stack (regcache, (const gdb_byte*) &sp, len, regsize, &addr);
	    }
	  break;
	case TYPE_CODE_COMPLEX:
	  {
	    struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
	    size_t target_len = TYPE_LENGTH (target_type);

	    if (target_len < regsize)
	      {
		/* The complex with two float members
		   is passed in a pair of available FAR,
		   with the low-order float member bits in the lower-numbered FAR
		   and the high-order float member bits in the higher-numbered FAR.
		   If the number of available FAR is less than 2, it's passed in a GAR,
		   and passed on the stack if no GAR is available.  */
		if (far >= 2)
		  {
		    pass_in_far (regcache, far--, val);
		    pass_in_far (regcache, far--, val + align);
		  }
		else if (gar > 0)
		  {
		    pass_in_gar (regcache, gar--, val);
		  }
		else
		  {
		    pass_on_stack (regcache, val, len, align, &addr);
		  }
	      }
	    else if (target_len == regsize)
	      {
		/* The complex with two double members
		   is passed in a pair of available FAR,
		   with the low-order bits in the lower-numbered FAR
		   and the high-order bits in the higher-numbered FAR.
		   If no a pair of available FAR,
		   it's passed in a pair of available GAR,
		   with the low-order bits in the lower-numbered GAR
		   and the high-order bits in the higher-numbered GAR.
		   If only one GAR is available,
		   the low-order bits are in the GAR
		   and the high-order bits are on stack,
		   and passed on the stack if no GAR is available.  */
		{
		  if (far >= 2)
		    {
		      pass_in_far (regcache, far--, val);
		      pass_in_far (regcache, far--, val + align);
		    }
		  else if (gar >= 2)
		    {
		      pass_in_gar (regcache, gar--, val);
		      pass_in_gar (regcache, gar--, val + align);
		    }
		  else if (gar == 1)
		    {
		      pass_in_gar (regcache, gar--, val);
		      pass_on_stack (regcache, val + align, len - align, align, &addr);
		    }
		  else
		    {
		      pass_on_stack (regcache, val, len, align, &addr);
		    }
		}
	      }
	    else if (target_len == 2 * regsize)
	      {
		/* The complex with two long double members
		   is passed by reference and are replaced in the argument list with the address.
		   If there is an available GAR, the reference is passed in the GAR,
		   and passed on the stack if no GAR is available.  */
		sp = align_down (sp - len, 16);
		write_memory (sp, val, len);

		if (gar > 0)
		  pass_in_gar (regcache, gar--, (const gdb_byte *) &sp);
		else
		  pass_on_stack (regcache, (const gdb_byte*) &sp, regsize, regsize, &addr);
	      }
	  }
	  break;
	default:
	  break;
	}
    }

  if (addr > buf)
    {
      sp -= addr - buf;
      sp = align_down (sp, 16);
      write_memory (sp, buf, addr - buf);
    }

  regcache_cooked_write_unsigned (regcache, LOONGARCH_RA_REGNUM, bp_addr);
  regcache_cooked_write_unsigned (regcache, LOONGARCH_SP_REGNUM, sp);

  return sp;
}

/* Partial transfer of a cooked register.  */

static void
loongarch_xfer_reg (struct regcache *regcache,
		    int regnum, int len, gdb_byte *readbuf,
		    const gdb_byte *writebuf, size_t offset)
{
  if (readbuf)
    regcache->cooked_read_part (regnum, 0, len, readbuf + offset);
  if (writebuf)
    regcache->cooked_write_part (regnum, 0, len, writebuf + offset);
}

/* Implement the return_value gdbarch method.  */

static enum return_value_convention
loongarch_return_value (struct gdbarch *gdbarch, struct value *function,
			struct type *type, struct regcache *regcache,
			gdb_byte *readbuf, const gdb_byte *writebuf)
{
  int regsize = register_size (gdbarch, 0);
  enum type_code code = type->code ();
  size_t len = TYPE_LENGTH (type);
  unsigned int fixed_point_members;
  unsigned int floating_point_members;
  bool first_member_is_fixed_point;
  int a0 = LOONGARCH_A0_REGNUM;
  int a1 = LOONGARCH_A0_REGNUM + 1;
  int f0 = LOONGARCH_FIRST_FP_REGNUM;
  int f1 = LOONGARCH_FIRST_FP_REGNUM + 1;

  if (len > 2 * regsize)
    return RETURN_VALUE_STRUCT_CONVENTION;

  switch (code)
    {
    case TYPE_CODE_INT:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_PTR:
      {
	/* integer or pointer type.
	   The return value is passed in a0,
	   the unsigned integer scalars are zero-extended to GRLEN bits,
	   and the signed integer scalars are sign-extended.  */
	if (writebuf)
	  {
	    gdb_byte buf[regsize];
	    if (type->is_unsigned ())
	      {
		ULONGEST data = extract_unsigned_integer (writebuf, len, BFD_ENDIAN_LITTLE);
		store_unsigned_integer (buf, regsize, BFD_ENDIAN_LITTLE, data);
	      }
	    else
	      {
		LONGEST data = extract_signed_integer (writebuf, len, BFD_ENDIAN_LITTLE);
		store_signed_integer (buf, regsize, BFD_ENDIAN_LITTLE, data);
	      }
	    loongarch_xfer_reg (regcache, a0, regsize, nullptr, buf, 0);
	  }
	else
	  loongarch_xfer_reg (regcache, a0, len, readbuf, nullptr, 0);
      }
      break;
    case TYPE_CODE_FLT:
      /* long double type.
	 The return value is passed in a0 and a1.  */
      if (len == 2 * regsize)
	{
	  loongarch_xfer_reg (regcache, a0, regsize, readbuf, writebuf, 0);
	  loongarch_xfer_reg (regcache, a1, len - regsize, readbuf, writebuf, regsize);
	}
      /* float or double type.
	 The return value is passed in f0.  */
      else
	{
	  loongarch_xfer_reg (regcache, f0, len, readbuf, writebuf, 0);
	}
      break;
    case TYPE_CODE_STRUCT:
      {
	fixed_point_members = 0;
	floating_point_members = 0;
	first_member_is_fixed_point = false;
	compute_struct_member (type,
			       &fixed_point_members,
			       &floating_point_members,
			       &first_member_is_fixed_point);

	if (len > 0 && len <= regsize)
	  {
	    /* The structure has only fixed-point members.  */
	    if (fixed_point_members > 0 && floating_point_members == 0)
	      {
		/* The return value is passed in a0.  */
		loongarch_xfer_reg (regcache, a0, len, readbuf, writebuf, 0);
	      }
	    /* The structure has only floating-point members.  */
	    else if (fixed_point_members == 0 && floating_point_members > 0)
	      {
		/* The structure has one floating-point member.
		   The return value is passed in f0.  */
		if (floating_point_members == 1)
		  {
		    loongarch_xfer_reg (regcache, f0, len, readbuf, writebuf, 0);
		  }
		/* The structure has two floating-point members.
		   The return value is passed in f0 and f1.  */
		else if (floating_point_members == 2)
		  {
		    loongarch_xfer_reg (regcache, f0, len / 2, readbuf, writebuf, 0);
		    loongarch_xfer_reg (regcache, f1, len / 2, readbuf, writebuf, len / 2);
		  }
	      }
	    /* The structure has both fixed-point and floating-point members.  */
	    else if (fixed_point_members > 0 && floating_point_members > 0)
	      {
		/* The structure has one float member and multiple fixed-point members.
		   The return value is passed in a0.  */
		if (floating_point_members == 1 && fixed_point_members > 1)
		  {
		    loongarch_xfer_reg (regcache, a0, len, readbuf, writebuf, 0);
		  }
		/* The structure has one float member and one fixed-point member.  */
		else if (floating_point_members == 1 && fixed_point_members == 1)
		  {
		    /* The return value is passed in f0 and a0 if the first member is floating-point.  */
		    if (first_member_is_fixed_point == false)
		      {
			loongarch_xfer_reg (regcache, f0, regsize / 2, readbuf, writebuf, 0);
			loongarch_xfer_reg (regcache, a0, regsize / 2, readbuf, writebuf, regsize / 2);
		      }
		    /* The return value is passed in a0 and f0 if the first member is fixed-point.  */
		    else
		      {
			loongarch_xfer_reg (regcache, a0, regsize / 2, readbuf, writebuf, 0);
			loongarch_xfer_reg (regcache, f0, regsize / 2, readbuf, writebuf, regsize / 2);
		      }
		  }
	      }
	  }
	else if (len > regsize && len <= 2 * regsize)
	  {
	    /* The structure has only fixed-point members.  */
	    if (fixed_point_members > 0 && floating_point_members == 0)
	      {
		/* The return value is passed in a0 and a1.  */
		loongarch_xfer_reg (regcache, a0, regsize, readbuf, writebuf, 0);
		loongarch_xfer_reg (regcache, a1, len - regsize, readbuf, writebuf, regsize);
	      }
	    /* The structure has only floating-point members.  */
	    else if (fixed_point_members == 0 && floating_point_members > 0)
	      {
		/* The structure has one long double member
		   or one double member and two adjacent float members
		   or 3-4 float members.
		   The return value is passed in a0 and a1.  */
		if ((len == 16 && floating_point_members == 1)
		    || (len == 16 && floating_point_members == 3)
		    || (len == 12 && floating_point_members == 3)
		    || (len == 16 && floating_point_members == 4))
		  {
		    loongarch_xfer_reg (regcache, a0, regsize, readbuf, writebuf, 0);
		    loongarch_xfer_reg (regcache, a1, len - regsize, readbuf, writebuf, regsize);
		  }
		/* The structure has two double members
		   or one double member and one float member.
		   The return value is passed in f0 and f1.  */
		else if ((len == 16 && floating_point_members == 2)
			 || (len == 12 && floating_point_members == 2))
		  {
		    loongarch_xfer_reg (regcache, f0, regsize, readbuf, writebuf, 0);
		    loongarch_xfer_reg (regcache, f1, len - regsize, readbuf, writebuf, regsize);
		  }
	      }
	    /* The structure has both fixed-point and floating-point members.  */
	    else if (fixed_point_members > 0 && floating_point_members > 0)
	      {
		/* The structure has one floating-point member and one fixed-point member.  */
		if (floating_point_members == 1 && fixed_point_members == 1)
		  {
		    /* The return value is passed in f0 and a0 if the first member is floating-point.  */
		    if (first_member_is_fixed_point == false)
		      {
			loongarch_xfer_reg (regcache, f0, regsize, readbuf, writebuf, 0);
			loongarch_xfer_reg (regcache, a0, len - regsize, readbuf, writebuf, regsize);
		      }
		    /* The return value is passed in a0 and f0 if the first member is fixed-point.  */
		    else
		      {
			loongarch_xfer_reg (regcache, a0, regsize, readbuf, writebuf, 0);
			loongarch_xfer_reg (regcache, f0, len - regsize, readbuf, writebuf, regsize);
		      }
		  }
		else
		  {
		    /* The return value is passed in a0 and a1.  */
		    loongarch_xfer_reg (regcache, a0, regsize, readbuf, writebuf, 0);
		    loongarch_xfer_reg (regcache, a1, len - regsize, readbuf, writebuf, regsize);
		  }
	      }
	  }
      }
      break;
    case TYPE_CODE_UNION:
      if (len > 0 && len <= regsize)
	{
	  /* The return value is passed in a0.  */
	  loongarch_xfer_reg (regcache, a0, len, readbuf, writebuf, 0);
	}
      else if (len > regsize && len <= 2 * regsize)
	{
	  /* The return value is passed in a0 and a1.  */
	  loongarch_xfer_reg (regcache, a0, regsize, readbuf, writebuf, 0);
	  loongarch_xfer_reg (regcache, a1, len - regsize, readbuf, writebuf, regsize);
	}
      break;
    case TYPE_CODE_COMPLEX:
      {
	/* The return value is passed in f0 and f1.  */
	loongarch_xfer_reg (regcache, f0, len / 2, readbuf, writebuf, 0);
	loongarch_xfer_reg (regcache, f1, len / 2, readbuf, writebuf, len / 2);
      }
      break;
    default:
      break;
    }

  return RETURN_VALUE_REGISTER_CONVENTION;
}

/* Implement the dwarf2_reg_to_regnum gdbarch method.  */

static int
loongarch_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int regnum)
{
  if (regnum >= 0 && regnum < 32)
    return regnum;
  else if (regnum >= 32 && regnum < 66)
    return LOONGARCH_FIRST_FP_REGNUM + regnum - 32;
  else
    return -1;
}

static constexpr gdb_byte loongarch_default_breakpoint[] = {0x05, 0x00, 0x2a, 0x00};
typedef BP_MANIPULATION (loongarch_default_breakpoint) loongarch_breakpoint;

/* Extract a set of required target features out of ABFD.  If ABFD is nullptr
   then a LOONGARCH_GDBARCH_FEATURES is returned in its default state.  */

static struct loongarch_gdbarch_features
loongarch_features_from_bfd (const bfd *abfd)
{
  struct loongarch_gdbarch_features features;

  /* Now try to improve on the defaults by looking at the binary we are
     going to execute.  We assume the user knows what they are doing and
     that the target will match the binary.  Remember, this code path is
     only used at all if the target hasn't given us a description, so this
     is really a last ditched effort to do something sane before giving
     up.  */
  if (abfd != nullptr && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
    {
      unsigned char eclass = elf_elfheader (abfd)->e_ident[EI_CLASS];
      int e_flags = elf_elfheader (abfd)->e_flags;

      if (eclass == ELFCLASS32)
	features.xlen = 4;
      else if (eclass == ELFCLASS64)
	features.xlen = 8;
      else
	internal_error (__FILE__, __LINE__,
			_("unknown ELF header class %d"), eclass);

      if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
	features.fputype = SINGLE_FLOAT;
      else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
	features.fputype = DOUBLE_FLOAT;
    }

  return features;
}

/* Find a suitable default target description.  Use the contents of INFO,
   specifically the bfd object being executed, to guide the selection of a
   suitable default target description.  */

static const struct target_desc *
loongarch_find_default_target_description (const struct gdbarch_info info)
{
  /* Extract desired feature set from INFO.  */
  struct loongarch_gdbarch_features features
    = loongarch_features_from_bfd (info.abfd);

  /* If the XLEN field is still 0 then we got nothing useful from INFO.BFD,
     maybe there was no bfd object.  In this case we fall back to a minimal
     useful target, the x-register size is selected based on the architecture
     from INFO.  */
  if (features.xlen == 0)
    features.xlen = info.bfd_arch_info->bits_per_address == 32 ? 4 : 8;

  /* If the FPUTYPE field is still 0 then we got nothing useful from INFO.BFD,
     maybe there was no bfd object.  In this case we fall back to a usual useful
     target with double float.  */
  if (features.fputype == 0)
    features.fputype = DOUBLE_FLOAT;

  /* Now build a target description based on the feature set.  */
  return loongarch_lookup_target_description (features);
}

/* Initialize the current architecture based on INFO  */

static struct gdbarch *
loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  size_t regnum = 0;
  struct loongarch_gdbarch_features features;
  tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();
  loongarch_gdbarch_tdep *tdep = new loongarch_gdbarch_tdep;
  const struct target_desc *tdesc = info.target_desc;

  /* Ensure we always have a target description.  */
  if (!tdesc_has_registers (tdesc))
    tdesc = loongarch_find_default_target_description (info);

  const struct tdesc_feature *feature_cpu
    = tdesc_find_feature (tdesc, "org.gnu.gdb.loongarch.base");
  if (feature_cpu == nullptr)
    return nullptr;


  /* Validate the description provides the mandatory base registers
     and allocate their numbers.  */
  bool valid_p = true;
  for (int i = 0; i < 32; i++)
    valid_p &= tdesc_numbered_register (feature_cpu, tdesc_data.get (), regnum++,
					loongarch_r_normal_name[i] + 1);
  valid_p &= tdesc_numbered_register (feature_cpu, tdesc_data.get (), regnum++, "orig_a0");
  valid_p &= tdesc_numbered_register (feature_cpu, tdesc_data.get (), regnum++, "pc");
  valid_p &= tdesc_numbered_register (feature_cpu, tdesc_data.get (), regnum++, "badv");
  if (!valid_p)
    return nullptr;

  const struct tdesc_feature *feature_fpu
    = tdesc_find_feature (tdesc, "org.gnu.gdb.loongarch.fpu");
  if (feature_fpu == nullptr)
    return nullptr;

  /* Validate the description provides the fpu registers and
     allocate their numbers.  */
  regnum = LOONGARCH_FIRST_FP_REGNUM;
  for (int i = 0; i < 32; i++)
    valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (), regnum++,
					loongarch_f_normal_name[i] + 1);
  valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (), regnum++, "fcc");
  valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (), regnum++, "fcsr");
  if (!valid_p)
    return nullptr;

  /* LoongArch code is always little-endian.  */
  info.byte_order_for_code = BFD_ENDIAN_LITTLE;

  /* Have a look at what the supplied (if any) bfd object requires of the
     target, then check that this matches with what the target is
     providing.  */
  struct loongarch_gdbarch_features abi_features
    = loongarch_features_from_bfd (info.abfd);

  /* If the ABI_FEATURES xlen or fputype is 0 then this indicates we got
     no useful abi features from the INFO object.  In this case we just
     treat the hardware features as defining the abi.  */
  if (abi_features.xlen == 0)
    {
      int xlen_bitsize = tdesc_register_bitsize (feature_cpu, "pc");
      features.xlen = (xlen_bitsize / 8);
      features.fputype = abi_features.fputype;
      abi_features = features;
    }
  if (abi_features.fputype == 0)
    {
      features.xlen = abi_features.xlen;
      features.fputype = DOUBLE_FLOAT;
      abi_features = features;
    }

  /* Find a candidate among the list of pre-declared architectures.  */
  for (arches = gdbarch_list_lookup_by_info (arches, &info);
       arches != nullptr;
       arches = gdbarch_list_lookup_by_info (arches->next, &info))
    {
      /* Check that the feature set of the ARCHES matches the feature set
	 we are looking for.  If it doesn't then we can't reuse this
	 gdbarch.  */
      loongarch_gdbarch_tdep *candidate_tdep
	= gdbarch_tdep<loongarch_gdbarch_tdep> (arches->gdbarch);

      if (candidate_tdep->abi_features != abi_features)
	continue;

      break;
    }

  if (arches != nullptr)
    return arches->gdbarch;

  /* None found, so create a new architecture from the information provided.  */
  struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
  tdep->abi_features = abi_features;

  /* Target data types.  */
  set_gdbarch_short_bit (gdbarch, 16);
  set_gdbarch_int_bit (gdbarch, 32);
  set_gdbarch_long_bit (gdbarch, info.bfd_arch_info->bits_per_address);
  set_gdbarch_long_long_bit (gdbarch, 64);
  set_gdbarch_float_bit (gdbarch, 32);
  set_gdbarch_double_bit (gdbarch, 64);
  set_gdbarch_long_double_bit (gdbarch, 128);
  set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad);
  set_gdbarch_ptr_bit (gdbarch, info.bfd_arch_info->bits_per_address);
  set_gdbarch_char_signed (gdbarch, 0);

  info.target_desc = tdesc;
  info.tdesc_data = tdesc_data.get ();

  /* Information about registers.  */
  set_gdbarch_num_regs (gdbarch, regnum);
  set_gdbarch_sp_regnum (gdbarch, LOONGARCH_SP_REGNUM);
  set_gdbarch_pc_regnum (gdbarch, LOONGARCH_PC_REGNUM);

  /* Finalise the target description registers.  */
  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

  /* Functions handling dummy frames.  */
  set_gdbarch_push_dummy_call (gdbarch, loongarch_push_dummy_call);

  /* Return value info  */
  set_gdbarch_return_value (gdbarch, loongarch_return_value);

  /* Advance PC across function entry code.  */
  set_gdbarch_skip_prologue (gdbarch, loongarch_skip_prologue);

  /* Stack grows downward.  */
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);

  /* Frame info.  */
  set_gdbarch_frame_align (gdbarch, loongarch_frame_align);

  /* Breakpoint manipulation.  */
  set_gdbarch_software_single_step (gdbarch, loongarch_software_single_step);
  set_gdbarch_breakpoint_kind_from_pc (gdbarch, loongarch_breakpoint::kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch, loongarch_breakpoint::bp_from_kind);

  /* Frame unwinders. Use DWARF debug info if available, otherwise use our own unwinder.  */
  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, loongarch_dwarf2_reg_to_regnum);
  dwarf2_append_unwinders (gdbarch);
  frame_unwind_append_unwinder (gdbarch, &loongarch_frame_unwind);

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

  return gdbarch;
}

void _initialize_loongarch_tdep ();
void
_initialize_loongarch_tdep ()
{
  gdbarch_register (bfd_arch_loongarch, loongarch_gdbarch_init, nullptr);
}
