/* Native-dependent code for Alpha BSD's.
   Copyright (C) 2000 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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include "defs.h"
#include "inferior.h"

#include <sys/types.h>
#include <sys/ptrace.h>
#include <machine/reg.h>

#ifdef HAVE_SYS_PROCFS_H
#include <sys/procfs.h>
#endif

#ifndef HAVE_GREGSET_T
typedef struct reg gregset_t;
#endif

#ifndef HAVE_FPREGSET_T
typedef struct fpreg fpregset_t;
#endif

#include "gregset.h"

/* Number of general-purpose registers.  */
#define NUM_GREGS  32

/* Number of floating point registers.  */
#define NUM_FPREGS 31


/* Transfering the registers between GDB, inferiors and core files.  */

/* Fill GDB's register array with the genereal-purpose register values
   in *GREGSETP.  */

void
supply_gregset (gregset_t *gregsetp)
{
  int i;

  for (i = 0; i < NUM_GREGS; i++)
    {
      if (CANNOT_FETCH_REGISTER (i))
	supply_register (i, NULL);
      else
	supply_register (i, (char *) &gregsetp->r_regs[i]);
    }

  /* The PC travels in the R_ZERO slot.  */
  supply_register (PC_REGNUM, (char *) &gregsetp->r_regs[R_ZERO]);
}

/* Fill register REGNO (if it is a general-purpose register) in
   *GREGSETPS with the value in GDB's register array.  If REGNO is -1,
   do this for all registers.  */

void
fill_gregset (gregset_t *gregsetp, int regno)
{
  int i;

  for (i = 0; i < NUM_GREGS; i++)
    if ((regno == -1 || regno == i) && ! CANNOT_STORE_REGISTER (i))
      memcpy (&gregsetp->r_regs[i], &registers[REGISTER_BYTE (i)],
	      REGISTER_RAW_SIZE (i));

  /* The PC travels in the R_ZERO slot.  */
  if (regno == -1 || regno == PC_REGNUM)
    memcpy (&gregsetp->r_regs[R_ZERO], &registers[REGISTER_BYTE (PC_REGNUM)],
	    REGISTER_RAW_SIZE (PC_REGNUM));
}

/* Fill GDB's register array with the floating-point register values
   in *FPREGSETP.  */

void
supply_fpregset (fpregset_t *fpregsetp)
{
  int i;

  for (i = FP0_REGNUM; i < FP0_REGNUM + NUM_FPREGS; i++)
    {
      if (CANNOT_FETCH_REGISTER (i))
	supply_register (i, NULL);
      else
	supply_register (i, (char *) &fpregsetp->fpr_regs[i - FP0_REGNUM]);
    }

  supply_register (FPCR_REGNUM, (char *) &fpregsetp->fpr_cr);
}

/* Fill register REGNO (if it is a floating-point register) in
   *FPREGSETP with the value in GDB's register array.  If REGNO is -1,
   do this for all registers.  */

void
fill_fpregset (fpregset_t *fpregsetp, int regno)
{
  int i;

  for (i = FP0_REGNUM; i < FP0_REGNUM + NUM_FPREGS; i++)
    if ((regno == -1 || regno == i) && ! CANNOT_STORE_REGISTER (i))
      memcpy (&fpregsetp->fpr_regs[i - FP0_REGNUM],
	      &registers[REGISTER_BYTE (i)], REGISTER_RAW_SIZE (i));

  if (regno == -1 || regno == FPCR_REGNUM)
    memcpy (&fpregsetp->fpr_cr, &registers[REGISTER_BYTE (FPCR_REGNUM)],
	    REGISTER_RAW_SIZE (FPCR_REGNUM));
}

/* Fetch register REGNO from the inferior.  If REGNO is -1, do this
   for all registers (including the floating point registers).  */

void
fetch_inferior_registers (int regno)
{
  gregset_t gregs;

  if (ptrace (PT_GETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &gregs, 0) == -1)
    perror_with_name ("Couldn't get registers");

  supply_gregset (&gregs);

  if (regno == -1 || regno >= FP0_REGNUM)
    {
      fpregset_t fpregs;

      if (ptrace (PT_GETFPREGS, inferior_pid,
		  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
	perror_with_name ("Couldn't get floating point status");

      supply_fpregset (&fpregs);
    }

  /* Reset virtual frame pointer.  */
  supply_register (FP_REGNUM, NULL);
}

/* Store register REGNO back into the inferior.  If REGNO is -1, do
   this for all registers (including the floating point registers).  */

void
store_inferior_registers (int regno)
{
  gregset_t gregs;

  if (ptrace (PT_GETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &gregs, 0) == -1)
    perror_with_name ("Couldn't get registers");

  fill_gregset (&gregs, regno);

  if (ptrace (PT_SETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &gregs, 0) == -1)
    perror_with_name ("Couldn't write registers");

  if (regno == -1 || regno >= FP0_REGNUM)
    {
      fpregset_t fpregs;

      if (ptrace (PT_GETFPREGS, inferior_pid,
		  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
	perror_with_name ("Couldn't get floating point status");

      fill_fpregset (&fpregs, regno);

      if (ptrace (PT_SETFPREGS, inferior_pid,
		  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
	perror_with_name ("Couldn't write floating point status");
    }
}
