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

   Copyright (C) 2022-2024 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 "arch-utils.h"
#include "dwarf2/frame.h"
#include "elf-bfd.h"
#include "extract-store-integer.h"
#include "frame-unwind.h"
#include "gdbcore.h"
#include "loongarch-tdep.h"
#include "reggroups.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_vector buf (insn_len);
  int err;

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

  return extract_unsigned_integer (buf.data (), 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, const frame_info_ptr &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};
}

/* Callback function for user_reg_add.  */

static struct value *
value_of_loongarch_user_reg (const frame_info_ptr &frame, const void *baton)
{
  return value_of_register ((long long) baton,
			    get_next_frame_sentinel_okay (frame));
}

/* 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 (const frame_info_ptr &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 (const frame_info_ptr &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 (const frame_info_ptr &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,
		       bool *has_long_double)
{
  for (int i = 0; i < type->num_fields (); i++)
    {
      /* Ignore any static fields.  */
      if (type->field (i).is_static ())
	continue;

      struct type *field_type = check_typedef (type->field (i).type ());

      if ((field_type->code () == TYPE_CODE_FLT
	   && field_type->length () == 16)
	  || (field_type->code () == TYPE_CODE_COMPLEX
	      && field_type->length () == 32))
	*has_long_double = true;

      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,
			       has_long_double);
      else if (field_type->code () == TYPE_CODE_COMPLEX)
	(*floating_point_members) += 2;
    }
}

/* Compute the lengths and offsets of struct member.  */

static void
struct_member_info (struct type *type,
		    unsigned int *member_offsets,
		    unsigned int *member_lens,
		    unsigned int offset,
		    unsigned int *fields)
{
  unsigned int count = type->num_fields ();
  unsigned int i;

  for (i = 0; i < count; ++i)
    {
      if (type->field (i).loc_kind () != FIELD_LOC_KIND_BITPOS)
	continue;

      struct type *field_type = check_typedef (type->field (i).type ());
      int field_offset
	= offset + type->field (i).loc_bitpos () / TARGET_CHAR_BIT;

      switch (field_type->code ())
	{
	case TYPE_CODE_STRUCT:
	  struct_member_info (field_type, member_offsets, member_lens,
			      field_offset, fields);
	  break;

	case TYPE_CODE_COMPLEX:
	  if (*fields == 0)
	    {
	      /* _Complex float */
	      if (field_type->length () == 8)
		{
		  member_offsets[0] = field_offset;
		  member_offsets[1] = field_offset + 4;
		  member_lens[0] = member_lens[1] = 4;
		  *fields = 2;
		}
	      /* _Complex double */
	      else if (field_type->length () == 16)
		{
		  member_offsets[0] = field_offset;
		  member_offsets[1] = field_offset + 8;
		  member_lens[0] = member_lens[1] = 8;
		  *fields = 2;
		}
	    }
	  break;

	default:
	  if (*fields < 2)
	    {
	      member_offsets[*fields] = field_offset;
	      member_lens[*fields] = field_type->length ();
	    }
	  (*fields)++;
	  break;
	}

      /* only has special handling for structures with 1 or 2 fields. */
      if (*fields > 2)
	return;
    }
}

/* 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;
  bool has_long_double;
  unsigned int member_offsets[2];
  unsigned int member_lens[2];
  unsigned int fields;
  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 = arg->contents ().data ();
      struct type *type = check_typedef (arg->type ());
      size_t len = type->length ();
      int align = type_align (type);
      enum type_code code = type->code ();
      struct type *func_type = check_typedef (function->type ());
      bool varargs = (func_type->has_varargs () && i >= func_type->num_fields ());

      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)
	    {
	      if (!varargs)
		{
		  /* 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
		{
		  /* Variadic arguments are passed in GARs
		     in the same manner as named arguments.
		     And after a variadic argument has been passed on the stack,
		     all future arguments will also be passed on the stack,
		     i.e., the last argument register may be left unused
		     due to the aligned register pair rule.
		     long double data type is passed in an aligned GAR pair,
		     the first register in the pair is even-numbered.  */
		  if (gar >= 2)
		    {
		      if (gar % 2 == 0)
			{
			  pass_in_gar (regcache, gar--, val);
			  pass_in_gar (regcache, gar--, val + regsize);
			}
		      else
			{
			  gar--;
			  pass_in_gar (regcache, gar--, val);
			  pass_in_gar (regcache, gar--, val + regsize);
			}
		    }
		  else if (gar == 1)
		    {
		      gar--;
		      pass_on_stack (regcache, val, len, 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 (!varargs && 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;
	    has_long_double = false;
	    member_offsets[0] = member_offsets[1] = 0;
	    member_lens[0] = member_offsets[1] = 0;
	    fields = 0;
	    compute_struct_member (type,
				   &fixed_point_members,
				   &floating_point_members,
				   &first_member_is_fixed_point,
				   &has_long_double);
	    struct_member_info (type, member_offsets, member_lens, 0, &fields);
	    /* If the structure consists of one floating-point member within
	       FRLEN bits wide, it is passed in an FAR if available. If the
	       structure consists of two floating-point members both within
	       FRLEN bits wide, it is passed in two FARs if available. If the
	       structure consists of one integer member within GRLEN bits wide
	       and one floating-point member within FRLEN bits wide, it is
	       passed in a GAR and an FAR if available. */
	    if (has_long_double == false
		&& ((fixed_point_members == 0 && floating_point_members == 1
		     && far >= 1)
		    || (fixed_point_members == 0 && floating_point_members == 2
			&& far >= 2)
		    || (fixed_point_members == 1 && floating_point_members == 1
			&& far >= 1 && gar >= 1)))
	      {
		if (fixed_point_members == 0 && floating_point_members == 1)
		  {
		    pass_in_far (regcache, far--, val + member_offsets[0]);
		  }
		else if (fixed_point_members == 0 && floating_point_members == 2)
		  {
		    pass_in_far (regcache, far--, val + member_offsets[0]);
		    pass_in_far (regcache, far--, val + member_offsets[1]);
		  }
		else if (fixed_point_members == 1 && floating_point_members == 1)
		  {
		    if (first_member_is_fixed_point == false)
		      {
			pass_in_far (regcache, far--, val + member_offsets[0]);
			pass_in_gar (regcache, gar--, val + member_offsets[1]);
		      }
		    else
		      {
			pass_in_gar (regcache, gar--, val + member_offsets[0]);
			pass_in_far (regcache, far--, val + member_offsets[1]);
		      }
		  }
	      }
	    else 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 (!varargs && 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 (!varargs && 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 (!varargs && 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)
			  {
			    if (!varargs)
			      {
				pass_in_gar (regcache, gar--, val);
				pass_on_stack (regcache, val + regsize, len - regsize, align, &addr);
			      }
			    else
			      {
				gar--;
				pass_on_stack (regcache, val, len, 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 (!varargs && 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 (!varargs && 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 ((!varargs && far == 0 && gar >= 2) || (varargs && gar >= 2))
			  {
			    pass_in_gar (regcache, gar--, val);
			    pass_in_gar (regcache, gar--, val + regsize);
			  }
			else if ((!varargs && far == 0 && gar == 1) || (varargs && gar == 1))
			  {
			    pass_in_gar (regcache, gar--, val);
			    pass_on_stack (regcache, val + regsize, len - regsize, align, &addr);
			  }
			else if ((!varargs && far == 0 && gar == 0) || (varargs && 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 ());
	    size_t target_len = target_type->length ();

	    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 (!varargs && 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 (!varargs && 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 ();
  unsigned int fixed_point_members;
  unsigned int floating_point_members;
  bool first_member_is_fixed_point;
  bool has_long_double;
  unsigned int member_offsets[2];
  unsigned int member_lens[2];
  unsigned int fields;
  int a0 = LOONGARCH_A0_REGNUM;
  int a1 = LOONGARCH_A0_REGNUM + 1;
  int f0 = LOONGARCH_FIRST_FP_REGNUM;
  int f1 = LOONGARCH_FIRST_FP_REGNUM + 1;

  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_vector buf (regsize);
	    if (type->is_unsigned ())
	      {
		ULONGEST data = extract_unsigned_integer (writebuf, len,
							  BFD_ENDIAN_LITTLE);
		store_unsigned_integer (buf.data (), regsize,
					BFD_ENDIAN_LITTLE, data);
	      }
	    else
	      {
		LONGEST data
		  = extract_signed_integer (writebuf, len, BFD_ENDIAN_LITTLE);
		store_signed_integer (buf.data (), regsize, BFD_ENDIAN_LITTLE,
				      data);
	      }

	    loongarch_xfer_reg (regcache, a0, regsize, nullptr, buf.data (),
				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;
	has_long_double = false;
	member_offsets[0] = member_offsets[1] = 0;
	member_lens[0] = member_offsets[1] = 0;
	fields = 0;
	compute_struct_member (type,
			       &fixed_point_members,
			       &floating_point_members,
			       &first_member_is_fixed_point,
			       &has_long_double);
	struct_member_info (type, member_offsets, member_lens, 0, &fields);
	/* struct consists of one floating-point member;
	   struct consists of two floating-point members;
	   struct consists of one floating-point member
	   and one integer member. */
	if (has_long_double == false
	    && ((fixed_point_members == 0 && floating_point_members == 1)
		|| (fixed_point_members == 0 && floating_point_members == 2)
		|| (fixed_point_members == 1 && floating_point_members == 1)))
	  {
	    if (fixed_point_members == 0 && floating_point_members == 1)
	      {
		loongarch_xfer_reg (regcache, f0, member_lens[0], readbuf,
				    writebuf, member_offsets[0]);
	      }
	    else if (fixed_point_members == 0 && floating_point_members == 2)
	      {
		loongarch_xfer_reg (regcache, f0, member_lens[0], readbuf,
				    writebuf, member_offsets[0]);
		loongarch_xfer_reg (regcache, f1, member_lens[1], readbuf,
				    writebuf, member_offsets[1]);
	      }
	    else if (fixed_point_members == 1 && floating_point_members == 1)
	      {
		if (first_member_is_fixed_point == false)
		  {
		    loongarch_xfer_reg (regcache, f0, member_lens[0], readbuf,
					writebuf, member_offsets[0]);
		    loongarch_xfer_reg (regcache, a0, member_lens[1], readbuf,
					writebuf, member_offsets[1]);
		  }
		else
		  {
		    loongarch_xfer_reg (regcache, a0, member_lens[0], readbuf,
					writebuf, member_offsets[0]);
		    loongarch_xfer_reg (regcache, f0, member_lens[1], readbuf,
					writebuf, member_offsets[1]);
		  }
	      }
	  }
	else 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);
		  }
	      }
	  }
	else if (len > 2 * regsize)
	  return RETURN_VALUE_STRUCT_CONVENTION;
      }
      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);
	}
      else if (len > 2 * regsize)
	return RETURN_VALUE_STRUCT_CONVENTION;
      break;
    case TYPE_CODE_COMPLEX:
      if (len > 0 && len <= 2 * regsize)
	{
	  /* 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);
	}
      else if (len > 2 * regsize)
	return RETURN_VALUE_STRUCT_CONVENTION;
      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 (_("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);
}

static int
loongarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
			       const struct reggroup *group)
{
  if (gdbarch_register_name (gdbarch, regnum) == NULL
      || *gdbarch_register_name (gdbarch, regnum) == '\0')
    return 0;

  int raw_p = regnum < gdbarch_num_regs (gdbarch);

  if (group == save_reggroup || group == restore_reggroup)
    return raw_p;

  if (group == all_reggroup)
    return 1;

  if (0 <= regnum && regnum <= LOONGARCH_BADV_REGNUM)
    return group == general_reggroup;

  /* Only ORIG_A0, PC, BADV in general_reggroup */
  if (group == general_reggroup)
    return 0;

  if (LOONGARCH_FIRST_FP_REGNUM <= regnum && regnum <= LOONGARCH_FCSR_REGNUM)
    return group == float_reggroup;

  /* Only $fx / $fccx / $fcsr in float_reggroup */
  if (group == float_reggroup)
    return 0;

  if (LOONGARCH_FIRST_LSX_REGNUM <= regnum
     && regnum < LOONGARCH_FIRST_LASX_REGNUM + LOONGARCH_LINUX_NUM_LASXREGSET)
    return group == vector_reggroup;

  /* Only $vrx / $xrx in vector_reggroup */
  if (group == vector_reggroup)
    return 0;

  int ret = tdesc_register_in_reggroup_p (gdbarch, regnum, group);
  if (ret != -1)
    return ret;

  return default_register_reggroup_p (gdbarch, regnum, group);
}

/* 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 ();
  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 < LOONGARCH_LINUX_NUM_FPREGSET; i++)
    valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (), regnum++,
					loongarch_f_normal_name[i] + 1);
  for (int i = 0; i < LOONGARCH_LINUX_NUM_FCC; i++)
    valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (), regnum++,
					loongarch_c_normal_name[i] + 1);
  valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (), regnum++, "fcsr");
  if (!valid_p)
    return nullptr;

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

  /* Validate the description provides the lsx registers and
     allocate their numbers.  */
  regnum = LOONGARCH_FIRST_LSX_REGNUM;
  for (int i = 0; i < LOONGARCH_LINUX_NUM_LSXREGSET; i++)
    valid_p &= tdesc_numbered_register (feature_lsx, tdesc_data.get (), regnum++,
					loongarch_v_normal_name[i] + 1);
  if (!valid_p)
    return nullptr;

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

  /* Validate the description provides the lasx registers and
     allocate their numbers.  */
  regnum = LOONGARCH_FIRST_LASX_REGNUM;
  for (int i = 0; i < LOONGARCH_LINUX_NUM_LASXREGSET; i++)
    valid_p &= tdesc_numbered_register (feature_lasx, tdesc_data.get (), regnum++,
					loongarch_x_normal_name[i] + 1);
  if (!valid_p)
    return nullptr;

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

  /* Validate the description provides the lbt registers and
     allocate their numbers.  */
  regnum = LOONGARCH_FIRST_SCR_REGNUM;
  for (int i = 0; i < LOONGARCH_LINUX_NUM_SCR; i++)
    valid_p &= tdesc_numbered_register (feature_lbt, tdesc_data.get (), regnum++,
					loongarch_cr_normal_name[i] + 1);
  valid_p &= tdesc_numbered_register (feature_lbt, tdesc_data.get (), regnum++,
				      "eflags");
  valid_p &= tdesc_numbered_register (feature_lbt, tdesc_data.get (), regnum++,
				      "ftop");
  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.  */
  gdbarch *gdbarch
    = gdbarch_alloc (&info, gdbarch_tdep_up (new loongarch_gdbarch_tdep));
  loongarch_gdbarch_tdep *tdep = gdbarch_tdep<loongarch_gdbarch_tdep> (gdbarch);

  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 ();

  for (int i = 0; i < ARRAY_SIZE (loongarch_r_alias); ++i)
    if (loongarch_r_alias[i][0] != '\0')
      user_reg_add (gdbarch, loongarch_r_alias[i] + 1,
	value_of_loongarch_user_reg, (void *) (size_t) i);

  for (int i = 0; i < ARRAY_SIZE (loongarch_f_alias); ++i)
    {
      if (loongarch_f_alias[i][0] != '\0')
	user_reg_add (gdbarch, loongarch_f_alias[i] + 1,
		      value_of_loongarch_user_reg,
		      (void *) (size_t) (LOONGARCH_FIRST_FP_REGNUM + i));
    }

  /* 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);
  set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);

  /* 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);
  set_gdbarch_register_reggroup_p (gdbarch, loongarch_register_reggroup_p);

  return gdbarch;
}

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