1 /* Native-dependent code for the i387.
2 Copyright 2000 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
25 /* FIXME: kettenis/2000-05-21: Right now more than a few i386 targets
26 define their own routines to manage the floating-point registers in
27 GDB's register array. Most (if not all) of these targets use the
28 format used by the "fsave" instruction in their communication with
29 the OS. They should all be converted to use the routines below. */
31 /* At fsave_offset[REGNO] you'll find the offset to the location in
32 the data structure used by the "fsave" instruction where GDB
33 register REGNO is stored. */
35 static int fsave_offset[] =
37 28 + 0 * FPU_REG_RAW_SIZE, /* FP0_REGNUM through ... */
38 28 + 1 * FPU_REG_RAW_SIZE,
39 28 + 2 * FPU_REG_RAW_SIZE,
40 28 + 3 * FPU_REG_RAW_SIZE,
41 28 + 4 * FPU_REG_RAW_SIZE,
42 28 + 5 * FPU_REG_RAW_SIZE,
43 28 + 6 * FPU_REG_RAW_SIZE,
44 28 + 7 * FPU_REG_RAW_SIZE, /* ... FP7_REGNUM. */
45 0, /* FCTRL_REGNUM (16 bits). */
46 4, /* FSTAT_REGNUM (16 bits). */
47 8, /* FTAG_REGNUM (16 bits). */
48 16, /* FCS_REGNUM (16 bits). */
49 12, /* FCOFF_REGNUM. */
51 20, /* FDOFF_REGNUM. */
52 18 /* FOP_REGNUM (bottom 11 bits). */
55 #define FSAVE_ADDR(fsave, regnum) (fsave + fsave_offset[regnum - FP0_REGNUM])
58 /* Fill GDB's register array with the floating-point register values
59 in *FSAVE. This function masks off any of the reserved
63 i387_supply_fsave (char *fsave)
67 for (i = FP0_REGNUM; i <= LAST_FPU_CTRL_REGNUM; i++)
69 /* Most of the FPU control registers occupy only 16 bits in
70 the fsave area. Give those a special treatment. */
71 if (i >= FIRST_FPU_CTRL_REGNUM
72 && i != FCOFF_REGNUM && i != FDOFF_REGNUM)
74 unsigned int val = *(unsigned short *) (FSAVE_ADDR (fsave, i));
78 val &= ((1 << 11) - 1);
79 supply_register (i, (char *) &val);
82 supply_register (i, (char *) &val);
85 supply_register (i, FSAVE_ADDR (fsave, i));
89 /* Fill register REGNO (if it is a floating-point register) in *FSAVE
90 with the value in GDB's register array. If REGNO is -1, do this
91 for all registers. This function doesn't touch any of the reserved
95 i387_fill_fsave (char *fsave, int regno)
99 for (i = FP0_REGNUM; i <= LAST_FPU_CTRL_REGNUM; i++)
100 if (regno == -1 || regno == i)
102 /* Most of the FPU control registers occupy only 16 bits in
103 the fsave area. Give those a special treatment. */
104 if (i >= FIRST_FPU_CTRL_REGNUM
105 && i != FCOFF_REGNUM && i != FDOFF_REGNUM)
109 unsigned short oldval, newval;
111 /* The opcode occupies only 11 bits. */
112 oldval = (*(unsigned short *) (FSAVE_ADDR (fsave, i)));
113 newval = *(unsigned short *) ®isters[REGISTER_BYTE (i)];
114 newval &= ((1 << 11) - 1);
115 newval |= oldval & ~((1 << 11) - 1);
116 memcpy (FSAVE_ADDR (fsave, i), &newval, 2);
119 memcpy (FSAVE_ADDR (fsave, i), ®isters[REGISTER_BYTE (i)], 2);
122 memcpy (FSAVE_ADDR (fsave, i), ®isters[REGISTER_BYTE (i)],
123 REGISTER_RAW_SIZE (i));
128 /* At fxsave_offset[REGNO] you'll find the offset to the location in
129 the data structure used by the "fxsave" instruction where GDB
130 register REGNO is stored. */
132 static int fxsave_offset[] =
134 32, /* FP0_REGNUM through ... */
141 144, /* ... FP7_REGNUM (80 bits each). */
142 0, /* FCTRL_REGNUM (16 bits). */
143 2, /* FSTAT_REGNUM (16 bits). */
144 4, /* FTAG_REGNUM (16 bits). */
145 12, /* FCS_REGNUM (16 bits). */
146 8, /* FCOFF_REGNUM. */
147 20, /* FDS_REGNUM (16 bits). */
148 16, /* FDOFF_REGNUM. */
149 6, /* FOP_REGNUM (bottom 11 bits). */
150 160, /* XMM0_REGNUM through ... */
157 272, /* ... XMM7_REGNUM (128 bits each). */
158 24, /* MXCSR_REGNUM. */
161 #define FXSAVE_ADDR(fxsave, regnum) \
162 (fxsave + fxsave_offset[regnum - FP0_REGNUM])
164 static int i387_tag (unsigned char *raw);
167 /* Fill GDB's register array with the floating-point and SSE register
168 values in *FXSAVE. This function masks off any of the reserved
172 i387_supply_fxsave (char *fxsave)
176 for (i = FP0_REGNUM; i <= MXCSR_REGNUM; i++)
178 /* Most of the FPU control registers occupy only 16 bits in
179 the fxsave area. Give those a special treatment. */
180 if (i >= FIRST_FPU_CTRL_REGNUM && i < XMM0_REGNUM
181 && i != FCOFF_REGNUM && i != FDOFF_REGNUM)
183 unsigned long val = *(unsigned short *) (FXSAVE_ADDR (fxsave, i));
187 val &= ((1 << 11) - 1);
188 supply_register (i, (char *) &val);
190 else if (i== FTAG_REGNUM)
192 /* The fxsave area contains a simplified version of the
193 tag word. We have to look at the actual 80-bit FP
194 data to recreate the traditional i387 tag word. */
196 unsigned long ftag = 0;
201 fstat = *(unsigned short *) (FXSAVE_ADDR (fxsave, FSTAT_REGNUM));
202 top = ((fstat >> 11) & 0x111);
204 for (fpreg = 7; fpreg >= 0; fpreg--)
208 if (val & (1 << fpreg))
210 int regnum = (fpreg + 8 - top) % 8 + FP0_REGNUM;
211 tag = i387_tag (FXSAVE_ADDR (fxsave, regnum));
214 ftag |= tag << (2 * fpreg);
216 supply_register (i, (char *) &ftag);
219 supply_register (i, (char *) &val);
222 supply_register (i, FXSAVE_ADDR (fxsave, i));
226 /* Fill register REGNO (if it is a floating-point or SSE register) in
227 *FXSAVE with the value in GDB's register array. If REGNO is -1, do
228 this for all registers. This function doesn't touch any of the
229 reserved bits in *FXSAVE. */
232 i387_fill_fxsave (char *fxsave, int regno)
236 for (i = FP0_REGNUM; i <= MXCSR_REGNUM; i++)
237 if (regno == -1 || regno == i)
239 /* Most of the FPU control registers occupy only 16 bits in
240 the fxsave area. Give those a special treatment. */
241 if (i >= FIRST_FPU_CTRL_REGNUM && i < XMM0_REGNUM
242 && i != FCOFF_REGNUM && i != FDOFF_REGNUM)
246 unsigned short oldval, newval;
248 /* The opcode occupies only 11 bits. */
249 oldval = (*(unsigned short *) (FXSAVE_ADDR (fxsave, i)));
250 newval = *(unsigned short *) ®isters[REGISTER_BYTE (i)];
251 newval &= ((1 << 11) - 1);
252 newval |= oldval & ~((1 << 11) - 1);
253 memcpy (FXSAVE_ADDR (fxsave, i), &newval, 2);
255 else if (i == FTAG_REGNUM)
257 /* Converting back is much easier. */
259 unsigned char val = 0;
263 ftag = *(unsigned short *) ®isters[REGISTER_BYTE (i)];
265 for (fpreg = 7; fpreg >= 0; fpreg--)
267 int tag = (ftag >> (fpreg * 2)) & 0x11;
273 memcpy (FXSAVE_ADDR (fxsave, i), &val, 2);
276 memcpy (FXSAVE_ADDR (fxsave, i),
277 ®isters[REGISTER_BYTE (i)], 2);
280 memcpy (FXSAVE_ADDR (fxsave, i), ®isters[REGISTER_BYTE (i)],
281 REGISTER_RAW_SIZE (i));
285 /* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
289 i387_tag (unsigned char *raw)
292 unsigned int exponent;
293 unsigned long fraction[2];
295 integer = raw[7] & 0x80;
296 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
297 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
298 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
299 | (raw[5] << 8) | raw[4]);
301 if (exponent == 0x7fff)
306 else if (exponent == 0x0000)
321 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)