*stack.c: Include valprint.h.
[deliverable/binutils-gdb.git] / gdb / i387-tdep.c
CommitLineData
c906108c 1/* Intel 387 floating point stuff.
38edeab8 2
6aba47ca 3 Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000, 2001,
0fb0cc75 4 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
c5aa993b 11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b 18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
20
21#include "defs.h"
786a90bb
MK
22#include "doublest.h"
23#include "floatformat.h"
c906108c 24#include "frame.h"
786a90bb 25#include "gdbcore.h"
c906108c
SS
26#include "inferior.h"
27#include "language.h"
4e052eda 28#include "regcache.h"
786a90bb
MK
29#include "value.h"
30
d0df8472 31#include "gdb_assert.h"
309367d4 32#include "gdb_string.h"
c906108c 33
9a82579f 34#include "i386-tdep.h"
42c466d7 35#include "i387-tdep.h"
c906108c 36
de57eccd 37/* Print the floating point number specified by RAW. */
786a90bb 38
de57eccd 39static void
b4ad899f 40print_i387_value (const gdb_byte *raw, struct ui_file *file)
de57eccd
JM
41{
42 DOUBLEST value;
4583280c
MK
43
44 /* Using extract_typed_floating here might affect the representation
45 of certain numbers such as NaNs, even if GDB is running natively.
46 This is fine since our caller already detects such special
47 numbers and we print the hexadecimal representation anyway. */
48 value = extract_typed_floating (raw, builtin_type_i387_ext);
de57eccd
JM
49
50 /* We try to print 19 digits. The last digit may or may not contain
51 garbage, but we'd better print one too many. We need enough room
52 to print the value, 1 position for the sign, 1 for the decimal
53 point, 19 for the digits and 6 for the exponent adds up to 27. */
54#ifdef PRINTF_HAS_LONG_DOUBLE
61113f8b 55 fprintf_filtered (file, " %-+27.19Lg", (long double) value);
de57eccd 56#else
61113f8b 57 fprintf_filtered (file, " %-+27.19g", (double) value);
de57eccd
JM
58#endif
59}
60
61/* Print the classification for the register contents RAW. */
786a90bb 62
de57eccd 63static void
b4ad899f 64print_i387_ext (const gdb_byte *raw, struct ui_file *file)
de57eccd
JM
65{
66 int sign;
67 int integer;
68 unsigned int exponent;
69 unsigned long fraction[2];
70
71 sign = raw[9] & 0x80;
72 integer = raw[7] & 0x80;
73 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
74 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
75 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
76 | (raw[5] << 8) | raw[4]);
77
78 if (exponent == 0x7fff && integer)
79 {
80 if (fraction[0] == 0x00000000 && fraction[1] == 0x00000000)
81 /* Infinity. */
61113f8b 82 fprintf_filtered (file, " %cInf", (sign ? '-' : '+'));
de57eccd
JM
83 else if (sign && fraction[0] == 0x00000000 && fraction[1] == 0x40000000)
84 /* Real Indefinite (QNaN). */
61113f8b 85 fputs_unfiltered (" Real Indefinite (QNaN)", file);
de57eccd
JM
86 else if (fraction[1] & 0x40000000)
87 /* QNaN. */
61113f8b 88 fputs_filtered (" QNaN", file);
de57eccd
JM
89 else
90 /* SNaN. */
61113f8b 91 fputs_filtered (" SNaN", file);
de57eccd
JM
92 }
93 else if (exponent < 0x7fff && exponent > 0x0000 && integer)
94 /* Normal. */
61113f8b 95 print_i387_value (raw, file);
de57eccd
JM
96 else if (exponent == 0x0000)
97 {
98 /* Denormal or zero. */
61113f8b 99 print_i387_value (raw, file);
de57eccd
JM
100
101 if (integer)
102 /* Pseudo-denormal. */
61113f8b 103 fputs_filtered (" Pseudo-denormal", file);
de57eccd
JM
104 else if (fraction[0] || fraction[1])
105 /* Denormal. */
61113f8b 106 fputs_filtered (" Denormal", file);
de57eccd
JM
107 }
108 else
109 /* Unsupported. */
61113f8b 110 fputs_filtered (" Unsupported", file);
de57eccd
JM
111}
112
113/* Print the status word STATUS. */
786a90bb 114
de57eccd 115static void
61113f8b 116print_i387_status_word (unsigned int status, struct ui_file *file)
de57eccd 117{
61113f8b 118 fprintf_filtered (file, "Status Word: %s",
bb599908 119 hex_string_custom (status, 4));
61113f8b
MK
120 fputs_filtered (" ", file);
121 fprintf_filtered (file, " %s", (status & 0x0001) ? "IE" : " ");
122 fprintf_filtered (file, " %s", (status & 0x0002) ? "DE" : " ");
123 fprintf_filtered (file, " %s", (status & 0x0004) ? "ZE" : " ");
124 fprintf_filtered (file, " %s", (status & 0x0008) ? "OE" : " ");
125 fprintf_filtered (file, " %s", (status & 0x0010) ? "UE" : " ");
126 fprintf_filtered (file, " %s", (status & 0x0020) ? "PE" : " ");
127 fputs_filtered (" ", file);
128 fprintf_filtered (file, " %s", (status & 0x0080) ? "ES" : " ");
129 fputs_filtered (" ", file);
130 fprintf_filtered (file, " %s", (status & 0x0040) ? "SF" : " ");
131 fputs_filtered (" ", file);
132 fprintf_filtered (file, " %s", (status & 0x0100) ? "C0" : " ");
133 fprintf_filtered (file, " %s", (status & 0x0200) ? "C1" : " ");
134 fprintf_filtered (file, " %s", (status & 0x0400) ? "C2" : " ");
135 fprintf_filtered (file, " %s", (status & 0x4000) ? "C3" : " ");
136
137 fputs_filtered ("\n", file);
138
139 fprintf_filtered (file,
140 " TOP: %d\n", ((status >> 11) & 7));
de57eccd
JM
141}
142
143/* Print the control word CONTROL. */
786a90bb 144
de57eccd 145static void
61113f8b 146print_i387_control_word (unsigned int control, struct ui_file *file)
de57eccd 147{
61113f8b 148 fprintf_filtered (file, "Control Word: %s",
bb599908 149 hex_string_custom (control, 4));
61113f8b
MK
150 fputs_filtered (" ", file);
151 fprintf_filtered (file, " %s", (control & 0x0001) ? "IM" : " ");
152 fprintf_filtered (file, " %s", (control & 0x0002) ? "DM" : " ");
153 fprintf_filtered (file, " %s", (control & 0x0004) ? "ZM" : " ");
154 fprintf_filtered (file, " %s", (control & 0x0008) ? "OM" : " ");
155 fprintf_filtered (file, " %s", (control & 0x0010) ? "UM" : " ");
156 fprintf_filtered (file, " %s", (control & 0x0020) ? "PM" : " ");
de57eccd 157
61113f8b 158 fputs_filtered ("\n", file);
de57eccd 159
61113f8b 160 fputs_filtered (" PC: ", file);
de57eccd
JM
161 switch ((control >> 8) & 3)
162 {
163 case 0:
61113f8b 164 fputs_filtered ("Single Precision (24-bits)\n", file);
de57eccd
JM
165 break;
166 case 1:
61113f8b 167 fputs_filtered ("Reserved\n", file);
de57eccd
JM
168 break;
169 case 2:
61113f8b 170 fputs_filtered ("Double Precision (53-bits)\n", file);
de57eccd
JM
171 break;
172 case 3:
61113f8b 173 fputs_filtered ("Extended Precision (64-bits)\n", file);
de57eccd
JM
174 break;
175 }
176
61113f8b 177 fputs_filtered (" RC: ", file);
de57eccd
JM
178 switch ((control >> 10) & 3)
179 {
180 case 0:
61113f8b 181 fputs_filtered ("Round to nearest\n", file);
de57eccd
JM
182 break;
183 case 1:
61113f8b 184 fputs_filtered ("Round down\n", file);
de57eccd
JM
185 break;
186 case 2:
61113f8b 187 fputs_filtered ("Round up\n", file);
de57eccd
JM
188 break;
189 case 3:
61113f8b 190 fputs_filtered ("Round toward zero\n", file);
de57eccd
JM
191 break;
192 }
193}
194
9b949a49 195/* Print out the i387 floating point state. Note that we ignore FRAME
7d8d2918
MK
196 in the code below. That's OK since floating-point registers are
197 never saved on the stack. */
198
de57eccd 199void
61113f8b 200i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
8e186fd6 201 struct frame_info *frame, const char *args)
de57eccd 202{
5716833c 203 struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
b4ad899f 204 gdb_byte buf[4];
1d70089a
MK
205 ULONGEST fctrl;
206 ULONGEST fstat;
207 ULONGEST ftag;
208 ULONGEST fiseg;
209 ULONGEST fioff;
210 ULONGEST foseg;
211 ULONGEST fooff;
212 ULONGEST fop;
de57eccd
JM
213 int fpreg;
214 int top;
215
5716833c
MK
216 gdb_assert (gdbarch == get_frame_arch (frame));
217
20a6ec49
MD
218 fctrl = get_frame_register_unsigned (frame, I387_FCTRL_REGNUM (tdep));
219 fstat = get_frame_register_unsigned (frame, I387_FSTAT_REGNUM (tdep));
220 ftag = get_frame_register_unsigned (frame, I387_FTAG_REGNUM (tdep));
221 fiseg = get_frame_register_unsigned (frame, I387_FISEG_REGNUM (tdep));
222 fioff = get_frame_register_unsigned (frame, I387_FIOFF_REGNUM (tdep));
223 foseg = get_frame_register_unsigned (frame, I387_FOSEG_REGNUM (tdep));
224 fooff = get_frame_register_unsigned (frame, I387_FOOFF_REGNUM (tdep));
225 fop = get_frame_register_unsigned (frame, I387_FOP_REGNUM (tdep));
1d70089a 226
de57eccd
JM
227 top = ((fstat >> 11) & 7);
228
229 for (fpreg = 7; fpreg >= 0; fpreg--)
230 {
b4ad899f 231 gdb_byte raw[I386_MAX_REGISTER_SIZE];
de57eccd
JM
232 int tag = (ftag >> (fpreg * 2)) & 3;
233 int i;
234
61113f8b 235 fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg);
de57eccd
JM
236
237 switch (tag)
238 {
239 case 0:
61113f8b 240 fputs_filtered ("Valid ", file);
de57eccd
JM
241 break;
242 case 1:
61113f8b 243 fputs_filtered ("Zero ", file);
de57eccd
JM
244 break;
245 case 2:
61113f8b 246 fputs_filtered ("Special ", file);
de57eccd
JM
247 break;
248 case 3:
61113f8b 249 fputs_filtered ("Empty ", file);
de57eccd
JM
250 break;
251 }
252
20a6ec49
MD
253 get_frame_register (frame, (fpreg + 8 - top) % 8 + I387_ST0_REGNUM (tdep),
254 raw);
de57eccd 255
61113f8b 256 fputs_filtered ("0x", file);
de57eccd 257 for (i = 9; i >= 0; i--)
61113f8b 258 fprintf_filtered (file, "%02x", raw[i]);
de57eccd
JM
259
260 if (tag != 3)
61113f8b 261 print_i387_ext (raw, file);
de57eccd 262
61113f8b 263 fputs_filtered ("\n", file);
de57eccd
JM
264 }
265
f16a25ae 266 fputs_filtered ("\n", file);
de57eccd 267
61113f8b
MK
268 print_i387_status_word (fstat, file);
269 print_i387_control_word (fctrl, file);
270 fprintf_filtered (file, "Tag Word: %s\n",
bb599908 271 hex_string_custom (ftag, 4));
61113f8b 272 fprintf_filtered (file, "Instruction Pointer: %s:",
bb599908
PH
273 hex_string_custom (fiseg, 2));
274 fprintf_filtered (file, "%s\n", hex_string_custom (fioff, 8));
61113f8b 275 fprintf_filtered (file, "Operand Pointer: %s:",
bb599908
PH
276 hex_string_custom (foseg, 2));
277 fprintf_filtered (file, "%s\n", hex_string_custom (fooff, 8));
61113f8b 278 fprintf_filtered (file, "Opcode: %s\n",
bb599908 279 hex_string_custom (fop ? (fop | 0xd800) : 0, 4));
de57eccd 280}
d532c08f
MK
281\f
282
83acabca
DJ
283/* Return nonzero if a value of type TYPE stored in register REGNUM
284 needs any special handling. */
285
286int
0abe36f5 287i387_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type)
83acabca 288{
20a6ec49 289 if (i386_fp_regnum_p (gdbarch, regnum))
83acabca
DJ
290 {
291 /* Floating point registers must be converted unless we are
292 accessing them in their hardware type. */
293 if (type == builtin_type_i387_ext)
294 return 0;
295 else
296 return 1;
297 }
298
299 return 0;
300}
301
d532c08f
MK
302/* Read a value of type TYPE from register REGNUM in frame FRAME, and
303 return its contents in TO. */
304
305void
306i387_register_to_value (struct frame_info *frame, int regnum,
42835c2b 307 struct type *type, gdb_byte *to)
d532c08f 308{
b4ad899f 309 gdb_byte from[I386_MAX_REGISTER_SIZE];
d532c08f 310
20a6ec49 311 gdb_assert (i386_fp_regnum_p (get_frame_arch (frame), regnum));
d532c08f
MK
312
313 /* We only support floating-point values. */
314 if (TYPE_CODE (type) != TYPE_CODE_FLT)
315 {
8a3fe4f8
AC
316 warning (_("Cannot convert floating-point register value "
317 "to non-floating-point type."));
d532c08f
MK
318 return;
319 }
320
83acabca 321 /* Convert to TYPE. */
192285c6 322 get_frame_register (frame, regnum, from);
d532c08f
MK
323 convert_typed_floating (from, builtin_type_i387_ext, to, type);
324}
325
326/* Write the contents FROM of a value of type TYPE into register
327 REGNUM in frame FRAME. */
328
329void
330i387_value_to_register (struct frame_info *frame, int regnum,
42835c2b 331 struct type *type, const gdb_byte *from)
d532c08f 332{
b4ad899f 333 gdb_byte to[I386_MAX_REGISTER_SIZE];
d532c08f 334
20a6ec49 335 gdb_assert (i386_fp_regnum_p (get_frame_arch (frame), regnum));
d532c08f
MK
336
337 /* We only support floating-point values. */
338 if (TYPE_CODE (type) != TYPE_CODE_FLT)
339 {
8a3fe4f8
AC
340 warning (_("Cannot convert non-floating-point type "
341 "to floating-point register value."));
d532c08f
MK
342 return;
343 }
344
83acabca 345 /* Convert from TYPE. */
d532c08f
MK
346 convert_typed_floating (from, type, to, builtin_type_i387_ext);
347 put_frame_register (frame, regnum, to);
348}
349\f
e750d25e 350
786a90bb 351/* Handle FSAVE and FXSAVE formats. */
e750d25e
JT
352
353/* At fsave_offset[REGNUM] you'll find the offset to the location in
354 the data structure used by the "fsave" instruction where GDB
355 register REGNUM is stored. */
356
357static int fsave_offset[] =
358{
5716833c
MK
359 28 + 0 * 10, /* %st(0) ... */
360 28 + 1 * 10,
361 28 + 2 * 10,
362 28 + 3 * 10,
363 28 + 4 * 10,
364 28 + 5 * 10,
365 28 + 6 * 10,
366 28 + 7 * 10, /* ... %st(7). */
367 0, /* `fctrl' (16 bits). */
368 4, /* `fstat' (16 bits). */
369 8, /* `ftag' (16 bits). */
370 16, /* `fiseg' (16 bits). */
371 12, /* `fioff'. */
372 24, /* `foseg' (16 bits). */
373 20, /* `fooff'. */
374 18 /* `fop' (bottom 11 bits). */
e750d25e
JT
375};
376
20a6ec49
MD
377#define FSAVE_ADDR(tdep, fsave, regnum) \
378 (fsave + fsave_offset[regnum - I387_ST0_REGNUM (tdep)])
e750d25e
JT
379\f
380
41d041d6
MK
381/* Fill register REGNUM in REGCACHE with the appropriate value from
382 *FSAVE. This function masks off any of the reserved bits in
383 *FSAVE. */
e750d25e
JT
384
385void
41d041d6 386i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave)
e750d25e 387{
41d041d6 388 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
b4ad899f 389 const gdb_byte *regs = fsave;
e750d25e
JT
390 int i;
391
5716833c
MK
392 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
393
20a6ec49 394 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
ed504bdf
MK
395 if (regnum == -1 || regnum == i)
396 {
397 if (fsave == NULL)
398 {
5716833c
MK
399 regcache_raw_supply (regcache, i, NULL);
400 continue;
ed504bdf
MK
401 }
402
403 /* Most of the FPU control registers occupy only 16 bits in the
404 fsave area. Give those a special treatment. */
20a6ec49
MD
405 if (i >= I387_FCTRL_REGNUM (tdep)
406 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
ed504bdf 407 {
b4ad899f 408 gdb_byte val[4];
ed504bdf 409
20a6ec49 410 memcpy (val, FSAVE_ADDR (tdep, regs, i), 2);
ed504bdf 411 val[2] = val[3] = 0;
20a6ec49 412 if (i == I387_FOP_REGNUM (tdep))
ed504bdf 413 val[1] &= ((1 << 3) - 1);
5716833c 414 regcache_raw_supply (regcache, i, val);
ed504bdf
MK
415 }
416 else
20a6ec49 417 regcache_raw_supply (regcache, i, FSAVE_ADDR (tdep, regs, i));
ed504bdf 418 }
b87bc0d8
MK
419
420 /* Provide dummy values for the SSE registers. */
20a6ec49 421 for (i = I387_XMM0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
b87bc0d8
MK
422 if (regnum == -1 || regnum == i)
423 regcache_raw_supply (regcache, i, NULL);
20a6ec49 424 if (regnum == -1 || regnum == I387_MXCSR_REGNUM (tdep))
b87bc0d8 425 {
b4ad899f 426 gdb_byte buf[4];
b87bc0d8
MK
427
428 store_unsigned_integer (buf, 4, 0x1f80);
20a6ec49 429 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), buf);
b87bc0d8 430 }
e750d25e
JT
431}
432
433/* Fill register REGNUM (if it is a floating-point register) in *FSAVE
63b6c53f
MK
434 with the value from REGCACHE. If REGNUM is -1, do this for all
435 registers. This function doesn't touch any of the reserved bits in
436 *FSAVE. */
e750d25e
JT
437
438void
63b6c53f 439i387_collect_fsave (const struct regcache *regcache, int regnum, void *fsave)
e750d25e 440{
e071d1f6 441 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
b4ad899f 442 gdb_byte *regs = fsave;
e750d25e
JT
443 int i;
444
5716833c
MK
445 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
446
20a6ec49 447 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
e750d25e
JT
448 if (regnum == -1 || regnum == i)
449 {
450 /* Most of the FPU control registers occupy only 16 bits in
451 the fsave area. Give those a special treatment. */
20a6ec49
MD
452 if (i >= I387_FCTRL_REGNUM (tdep)
453 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
e750d25e 454 {
b4ad899f 455 gdb_byte buf[4];
e750d25e 456
5716833c 457 regcache_raw_collect (regcache, i, buf);
e750d25e 458
20a6ec49 459 if (i == I387_FOP_REGNUM (tdep))
e750d25e
JT
460 {
461 /* The opcode occupies only 11 bits. Make sure we
462 don't touch the other bits. */
463 buf[1] &= ((1 << 3) - 1);
20a6ec49 464 buf[1] |= ((FSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
e750d25e 465 }
20a6ec49 466 memcpy (FSAVE_ADDR (tdep, regs, i), buf, 2);
e750d25e
JT
467 }
468 else
20a6ec49 469 regcache_raw_collect (regcache, i, FSAVE_ADDR (tdep, regs, i));
e750d25e
JT
470 }
471}
472\f
473
474/* At fxsave_offset[REGNUM] you'll find the offset to the location in
475 the data structure used by the "fxsave" instruction where GDB
476 register REGNUM is stored. */
477
478static int fxsave_offset[] =
479{
5716833c 480 32, /* %st(0) through ... */
e750d25e
JT
481 48,
482 64,
483 80,
484 96,
485 112,
486 128,
5716833c
MK
487 144, /* ... %st(7) (80 bits each). */
488 0, /* `fctrl' (16 bits). */
489 2, /* `fstat' (16 bits). */
490 4, /* `ftag' (16 bits). */
491 12, /* `fiseg' (16 bits). */
492 8, /* `fioff'. */
493 20, /* `foseg' (16 bits). */
494 16, /* `fooff'. */
495 6, /* `fop' (bottom 11 bits). */
496 160 + 0 * 16, /* %xmm0 through ... */
04c8243f
MK
497 160 + 1 * 16,
498 160 + 2 * 16,
499 160 + 3 * 16,
500 160 + 4 * 16,
501 160 + 5 * 16,
502 160 + 6 * 16,
503 160 + 7 * 16,
504 160 + 8 * 16,
505 160 + 9 * 16,
506 160 + 10 * 16,
507 160 + 11 * 16,
508 160 + 12 * 16,
509 160 + 13 * 16,
510 160 + 14 * 16,
5716833c 511 160 + 15 * 16, /* ... %xmm15 (128 bits each). */
e750d25e
JT
512};
513
20a6ec49
MD
514#define FXSAVE_ADDR(tdep, fxsave, regnum) \
515 (fxsave + fxsave_offset[regnum - I387_ST0_REGNUM (tdep)])
5716833c
MK
516
517/* We made an unfortunate choice in putting %mxcsr after the SSE
518 registers %xmm0-%xmm7 instead of before, since it makes supporting
519 the registers %xmm8-%xmm15 on AMD64 a bit involved. Therefore we
520 don't include the offset for %mxcsr here above. */
521
522#define FXSAVE_MXCSR_ADDR(fxsave) (fxsave + 24)
e750d25e 523
b4ad899f 524static int i387_tag (const gdb_byte *raw);
e750d25e
JT
525\f
526
41d041d6 527/* Fill register REGNUM in REGCACHE with the appropriate
ed504bdf
MK
528 floating-point or SSE register value from *FXSAVE. This function
529 masks off any of the reserved bits in *FXSAVE. */
e750d25e
JT
530
531void
41d041d6 532i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
e750d25e 533{
41d041d6 534 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
b4ad899f 535 const gdb_byte *regs = fxsave;
5716833c
MK
536 int i;
537
538 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
539 gdb_assert (tdep->num_xmm_regs > 0);
dff95cc7 540
20a6ec49 541 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
ed504bdf
MK
542 if (regnum == -1 || regnum == i)
543 {
5716833c 544 if (regs == NULL)
ed504bdf 545 {
5716833c 546 regcache_raw_supply (regcache, i, NULL);
ed504bdf
MK
547 continue;
548 }
932bb524 549
ed504bdf
MK
550 /* Most of the FPU control registers occupy only 16 bits in
551 the fxsave area. Give those a special treatment. */
20a6ec49
MD
552 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
553 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
ed504bdf 554 {
b4ad899f 555 gdb_byte val[4];
ed504bdf 556
20a6ec49 557 memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
ed504bdf 558 val[2] = val[3] = 0;
20a6ec49 559 if (i == I387_FOP_REGNUM (tdep))
ed504bdf 560 val[1] &= ((1 << 3) - 1);
20a6ec49 561 else if (i== I387_FTAG_REGNUM (tdep))
ed504bdf
MK
562 {
563 /* The fxsave area contains a simplified version of
564 the tag word. We have to look at the actual 80-bit
565 FP data to recreate the traditional i387 tag word. */
566
567 unsigned long ftag = 0;
568 int fpreg;
569 int top;
570
20a6ec49
MD
571 top = ((FXSAVE_ADDR (tdep, regs,
572 I387_FSTAT_REGNUM (tdep)))[1] >> 3);
5716833c 573 top &= 0x7;
ed504bdf
MK
574
575 for (fpreg = 7; fpreg >= 0; fpreg--)
576 {
577 int tag;
578
579 if (val[0] & (1 << fpreg))
580 {
20a6ec49
MD
581 int regnum = (fpreg + 8 - top) % 8
582 + I387_ST0_REGNUM (tdep);
583 tag = i387_tag (FXSAVE_ADDR (tdep, regs, regnum));
ed504bdf
MK
584 }
585 else
586 tag = 3; /* Empty */
587
588 ftag |= tag << (2 * fpreg);
589 }
590 val[0] = ftag & 0xff;
591 val[1] = (ftag >> 8) & 0xff;
592 }
5716833c 593 regcache_raw_supply (regcache, i, val);
ed504bdf
MK
594 }
595 else
20a6ec49 596 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
ed504bdf 597 }
5716833c 598
20a6ec49 599 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
5716833c
MK
600 {
601 if (regs == NULL)
20a6ec49 602 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), NULL);
5716833c 603 else
20a6ec49 604 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep),
5716833c
MK
605 FXSAVE_MXCSR_ADDR (regs));
606 }
e750d25e
JT
607}
608
609/* Fill register REGNUM (if it is a floating-point or SSE register) in
80571bff
MK
610 *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for
611 all registers. This function doesn't touch any of the reserved
612 bits in *FXSAVE. */
e750d25e
JT
613
614void
80571bff 615i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave)
e750d25e 616{
e071d1f6 617 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
b4ad899f 618 gdb_byte *regs = fxsave;
5716833c
MK
619 int i;
620
621 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
622 gdb_assert (tdep->num_xmm_regs > 0);
dff95cc7 623
20a6ec49 624 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
e750d25e
JT
625 if (regnum == -1 || regnum == i)
626 {
627 /* Most of the FPU control registers occupy only 16 bits in
628 the fxsave area. Give those a special treatment. */
20a6ec49
MD
629 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
630 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
e750d25e 631 {
b4ad899f 632 gdb_byte buf[4];
e750d25e 633
5716833c 634 regcache_raw_collect (regcache, i, buf);
e750d25e 635
20a6ec49 636 if (i == I387_FOP_REGNUM (tdep))
e750d25e
JT
637 {
638 /* The opcode occupies only 11 bits. Make sure we
639 don't touch the other bits. */
640 buf[1] &= ((1 << 3) - 1);
20a6ec49 641 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
e750d25e 642 }
20a6ec49 643 else if (i == I387_FTAG_REGNUM (tdep))
e750d25e
JT
644 {
645 /* Converting back is much easier. */
646
647 unsigned short ftag;
648 int fpreg;
649
650 ftag = (buf[1] << 8) | buf[0];
651 buf[0] = 0;
652 buf[1] = 0;
653
654 for (fpreg = 7; fpreg >= 0; fpreg--)
655 {
656 int tag = (ftag >> (fpreg * 2)) & 3;
657
658 if (tag != 3)
659 buf[0] |= (1 << fpreg);
660 }
661 }
20a6ec49 662 memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
e750d25e
JT
663 }
664 else
20a6ec49 665 regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
e750d25e 666 }
5716833c 667
20a6ec49
MD
668 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
669 regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
5716833c 670 FXSAVE_MXCSR_ADDR (regs));
e750d25e
JT
671}
672
673/* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
674 *RAW. */
675
676static int
b4ad899f 677i387_tag (const gdb_byte *raw)
e750d25e
JT
678{
679 int integer;
680 unsigned int exponent;
681 unsigned long fraction[2];
682
683 integer = raw[7] & 0x80;
684 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
685 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
686 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
687 | (raw[5] << 8) | raw[4]);
688
689 if (exponent == 0x7fff)
690 {
691 /* Special. */
692 return (2);
693 }
694 else if (exponent == 0x0000)
695 {
696 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
697 {
698 /* Zero. */
699 return (1);
700 }
701 else
702 {
703 /* Special. */
704 return (2);
705 }
706 }
707 else
708 {
709 if (integer)
710 {
711 /* Valid. */
712 return (0);
713 }
714 else
715 {
716 /* Special. */
717 return (2);
718 }
719 }
720}
efb1c01c
MK
721
722/* Prepare the FPU stack in REGCACHE for a function return. */
723
724void
725i387_return_value (struct gdbarch *gdbarch, struct regcache *regcache)
726{
727 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
728 ULONGEST fstat;
729
efb1c01c
MK
730 /* Set the top of the floating-point register stack to 7. The
731 actual value doesn't really matter, but 7 is what a normal
732 function return would end up with if the program started out with
733 a freshly initialized FPU. */
20a6ec49 734 regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM (tdep), &fstat);
efb1c01c 735 fstat |= (7 << 11);
20a6ec49 736 regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM (tdep), fstat);
efb1c01c
MK
737
738 /* Mark %st(1) through %st(7) as empty. Since we set the top of the
739 floating-point register stack to 7, the appropriate value for the
740 tag word is 0x3fff. */
20a6ec49 741 regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM (tdep), 0x3fff);
efb1c01c 742
efb1c01c 743}
This page took 0.744686 seconds and 4 git commands to generate.