198944Sobrien/* Native-dependent code for PowerPC's running NetBSD, for GDB.
2130803Smarcel   Copyright 2002 Free Software Foundation, Inc.
3130803Smarcel   Contributed by Wasabi Systems, Inc.
498944Sobrien
598944Sobrien   This file is part of GDB.
698944Sobrien
798944Sobrien   This program is free software; you can redistribute it and/or modify
898944Sobrien   it under the terms of the GNU General Public License as published by
998944Sobrien   the Free Software Foundation; either version 2 of the License, or
1098944Sobrien   (at your option) any later version.
1198944Sobrien
1298944Sobrien   This program is distributed in the hope that it will be useful,
1398944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1498944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1598944Sobrien   GNU General Public License for more details.
1698944Sobrien
1798944Sobrien   You should have received a copy of the GNU General Public License
1898944Sobrien   along with this program; if not, write to the Free Software
1998944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2098944Sobrien   Boston, MA 02111-1307, USA.  */
2198944Sobrien
2298944Sobrien#include <sys/types.h>
2398944Sobrien#include <sys/ptrace.h>
2498944Sobrien#include <machine/reg.h>
2598944Sobrien
2698944Sobrien#include "defs.h"
2798944Sobrien#include "inferior.h"
28130803Smarcel
2998944Sobrien#include "ppc-tdep.h"
30130803Smarcel#include "ppcnbsd-tdep.h"
3198944Sobrien
32130803Smarcel/* Returns true if PT_GETREGS fetches this register.  */
33130803Smarcelstatic int
34130803Smarcelgetregs_supplies (int regno)
3598944Sobrien{
36130803Smarcel  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
3798944Sobrien
38130803Smarcel  return ((regno >= 0 && regno <= 31)
39130803Smarcel          || regno == tdep->ppc_lr_regnum
40130803Smarcel          || regno == tdep->ppc_cr_regnum
41130803Smarcel          || regno == tdep->ppc_xer_regnum
42130803Smarcel          || regno == tdep->ppc_ctr_regnum
43130803Smarcel	  || regno == PC_REGNUM);
44130803Smarcel}
4598944Sobrien
46130803Smarcel/* Like above, but for PT_GETFPREGS.  */
47130803Smarcelstatic int
48130803Smarcelgetfpregs_supplies (int regno)
49130803Smarcel{
50130803Smarcel  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
5198944Sobrien
52130803Smarcel  return ((regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31)
53130803Smarcel	  || regno == tdep->ppc_fpscr_regnum);
5498944Sobrien}
5598944Sobrien
5698944Sobrienvoid
57130803Smarcelfetch_inferior_registers (int regno)
5898944Sobrien{
59130803Smarcel  if (regno == -1 || getregs_supplies (regno))
60130803Smarcel    {
61130803Smarcel      struct reg regs;
6298944Sobrien
63130803Smarcel      if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
64130803Smarcel		  (PTRACE_ARG3_TYPE) &regs, 0) == -1)
65130803Smarcel        perror_with_name ("Couldn't get registers");
6698944Sobrien
67130803Smarcel      ppcnbsd_supply_reg ((char *) &regs, regno);
68130803Smarcel      if (regno != -1)
69130803Smarcel	return;
70130803Smarcel    }
7198944Sobrien
72130803Smarcel  if (regno == -1 || getfpregs_supplies (regno))
73130803Smarcel    {
74130803Smarcel      struct fpreg fpregs;
75130803Smarcel
76130803Smarcel      if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
77130803Smarcel		  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
78130803Smarcel	perror_with_name ("Couldn't get FP registers");
79130803Smarcel
80130803Smarcel      ppcnbsd_supply_fpreg ((char *) &fpregs, regno);
81130803Smarcel      if (regno != -1)
82130803Smarcel	return;
83130803Smarcel    }
8498944Sobrien}
8598944Sobrien
8698944Sobrienvoid
87130803Smarcelstore_inferior_registers (int regno)
8898944Sobrien{
89130803Smarcel  if (regno == -1 || getregs_supplies (regno))
90130803Smarcel    {
91130803Smarcel      struct reg regs;
9298944Sobrien
93130803Smarcel      if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
94130803Smarcel		  (PTRACE_ARG3_TYPE) &regs, 0) == -1)
95130803Smarcel	perror_with_name ("Couldn't get registers");
9698944Sobrien
97130803Smarcel      ppcnbsd_fill_reg ((char *) &regs, regno);
9898944Sobrien
99130803Smarcel      if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
100130803Smarcel		  (PTRACE_ARG3_TYPE) &regs, 0) == -1)
101130803Smarcel	perror_with_name ("Couldn't write registers");
10298944Sobrien
103130803Smarcel      if (regno != -1)
104130803Smarcel	return;
105130803Smarcel    }
10698944Sobrien
107130803Smarcel  if (regno == -1 || getfpregs_supplies (regno))
108130803Smarcel    {
109130803Smarcel      struct fpreg fpregs;
11098944Sobrien
111130803Smarcel      if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
112130803Smarcel		  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
113130803Smarcel	perror_with_name ("Couldn't get FP registers");
114130803Smarcel
115130803Smarcel      ppcnbsd_fill_fpreg ((char *) &fpregs, regno);
116130803Smarcel
117130803Smarcel      if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
118130803Smarcel		  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
119130803Smarcel	perror_with_name ("Couldn't set FP registers");
120130803Smarcel    }
12198944Sobrien}
122