/* Target-dependent code for UltraSPARC.

   Copyright (C) 2003-2019 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 "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 (const 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 = inferior_ptid.pid ();
  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_top_target (), AT_ADI_BLKSZ, &value) <= 0)
    return false;
  proc->stat.blksize = value;
  target_auxv_search (current_top_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 (inferior_ptid.pid ());

  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 (inferior_ptid.pid ());

  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 (inferior_ptid.pid ());

  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 = inferior_ptid.pid ();
  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/%ld/adi/tags", (long) 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 = inferior_ptid.pid ();
  snprintf (filename, sizeof filename, "/proc/%ld/adi/maps", (long) pid);
  gdb::unique_xmalloc_ptr<char> data
    = target_fileio_read_stralloc (NULL, filename);
  if (data)
    {
      adi_stat_t adi_stat = get_adi_info (pid);
      char *line;
      for (line = strtok (data.get (), "\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)
		return true;
            }
        }
      }
    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, gdb_byte *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 (inferior_ptid.pid ());
      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 (inferior_ptid.pid ());
      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, gdb_byte *tags)
{
  int v_idx = 0;
  const int maxelts = 8;  /* # of elements per line */

  adi_stat_t adi_stat = get_adi_info (inferior_ptid.pid ());

  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");
      vaddr += maxelts;
    }
}

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

  CORE_ADDR vstart = adi_align_address (vaddr);
  int cnt = adi_convert_byte_count (vaddr, bcnt, vstart);
  gdb::def_vector<gdb_byte> buf (cnt);
  int read_cnt = adi_read_versions (vstart, cnt, buf.data ());
  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.data ());
}

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

  int cnt = 1;
  const 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 (const char *args, int from_tty)
{
  static const char *adi_usage
    = N_("Usage: adi assign|a[/COUNT] ADDR = VERSION");

  /* 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"));

  const char *exp = args;
  if (exp == 0)
    error_no_arg (_(adi_usage));

  char *q = (char *) strchr (exp, '=');
  if (q)
    *q++ = 0;
  else
    error ("%s", _(adi_usage));

  size_t cnt = 1;
  const 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 ("%s", _(adi_usage));

  int version = 0;
  if (q != NULL)           /* parse version tag */
    {
      adi_stat_t ast = get_adi_info (inferior_ptid.pid ());
      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", 64);
      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", 64);
      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", 64);
      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", 64);
      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,
			      readable_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 (regnum, buf);
      if (status == REG_VALID)
	status = regcache->raw_read (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 (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 (regnum, buf);
      if (status == REG_VALID)
	status = regcache->raw_read (regnum + 1, buf + 4);
      if (status == REG_VALID)
	status = regcache->raw_read (regnum + 2, buf + 8);
      if (status == REG_VALID)
	status = regcache->raw_read (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 (regnum, buf);
      if (status == REG_VALID)
	status = regcache->raw_read (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 (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 (regnum, buf);
      regcache->raw_write (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 (regnum, buf);
    }
  else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q28_REGNUM)
    {
      regnum = SPARC_F0_REGNUM + 4 * (regnum - SPARC64_Q0_REGNUM);
      regcache->raw_write (regnum, buf);
      regcache->raw_write (regnum + 1, buf + 4);
      regcache->raw_write (regnum + 2, buf + 8);
      regcache->raw_write (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 (regnum, buf);
      regcache->raw_write (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 = regcache->arch ();
  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 (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 (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 (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 (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 (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 = regcache->arch ();

  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 (regnum, buf);
          memcpy (valbuf, buf + 4 - len, len);
        }
      else
        for (int i = 0; i < (len + 3) / 4; i++)
          regcache->cooked_read (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 (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 (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 (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,
			 function_call_return_method return_method,
			 CORE_ADDR struct_addr)
{
  struct gdbarch *gdbarch = regcache->arch ();
  /* 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 (return_method == return_method_struct)
    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 (return_method == return_method_struct)
    {
      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 (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 (regnum + 1, valbuf + 8);
		  if (regnum < gdbarch_num_regs (gdbarch) + SPARC64_D10_REGNUM)
		    regcache->cooked_write (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 (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 (regnum, valbuf);
                }
              else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q8_REGNUM)
                {
                  gdb_assert (element < 5);
                  regnum = SPARC_O0_REGNUM + element;
                  regcache->cooked_write (regnum, valbuf);
                  regcache->cooked_write (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,
			 function_call_return_method return_method,
			 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, return_method,
				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 (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 (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 (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 (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 (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 (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 (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 (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
#ifndef PSR_ICC
#define PSR_ICC		0x00f00000
#endif
#define PSR_VERS	0x0f000000
#ifndef PSR_IMPL
#define PSR_IMPL	0xf0000000
#endif
#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 = regcache->arch ();
  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 (SPARC32_PSR_REGNUM, buf);
	}

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

      if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
	regcache->raw_supply (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 (SPARC32_Y_REGNUM, regs + offset);
	}
    }
  else
    {
      if (regnum == SPARC64_STATE_REGNUM || regnum == -1)
	regcache->raw_supply (SPARC64_STATE_REGNUM,
			      regs + gregmap->r_tstate_offset);

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

      if (regnum == SPARC64_NPC_REGNUM || regnum == -1)
	regcache->raw_supply (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 (SPARC64_Y_REGNUM, buf);
	}

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

  if (regnum == SPARC_G0_REGNUM || regnum == -1)
    regcache->raw_supply (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 (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 (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 = regcache->arch ();
  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 (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 (SPARC32_PC_REGNUM,
			       regs + gregmap->r_pc_offset + 4);

      if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
	regcache->raw_collect (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 (SPARC32_Y_REGNUM, regs + offset);
	}
    }
  else
    {
      if (regnum == SPARC64_STATE_REGNUM || regnum == -1)
	regcache->raw_collect (SPARC64_STATE_REGNUM,
			       regs + gregmap->r_tstate_offset);

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

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

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

	  regcache->raw_collect (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 (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 (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 (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 (regcache->arch ()) == 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 (SPARC_F0_REGNUM + i,
			      regs + fpregmap->r_f0_offset + (i * 4));
    }

  if (sparc32)
    {
      if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
	regcache->raw_supply (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
	      (SPARC64_F32_REGNUM + i,
	       regs + fpregmap->r_f0_offset + (32 * 4) + (i * 8));
	}

      if (regnum == SPARC64_FSR_REGNUM || regnum == -1)
	regcache->raw_supply (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 (regcache->arch ()) == 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 (SPARC_F0_REGNUM + i,
			       regs + fpregmap->r_f0_offset + (i * 4));
    }

  if (sparc32)
    {
      if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
	regcache->raw_collect (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 (SPARC64_F32_REGNUM + i,
				   (regs + fpregmap->r_f0_offset
				    + (32 * 4) + (i * 8)));
	}

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

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