Allow configuration of texinfo for Cygwin hosts.
[deliverable/binutils-gdb.git] / gdb / i387-nat.c
1 /* Native-dependent code for the i387.
2 Copyright 2000 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
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.
10
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.
15
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. */
20
21 #include "defs.h"
22 #include "inferior.h"
23 #include "value.h"
24
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. */
30
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. */
34
35 static int fsave_offset[] =
36 {
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. */
50 24, /* FDS_REGNUM. */
51 20, /* FDOFF_REGNUM. */
52 18 /* FOP_REGNUM (bottom 11 bits). */
53 };
54
55 #define FSAVE_ADDR(fsave, regnum) (fsave + fsave_offset[regnum - FP0_REGNUM])
56 \f
57
58 /* Fill GDB's register array with the floating-point register values
59 in *FSAVE. This function masks off any of the reserved
60 bits in *FSAVE. */
61
62 void
63 i387_supply_fsave (char *fsave)
64 {
65 int i;
66
67 for (i = FP0_REGNUM; i <= LAST_FPU_CTRL_REGNUM; i++)
68 {
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)
73 {
74 unsigned int val = *(unsigned short *) (FSAVE_ADDR (fsave, i));
75
76 if (i == FOP_REGNUM)
77 {
78 val &= ((1 << 11) - 1);
79 supply_register (i, (char *) &val);
80 }
81 else
82 supply_register (i, (char *) &val);
83 }
84 else
85 supply_register (i, FSAVE_ADDR (fsave, i));
86 }
87 }
88
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
92 bits in *FSAVE. */
93
94 void
95 i387_fill_fsave (char *fsave, int regno)
96 {
97 int i;
98
99 for (i = FP0_REGNUM; i <= LAST_FPU_CTRL_REGNUM; i++)
100 if (regno == -1 || regno == i)
101 {
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)
106 {
107 if (i == FOP_REGNUM)
108 {
109 unsigned short oldval, newval;
110
111 /* The opcode occupies only 11 bits. */
112 oldval = (*(unsigned short *) (FSAVE_ADDR (fsave, i)));
113 newval = *(unsigned short *) &registers[REGISTER_BYTE (i)];
114 newval &= ((1 << 11) - 1);
115 newval |= oldval & ~((1 << 11) - 1);
116 memcpy (FSAVE_ADDR (fsave, i), &newval, 2);
117 }
118 else
119 memcpy (FSAVE_ADDR (fsave, i), &registers[REGISTER_BYTE (i)], 2);
120 }
121 else
122 memcpy (FSAVE_ADDR (fsave, i), &registers[REGISTER_BYTE (i)],
123 REGISTER_RAW_SIZE (i));
124 }
125 }
126 \f
127
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. */
131
132 static int fxsave_offset[] =
133 {
134 32, /* FP0_REGNUM through ... */
135 48,
136 64,
137 80,
138 96,
139 112,
140 128,
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 ... */
151 176,
152 192,
153 208,
154 224,
155 240,
156 256,
157 272, /* ... XMM7_REGNUM (128 bits each). */
158 24, /* MXCSR_REGNUM. */
159 };
160
161 #define FXSAVE_ADDR(fxsave, regnum) \
162 (fxsave + fxsave_offset[regnum - FP0_REGNUM])
163
164 static int i387_tag (unsigned char *raw);
165 \f
166
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
169 bits in *FXSAVE. */
170
171 void
172 i387_supply_fxsave (char *fxsave)
173 {
174 int i;
175
176 for (i = FP0_REGNUM; i <= MXCSR_REGNUM; i++)
177 {
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)
182 {
183 unsigned long val = *(unsigned short *) (FXSAVE_ADDR (fxsave, i));
184
185 if (i == FOP_REGNUM)
186 {
187 val &= ((1 << 11) - 1);
188 supply_register (i, (char *) &val);
189 }
190 else if (i== FTAG_REGNUM)
191 {
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. */
195
196 unsigned long ftag = 0;
197 unsigned long fstat;
198 int fpreg;
199 int top;
200
201 fstat = *(unsigned short *) (FXSAVE_ADDR (fxsave, FSTAT_REGNUM));
202 top = ((fstat >> 11) & 0x111);
203
204 for (fpreg = 7; fpreg >= 0; fpreg--)
205 {
206 int tag = 0x11;
207
208 if (val & (1 << fpreg))
209 {
210 int regnum = (fpreg + 8 - top) % 8 + FP0_REGNUM;
211 tag = i387_tag (FXSAVE_ADDR (fxsave, regnum));
212 }
213
214 ftag |= tag << (2 * fpreg);
215 }
216 supply_register (i, (char *) &ftag);
217 }
218 else
219 supply_register (i, (char *) &val);
220 }
221 else
222 supply_register (i, FXSAVE_ADDR (fxsave, i));
223 }
224 }
225
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. */
230
231 void
232 i387_fill_fxsave (char *fxsave, int regno)
233 {
234 int i;
235
236 for (i = FP0_REGNUM; i <= MXCSR_REGNUM; i++)
237 if (regno == -1 || regno == i)
238 {
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)
243 {
244 if (i == FOP_REGNUM)
245 {
246 unsigned short oldval, newval;
247
248 /* The opcode occupies only 11 bits. */
249 oldval = (*(unsigned short *) (FXSAVE_ADDR (fxsave, i)));
250 newval = *(unsigned short *) &registers[REGISTER_BYTE (i)];
251 newval &= ((1 << 11) - 1);
252 newval |= oldval & ~((1 << 11) - 1);
253 memcpy (FXSAVE_ADDR (fxsave, i), &newval, 2);
254 }
255 else if (i == FTAG_REGNUM)
256 {
257 /* Converting back is much easier. */
258
259 unsigned char val = 0;
260 unsigned short ftag;
261 int fpreg;
262
263 ftag = *(unsigned short *) &registers[REGISTER_BYTE (i)];
264
265 for (fpreg = 7; fpreg >= 0; fpreg--)
266 {
267 int tag = (ftag >> (fpreg * 2)) & 0x11;
268
269 if (tag != 0x11)
270 val |= (1 << fpreg);
271 }
272
273 memcpy (FXSAVE_ADDR (fxsave, i), &val, 2);
274 }
275 else
276 memcpy (FXSAVE_ADDR (fxsave, i),
277 &registers[REGISTER_BYTE (i)], 2);
278 }
279 else
280 memcpy (FXSAVE_ADDR (fxsave, i), &registers[REGISTER_BYTE (i)],
281 REGISTER_RAW_SIZE (i));
282 }
283 }
284
285 /* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
286 *RAW. */
287
288 static int
289 i387_tag (unsigned char *raw)
290 {
291 int integer;
292 unsigned int exponent;
293 unsigned long fraction[2];
294
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]);
300
301 if (exponent == 0x7fff)
302 {
303 /* Special. */
304 return (0x10);
305 }
306 else if (exponent == 0x0000)
307 {
308 if (integer)
309 {
310 /* Valid. */
311 return (0x00);
312 }
313 else
314 {
315 /* Special. */
316 return (0x10);
317 }
318 }
319 else
320 {
321 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
322 {
323 /* Zero. */
324 return (0x01);
325 }
326 else
327 {
328 /* Special. */
329 return (0x10);
330 }
331 }
332 }
This page took 0.036521 seconds and 4 git commands to generate.