/* Target-dependent code for UltraSPARC.

   Copyright (C) 2003-2017 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 "floatformat.h"
#include "frame.h"
#include "frame-base.h"
#include "frame-unwind.h"
#include "gdbcore.h"
#include "gdbtypes.h"
#include "inferior.h"
#include "symtab.h"
#include "objfiles.h"
#include "osabi.h"
#include "regcache.h"
#include "target-descriptions.h"
#include "target.h"
#include "value.h"

#include "sparc64-tdep.h"

/* This file implements the SPARC 64-bit ABI as defined by the
   section "Low-Level System Information" of the SPARC Compliance
   Definition (SCD) 2.4.1, which is the 64-bit System V psABI for
   SPARC.  */

/* Please use the sparc32_-prefix for 32-bit specific code, the
   sparc64_-prefix for 64-bit specific code and the sparc_-prefix for
   code can handle both.  */

/* The M7 processor supports an Application Data Integrity (ADI) feature
   that detects invalid data accesses.  When software allocates memory and 
   enables ADI on the allocated memory, it chooses a 4-bit version number, 
   sets the version in the upper 4 bits of the 64-bit pointer to that data, 
   and stores the 4-bit version in every cacheline of the object.  Hardware 
   saves the latter in spare bits in the cache and memory hierarchy. On each 
   load and store, the processor compares the upper 4 VA (virtual address) bits 
   to the cacheline's version. If there is a mismatch, the processor generates
   a version mismatch trap which can be either precise or disrupting.
   The trap is an error condition which the kernel delivers to the process
   as a SIGSEGV signal.

   The upper 4 bits of the VA represent a version and are not part of the
   true address.  The processor clears these bits and sign extends bit 59
   to generate the true address.

   Note that 32-bit applications cannot use ADI. */


#include <algorithm>
#include "cli/cli-utils.h"
#include "gdbcmd.h"
#include "auxv.h"

#define MAX_PROC_NAME_SIZE sizeof("/proc/99999/lwp/9999/adi/lstatus")

/* ELF Auxiliary vectors */
#ifndef AT_ADI_BLKSZ
#define AT_ADI_BLKSZ    34
#endif
#ifndef AT_ADI_NBITS
#define AT_ADI_NBITS    35
#endif
#ifndef AT_ADI_UEONADI
#define AT_ADI_UEONADI  36
#endif

/* ADI command list.  */
static struct cmd_list_element *sparc64adilist = NULL;

/* ADI stat settings.  */
typedef struct
{
  /* The ADI block size.  */
  unsigned long blksize;

  /* Number of bits used for an ADI version tag which can be
     used together with the shift value for an ADI version tag
     to encode or extract the ADI version value in a pointer.  */
  unsigned long nbits;

  /* The maximum ADI version tag value supported.  */
  int max_version;

  /* ADI version tag file.  */
  int tag_fd = 0;

  /* ADI availability check has been done.  */
  bool checked_avail = false;

  /* ADI is available.  */
  bool is_avail = false;

} adi_stat_t;

/* Per-process ADI stat info.  */

typedef struct sparc64_adi_info
{
  sparc64_adi_info (pid_t pid_)
    : pid (pid_)
  {}

  /* The process identifier.  */
  pid_t pid;

  /* The ADI stat.  */
  adi_stat_t stat = {};

} sparc64_adi_info;

static std::forward_list<sparc64_adi_info> adi_proc_list;


/* Get ADI info for process PID, creating one if it doesn't exist.  */

static sparc64_adi_info * 
get_adi_info_proc (pid_t pid)
{
  auto found = std::find_if (adi_proc_list.begin (), adi_proc_list.end (),
                             [&pid] (const sparc64_adi_info &info)
                             {
                               return info.pid == pid;
                             });

  if (found == adi_proc_list.end ())
    {
      adi_proc_list.emplace_front (pid);
      return &adi_proc_list.front ();
    }
  else
    {
      return &(*found);
    }
}

static adi_stat_t 
get_adi_info (pid_t pid)
{
  sparc64_adi_info *proc;

  proc = get_adi_info_proc (pid);
  return proc->stat;
}

/* Is called when GDB is no longer debugging process PID.  It
   deletes data structure that keeps track of the ADI stat.  */

void
sparc64_forget_process (pid_t pid)
{
  int target_errno;

  for (auto pit = adi_proc_list.before_begin (),
	 it = std::next (pit);
       it != adi_proc_list.end ();
       )
    {
      if ((*it).pid == pid)
	{
          if ((*it).stat.tag_fd > 0) 
            target_fileio_close ((*it).stat.tag_fd, &target_errno);
	  adi_proc_list.erase_after (pit);
          break;
	}
      else
	pit = it++;
    }

}

static void
info_adi_command (char *args, int from_tty)
{
  printf_unfiltered ("\"adi\" must be followed by \"examine\" "
                     "or \"assign\".\n");
  help_list (sparc64adilist, "adi ", all_commands, gdb_stdout);
}

/* Read attributes of a maps entry in /proc/[pid]/adi/maps.  */

static void
read_maps_entry (const char *line,
              ULONGEST *addr, ULONGEST *endaddr)
{
  const char *p = line;

  *addr = strtoulst (p, &p, 16);
  if (*p == '-')
    p++;

  *endaddr = strtoulst (p, &p, 16);
}

/* Check if ADI is available.  */

static bool
adi_available (void)
{
  pid_t pid = ptid_get_pid (inferior_ptid);
  sparc64_adi_info *proc = get_adi_info_proc (pid);
  CORE_ADDR value;

  if (proc->stat.checked_avail)
    return proc->stat.is_avail;

  proc->stat.checked_avail = true;
  if (target_auxv_search (&current_target, AT_ADI_BLKSZ, &value) <= 0)
    return false;
  proc->stat.blksize = value;
  target_auxv_search (&current_target, AT_ADI_NBITS, &value);
  proc->stat.nbits = value;
  proc->stat.max_version = (1 << proc->stat.nbits) - 2;
  proc->stat.is_avail = true;

  return proc->stat.is_avail;
}

/* Normalize a versioned address - a VA with ADI bits (63-60) set.  */

static CORE_ADDR
adi_normalize_address (CORE_ADDR addr)
{
  adi_stat_t ast = get_adi_info (ptid_get_pid (inferior_ptid));

  if (ast.nbits)
    {
      /* Clear upper bits.  */
      addr &= ((uint64_t) -1) >> ast.nbits;

      /* Sign extend.  */
      CORE_ADDR signbit = (uint64_t) 1 << (64 - ast.nbits - 1);
      return (addr ^ signbit) - signbit;
    }
  return addr;
}

/* Align a normalized address - a VA with bit 59 sign extended into 
   ADI bits.  */

static CORE_ADDR
adi_align_address (CORE_ADDR naddr)
{
  adi_stat_t ast = get_adi_info (ptid_get_pid (inferior_ptid));

  return (naddr - (naddr % ast.blksize)) / ast.blksize;
}

/* Convert a byte count to count at a ratio of 1:adi_blksz.  */

static int
adi_convert_byte_count (CORE_ADDR naddr, int nbytes, CORE_ADDR locl)
{
  adi_stat_t ast = get_adi_info (ptid_get_pid (inferior_ptid));

  return ((naddr + nbytes + ast.blksize - 1) / ast.blksize) - locl;
}

/* The /proc/[pid]/adi/tags file, which allows gdb to get/set ADI
   version in a target process, maps linearly to the address space
   of the target process at a ratio of 1:adi_blksz.

   A read (or write) at offset K in the file returns (or modifies)
   the ADI version tag stored in the cacheline containing address
   K * adi_blksz, encoded as 1 version tag per byte.  The allowed
   version tag values are between 0 and adi_stat.max_version.  */

static int
adi_tag_fd (void)
{
  pid_t pid = ptid_get_pid (inferior_ptid);
  sparc64_adi_info *proc = get_adi_info_proc (pid);

  if (proc->stat.tag_fd != 0)
    return proc->stat.tag_fd;

  char cl_name[MAX_PROC_NAME_SIZE];
  snprintf (cl_name, sizeof(cl_name), "/proc/%d/adi/tags", pid);
  int target_errno;
  proc->stat.tag_fd = target_fileio_open (NULL, cl_name, O_RDWR|O_EXCL, 
                                          0, &target_errno);
  return proc->stat.tag_fd;
}

/* Check if an address set is ADI enabled, using /proc/[pid]/adi/maps
   which was exported by the kernel and contains the currently ADI
   mapped memory regions and their access permissions.  */

static bool
adi_is_addr_mapped (CORE_ADDR vaddr, size_t cnt)
{
  char filename[MAX_PROC_NAME_SIZE];
  size_t i = 0;

  pid_t pid = ptid_get_pid (inferior_ptid);
  snprintf (filename, sizeof filename, "/proc/%d/adi/maps", pid);
  char *data = target_fileio_read_stralloc (NULL, filename);
  if (data)
    {
      struct cleanup *cleanup = make_cleanup (xfree, data);
      adi_stat_t adi_stat = get_adi_info (pid);
      char *line;
      for (line = strtok (data, "\n"); line; line = strtok (NULL, "\n"))
        {
          ULONGEST addr, endaddr;

          read_maps_entry (line, &addr, &endaddr);

          while (((vaddr + i) * adi_stat.blksize) >= addr
                 && ((vaddr + i) * adi_stat.blksize) < endaddr)
            {
              if (++i == cnt)
                {
                  do_cleanups (cleanup);
                  return true;
                }
            }
        }
        do_cleanups (cleanup);
      }
    else
      warning (_("unable to open /proc file '%s'"), filename);

  return false;
}

/* Read ADI version tag value for memory locations starting at "VADDR"
   for "SIZE" number of bytes.  */

static int
adi_read_versions (CORE_ADDR vaddr, size_t size, unsigned char *tags)
{
  int fd = adi_tag_fd ();
  if (fd == -1)
    return -1;

  if (!adi_is_addr_mapped (vaddr, size))
    {
      adi_stat_t ast = get_adi_info (ptid_get_pid (inferior_ptid));
      error(_("Address at %s is not in ADI maps"),
            paddress (target_gdbarch (), vaddr * ast.blksize));
    }

  int target_errno;
  return target_fileio_pread (fd, tags, size, vaddr, &target_errno);
}

/* Write ADI version tag for memory locations starting at "VADDR" for
 "SIZE" number of bytes to "TAGS".  */

static int
adi_write_versions (CORE_ADDR vaddr, size_t size, unsigned char *tags)
{
  int fd = adi_tag_fd ();
  if (fd == -1)
    return -1;

  if (!adi_is_addr_mapped (vaddr, size))
    {
      adi_stat_t ast = get_adi_info (ptid_get_pid (inferior_ptid));
      error(_("Address at %s is not in ADI maps"),
            paddress (target_gdbarch (), vaddr * ast.blksize));
    }

  int target_errno;
  return target_fileio_pwrite (fd, tags, size, vaddr, &target_errno);
}

/* Print ADI version tag value in "TAGS" for memory locations starting
   at "VADDR" with number of "CNT".  */

static void
adi_print_versions (CORE_ADDR vaddr, size_t cnt, unsigned char *tags)
{
  int v_idx = 0;
  const int maxelts = 8;  /* # of elements per line */

  adi_stat_t adi_stat = get_adi_info (ptid_get_pid (inferior_ptid));

  while (cnt > 0)
    {
      QUIT;
      printf_filtered ("%s:\t",
	               paddress (target_gdbarch (), vaddr * adi_stat.blksize));
      for (int i = maxelts; i > 0 && cnt > 0; i--, cnt--)
        {
          if (tags[v_idx] == 0xff)    /* no version tag */
            printf_filtered ("-");
          else
            printf_filtered ("%1X", tags[v_idx]);
	  if (cnt > 1)
            printf_filtered (" ");
          ++v_idx;
        }
      printf_filtered ("\n");
      gdb_flush (gdb_stdout);
      vaddr += maxelts;
    }
}

static void
do_examine (CORE_ADDR start, int bcnt)
{
  CORE_ADDR vaddr = adi_normalize_address (start);
  struct cleanup *cleanup;

  CORE_ADDR vstart = adi_align_address (vaddr);
  int cnt = adi_convert_byte_count (vaddr, bcnt, vstart);
  unsigned char *buf = (unsigned char *) xmalloc (cnt);
  cleanup = make_cleanup (xfree, buf);
  int read_cnt = adi_read_versions (vstart, cnt, buf);
  if (read_cnt == -1)
    error (_("No ADI information"));
  else if (read_cnt < cnt)
    error(_("No ADI information at %s"), paddress (target_gdbarch (), vaddr));

  adi_print_versions (vstart, cnt, buf);

  do_cleanups (cleanup);
}

static void
do_assign (CORE_ADDR start, size_t bcnt, int version)
{
  CORE_ADDR vaddr = adi_normalize_address (start);

  CORE_ADDR vstart = adi_align_address (vaddr);
  int cnt = adi_convert_byte_count (vaddr, bcnt, vstart);
  std::vector<unsigned char> buf (cnt, version);
  int set_cnt = adi_write_versions (vstart, cnt, buf.data ());

  if (set_cnt == -1)
    error (_("No ADI information"));
  else if (set_cnt < cnt)
    error(_("No ADI information at %s"), paddress (target_gdbarch (), vaddr));

}

/* ADI examine version tag command.

   Command syntax:

     adi (examine|x)/count <addr> */

static void
adi_examine_command (char *args, int from_tty)
{
  /* make sure program is active and adi is available */
  if (!target_has_execution)
    error (_("ADI command requires a live process/thread"));

  if (!adi_available ())
    error (_("No ADI information"));

  pid_t pid = ptid_get_pid (inferior_ptid);
  sparc64_adi_info *proc = get_adi_info_proc (pid);
  int cnt = 1;
  char *p = args;
  if (p && *p == '/')
    {
      p++;
      cnt = get_number (&p);
    }

  CORE_ADDR next_address = 0;
  if (p != 0 && *p != 0)
    next_address = parse_and_eval_address (p);
  if (!cnt || !next_address)
    error (_("Usage: adi examine|x[/count] <addr>"));

  do_examine (next_address, cnt);
}

/* ADI assign version tag command.

   Command syntax:

     adi (assign|a)/count <addr> = <version>  */

static void
adi_assign_command (char *args, int from_tty)
{
  /* make sure program is active and adi is available */
  if (!target_has_execution)
    error (_("ADI command requires a live process/thread"));

  if (!adi_available ())
    error (_("No ADI information"));

  char *exp = args;
  if (exp == 0)
    error_no_arg (_("Usage: adi assign|a[/count] <addr> = <version>"));

  char *q = (char *) strchr (exp, '=');
  if (q)
    *q++ = 0;
  else
    error (_("Usage: adi assign|a[/count] <addr> = <version>"));

  size_t cnt = 1;
  char *p = args;
  if (exp && *exp == '/')
    {
      p = exp + 1;
      cnt = get_number (&p);
    }

  CORE_ADDR next_address = 0;
  if (p != 0 && *p != 0)
    next_address = parse_and_eval_address (p);
  else
    error (_("Usage: adi assign|a[/count] <addr> = <version>"));

  int version = 0;
  if (q != NULL)           /* parse version tag */
    {
      adi_stat_t ast = get_adi_info (ptid_get_pid (inferior_ptid));
      version = parse_and_eval_long (q);
      if (version < 0 || version > ast.max_version)
        error (_("Invalid ADI version tag %d"), version);
    }

  do_assign (next_address, cnt, version);
}

void
_initialize_sparc64_adi_tdep (void)
{

  add_prefix_cmd ("adi", class_support, info_adi_command,
                  _("ADI version related commands."),
                  &sparc64adilist, "adi ", 0, &cmdlist);
  add_cmd ("examine", class_support, adi_examine_command,
           _("Examine ADI versions."), &sparc64adilist);
  add_alias_cmd ("x", "examine", no_class, 1, &sparc64adilist);
  add_cmd ("assign", class_support, adi_assign_command,
           _("Assign ADI versions."), &sparc64adilist);

}


/* The functions on this page are intended to be used to classify
   function arguments.  */

/* Check whether TYPE is "Integral or Pointer".  */

static int
sparc64_integral_or_pointer_p (const struct type *type)
{
  switch (TYPE_CODE (type))
    {
    case TYPE_CODE_INT:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_RANGE:
      {
	int len = TYPE_LENGTH (type);
	gdb_assert (len == 1 || len == 2 || len == 4 || len == 8);
      }
      return 1;
    case TYPE_CODE_PTR:
    case TYPE_CODE_REF:
    case TYPE_CODE_RVALUE_REF:
      {
	int len = TYPE_LENGTH (type);
	gdb_assert (len == 8);
      }
      return 1;
    default:
      break;
    }

  return 0;
}

/* Check whether TYPE is "Floating".  */

static int
sparc64_floating_p (const struct type *type)
{
  switch (TYPE_CODE (type))
    {
    case TYPE_CODE_FLT:
      {
	int len = TYPE_LENGTH (type);
	gdb_assert (len == 4 || len == 8 || len == 16);
      }
      return 1;
    default:
      break;
    }

  return 0;
}

/* Check whether TYPE is "Complex Floating".  */

static int
sparc64_complex_floating_p (const struct type *type)
{
  switch (TYPE_CODE (type))
    {
    case TYPE_CODE_COMPLEX:
      {
	int len = TYPE_LENGTH (type);
	gdb_assert (len == 8 || len == 16 || len == 32);
      }
      return 1;
    default:
      break;
    }

  return 0;
}

/* Check whether TYPE is "Structure or Union".

   In terms of Ada subprogram calls, arrays are treated the same as
   struct and union types.  So this function also returns non-zero
   for array types.  */

static int
sparc64_structure_or_union_p (const struct type *type)
{
  switch (TYPE_CODE (type))
    {
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
    case TYPE_CODE_ARRAY:
      return 1;
    default:
      break;
    }

  return 0;
}


/* Construct types for ISA-specific registers.  */

static struct type *
sparc64_pstate_type (struct gdbarch *gdbarch)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  if (!tdep->sparc64_pstate_type)
    {
      struct type *type;

      type = arch_flags_type (gdbarch, "builtin_type_sparc64_pstate", 8);
      append_flags_type_flag (type, 0, "AG");
      append_flags_type_flag (type, 1, "IE");
      append_flags_type_flag (type, 2, "PRIV");
      append_flags_type_flag (type, 3, "AM");
      append_flags_type_flag (type, 4, "PEF");
      append_flags_type_flag (type, 5, "RED");
      append_flags_type_flag (type, 8, "TLE");
      append_flags_type_flag (type, 9, "CLE");
      append_flags_type_flag (type, 10, "PID0");
      append_flags_type_flag (type, 11, "PID1");

      tdep->sparc64_pstate_type = type;
    }

  return tdep->sparc64_pstate_type;
}

static struct type *
sparc64_ccr_type (struct gdbarch *gdbarch)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  if (tdep->sparc64_ccr_type == NULL)
    {
      struct type *type;

      type = arch_flags_type (gdbarch, "builtin_type_sparc64_ccr", 8);
      append_flags_type_flag (type, 0, "icc.c");
      append_flags_type_flag (type, 1, "icc.v");
      append_flags_type_flag (type, 2, "icc.z");
      append_flags_type_flag (type, 3, "icc.n");
      append_flags_type_flag (type, 4, "xcc.c");
      append_flags_type_flag (type, 5, "xcc.v");
      append_flags_type_flag (type, 6, "xcc.z");
      append_flags_type_flag (type, 7, "xcc.n");

      tdep->sparc64_ccr_type = type;
    }

  return tdep->sparc64_ccr_type;
}

static struct type *
sparc64_fsr_type (struct gdbarch *gdbarch)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  if (!tdep->sparc64_fsr_type)
    {
      struct type *type;

      type = arch_flags_type (gdbarch, "builtin_type_sparc64_fsr", 8);
      append_flags_type_flag (type, 0, "NXC");
      append_flags_type_flag (type, 1, "DZC");
      append_flags_type_flag (type, 2, "UFC");
      append_flags_type_flag (type, 3, "OFC");
      append_flags_type_flag (type, 4, "NVC");
      append_flags_type_flag (type, 5, "NXA");
      append_flags_type_flag (type, 6, "DZA");
      append_flags_type_flag (type, 7, "UFA");
      append_flags_type_flag (type, 8, "OFA");
      append_flags_type_flag (type, 9, "NVA");
      append_flags_type_flag (type, 22, "NS");
      append_flags_type_flag (type, 23, "NXM");
      append_flags_type_flag (type, 24, "DZM");
      append_flags_type_flag (type, 25, "UFM");
      append_flags_type_flag (type, 26, "OFM");
      append_flags_type_flag (type, 27, "NVM");

      tdep->sparc64_fsr_type = type;
    }

  return tdep->sparc64_fsr_type;
}

static struct type *
sparc64_fprs_type (struct gdbarch *gdbarch)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  if (!tdep->sparc64_fprs_type)
    {
      struct type *type;

      type = arch_flags_type (gdbarch, "builtin_type_sparc64_fprs", 8);
      append_flags_type_flag (type, 0, "DL");
      append_flags_type_flag (type, 1, "DU");
      append_flags_type_flag (type, 2, "FEF");

      tdep->sparc64_fprs_type = type;
    }

  return tdep->sparc64_fprs_type;
}


/* Register information.  */
#define SPARC64_FPU_REGISTERS                             \
  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",         \
  "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",   \
  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
  "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \
  "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62"
#define SPARC64_CP0_REGISTERS                                             \
  "pc", "npc",                                                            \
  /* FIXME: Give "state" a name until we start using register groups.  */ \
  "state",                                                                \
  "fsr",                                                                  \
  "fprs",                                                                 \
  "y"

static const char *sparc64_fpu_register_names[] = { SPARC64_FPU_REGISTERS };
static const char *sparc64_cp0_register_names[] = { SPARC64_CP0_REGISTERS };

static const char *sparc64_register_names[] =
{
  SPARC_CORE_REGISTERS,
  SPARC64_FPU_REGISTERS,
  SPARC64_CP0_REGISTERS
};

/* Total number of registers.  */
#define SPARC64_NUM_REGS ARRAY_SIZE (sparc64_register_names)

/* We provide the aliases %d0..%d62 and %q0..%q60 for the floating
   registers as "psuedo" registers.  */

static const char *sparc64_pseudo_register_names[] =
{
  "cwp", "pstate", "asi", "ccr",

  "d0", "d2", "d4", "d6", "d8", "d10", "d12", "d14",
  "d16", "d18", "d20", "d22", "d24", "d26", "d28", "d30",
  "d32", "d34", "d36", "d38", "d40", "d42", "d44", "d46",
  "d48", "d50", "d52", "d54", "d56", "d58", "d60", "d62",

  "q0", "q4", "q8", "q12", "q16", "q20", "q24", "q28",
  "q32", "q36", "q40", "q44", "q48", "q52", "q56", "q60",
};

/* Total number of pseudo registers.  */
#define SPARC64_NUM_PSEUDO_REGS ARRAY_SIZE (sparc64_pseudo_register_names)

/* Return the name of pseudo register REGNUM.  */

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

  if (regnum < SPARC64_NUM_PSEUDO_REGS)
    return sparc64_pseudo_register_names[regnum];

  internal_error (__FILE__, __LINE__,
                  _("sparc64_pseudo_register_name: bad register number %d"),
                  regnum);
}

/* Return the name of register REGNUM.  */

static const char *
sparc64_register_name (struct gdbarch *gdbarch, int regnum)
{
  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
    return tdesc_register_name (gdbarch, regnum);

  if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch))
    return sparc64_register_names[regnum];

  return sparc64_pseudo_register_name (gdbarch, regnum);
}

/* Return the GDB type object for the "standard" data type of data in
   pseudo register REGNUM.  */

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

  if (regnum == SPARC64_CWP_REGNUM)
    return builtin_type (gdbarch)->builtin_int64;
  if (regnum == SPARC64_PSTATE_REGNUM)
    return sparc64_pstate_type (gdbarch);
  if (regnum == SPARC64_ASI_REGNUM)
    return builtin_type (gdbarch)->builtin_int64;
  if (regnum == SPARC64_CCR_REGNUM)
    return sparc64_ccr_type (gdbarch);
  if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D62_REGNUM)
    return builtin_type (gdbarch)->builtin_double;
  if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q60_REGNUM)
    return builtin_type (gdbarch)->builtin_long_double;

  internal_error (__FILE__, __LINE__,
                  _("sparc64_pseudo_register_type: bad register number %d"),
                  regnum);
}

/* Return the GDB type object for the "standard" data type of data in
   register REGNUM.  */

static struct type *
sparc64_register_type (struct gdbarch *gdbarch, int regnum)
{
  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
    return tdesc_register_type (gdbarch, regnum);

  /* Raw registers.  */
  if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM)
    return builtin_type (gdbarch)->builtin_data_ptr;
  if (regnum >= SPARC_G0_REGNUM && regnum <= SPARC_I7_REGNUM)
    return builtin_type (gdbarch)->builtin_int64;
  if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
    return builtin_type (gdbarch)->builtin_float;
  if (regnum >= SPARC64_F32_REGNUM && regnum <= SPARC64_F62_REGNUM)
    return builtin_type (gdbarch)->builtin_double;
  if (regnum == SPARC64_PC_REGNUM || regnum == SPARC64_NPC_REGNUM)
    return builtin_type (gdbarch)->builtin_func_ptr;
  /* This raw register contains the contents of %cwp, %pstate, %asi
     and %ccr as laid out in a %tstate register.  */
  if (regnum == SPARC64_STATE_REGNUM)
    return builtin_type (gdbarch)->builtin_int64;
  if (regnum == SPARC64_FSR_REGNUM)
    return sparc64_fsr_type (gdbarch);
  if (regnum == SPARC64_FPRS_REGNUM)
    return sparc64_fprs_type (gdbarch);
  /* "Although Y is a 64-bit register, its high-order 32 bits are
     reserved and always read as 0."  */
  if (regnum == SPARC64_Y_REGNUM)
    return builtin_type (gdbarch)->builtin_int64;

  /* Pseudo registers.  */
  if (regnum >= gdbarch_num_regs (gdbarch))
    return sparc64_pseudo_register_type (gdbarch, regnum);

  internal_error (__FILE__, __LINE__, _("invalid regnum"));
}

static enum register_status
sparc64_pseudo_register_read (struct gdbarch *gdbarch,
			      struct regcache *regcache,
			      int regnum, gdb_byte *buf)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  enum register_status status;

  regnum -= gdbarch_num_regs (gdbarch);

  if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D30_REGNUM)
    {
      regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC64_D0_REGNUM);
      status = regcache_raw_read (regcache, regnum, buf);
      if (status == REG_VALID)
	status = regcache_raw_read (regcache, regnum + 1, buf + 4);
      return status;
    }
  else if (regnum >= SPARC64_D32_REGNUM && regnum <= SPARC64_D62_REGNUM)
    {
      regnum = SPARC64_F32_REGNUM + (regnum - SPARC64_D32_REGNUM);
      return regcache_raw_read (regcache, regnum, buf);
    }
  else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q28_REGNUM)
    {
      regnum = SPARC_F0_REGNUM + 4 * (regnum - SPARC64_Q0_REGNUM);

      status = regcache_raw_read (regcache, regnum, buf);
      if (status == REG_VALID)
	status = regcache_raw_read (regcache, regnum + 1, buf + 4);
      if (status == REG_VALID)
	status = regcache_raw_read (regcache, regnum + 2, buf + 8);
      if (status == REG_VALID)
	status = regcache_raw_read (regcache, regnum + 3, buf + 12);

      return status;
    }
  else if (regnum >= SPARC64_Q32_REGNUM && regnum <= SPARC64_Q60_REGNUM)
    {
      regnum = SPARC64_F32_REGNUM + 2 * (regnum - SPARC64_Q32_REGNUM);

      status = regcache_raw_read (regcache, regnum, buf);
      if (status == REG_VALID)
	status = regcache_raw_read (regcache, regnum + 1, buf + 8);

      return status;
    }
  else if (regnum == SPARC64_CWP_REGNUM
	   || regnum == SPARC64_PSTATE_REGNUM
	   || regnum == SPARC64_ASI_REGNUM
	   || regnum == SPARC64_CCR_REGNUM)
    {
      ULONGEST state;

      status = regcache_raw_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state);
      if (status != REG_VALID)
	return status;

      switch (regnum)
	{
	case SPARC64_CWP_REGNUM:
	  state = (state >> 0) & ((1 << 5) - 1);
	  break;
	case SPARC64_PSTATE_REGNUM:
	  state = (state >> 8) & ((1 << 12) - 1);
	  break;
	case SPARC64_ASI_REGNUM:
	  state = (state >> 24) & ((1 << 8) - 1);
	  break;
	case SPARC64_CCR_REGNUM:
	  state = (state >> 32) & ((1 << 8) - 1);
	  break;
	}
      store_unsigned_integer (buf, 8, byte_order, state);
    }

  return REG_VALID;
}

static void
sparc64_pseudo_register_write (struct gdbarch *gdbarch,
			       struct regcache *regcache,
			       int regnum, const gdb_byte *buf)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  regnum -= gdbarch_num_regs (gdbarch);

  if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D30_REGNUM)
    {
      regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC64_D0_REGNUM);
      regcache_raw_write (regcache, regnum, buf);
      regcache_raw_write (regcache, regnum + 1, buf + 4);
    }
  else if (regnum >= SPARC64_D32_REGNUM && regnum <= SPARC64_D62_REGNUM)
    {
      regnum = SPARC64_F32_REGNUM + (regnum - SPARC64_D32_REGNUM);
      regcache_raw_write (regcache, regnum, buf);
    }
  else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q28_REGNUM)
    {
      regnum = SPARC_F0_REGNUM + 4 * (regnum - SPARC64_Q0_REGNUM);
      regcache_raw_write (regcache, regnum, buf);
      regcache_raw_write (regcache, regnum + 1, buf + 4);
      regcache_raw_write (regcache, regnum + 2, buf + 8);
      regcache_raw_write (regcache, regnum + 3, buf + 12);
    }
  else if (regnum >= SPARC64_Q32_REGNUM && regnum <= SPARC64_Q60_REGNUM)
    {
      regnum = SPARC64_F32_REGNUM + 2 * (regnum - SPARC64_Q32_REGNUM);
      regcache_raw_write (regcache, regnum, buf);
      regcache_raw_write (regcache, regnum + 1, buf + 8);
    }
  else if (regnum == SPARC64_CWP_REGNUM
	   || regnum == SPARC64_PSTATE_REGNUM
	   || regnum == SPARC64_ASI_REGNUM
	   || regnum == SPARC64_CCR_REGNUM)
    {
      ULONGEST state, bits;

      regcache_raw_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state);
      bits = extract_unsigned_integer (buf, 8, byte_order);
      switch (regnum)
	{
	case SPARC64_CWP_REGNUM:
	  state |= ((bits & ((1 << 5) - 1)) << 0);
	  break;
	case SPARC64_PSTATE_REGNUM:
	  state |= ((bits & ((1 << 12) - 1)) << 8);
	  break;
	case SPARC64_ASI_REGNUM:
	  state |= ((bits & ((1 << 8) - 1)) << 24);
	  break;
	case SPARC64_CCR_REGNUM:
	  state |= ((bits & ((1 << 8) - 1)) << 32);
	  break;
	}
      regcache_raw_write_unsigned (regcache, SPARC64_STATE_REGNUM, state);
    }
}


/* Return PC of first real instruction of the function starting at
   START_PC.  */

static CORE_ADDR
sparc64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
{
  struct symtab_and_line sal;
  CORE_ADDR func_start, func_end;
  struct sparc_frame_cache cache;

  /* This is the preferred method, find the end of the prologue by
     using the debugging information.  */
  if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end))
    {
      sal = find_pc_line (func_start, 0);

      if (sal.end < func_end
	  && start_pc <= sal.end)
	return sal.end;
    }

  return sparc_analyze_prologue (gdbarch, start_pc, 0xffffffffffffffffULL,
				 &cache);
}

/* Normal frames.  */

static struct sparc_frame_cache *
sparc64_frame_cache (struct frame_info *this_frame, void **this_cache)
{
  return sparc_frame_cache (this_frame, this_cache);
}

static void
sparc64_frame_this_id (struct frame_info *this_frame, void **this_cache,
		       struct frame_id *this_id)
{
  struct sparc_frame_cache *cache =
    sparc64_frame_cache (this_frame, this_cache);

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

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

static struct value *
sparc64_frame_prev_register (struct frame_info *this_frame, void **this_cache,
			     int regnum)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct sparc_frame_cache *cache =
    sparc64_frame_cache (this_frame, this_cache);

  if (regnum == SPARC64_PC_REGNUM || regnum == SPARC64_NPC_REGNUM)
    {
      CORE_ADDR pc = (regnum == SPARC64_NPC_REGNUM) ? 4 : 0;

      regnum =
	(cache->copied_regs_mask & 0x80) ? SPARC_I7_REGNUM : SPARC_O7_REGNUM;
      pc += get_frame_register_unsigned (this_frame, regnum) + 8;
      return frame_unwind_got_constant (this_frame, regnum, pc);
    }

  /* Handle StackGhost.  */
  {
    ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);

    if (wcookie != 0 && !cache->frameless_p && regnum == SPARC_I7_REGNUM)
      {
        CORE_ADDR addr = cache->base + (regnum - SPARC_L0_REGNUM) * 8;
        ULONGEST i7;

        /* Read the value in from memory.  */
        i7 = get_frame_memory_unsigned (this_frame, addr, 8);
        return frame_unwind_got_constant (this_frame, regnum, i7 ^ wcookie);
      }
  }

  /* The previous frame's `local' and `in' registers may have been saved
     in the register save area.  */
  if (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM
      && (cache->saved_regs_mask & (1 << (regnum - SPARC_L0_REGNUM))))
    {
      CORE_ADDR addr = cache->base + (regnum - SPARC_L0_REGNUM) * 8;

      return frame_unwind_got_memory (this_frame, regnum, addr);
    }

  /* The previous frame's `out' registers may be accessible as the current
     frame's `in' registers.  */
  if (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM
      && (cache->copied_regs_mask & (1 << (regnum - SPARC_O0_REGNUM))))
    regnum += (SPARC_I0_REGNUM - SPARC_O0_REGNUM);

  return frame_unwind_got_register (this_frame, regnum, regnum);
}

static const struct frame_unwind sparc64_frame_unwind =
{
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  sparc64_frame_this_id,
  sparc64_frame_prev_register,
  NULL,
  default_frame_sniffer
};


static CORE_ADDR
sparc64_frame_base_address (struct frame_info *this_frame, void **this_cache)
{
  struct sparc_frame_cache *cache =
    sparc64_frame_cache (this_frame, this_cache);

  return cache->base;
}

static const struct frame_base sparc64_frame_base =
{
  &sparc64_frame_unwind,
  sparc64_frame_base_address,
  sparc64_frame_base_address,
  sparc64_frame_base_address
};

/* Check whether TYPE must be 16-byte aligned.  */

static int
sparc64_16_byte_align_p (struct type *type)
{
  if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
    {
      struct type *t = check_typedef (TYPE_TARGET_TYPE (type));

      if (sparc64_floating_p (t))
        return 1;
    }
  if (sparc64_floating_p (type) && TYPE_LENGTH (type) == 16)
    return 1;

  if (sparc64_structure_or_union_p (type))
    {
      int i;

      for (i = 0; i < TYPE_NFIELDS (type); i++)
	{
	  struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));

	  if (sparc64_16_byte_align_p (subtype))
	    return 1;
	}
    }

  return 0;
}

/* Store floating fields of element ELEMENT of an "parameter array"
   that has type TYPE and is stored at BITPOS in VALBUF in the
   apropriate registers of REGCACHE.  This function can be called
   recursively and therefore handles floating types in addition to
   structures.  */

static void
sparc64_store_floating_fields (struct regcache *regcache, struct type *type,
			       const gdb_byte *valbuf, int element, int bitpos)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int len = TYPE_LENGTH (type);

  gdb_assert (element < 16);

  if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
    {
      gdb_byte buf[8];
      int regnum = SPARC_F0_REGNUM + element * 2 + bitpos / 32;

      valbuf += bitpos / 8;
      if (len < 8)
        {
          memset (buf, 0, 8 - len);
          memcpy (buf + 8 - len, valbuf, len);
          valbuf = buf;
          len = 8;
        }
      for (int n = 0; n < (len + 3) / 4; n++)
        regcache_cooked_write (regcache, regnum + n, valbuf + n * 4);
    }
  else if (sparc64_floating_p (type)
      || (sparc64_complex_floating_p (type) && len <= 16))
    {
      int regnum;

      if (len == 16)
	{
	  gdb_assert (bitpos == 0);
	  gdb_assert ((element % 2) == 0);

	  regnum = gdbarch_num_regs (gdbarch) + SPARC64_Q0_REGNUM + element / 2;
	  regcache_cooked_write (regcache, regnum, valbuf);
	}
      else if (len == 8)
	{
	  gdb_assert (bitpos == 0 || bitpos == 64);

	  regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM
                   + element + bitpos / 64;
	  regcache_cooked_write (regcache, regnum, valbuf + (bitpos / 8));
	}
      else
	{
	  gdb_assert (len == 4);
	  gdb_assert (bitpos % 32 == 0 && bitpos >= 0 && bitpos < 128);

	  regnum = SPARC_F0_REGNUM + element * 2 + bitpos / 32;
	  regcache_cooked_write (regcache, regnum, valbuf + (bitpos / 8));
	}
    }
  else if (sparc64_structure_or_union_p (type))
    {
      int i;

      for (i = 0; i < TYPE_NFIELDS (type); i++)
	{
	  struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
	  int subpos = bitpos + TYPE_FIELD_BITPOS (type, i);

	  sparc64_store_floating_fields (regcache, subtype, valbuf,
					 element, subpos);
	}

      /* GCC has an interesting bug.  If TYPE is a structure that has
         a single `float' member, GCC doesn't treat it as a structure
         at all, but rather as an ordinary `float' argument.  This
         argument will be stored in %f1, as required by the psABI.
         However, as a member of a structure the psABI requires it to
         be stored in %f0.  This bug is present in GCC 3.3.2, but
         probably in older releases to.  To appease GCC, if a
         structure has only a single `float' member, we store its
         value in %f1 too (we already have stored in %f0).  */
      if (TYPE_NFIELDS (type) == 1)
	{
	  struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, 0));

	  if (sparc64_floating_p (subtype) && TYPE_LENGTH (subtype) == 4)
	    regcache_cooked_write (regcache, SPARC_F1_REGNUM, valbuf);
	}
    }
}

/* Fetch floating fields from a variable of type TYPE from the
   appropriate registers for BITPOS in REGCACHE and store it at BITPOS
   in VALBUF.  This function can be called recursively and therefore
   handles floating types in addition to structures.  */

static void
sparc64_extract_floating_fields (struct regcache *regcache, struct type *type,
				 gdb_byte *valbuf, int bitpos)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);

  if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
    {
      int len = TYPE_LENGTH (type);
      int regnum =  SPARC_F0_REGNUM + bitpos / 32;

      valbuf += bitpos / 8;
      if (len < 4)
        {
          gdb_byte buf[4];
          regcache_cooked_read (regcache, regnum, buf);
          memcpy (valbuf, buf + 4 - len, len);
        }
      else
        for (int i = 0; i < (len + 3) / 4; i++)
          regcache_cooked_read (regcache, regnum + i, valbuf + i * 4);
    }
  else if (sparc64_floating_p (type))
    {
      int len = TYPE_LENGTH (type);
      int regnum;

      if (len == 16)
	{
	  gdb_assert (bitpos == 0 || bitpos == 128);

	  regnum = gdbarch_num_regs (gdbarch) + SPARC64_Q0_REGNUM
                   + bitpos / 128;
	  regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8));
	}
      else if (len == 8)
	{
	  gdb_assert (bitpos % 64 == 0 && bitpos >= 0 && bitpos < 256);

	  regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + bitpos / 64;
	  regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8));
	}
      else
	{
	  gdb_assert (len == 4);
	  gdb_assert (bitpos % 32 == 0 && bitpos >= 0 && bitpos < 256);

	  regnum = SPARC_F0_REGNUM + bitpos / 32;
	  regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8));
	}
    }
  else if (sparc64_structure_or_union_p (type))
    {
      int i;

      for (i = 0; i < TYPE_NFIELDS (type); i++)
	{
	  struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
	  int subpos = bitpos + TYPE_FIELD_BITPOS (type, i);

	  sparc64_extract_floating_fields (regcache, subtype, valbuf, subpos);
	}
    }
}

/* Store the NARGS arguments ARGS and STRUCT_ADDR (if STRUCT_RETURN is
   non-zero) in REGCACHE and on the stack (starting from address SP).  */

static CORE_ADDR
sparc64_store_arguments (struct regcache *regcache, int nargs,
			 struct value **args, CORE_ADDR sp,
			 int struct_return, CORE_ADDR struct_addr)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  /* Number of extended words in the "parameter array".  */
  int num_elements = 0;
  int element = 0;
  int i;

  /* Take BIAS into account.  */
  sp += BIAS;

  /* First we calculate the number of extended words in the "parameter
     array".  While doing so we also convert some of the arguments.  */

  if (struct_return)
    num_elements++;

  for (i = 0; i < nargs; i++)
    {
      struct type *type = value_type (args[i]);
      int len = TYPE_LENGTH (type);

      if (sparc64_structure_or_union_p (type)
	  || (sparc64_complex_floating_p (type) && len == 32))
	{
	  /* Structure or Union arguments.  */
	  if (len <= 16)
	    {
	      if (num_elements % 2 && sparc64_16_byte_align_p (type))
		num_elements++;
	      num_elements += ((len + 7) / 8);
	    }
	  else
	    {
	      /* The psABI says that "Structures or unions larger than
		 sixteen bytes are copied by the caller and passed
		 indirectly; the caller will pass the address of a
		 correctly aligned structure value.  This sixty-four
		 bit address will occupy one word in the parameter
		 array, and may be promoted to an %o register like any
		 other pointer value."  Allocate memory for these
		 values on the stack.  */
	      sp -= len;

	      /* Use 16-byte alignment for these values.  That's
                 always correct, and wasting a few bytes shouldn't be
                 a problem.  */
	      sp &= ~0xf;

	      write_memory (sp, value_contents (args[i]), len);
	      args[i] = value_from_pointer (lookup_pointer_type (type), sp);
	      num_elements++;
	    }
	}
      else if (sparc64_floating_p (type) || sparc64_complex_floating_p (type))
	{
	  /* Floating arguments.  */
	  if (len == 16)
	    {
	      /* The psABI says that "Each quad-precision parameter
                 value will be assigned to two extended words in the
                 parameter array.  */
	      num_elements += 2;

	      /* The psABI says that "Long doubles must be
                 quad-aligned, and thus a hole might be introduced
                 into the parameter array to force alignment."  Skip
                 an element if necessary.  */
	      if ((num_elements % 2) && sparc64_16_byte_align_p (type))
		num_elements++;
	    }
	  else
	    num_elements++;
	}
      else
	{
	  /* Integral and pointer arguments.  */
	  gdb_assert (sparc64_integral_or_pointer_p (type));

	  /* The psABI says that "Each argument value of integral type
	     smaller than an extended word will be widened by the
	     caller to an extended word according to the signed-ness
	     of the argument type."  */
	  if (len < 8)
	    args[i] = value_cast (builtin_type (gdbarch)->builtin_int64,
				  args[i]);
	  num_elements++;
	}
    }

  /* Allocate the "parameter array".  */
  sp -= num_elements * 8;

  /* The psABI says that "Every stack frame must be 16-byte aligned."  */
  sp &= ~0xf;

  /* Now we store the arguments in to the "paramater array".  Some
     Integer or Pointer arguments and Structure or Union arguments
     will be passed in %o registers.  Some Floating arguments and
     floating members of structures are passed in floating-point
     registers.  However, for functions with variable arguments,
     floating arguments are stored in an %0 register, and for
     functions without a prototype floating arguments are stored in
     both a floating-point and an %o registers, or a floating-point
     register and memory.  To simplify the logic here we always pass
     arguments in memory, an %o register, and a floating-point
     register if appropriate.  This should be no problem since the
     contents of any unused memory or registers in the "parameter
     array" are undefined.  */

  if (struct_return)
    {
      regcache_cooked_write_unsigned (regcache, SPARC_O0_REGNUM, struct_addr);
      element++;
    }

  for (i = 0; i < nargs; i++)
    {
      const gdb_byte *valbuf = value_contents (args[i]);
      struct type *type = value_type (args[i]);
      int len = TYPE_LENGTH (type);
      int regnum = -1;
      gdb_byte buf[16];

      if (sparc64_structure_or_union_p (type)
	  || (sparc64_complex_floating_p (type) && len == 32))
	{
	  /* Structure, Union or long double Complex arguments.  */
	  gdb_assert (len <= 16);
	  memset (buf, 0, sizeof (buf));
	  memcpy (buf, valbuf, len);
	  valbuf = buf;

	  if (element % 2 && sparc64_16_byte_align_p (type))
	    element++;

	  if (element < 6)
	    {
	      regnum = SPARC_O0_REGNUM + element;
	      if (len > 8 && element < 5)
		regcache_cooked_write (regcache, regnum + 1, valbuf + 8);
	    }

	  if (element < 16)
	    sparc64_store_floating_fields (regcache, type, valbuf, element, 0);
	}
      else if (sparc64_complex_floating_p (type))
	{
	  /* Float Complex or double Complex arguments.  */
	  if (element < 16)
	    {
	      regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + element;

	      if (len == 16)
		{
		  if (regnum < gdbarch_num_regs (gdbarch) + SPARC64_D30_REGNUM)
		    regcache_cooked_write (regcache, regnum + 1, valbuf + 8);
		  if (regnum < gdbarch_num_regs (gdbarch) + SPARC64_D10_REGNUM)
		    regcache_cooked_write (regcache,
					   SPARC_O0_REGNUM + element + 1,
					   valbuf + 8);
		}
	    }
	}
      else if (sparc64_floating_p (type))
	{
	  /* Floating arguments.  */
	  if (len == 16)
	    {
	      if (element % 2)
		element++;
	      if (element < 16)
		regnum = gdbarch_num_regs (gdbarch) + SPARC64_Q0_REGNUM
                         + element / 2;
	    }
	  else if (len == 8)
	    {
	      if (element < 16)
		regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM
                         + element;
	    }
	  else if (len == 4)
	    {
	      /* The psABI says "Each single-precision parameter value
                 will be assigned to one extended word in the
                 parameter array, and right-justified within that
                 word; the left half (even float register) is
                 undefined."  Even though the psABI says that "the
                 left half is undefined", set it to zero here.  */
	      memset (buf, 0, 4);
	      memcpy (buf + 4, valbuf, 4);
	      valbuf = buf;
	      len = 8;
	      if (element < 16)
		regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM
                         + element;
	    }
	}
      else
	{
	  /* Integral and pointer arguments.  */
	  gdb_assert (len == 8);
	  if (element < 6)
	    regnum = SPARC_O0_REGNUM + element;
	}

      if (regnum != -1)
	{
	  regcache_cooked_write (regcache, regnum, valbuf);

	  /* If we're storing the value in a floating-point register,
             also store it in the corresponding %0 register(s).  */
	  if (regnum >= gdbarch_num_regs (gdbarch))
            {
              regnum -= gdbarch_num_regs (gdbarch);

              if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D10_REGNUM)
	        {
	          gdb_assert (element < 6);
	          regnum = SPARC_O0_REGNUM + element;
	          regcache_cooked_write (regcache, regnum, valbuf);
                }
              else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q8_REGNUM)
                {
                  gdb_assert (element < 5);
                  regnum = SPARC_O0_REGNUM + element;
                  regcache_cooked_write (regcache, regnum, valbuf);
                  regcache_cooked_write (regcache, regnum + 1, valbuf + 8);
	        }
            }
	}

      /* Always store the argument in memory.  */
      write_memory (sp + element * 8, valbuf, len);
      element += ((len + 7) / 8);
    }

  gdb_assert (element == num_elements);

  /* Take BIAS into account.  */
  sp -= BIAS;
  return sp;
}

static CORE_ADDR
sparc64_frame_align (struct gdbarch *gdbarch, CORE_ADDR address)
{
  /* The ABI requires 16-byte alignment.  */
  return address & ~0xf;
}

static CORE_ADDR
sparc64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
			 struct regcache *regcache, CORE_ADDR bp_addr,
			 int nargs, struct value **args, CORE_ADDR sp,
			 int struct_return, CORE_ADDR struct_addr)
{
  /* Set return address.  */
  regcache_cooked_write_unsigned (regcache, SPARC_O7_REGNUM, bp_addr - 8);

  /* Set up function arguments.  */
  sp = sparc64_store_arguments (regcache, nargs, args, sp,
				struct_return, struct_addr);

  /* Allocate the register save area.  */
  sp -= 16 * 8;

  /* Stack should be 16-byte aligned at this point.  */
  gdb_assert ((sp + BIAS) % 16 == 0);

  /* Finally, update the stack pointer.  */
  regcache_cooked_write_unsigned (regcache, SPARC_SP_REGNUM, sp);

  return sp + BIAS;
}


/* Extract from an array REGBUF containing the (raw) register state, a
   function return value of TYPE, and copy that into VALBUF.  */

static void
sparc64_extract_return_value (struct type *type, struct regcache *regcache,
			      gdb_byte *valbuf)
{
  int len = TYPE_LENGTH (type);
  gdb_byte buf[32];
  int i;

  if (sparc64_structure_or_union_p (type))
    {
      /* Structure or Union return values.  */
      gdb_assert (len <= 32);

      for (i = 0; i < ((len + 7) / 8); i++)
	regcache_cooked_read (regcache, SPARC_O0_REGNUM + i, buf + i * 8);
      if (TYPE_CODE (type) != TYPE_CODE_UNION)
	sparc64_extract_floating_fields (regcache, type, buf, 0);
      memcpy (valbuf, buf, len);
    }
  else if (sparc64_floating_p (type) || sparc64_complex_floating_p (type))
    {
      /* Floating return values.  */
      for (i = 0; i < len / 4; i++)
	regcache_cooked_read (regcache, SPARC_F0_REGNUM + i, buf + i * 4);
      memcpy (valbuf, buf, len);
    }
  else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
    {
      /* Small arrays are returned the same way as small structures.  */
      gdb_assert (len <= 32);

      for (i = 0; i < ((len + 7) / 8); i++)
	regcache_cooked_read (regcache, SPARC_O0_REGNUM + i, buf + i * 8);
      memcpy (valbuf, buf, len);
    }
  else
    {
      /* Integral and pointer return values.  */
      gdb_assert (sparc64_integral_or_pointer_p (type));

      /* Just stripping off any unused bytes should preserve the
         signed-ness just fine.  */
      regcache_cooked_read (regcache, SPARC_O0_REGNUM, buf);
      memcpy (valbuf, buf + 8 - len, len);
    }
}

/* Write into the appropriate registers a function return value stored
   in VALBUF of type TYPE.  */

static void
sparc64_store_return_value (struct type *type, struct regcache *regcache,
			    const gdb_byte *valbuf)
{
  int len = TYPE_LENGTH (type);
  gdb_byte buf[16];
  int i;

  if (sparc64_structure_or_union_p (type))
    {
      /* Structure or Union return values.  */
      gdb_assert (len <= 32);

      /* Simplify matters by storing the complete value (including
         floating members) into %o0 and %o1.  Floating members are
         also store in the appropriate floating-point registers.  */
      memset (buf, 0, sizeof (buf));
      memcpy (buf, valbuf, len);
      for (i = 0; i < ((len + 7) / 8); i++)
	regcache_cooked_write (regcache, SPARC_O0_REGNUM + i, buf + i * 8);
      if (TYPE_CODE (type) != TYPE_CODE_UNION)
	sparc64_store_floating_fields (regcache, type, buf, 0, 0);
    }
  else if (sparc64_floating_p (type) || sparc64_complex_floating_p (type))
    {
      /* Floating return values.  */
      memcpy (buf, valbuf, len);
      for (i = 0; i < len / 4; i++)
	regcache_cooked_write (regcache, SPARC_F0_REGNUM + i, buf + i * 4);
    }
  else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
    {
      /* Small arrays are returned the same way as small structures.  */
      gdb_assert (len <= 32);

      memset (buf, 0, sizeof (buf));
      memcpy (buf, valbuf, len);
      for (i = 0; i < ((len + 7) / 8); i++)
	regcache_cooked_write (regcache, SPARC_O0_REGNUM + i, buf + i * 8);
    }
  else
    {
      /* Integral and pointer return values.  */
      gdb_assert (sparc64_integral_or_pointer_p (type));

      /* ??? Do we need to do any sign-extension here?  */
      memset (buf, 0, 8);
      memcpy (buf + 8 - len, valbuf, len);
      regcache_cooked_write (regcache, SPARC_O0_REGNUM, buf);
    }
}

static enum return_value_convention
sparc64_return_value (struct gdbarch *gdbarch, struct value *function,
		      struct type *type, struct regcache *regcache,
		      gdb_byte *readbuf, const gdb_byte *writebuf)
{
  if (TYPE_LENGTH (type) > 32)
    return RETURN_VALUE_STRUCT_CONVENTION;

  if (readbuf)
    sparc64_extract_return_value (type, regcache, readbuf);
  if (writebuf)
    sparc64_store_return_value (type, regcache, writebuf);

  return RETURN_VALUE_REGISTER_CONVENTION;
}


static void
sparc64_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
			       struct dwarf2_frame_state_reg *reg,
			       struct frame_info *this_frame)
{
  switch (regnum)
    {
    case SPARC_G0_REGNUM:
      /* Since %g0 is always zero, there is no point in saving it, and
	 people will be inclined omit it from the CFI.  Make sure we
	 don't warn about that.  */
      reg->how = DWARF2_FRAME_REG_SAME_VALUE;
      break;
    case SPARC_SP_REGNUM:
      reg->how = DWARF2_FRAME_REG_CFA;
      break;
    case SPARC64_PC_REGNUM:
      reg->how = DWARF2_FRAME_REG_RA_OFFSET;
      reg->loc.offset = 8;
      break;
    case SPARC64_NPC_REGNUM:
      reg->how = DWARF2_FRAME_REG_RA_OFFSET;
      reg->loc.offset = 12;
      break;
    }
}

/* sparc64_addr_bits_remove - remove useless address bits  */

static CORE_ADDR
sparc64_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return adi_normalize_address (addr);
}

void
sparc64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  tdep->pc_regnum = SPARC64_PC_REGNUM;
  tdep->npc_regnum = SPARC64_NPC_REGNUM;
  tdep->fpu_register_names = sparc64_fpu_register_names;
  tdep->fpu_registers_num = ARRAY_SIZE (sparc64_fpu_register_names);
  tdep->cp0_register_names = sparc64_cp0_register_names;
  tdep->cp0_registers_num = ARRAY_SIZE (sparc64_cp0_register_names);

  /* This is what all the fuss is about.  */
  set_gdbarch_long_bit (gdbarch, 64);
  set_gdbarch_long_long_bit (gdbarch, 64);
  set_gdbarch_ptr_bit (gdbarch, 64);

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

  set_gdbarch_num_regs (gdbarch, SPARC64_NUM_REGS);
  set_gdbarch_register_name (gdbarch, sparc64_register_name);
  set_gdbarch_register_type (gdbarch, sparc64_register_type);
  set_gdbarch_num_pseudo_regs (gdbarch, SPARC64_NUM_PSEUDO_REGS);
  set_tdesc_pseudo_register_name (gdbarch, sparc64_pseudo_register_name);
  set_tdesc_pseudo_register_type (gdbarch, sparc64_pseudo_register_type);
  set_gdbarch_pseudo_register_read (gdbarch, sparc64_pseudo_register_read);
  set_gdbarch_pseudo_register_write (gdbarch, sparc64_pseudo_register_write);

  /* Register numbers of various important registers.  */
  set_gdbarch_pc_regnum (gdbarch, SPARC64_PC_REGNUM); /* %pc */

  /* Call dummy code.  */
  set_gdbarch_frame_align (gdbarch, sparc64_frame_align);
  set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
  set_gdbarch_push_dummy_code (gdbarch, NULL);
  set_gdbarch_push_dummy_call (gdbarch, sparc64_push_dummy_call);

  set_gdbarch_return_value (gdbarch, sparc64_return_value);
  set_gdbarch_stabs_argument_has_addr
    (gdbarch, default_stabs_argument_has_addr);

  set_gdbarch_skip_prologue (gdbarch, sparc64_skip_prologue);
  set_gdbarch_stack_frame_destroyed_p (gdbarch, sparc_stack_frame_destroyed_p);

  /* Hook in the DWARF CFI frame unwinder.  */
  dwarf2_frame_set_init_reg (gdbarch, sparc64_dwarf2_frame_init_reg);
  /* FIXME: kettenis/20050423: Don't enable the unwinder until the
     StackGhost issues have been resolved.  */

  frame_unwind_append_unwinder (gdbarch, &sparc64_frame_unwind);
  frame_base_set_default (gdbarch, &sparc64_frame_base);

  set_gdbarch_addr_bits_remove (gdbarch, sparc64_addr_bits_remove);
}


/* Helper functions for dealing with register sets.  */

#define TSTATE_CWP	0x000000000000001fULL
#define TSTATE_ICC	0x0000000f00000000ULL
#define TSTATE_XCC	0x000000f000000000ULL

#define PSR_S		0x00000080
#define PSR_ICC		0x00f00000
#define PSR_VERS	0x0f000000
#define PSR_IMPL	0xf0000000
#define PSR_V8PLUS	0xff000000
#define PSR_XCC		0x000f0000

void
sparc64_supply_gregset (const struct sparc_gregmap *gregmap,
			struct regcache *regcache,
			int regnum, const void *gregs)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int sparc32 = (gdbarch_ptr_bit (gdbarch) == 32);
  const gdb_byte *regs = (const gdb_byte *) gregs;
  gdb_byte zero[8] = { 0 };
  int i;

  if (sparc32)
    {
      if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
	{
	  int offset = gregmap->r_tstate_offset;
	  ULONGEST tstate, psr;
	  gdb_byte buf[4];

	  tstate = extract_unsigned_integer (regs + offset, 8, byte_order);
	  psr = ((tstate & TSTATE_CWP) | PSR_S | ((tstate & TSTATE_ICC) >> 12)
		 | ((tstate & TSTATE_XCC) >> 20) | PSR_V8PLUS);
	  store_unsigned_integer (buf, 4, byte_order, psr);
	  regcache_raw_supply (regcache, SPARC32_PSR_REGNUM, buf);
	}

      if (regnum == SPARC32_PC_REGNUM || regnum == -1)
	regcache_raw_supply (regcache, SPARC32_PC_REGNUM,
			     regs + gregmap->r_pc_offset + 4);

      if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
	regcache_raw_supply (regcache, SPARC32_NPC_REGNUM,
			     regs + gregmap->r_npc_offset + 4);

      if (regnum == SPARC32_Y_REGNUM || regnum == -1)
	{
	  int offset = gregmap->r_y_offset + 8 - gregmap->r_y_size;
	  regcache_raw_supply (regcache, SPARC32_Y_REGNUM, regs + offset);
	}
    }
  else
    {
      if (regnum == SPARC64_STATE_REGNUM || regnum == -1)
	regcache_raw_supply (regcache, SPARC64_STATE_REGNUM,
			     regs + gregmap->r_tstate_offset);

      if (regnum == SPARC64_PC_REGNUM || regnum == -1)
	regcache_raw_supply (regcache, SPARC64_PC_REGNUM,
			     regs + gregmap->r_pc_offset);

      if (regnum == SPARC64_NPC_REGNUM || regnum == -1)
	regcache_raw_supply (regcache, SPARC64_NPC_REGNUM,
			     regs + gregmap->r_npc_offset);

      if (regnum == SPARC64_Y_REGNUM || regnum == -1)
	{
	  gdb_byte buf[8];

	  memset (buf, 0, 8);
	  memcpy (buf + 8 - gregmap->r_y_size,
		  regs + gregmap->r_y_offset, gregmap->r_y_size);
	  regcache_raw_supply (regcache, SPARC64_Y_REGNUM, buf);
	}

      if ((regnum == SPARC64_FPRS_REGNUM || regnum == -1)
	  && gregmap->r_fprs_offset != -1)
	regcache_raw_supply (regcache, SPARC64_FPRS_REGNUM,
			     regs + gregmap->r_fprs_offset);
    }

  if (regnum == SPARC_G0_REGNUM || regnum == -1)
    regcache_raw_supply (regcache, SPARC_G0_REGNUM, &zero);

  if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
    {
      int offset = gregmap->r_g1_offset;

      if (sparc32)
	offset += 4;

      for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
	{
	  if (regnum == i || regnum == -1)
	    regcache_raw_supply (regcache, i, regs + offset);
	  offset += 8;
	}
    }

  if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1)
    {
      /* Not all of the register set variants include Locals and
         Inputs.  For those that don't, we read them off the stack.  */
      if (gregmap->r_l0_offset == -1)
	{
	  ULONGEST sp;

	  regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
	  sparc_supply_rwindow (regcache, sp, regnum);
	}
      else
	{
	  int offset = gregmap->r_l0_offset;

	  if (sparc32)
	    offset += 4;

	  for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
	    {
	      if (regnum == i || regnum == -1)
		regcache_raw_supply (regcache, i, regs + offset);
	      offset += 8;
	    }
	}
    }
}

void
sparc64_collect_gregset (const struct sparc_gregmap *gregmap,
			 const struct regcache *regcache,
			 int regnum, void *gregs)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int sparc32 = (gdbarch_ptr_bit (gdbarch) == 32);
  gdb_byte *regs = (gdb_byte *) gregs;
  int i;

  if (sparc32)
    {
      if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
	{
	  int offset = gregmap->r_tstate_offset;
	  ULONGEST tstate, psr;
	  gdb_byte buf[8];

	  tstate = extract_unsigned_integer (regs + offset, 8, byte_order);
	  regcache_raw_collect (regcache, SPARC32_PSR_REGNUM, buf);
	  psr = extract_unsigned_integer (buf, 4, byte_order);
	  tstate |= (psr & PSR_ICC) << 12;
	  if ((psr & (PSR_VERS | PSR_IMPL)) == PSR_V8PLUS)
	    tstate |= (psr & PSR_XCC) << 20;
	  store_unsigned_integer (buf, 8, byte_order, tstate);
	  memcpy (regs + offset, buf, 8);
	}

      if (regnum == SPARC32_PC_REGNUM || regnum == -1)
	regcache_raw_collect (regcache, SPARC32_PC_REGNUM,
			      regs + gregmap->r_pc_offset + 4);

      if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
	regcache_raw_collect (regcache, SPARC32_NPC_REGNUM,
			      regs + gregmap->r_npc_offset + 4);

      if (regnum == SPARC32_Y_REGNUM || regnum == -1)
	{
	  int offset = gregmap->r_y_offset + 8 - gregmap->r_y_size;
	  regcache_raw_collect (regcache, SPARC32_Y_REGNUM, regs + offset);
	}
    }
  else
    {
      if (regnum == SPARC64_STATE_REGNUM || regnum == -1)
	regcache_raw_collect (regcache, SPARC64_STATE_REGNUM,
			      regs + gregmap->r_tstate_offset);

      if (regnum == SPARC64_PC_REGNUM || regnum == -1)
	regcache_raw_collect (regcache, SPARC64_PC_REGNUM,
			      regs + gregmap->r_pc_offset);

      if (regnum == SPARC64_NPC_REGNUM || regnum == -1)
	regcache_raw_collect (regcache, SPARC64_NPC_REGNUM,
			      regs + gregmap->r_npc_offset);

      if (regnum == SPARC64_Y_REGNUM || regnum == -1)
	{
	  gdb_byte buf[8];

	  regcache_raw_collect (regcache, SPARC64_Y_REGNUM, buf);
	  memcpy (regs + gregmap->r_y_offset,
		  buf + 8 - gregmap->r_y_size, gregmap->r_y_size);
	}

      if ((regnum == SPARC64_FPRS_REGNUM || regnum == -1)
	  && gregmap->r_fprs_offset != -1)
	regcache_raw_collect (regcache, SPARC64_FPRS_REGNUM,
			      regs + gregmap->r_fprs_offset);

    }

  if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
    {
      int offset = gregmap->r_g1_offset;

      if (sparc32)
	offset += 4;

      /* %g0 is always zero.  */
      for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
	{
	  if (regnum == i || regnum == -1)
	    regcache_raw_collect (regcache, i, regs + offset);
	  offset += 8;
	}
    }

  if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1)
    {
      /* Not all of the register set variants include Locals and
         Inputs.  For those that don't, we read them off the stack.  */
      if (gregmap->r_l0_offset != -1)
	{
	  int offset = gregmap->r_l0_offset;

	  if (sparc32)
	    offset += 4;

	  for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
	    {
	      if (regnum == i || regnum == -1)
		regcache_raw_collect (regcache, i, regs + offset);
	      offset += 8;
	    }
	}
    }
}

void
sparc64_supply_fpregset (const struct sparc_fpregmap *fpregmap,
			 struct regcache *regcache,
			 int regnum, const void *fpregs)
{
  int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
  const gdb_byte *regs = (const gdb_byte *) fpregs;
  int i;

  for (i = 0; i < 32; i++)
    {
      if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1)
	regcache_raw_supply (regcache, SPARC_F0_REGNUM + i,
			     regs + fpregmap->r_f0_offset + (i * 4));
    }

  if (sparc32)
    {
      if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
	regcache_raw_supply (regcache, SPARC32_FSR_REGNUM,
			     regs + fpregmap->r_fsr_offset);
    }
  else
    {
      for (i = 0; i < 16; i++)
	{
	  if (regnum == (SPARC64_F32_REGNUM + i) || regnum == -1)
	    regcache_raw_supply (regcache, SPARC64_F32_REGNUM + i,
				 (regs + fpregmap->r_f0_offset
				  + (32 * 4) + (i * 8)));
	}

      if (regnum == SPARC64_FSR_REGNUM || regnum == -1)
	regcache_raw_supply (regcache, SPARC64_FSR_REGNUM,
			     regs + fpregmap->r_fsr_offset);
    }
}

void
sparc64_collect_fpregset (const struct sparc_fpregmap *fpregmap,
			  const struct regcache *regcache,
			  int regnum, void *fpregs)
{
  int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
  gdb_byte *regs = (gdb_byte *) fpregs;
  int i;

  for (i = 0; i < 32; i++)
    {
      if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1)
	regcache_raw_collect (regcache, SPARC_F0_REGNUM + i,
			      regs + fpregmap->r_f0_offset + (i * 4));
    }

  if (sparc32)
    {
      if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
	regcache_raw_collect (regcache, SPARC32_FSR_REGNUM,
			      regs + fpregmap->r_fsr_offset);
    }
  else
    {
      for (i = 0; i < 16; i++)
	{
	  if (regnum == (SPARC64_F32_REGNUM + i) || regnum == -1)
	    regcache_raw_collect (regcache, SPARC64_F32_REGNUM + i,
				  (regs + fpregmap->r_f0_offset
				   + (32 * 4) + (i * 8)));
	}

      if (regnum == SPARC64_FSR_REGNUM || regnum == -1)
	regcache_raw_collect (regcache, SPARC64_FSR_REGNUM,
			      regs + fpregmap->r_fsr_offset);
    }
}

const struct sparc_fpregmap sparc64_bsd_fpregmap =
{
  0 * 8,			/* %f0 */
  32 * 8,			/* %fsr */
};
