1130812Smarcel/* Native-dependent code for SVR4 Unix running on i386's.
2130812Smarcel   Copyright 1988, 1989, 1991, 1992, 1996, 1997, 1998, 1999, 2000,
3130812Smarcel   2001, 2002
4130812Smarcel   Free Software Foundation, Inc.
5130812Smarcel
6130812Smarcel   This file is part of GDB.
7130812Smarcel
8130812Smarcel   This program is free software; you can redistribute it and/or modify
9130812Smarcel   it under the terms of the GNU General Public License as published by
10130812Smarcel   the Free Software Foundation; either version 2 of the License, or
11130812Smarcel   (at your option) any later version.
12130812Smarcel
13130812Smarcel   This program is distributed in the hope that it will be useful,
14130812Smarcel   but WITHOUT ANY WARRANTY; without even the implied warranty of
15130812Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16130812Smarcel   GNU General Public License for more details.
17130812Smarcel
18130812Smarcel   You should have received a copy of the GNU General Public License
19130812Smarcel   along with this program; if not, write to the Free Software
20130812Smarcel   Foundation, Inc., 59 Temple Place - Suite 330,
21130812Smarcel   Boston, MA 02111-1307, USA.  */
22130812Smarcel
23130812Smarcel#include "defs.h"
24130812Smarcel#include "value.h"
25130812Smarcel#include "inferior.h"
26130812Smarcel#include "regcache.h"
27130812Smarcel
28130812Smarcel#ifdef HAVE_SYS_REG_H
29130812Smarcel#include <sys/reg.h>
30130812Smarcel#endif
31130812Smarcel
32130812Smarcel#include "i386-tdep.h"
33130812Smarcel#include "i387-tdep.h"
34130812Smarcel
35130812Smarcel#ifdef HAVE_SYS_PROCFS_H
36130812Smarcel
37130812Smarcel#include <sys/procfs.h>
38130812Smarcel
39130812Smarcel/* Prototypes for supply_gregset etc. */
40130812Smarcel#include "gregset.h"
41130812Smarcel
42130812Smarcel/* The `/proc' interface divides the target machine's register set up
43130812Smarcel   into two different sets, the general purpose register set (gregset)
44130812Smarcel   and the floating-point register set (fpregset).  For each set,
45130812Smarcel   there is an ioctl to get the current register set and another ioctl
46130812Smarcel   to set the current values.
47130812Smarcel
48130812Smarcel   The actual structure passed through the ioctl interface is, of
49130812Smarcel   course, naturally machine dependent, and is different for each set
50130812Smarcel   of registers.  For the i386 for example, the general-purpose
51130812Smarcel   register set is typically defined by:
52130812Smarcel
53130812Smarcel   typedef int gregset_t[19];           (in <sys/regset.h>)
54130812Smarcel
55130812Smarcel   #define GS   0                       (in <sys/reg.h>)
56130812Smarcel   #define FS   1
57130812Smarcel   ...
58130812Smarcel   #define UESP 17
59130812Smarcel   #define SS   18
60130812Smarcel
61130812Smarcel   and the floating-point set by:
62130812Smarcel
63130812Smarcel   typedef struct fpregset   {
64130812Smarcel           union {
65130812Smarcel                   struct fpchip_state            // fp extension state //
66130812Smarcel                   {
67130812Smarcel                           int     state[27];     // 287/387 saved state //
68130812Smarcel                           int     status;        // status word saved at //
69130812Smarcel                                                  // exception //
70130812Smarcel                   } fpchip_state;
71130812Smarcel                   struct fp_emul_space           // for emulators //
72130812Smarcel                   {
73130812Smarcel                           char    fp_emul[246];
74130812Smarcel                           char    fp_epad[2];
75130812Smarcel                   } fp_emul_space;
76130812Smarcel                   int     f_fpregs[62];          // union of the above //
77130812Smarcel           } fp_reg_set;
78130812Smarcel           long            f_wregs[33];           // saved weitek state //
79130812Smarcel   } fpregset_t;
80130812Smarcel
81130812Smarcel   Incidentally fpchip_state contains the FPU state in the same format
82130812Smarcel   as used by the "fsave" instruction, and that's the only thing we
83130812Smarcel   support here.  I don't know how the emulator stores it state.  The
84130812Smarcel   Weitek stuff definitely isn't supported.
85130812Smarcel
86130812Smarcel   The routines defined here, provide the packing and unpacking of
87130812Smarcel   gregset_t and fpregset_t formatted data.  */
88130812Smarcel
89130812Smarcel#ifdef HAVE_GREGSET_T
90130812Smarcel
91130812Smarcel/* Mapping between the general-purpose registers in `/proc'
92130812Smarcel   format and GDB's register array layout.  */
93130812Smarcelstatic int regmap[] =
94130812Smarcel{
95130812Smarcel  EAX, ECX, EDX, EBX,
96130812Smarcel  UESP, EBP, ESI, EDI,
97130812Smarcel  EIP, EFL, CS, SS,
98130812Smarcel  DS, ES, FS, GS,
99130812Smarcel};
100130812Smarcel
101130812Smarcel/* Fill GDB's register array with the general-purpose register values
102130812Smarcel   in *GREGSETP.  */
103130812Smarcel
104130812Smarcelvoid
105130812Smarcelsupply_gregset (gregset_t *gregsetp)
106130812Smarcel{
107130812Smarcel  greg_t *regp = (greg_t *) gregsetp;
108130812Smarcel  int i;
109130812Smarcel
110130812Smarcel  for (i = 0; i < I386_NUM_GREGS; i++)
111130812Smarcel    supply_register (i, (char *) (regp + regmap[i]));
112130812Smarcel}
113130812Smarcel
114130812Smarcel/* Fill register REGNO (if it is a general-purpose register) in
115130812Smarcel   *GREGSETPS with the value in GDB's register array.  If REGNO is -1,
116130812Smarcel   do this for all registers.  */
117130812Smarcel
118130812Smarcelvoid
119130812Smarcelfill_gregset (gregset_t *gregsetp, int regno)
120130812Smarcel{
121130812Smarcel  greg_t *regp = (greg_t *) gregsetp;
122130812Smarcel  int i;
123130812Smarcel
124130812Smarcel  for (i = 0; i < I386_NUM_GREGS; i++)
125130812Smarcel    if (regno == -1 || regno == i)
126130812Smarcel      regcache_collect (i, regp + regmap[i]);
127130812Smarcel}
128130812Smarcel
129130812Smarcel#endif /* HAVE_GREGSET_T */
130130812Smarcel
131130812Smarcel#ifdef HAVE_FPREGSET_T
132130812Smarcel
133130812Smarcel/* Fill GDB's register array with the floating-point register values in
134130812Smarcel   *FPREGSETP.  */
135130812Smarcel
136130812Smarcelvoid
137130812Smarcelsupply_fpregset (fpregset_t *fpregsetp)
138130812Smarcel{
139130812Smarcel  if (FP0_REGNUM == 0)
140130812Smarcel    return;
141130812Smarcel
142130812Smarcel  i387_supply_fsave (current_regcache, -1, fpregsetp);
143130812Smarcel}
144130812Smarcel
145130812Smarcel/* Fill register REGNO (if it is a floating-point register) in
146130812Smarcel   *FPREGSETP with the value in GDB's register array.  If REGNO is -1,
147130812Smarcel   do this for all registers.  */
148130812Smarcel
149130812Smarcelvoid
150130812Smarcelfill_fpregset (fpregset_t *fpregsetp, int regno)
151130812Smarcel{
152130812Smarcel  if (FP0_REGNUM == 0)
153130812Smarcel    return;
154130812Smarcel
155130812Smarcel  i387_fill_fsave ((char *) fpregsetp, regno);
156130812Smarcel}
157130812Smarcel
158130812Smarcel#endif /* HAVE_FPREGSET_T */
159130812Smarcel
160130812Smarcel#endif /* HAVE_SYS_PROCFS_H */
161