1161561Smarcel/* Native-dependent code for PowerPC's running FreeBSD, for GDB.
2161561Smarcel   Copyright 2002, 2004 Free Software Foundation, Inc.
3161561Smarcel   Contributed by Wasabi Systems, Inc.
4161561Smarcel
5161561Smarcel   This file is part of GDB.
6161561Smarcel
7161561Smarcel   This program is free software; you can redistribute it and/or modify
8161561Smarcel   it under the terms of the GNU General Public License as published by
9161561Smarcel   the Free Software Foundation; either version 2 of the License, or
10161561Smarcel   (at your option) any later version.
11161561Smarcel
12161561Smarcel   This program is distributed in the hope that it will be useful,
13161561Smarcel   but WITHOUT ANY WARRANTY; without even the implied warranty of
14161561Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15161561Smarcel   GNU General Public License for more details.
16161561Smarcel
17161561Smarcel   You should have received a copy of the GNU General Public License
18161561Smarcel   along with this program; if not, write to the Free Software
19161561Smarcel   Foundation, Inc., 59 Temple Place - Suite 330,
20161561Smarcel   Boston, MA 02111-1307, USA.  */
21161561Smarcel
22161561Smarcel#include <sys/types.h>
23161561Smarcel#include <sys/ptrace.h>
24161561Smarcel#include <machine/reg.h>
25161561Smarcel#include <machine/frame.h>
26161561Smarcel
27161561Smarcel#include "defs.h"
28161561Smarcel#include "inferior.h"
29161561Smarcel#include "gdb_assert.h"
30161561Smarcel#include "gdbcore.h"
31161561Smarcel#include "regcache.h"
32161561Smarcel
33161561Smarcel#include "ppc-tdep.h"
34161561Smarcel#include "ppcfbsd-tdep.h"
35161561Smarcel
36161561Smarcel/* Returns true if PT_GETREGS fetches this register.  */
37161561Smarcelstatic int
38161561Smarcelgetregs_supplies (int regno)
39161561Smarcel{
40161561Smarcel  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
41161561Smarcel
42161561Smarcel  return ((regno >= tdep->ppc_gp0_regnum && regno <= tdep->ppc_gplast_regnum)
43161561Smarcel          || regno == tdep->ppc_lr_regnum
44161561Smarcel          || regno == tdep->ppc_cr_regnum
45161561Smarcel          || regno == tdep->ppc_xer_regnum
46161561Smarcel          || regno == tdep->ppc_ctr_regnum
47161561Smarcel	  || regno == PC_REGNUM);
48161561Smarcel}
49161561Smarcel
50161561Smarcel/* Like above, but for PT_GETFPREGS.  */
51161561Smarcelstatic int
52161561Smarcelgetfpregs_supplies (int regno)
53161561Smarcel{
54161561Smarcel  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
55161561Smarcel
56161561Smarcel  /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
57161561Smarcel     point registers.  Traditionally, GDB's register set has still
58161561Smarcel     listed the floating point registers for such machines, so this
59161561Smarcel     code is harmless.  However, the new E500 port actually omits the
60161561Smarcel     floating point registers entirely from the register set --- they
61161561Smarcel     don't even have register numbers assigned to them.
62161561Smarcel
63161561Smarcel     It's not clear to me how best to update this code, so this assert
64161561Smarcel     will alert the first person to encounter the NetBSD/E500
65161561Smarcel     combination to the problem.  */
66161561Smarcel  gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
67161561Smarcel
68161561Smarcel  return ((regno >= FP0_REGNUM && regno <= FPLAST_REGNUM)
69161561Smarcel	  || regno == tdep->ppc_fpscr_regnum);
70161561Smarcel}
71161561Smarcel
72161561Smarcelvoid
73161561Smarcelfetch_inferior_registers (int regno)
74161561Smarcel{
75161561Smarcel  if (regno == -1 || getregs_supplies (regno))
76161561Smarcel    {
77161561Smarcel      struct reg regs;
78161561Smarcel
79161561Smarcel      if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
80161561Smarcel		  (PTRACE_ARG3_TYPE) &regs, 0) == -1)
81161561Smarcel        perror_with_name (_("Couldn't get registers"));
82161561Smarcel
83161561Smarcel      ppcfbsd_supply_reg ((char *) &regs, regno);
84161561Smarcel      if (regno != -1)
85161561Smarcel	return;
86161561Smarcel    }
87161561Smarcel
88161561Smarcel  if (regno == -1 || getfpregs_supplies (regno))
89161561Smarcel    {
90161561Smarcel      struct fpreg fpregs;
91161561Smarcel
92161561Smarcel      if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
93161561Smarcel		  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
94161561Smarcel	perror_with_name (_("Couldn't get FP registers"));
95161561Smarcel
96161561Smarcel      ppcfbsd_supply_fpreg ((char *) &fpregs, regno);
97161561Smarcel      if (regno != -1)
98161561Smarcel	return;
99161561Smarcel    }
100161561Smarcel}
101161561Smarcel
102161561Smarcelvoid
103161561Smarcelstore_inferior_registers (int regno)
104161561Smarcel{
105161561Smarcel  if (regno == -1 || getregs_supplies (regno))
106161561Smarcel    {
107161561Smarcel      struct reg regs;
108161561Smarcel
109161561Smarcel      if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
110161561Smarcel		  (PTRACE_ARG3_TYPE) &regs, 0) == -1)
111161561Smarcel	perror_with_name (_("Couldn't get registers"));
112161561Smarcel
113161561Smarcel      ppcfbsd_fill_reg ((char *) &regs, regno);
114161561Smarcel
115161561Smarcel      if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
116161561Smarcel		  (PTRACE_ARG3_TYPE) &regs, 0) == -1)
117161561Smarcel	perror_with_name (_("Couldn't write registers"));
118161561Smarcel
119161561Smarcel      if (regno != -1)
120161561Smarcel	return;
121161561Smarcel    }
122161561Smarcel
123161561Smarcel  if (regno == -1 || getfpregs_supplies (regno))
124161561Smarcel    {
125161561Smarcel      struct fpreg fpregs;
126161561Smarcel
127161561Smarcel      if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
128161561Smarcel		  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
129161561Smarcel	perror_with_name (_("Couldn't get FP registers"));
130161561Smarcel
131161561Smarcel      ppcfbsd_fill_fpreg ((char *) &fpregs, regno);
132161561Smarcel
133161561Smarcel      if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
134161561Smarcel		  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
135161561Smarcel	perror_with_name (_("Couldn't set FP registers"));
136161561Smarcel    }
137161561Smarcel}
138161561Smarcel
139161561Smarcelvoid
140161561Smarcelfill_gregset (char *regs, int regnum)
141161561Smarcel{
142161561Smarcel  ppcfbsd_fill_reg (regs, regnum);
143161561Smarcel}
144161561Smarcel
145161561Smarcelvoid
146169185Smarcelsupply_gregset (char *regs)
147169185Smarcel{
148169185Smarcel  ppcfbsd_supply_reg (regs, -1);
149169185Smarcel}
150169185Smarcel
151169185Smarcelvoid
152161561Smarcelfill_fpregset (char *fpregs, int regnum)
153161561Smarcel{
154161561Smarcel  ppcfbsd_fill_fpreg (fpregs, regnum);
155161561Smarcel}
156161561Smarcel
157169185Smarcelvoid
158169185Smarcelsupply_fpregset (char *fpregs)
159169185Smarcel{
160169185Smarcel  ppcfbsd_supply_fpreg (fpregs, -1);
161169185Smarcel}
162169185Smarcel
163161561Smarcel/* Provide a prototype to silence -Wmissing-prototypes.  */
164161561Smarcelvoid _initialize_ppcfbsd_nat (void);
165161561Smarcel
166161561Smarcelvoid
167161561Smarcel_initialize_ppcfbsd_nat (void)
168161561Smarcel{
169161561Smarcel}
170