gdb/doc/
[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,
7b6bb8da 4 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
4c38e0a4 5 Free Software Foundation, Inc.
c906108c 6
c5aa993b 7 This file is part of GDB.
c906108c 8
c5aa993b
JM
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
c5aa993b 12 (at your option) any later version.
c906108c 13
c5aa993b
JM
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
c906108c 18
c5aa993b 19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
21
22#include "defs.h"
786a90bb
MK
23#include "doublest.h"
24#include "floatformat.h"
c906108c 25#include "frame.h"
786a90bb 26#include "gdbcore.h"
c906108c
SS
27#include "inferior.h"
28#include "language.h"
4e052eda 29#include "regcache.h"
786a90bb
MK
30#include "value.h"
31
d0df8472 32#include "gdb_assert.h"
309367d4 33#include "gdb_string.h"
c906108c 34
9a82579f 35#include "i386-tdep.h"
42c466d7 36#include "i387-tdep.h"
31aeac78 37#include "i386-xstate.h"
c906108c 38
de57eccd 39/* Print the floating point number specified by RAW. */
786a90bb 40
de57eccd 41static void
27067745
UW
42print_i387_value (struct gdbarch *gdbarch,
43 const gdb_byte *raw, struct ui_file *file)
de57eccd
JM
44{
45 DOUBLEST value;
4583280c
MK
46
47 /* Using extract_typed_floating here might affect the representation
48 of certain numbers such as NaNs, even if GDB is running natively.
49 This is fine since our caller already detects such special
50 numbers and we print the hexadecimal representation anyway. */
27067745 51 value = extract_typed_floating (raw, i387_ext_type (gdbarch));
de57eccd
JM
52
53 /* We try to print 19 digits. The last digit may or may not contain
54 garbage, but we'd better print one too many. We need enough room
55 to print the value, 1 position for the sign, 1 for the decimal
56 point, 19 for the digits and 6 for the exponent adds up to 27. */
57#ifdef PRINTF_HAS_LONG_DOUBLE
61113f8b 58 fprintf_filtered (file, " %-+27.19Lg", (long double) value);
de57eccd 59#else
61113f8b 60 fprintf_filtered (file, " %-+27.19g", (double) value);
de57eccd
JM
61#endif
62}
63
64/* Print the classification for the register contents RAW. */
786a90bb 65
de57eccd 66static void
27067745
UW
67print_i387_ext (struct gdbarch *gdbarch,
68 const gdb_byte *raw, struct ui_file *file)
de57eccd
JM
69{
70 int sign;
71 int integer;
72 unsigned int exponent;
73 unsigned long fraction[2];
74
75 sign = raw[9] & 0x80;
76 integer = raw[7] & 0x80;
77 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
78 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
79 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
80 | (raw[5] << 8) | raw[4]);
81
82 if (exponent == 0x7fff && integer)
83 {
84 if (fraction[0] == 0x00000000 && fraction[1] == 0x00000000)
85 /* Infinity. */
61113f8b 86 fprintf_filtered (file, " %cInf", (sign ? '-' : '+'));
de57eccd
JM
87 else if (sign && fraction[0] == 0x00000000 && fraction[1] == 0x40000000)
88 /* Real Indefinite (QNaN). */
61113f8b 89 fputs_unfiltered (" Real Indefinite (QNaN)", file);
de57eccd
JM
90 else if (fraction[1] & 0x40000000)
91 /* QNaN. */
61113f8b 92 fputs_filtered (" QNaN", file);
de57eccd
JM
93 else
94 /* SNaN. */
61113f8b 95 fputs_filtered (" SNaN", file);
de57eccd
JM
96 }
97 else if (exponent < 0x7fff && exponent > 0x0000 && integer)
98 /* Normal. */
27067745 99 print_i387_value (gdbarch, raw, file);
de57eccd
JM
100 else if (exponent == 0x0000)
101 {
102 /* Denormal or zero. */
27067745 103 print_i387_value (gdbarch, raw, file);
de57eccd
JM
104
105 if (integer)
106 /* Pseudo-denormal. */
61113f8b 107 fputs_filtered (" Pseudo-denormal", file);
de57eccd
JM
108 else if (fraction[0] || fraction[1])
109 /* Denormal. */
61113f8b 110 fputs_filtered (" Denormal", file);
de57eccd
JM
111 }
112 else
113 /* Unsupported. */
61113f8b 114 fputs_filtered (" Unsupported", file);
de57eccd
JM
115}
116
117/* Print the status word STATUS. */
786a90bb 118
de57eccd 119static void
61113f8b 120print_i387_status_word (unsigned int status, struct ui_file *file)
de57eccd 121{
61113f8b 122 fprintf_filtered (file, "Status Word: %s",
bb599908 123 hex_string_custom (status, 4));
61113f8b
MK
124 fputs_filtered (" ", file);
125 fprintf_filtered (file, " %s", (status & 0x0001) ? "IE" : " ");
126 fprintf_filtered (file, " %s", (status & 0x0002) ? "DE" : " ");
127 fprintf_filtered (file, " %s", (status & 0x0004) ? "ZE" : " ");
128 fprintf_filtered (file, " %s", (status & 0x0008) ? "OE" : " ");
129 fprintf_filtered (file, " %s", (status & 0x0010) ? "UE" : " ");
130 fprintf_filtered (file, " %s", (status & 0x0020) ? "PE" : " ");
131 fputs_filtered (" ", file);
132 fprintf_filtered (file, " %s", (status & 0x0080) ? "ES" : " ");
133 fputs_filtered (" ", file);
134 fprintf_filtered (file, " %s", (status & 0x0040) ? "SF" : " ");
135 fputs_filtered (" ", file);
136 fprintf_filtered (file, " %s", (status & 0x0100) ? "C0" : " ");
137 fprintf_filtered (file, " %s", (status & 0x0200) ? "C1" : " ");
138 fprintf_filtered (file, " %s", (status & 0x0400) ? "C2" : " ");
139 fprintf_filtered (file, " %s", (status & 0x4000) ? "C3" : " ");
140
141 fputs_filtered ("\n", file);
142
143 fprintf_filtered (file,
144 " TOP: %d\n", ((status >> 11) & 7));
de57eccd
JM
145}
146
147/* Print the control word CONTROL. */
786a90bb 148
de57eccd 149static void
61113f8b 150print_i387_control_word (unsigned int control, struct ui_file *file)
de57eccd 151{
61113f8b 152 fprintf_filtered (file, "Control Word: %s",
bb599908 153 hex_string_custom (control, 4));
61113f8b
MK
154 fputs_filtered (" ", file);
155 fprintf_filtered (file, " %s", (control & 0x0001) ? "IM" : " ");
156 fprintf_filtered (file, " %s", (control & 0x0002) ? "DM" : " ");
157 fprintf_filtered (file, " %s", (control & 0x0004) ? "ZM" : " ");
158 fprintf_filtered (file, " %s", (control & 0x0008) ? "OM" : " ");
159 fprintf_filtered (file, " %s", (control & 0x0010) ? "UM" : " ");
160 fprintf_filtered (file, " %s", (control & 0x0020) ? "PM" : " ");
de57eccd 161
61113f8b 162 fputs_filtered ("\n", file);
de57eccd 163
61113f8b 164 fputs_filtered (" PC: ", file);
de57eccd
JM
165 switch ((control >> 8) & 3)
166 {
167 case 0:
61113f8b 168 fputs_filtered ("Single Precision (24-bits)\n", file);
de57eccd
JM
169 break;
170 case 1:
61113f8b 171 fputs_filtered ("Reserved\n", file);
de57eccd
JM
172 break;
173 case 2:
61113f8b 174 fputs_filtered ("Double Precision (53-bits)\n", file);
de57eccd
JM
175 break;
176 case 3:
61113f8b 177 fputs_filtered ("Extended Precision (64-bits)\n", file);
de57eccd
JM
178 break;
179 }
180
61113f8b 181 fputs_filtered (" RC: ", file);
de57eccd
JM
182 switch ((control >> 10) & 3)
183 {
184 case 0:
61113f8b 185 fputs_filtered ("Round to nearest\n", file);
de57eccd
JM
186 break;
187 case 1:
61113f8b 188 fputs_filtered ("Round down\n", file);
de57eccd
JM
189 break;
190 case 2:
61113f8b 191 fputs_filtered ("Round up\n", file);
de57eccd
JM
192 break;
193 case 3:
61113f8b 194 fputs_filtered ("Round toward zero\n", file);
de57eccd
JM
195 break;
196 }
197}
198
9b949a49 199/* Print out the i387 floating point state. Note that we ignore FRAME
7d8d2918
MK
200 in the code below. That's OK since floating-point registers are
201 never saved on the stack. */
202
de57eccd 203void
61113f8b 204i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
8e186fd6 205 struct frame_info *frame, const char *args)
de57eccd 206{
5716833c 207 struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
1d70089a
MK
208 ULONGEST fctrl;
209 ULONGEST fstat;
210 ULONGEST ftag;
211 ULONGEST fiseg;
212 ULONGEST fioff;
213 ULONGEST foseg;
214 ULONGEST fooff;
215 ULONGEST fop;
de57eccd
JM
216 int fpreg;
217 int top;
218
5716833c
MK
219 gdb_assert (gdbarch == get_frame_arch (frame));
220
20a6ec49
MD
221 fctrl = get_frame_register_unsigned (frame, I387_FCTRL_REGNUM (tdep));
222 fstat = get_frame_register_unsigned (frame, I387_FSTAT_REGNUM (tdep));
223 ftag = get_frame_register_unsigned (frame, I387_FTAG_REGNUM (tdep));
224 fiseg = get_frame_register_unsigned (frame, I387_FISEG_REGNUM (tdep));
225 fioff = get_frame_register_unsigned (frame, I387_FIOFF_REGNUM (tdep));
226 foseg = get_frame_register_unsigned (frame, I387_FOSEG_REGNUM (tdep));
227 fooff = get_frame_register_unsigned (frame, I387_FOOFF_REGNUM (tdep));
228 fop = get_frame_register_unsigned (frame, I387_FOP_REGNUM (tdep));
1d70089a 229
de57eccd
JM
230 top = ((fstat >> 11) & 7);
231
232 for (fpreg = 7; fpreg >= 0; fpreg--)
233 {
b4ad899f 234 gdb_byte raw[I386_MAX_REGISTER_SIZE];
de57eccd
JM
235 int tag = (ftag >> (fpreg * 2)) & 3;
236 int i;
237
61113f8b 238 fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg);
de57eccd
JM
239
240 switch (tag)
241 {
242 case 0:
61113f8b 243 fputs_filtered ("Valid ", file);
de57eccd
JM
244 break;
245 case 1:
61113f8b 246 fputs_filtered ("Zero ", file);
de57eccd
JM
247 break;
248 case 2:
61113f8b 249 fputs_filtered ("Special ", file);
de57eccd
JM
250 break;
251 case 3:
61113f8b 252 fputs_filtered ("Empty ", file);
de57eccd
JM
253 break;
254 }
255
1777feb0
MS
256 get_frame_register (frame,
257 (fpreg + 8 - top) % 8 + I387_ST0_REGNUM (tdep),
20a6ec49 258 raw);
de57eccd 259
61113f8b 260 fputs_filtered ("0x", file);
de57eccd 261 for (i = 9; i >= 0; i--)
61113f8b 262 fprintf_filtered (file, "%02x", raw[i]);
de57eccd
JM
263
264 if (tag != 3)
27067745 265 print_i387_ext (gdbarch, raw, file);
de57eccd 266
61113f8b 267 fputs_filtered ("\n", file);
de57eccd
JM
268 }
269
f16a25ae 270 fputs_filtered ("\n", file);
de57eccd 271
61113f8b
MK
272 print_i387_status_word (fstat, file);
273 print_i387_control_word (fctrl, file);
274 fprintf_filtered (file, "Tag Word: %s\n",
bb599908 275 hex_string_custom (ftag, 4));
61113f8b 276 fprintf_filtered (file, "Instruction Pointer: %s:",
bb599908
PH
277 hex_string_custom (fiseg, 2));
278 fprintf_filtered (file, "%s\n", hex_string_custom (fioff, 8));
61113f8b 279 fprintf_filtered (file, "Operand Pointer: %s:",
bb599908
PH
280 hex_string_custom (foseg, 2));
281 fprintf_filtered (file, "%s\n", hex_string_custom (fooff, 8));
61113f8b 282 fprintf_filtered (file, "Opcode: %s\n",
bb599908 283 hex_string_custom (fop ? (fop | 0xd800) : 0, 4));
de57eccd 284}
d532c08f
MK
285\f
286
83acabca
DJ
287/* Return nonzero if a value of type TYPE stored in register REGNUM
288 needs any special handling. */
289
290int
1777feb0
MS
291i387_convert_register_p (struct gdbarch *gdbarch, int regnum,
292 struct type *type)
83acabca 293{
20a6ec49 294 if (i386_fp_regnum_p (gdbarch, regnum))
83acabca
DJ
295 {
296 /* Floating point registers must be converted unless we are
297 accessing them in their hardware type. */
27067745 298 if (type == i387_ext_type (gdbarch))
83acabca
DJ
299 return 0;
300 else
301 return 1;
302 }
303
304 return 0;
305}
306
d532c08f
MK
307/* Read a value of type TYPE from register REGNUM in frame FRAME, and
308 return its contents in TO. */
309
8dccd430 310int
d532c08f 311i387_register_to_value (struct frame_info *frame, int regnum,
8dccd430
PA
312 struct type *type, gdb_byte *to,
313 int *optimizedp, int *unavailablep)
d532c08f 314{
27067745 315 struct gdbarch *gdbarch = get_frame_arch (frame);
b4ad899f 316 gdb_byte from[I386_MAX_REGISTER_SIZE];
d532c08f 317
27067745 318 gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
d532c08f
MK
319
320 /* We only support floating-point values. */
321 if (TYPE_CODE (type) != TYPE_CODE_FLT)
322 {
8a3fe4f8
AC
323 warning (_("Cannot convert floating-point register value "
324 "to non-floating-point type."));
8dccd430
PA
325 *optimizedp = *unavailablep = 0;
326 return 0;
d532c08f
MK
327 }
328
83acabca 329 /* Convert to TYPE. */
8dccd430
PA
330 if (!get_frame_register_bytes (frame, regnum, 0, TYPE_LENGTH (type),
331 from, optimizedp, unavailablep))
332 return 0;
333
27067745 334 convert_typed_floating (from, i387_ext_type (gdbarch), to, type);
8dccd430
PA
335 *optimizedp = *unavailablep = 0;
336 return 1;
d532c08f
MK
337}
338
339/* Write the contents FROM of a value of type TYPE into register
340 REGNUM in frame FRAME. */
341
342void
343i387_value_to_register (struct frame_info *frame, int regnum,
42835c2b 344 struct type *type, const gdb_byte *from)
d532c08f 345{
27067745 346 struct gdbarch *gdbarch = get_frame_arch (frame);
b4ad899f 347 gdb_byte to[I386_MAX_REGISTER_SIZE];
d532c08f 348
27067745 349 gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
d532c08f
MK
350
351 /* We only support floating-point values. */
352 if (TYPE_CODE (type) != TYPE_CODE_FLT)
353 {
8a3fe4f8
AC
354 warning (_("Cannot convert non-floating-point type "
355 "to floating-point register value."));
d532c08f
MK
356 return;
357 }
358
83acabca 359 /* Convert from TYPE. */
27067745 360 convert_typed_floating (from, type, to, i387_ext_type (gdbarch));
d532c08f
MK
361 put_frame_register (frame, regnum, to);
362}
363\f
e750d25e 364
786a90bb 365/* Handle FSAVE and FXSAVE formats. */
e750d25e
JT
366
367/* At fsave_offset[REGNUM] you'll find the offset to the location in
368 the data structure used by the "fsave" instruction where GDB
369 register REGNUM is stored. */
370
371static int fsave_offset[] =
372{
5716833c
MK
373 28 + 0 * 10, /* %st(0) ... */
374 28 + 1 * 10,
375 28 + 2 * 10,
376 28 + 3 * 10,
377 28 + 4 * 10,
378 28 + 5 * 10,
379 28 + 6 * 10,
380 28 + 7 * 10, /* ... %st(7). */
381 0, /* `fctrl' (16 bits). */
382 4, /* `fstat' (16 bits). */
383 8, /* `ftag' (16 bits). */
384 16, /* `fiseg' (16 bits). */
385 12, /* `fioff'. */
386 24, /* `foseg' (16 bits). */
387 20, /* `fooff'. */
388 18 /* `fop' (bottom 11 bits). */
e750d25e
JT
389};
390
20a6ec49
MD
391#define FSAVE_ADDR(tdep, fsave, regnum) \
392 (fsave + fsave_offset[regnum - I387_ST0_REGNUM (tdep)])
e750d25e
JT
393\f
394
41d041d6
MK
395/* Fill register REGNUM in REGCACHE with the appropriate value from
396 *FSAVE. This function masks off any of the reserved bits in
397 *FSAVE. */
e750d25e
JT
398
399void
41d041d6 400i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave)
e750d25e 401{
e17a4113
UW
402 struct gdbarch *gdbarch = get_regcache_arch (regcache);
403 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
404 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
b4ad899f 405 const gdb_byte *regs = fsave;
e750d25e
JT
406 int i;
407
5716833c
MK
408 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
409
20a6ec49 410 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
ed504bdf
MK
411 if (regnum == -1 || regnum == i)
412 {
413 if (fsave == NULL)
414 {
5716833c
MK
415 regcache_raw_supply (regcache, i, NULL);
416 continue;
ed504bdf
MK
417 }
418
419 /* Most of the FPU control registers occupy only 16 bits in the
420 fsave area. Give those a special treatment. */
20a6ec49
MD
421 if (i >= I387_FCTRL_REGNUM (tdep)
422 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
ed504bdf 423 {
b4ad899f 424 gdb_byte val[4];
ed504bdf 425
20a6ec49 426 memcpy (val, FSAVE_ADDR (tdep, regs, i), 2);
ed504bdf 427 val[2] = val[3] = 0;
20a6ec49 428 if (i == I387_FOP_REGNUM (tdep))
ed504bdf 429 val[1] &= ((1 << 3) - 1);
5716833c 430 regcache_raw_supply (regcache, i, val);
ed504bdf
MK
431 }
432 else
20a6ec49 433 regcache_raw_supply (regcache, i, FSAVE_ADDR (tdep, regs, i));
ed504bdf 434 }
b87bc0d8
MK
435
436 /* Provide dummy values for the SSE registers. */
20a6ec49 437 for (i = I387_XMM0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
b87bc0d8
MK
438 if (regnum == -1 || regnum == i)
439 regcache_raw_supply (regcache, i, NULL);
20a6ec49 440 if (regnum == -1 || regnum == I387_MXCSR_REGNUM (tdep))
b87bc0d8 441 {
b4ad899f 442 gdb_byte buf[4];
b87bc0d8 443
e17a4113 444 store_unsigned_integer (buf, 4, byte_order, 0x1f80);
20a6ec49 445 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), buf);
b87bc0d8 446 }
e750d25e
JT
447}
448
449/* Fill register REGNUM (if it is a floating-point register) in *FSAVE
63b6c53f
MK
450 with the value from REGCACHE. If REGNUM is -1, do this for all
451 registers. This function doesn't touch any of the reserved bits in
452 *FSAVE. */
e750d25e
JT
453
454void
63b6c53f 455i387_collect_fsave (const struct regcache *regcache, int regnum, void *fsave)
e750d25e 456{
e071d1f6 457 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
b4ad899f 458 gdb_byte *regs = fsave;
e750d25e
JT
459 int i;
460
5716833c
MK
461 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
462
20a6ec49 463 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
e750d25e
JT
464 if (regnum == -1 || regnum == i)
465 {
466 /* Most of the FPU control registers occupy only 16 bits in
467 the fsave area. Give those a special treatment. */
20a6ec49
MD
468 if (i >= I387_FCTRL_REGNUM (tdep)
469 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
e750d25e 470 {
b4ad899f 471 gdb_byte buf[4];
e750d25e 472
5716833c 473 regcache_raw_collect (regcache, i, buf);
e750d25e 474
20a6ec49 475 if (i == I387_FOP_REGNUM (tdep))
e750d25e
JT
476 {
477 /* The opcode occupies only 11 bits. Make sure we
478 don't touch the other bits. */
479 buf[1] &= ((1 << 3) - 1);
20a6ec49 480 buf[1] |= ((FSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
e750d25e 481 }
20a6ec49 482 memcpy (FSAVE_ADDR (tdep, regs, i), buf, 2);
e750d25e
JT
483 }
484 else
20a6ec49 485 regcache_raw_collect (regcache, i, FSAVE_ADDR (tdep, regs, i));
e750d25e
JT
486 }
487}
488\f
489
490/* At fxsave_offset[REGNUM] you'll find the offset to the location in
491 the data structure used by the "fxsave" instruction where GDB
492 register REGNUM is stored. */
493
494static int fxsave_offset[] =
495{
5716833c 496 32, /* %st(0) through ... */
e750d25e
JT
497 48,
498 64,
499 80,
500 96,
501 112,
502 128,
5716833c
MK
503 144, /* ... %st(7) (80 bits each). */
504 0, /* `fctrl' (16 bits). */
505 2, /* `fstat' (16 bits). */
506 4, /* `ftag' (16 bits). */
507 12, /* `fiseg' (16 bits). */
508 8, /* `fioff'. */
509 20, /* `foseg' (16 bits). */
510 16, /* `fooff'. */
511 6, /* `fop' (bottom 11 bits). */
512 160 + 0 * 16, /* %xmm0 through ... */
04c8243f
MK
513 160 + 1 * 16,
514 160 + 2 * 16,
515 160 + 3 * 16,
516 160 + 4 * 16,
517 160 + 5 * 16,
518 160 + 6 * 16,
519 160 + 7 * 16,
520 160 + 8 * 16,
521 160 + 9 * 16,
522 160 + 10 * 16,
523 160 + 11 * 16,
524 160 + 12 * 16,
525 160 + 13 * 16,
526 160 + 14 * 16,
5716833c 527 160 + 15 * 16, /* ... %xmm15 (128 bits each). */
e750d25e
JT
528};
529
20a6ec49
MD
530#define FXSAVE_ADDR(tdep, fxsave, regnum) \
531 (fxsave + fxsave_offset[regnum - I387_ST0_REGNUM (tdep)])
5716833c
MK
532
533/* We made an unfortunate choice in putting %mxcsr after the SSE
534 registers %xmm0-%xmm7 instead of before, since it makes supporting
535 the registers %xmm8-%xmm15 on AMD64 a bit involved. Therefore we
536 don't include the offset for %mxcsr here above. */
537
538#define FXSAVE_MXCSR_ADDR(fxsave) (fxsave + 24)
e750d25e 539
b4ad899f 540static int i387_tag (const gdb_byte *raw);
e750d25e
JT
541\f
542
41d041d6 543/* Fill register REGNUM in REGCACHE with the appropriate
ed504bdf
MK
544 floating-point or SSE register value from *FXSAVE. This function
545 masks off any of the reserved bits in *FXSAVE. */
e750d25e
JT
546
547void
41d041d6 548i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
e750d25e 549{
41d041d6 550 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
b4ad899f 551 const gdb_byte *regs = fxsave;
5716833c
MK
552 int i;
553
554 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
555 gdb_assert (tdep->num_xmm_regs > 0);
dff95cc7 556
20a6ec49 557 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
ed504bdf
MK
558 if (regnum == -1 || regnum == i)
559 {
5716833c 560 if (regs == NULL)
ed504bdf 561 {
5716833c 562 regcache_raw_supply (regcache, i, NULL);
ed504bdf
MK
563 continue;
564 }
932bb524 565
ed504bdf
MK
566 /* Most of the FPU control registers occupy only 16 bits in
567 the fxsave area. Give those a special treatment. */
20a6ec49
MD
568 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
569 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
ed504bdf 570 {
b4ad899f 571 gdb_byte val[4];
ed504bdf 572
20a6ec49 573 memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
ed504bdf 574 val[2] = val[3] = 0;
20a6ec49 575 if (i == I387_FOP_REGNUM (tdep))
ed504bdf 576 val[1] &= ((1 << 3) - 1);
20a6ec49 577 else if (i== I387_FTAG_REGNUM (tdep))
ed504bdf
MK
578 {
579 /* The fxsave area contains a simplified version of
580 the tag word. We have to look at the actual 80-bit
581 FP data to recreate the traditional i387 tag word. */
582
583 unsigned long ftag = 0;
584 int fpreg;
585 int top;
586
20a6ec49
MD
587 top = ((FXSAVE_ADDR (tdep, regs,
588 I387_FSTAT_REGNUM (tdep)))[1] >> 3);
5716833c 589 top &= 0x7;
ed504bdf
MK
590
591 for (fpreg = 7; fpreg >= 0; fpreg--)
592 {
593 int tag;
594
595 if (val[0] & (1 << fpreg))
596 {
6d5e094a
MS
597 int thisreg = (fpreg + 8 - top) % 8
598 + I387_ST0_REGNUM (tdep);
599 tag = i387_tag (FXSAVE_ADDR (tdep, regs, thisreg));
ed504bdf
MK
600 }
601 else
602 tag = 3; /* Empty */
603
604 ftag |= tag << (2 * fpreg);
605 }
606 val[0] = ftag & 0xff;
607 val[1] = (ftag >> 8) & 0xff;
608 }
5716833c 609 regcache_raw_supply (regcache, i, val);
ed504bdf
MK
610 }
611 else
20a6ec49 612 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
ed504bdf 613 }
5716833c 614
20a6ec49 615 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
5716833c
MK
616 {
617 if (regs == NULL)
20a6ec49 618 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), NULL);
5716833c 619 else
20a6ec49 620 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep),
5716833c
MK
621 FXSAVE_MXCSR_ADDR (regs));
622 }
e750d25e
JT
623}
624
625/* Fill register REGNUM (if it is a floating-point or SSE register) in
80571bff
MK
626 *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for
627 all registers. This function doesn't touch any of the reserved
628 bits in *FXSAVE. */
e750d25e
JT
629
630void
80571bff 631i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave)
e750d25e 632{
e071d1f6 633 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
b4ad899f 634 gdb_byte *regs = fxsave;
5716833c
MK
635 int i;
636
637 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
638 gdb_assert (tdep->num_xmm_regs > 0);
dff95cc7 639
20a6ec49 640 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
e750d25e
JT
641 if (regnum == -1 || regnum == i)
642 {
643 /* Most of the FPU control registers occupy only 16 bits in
644 the fxsave area. Give those a special treatment. */
20a6ec49
MD
645 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
646 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
e750d25e 647 {
b4ad899f 648 gdb_byte buf[4];
e750d25e 649
5716833c 650 regcache_raw_collect (regcache, i, buf);
e750d25e 651
31aeac78
L
652 if (i == I387_FOP_REGNUM (tdep))
653 {
654 /* The opcode occupies only 11 bits. Make sure we
655 don't touch the other bits. */
656 buf[1] &= ((1 << 3) - 1);
657 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
658 }
659 else if (i == I387_FTAG_REGNUM (tdep))
660 {
661 /* Converting back is much easier. */
662
663 unsigned short ftag;
664 int fpreg;
665
666 ftag = (buf[1] << 8) | buf[0];
667 buf[0] = 0;
668 buf[1] = 0;
669
670 for (fpreg = 7; fpreg >= 0; fpreg--)
671 {
672 int tag = (ftag >> (fpreg * 2)) & 3;
673
674 if (tag != 3)
675 buf[0] |= (1 << fpreg);
676 }
677 }
678 memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
679 }
680 else
681 regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
682 }
683
684 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
685 regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
686 FXSAVE_MXCSR_ADDR (regs));
687}
688
689/* `xstate_bv' is at byte offset 512. */
690#define XSAVE_XSTATE_BV_ADDR(xsave) (xsave + 512)
691
692/* At xsave_avxh_offset[REGNUM] you'll find the offset to the location in
693 the upper 128bit of AVX register data structure used by the "xsave"
694 instruction where GDB register REGNUM is stored. */
695
696static int xsave_avxh_offset[] =
697{
698 576 + 0 * 16, /* Upper 128bit of %ymm0 through ... */
699 576 + 1 * 16,
700 576 + 2 * 16,
701 576 + 3 * 16,
702 576 + 4 * 16,
703 576 + 5 * 16,
704 576 + 6 * 16,
705 576 + 7 * 16,
706 576 + 8 * 16,
707 576 + 9 * 16,
708 576 + 10 * 16,
709 576 + 11 * 16,
710 576 + 12 * 16,
711 576 + 13 * 16,
712 576 + 14 * 16,
713 576 + 15 * 16 /* Upper 128bit of ... %ymm15 (128 bits each). */
714};
715
716#define XSAVE_AVXH_ADDR(tdep, xsave, regnum) \
717 (xsave + xsave_avxh_offset[regnum - I387_YMM0H_REGNUM (tdep)])
718
719/* Similar to i387_supply_fxsave, but use XSAVE extended state. */
720
721void
722i387_supply_xsave (struct regcache *regcache, int regnum,
723 const void *xsave)
724{
725 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
726 const gdb_byte *regs = xsave;
727 int i;
728 unsigned int clear_bv;
729 const gdb_byte *p;
730 enum
731 {
732 none = 0x0,
733 x87 = 0x1,
734 sse = 0x2,
735 avxh = 0x4,
736 all = x87 | sse | avxh
737 } regclass;
738
739 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
740 gdb_assert (tdep->num_xmm_regs > 0);
741
742 if (regnum == -1)
743 regclass = all;
744 else if (regnum >= I387_YMM0H_REGNUM (tdep)
745 && regnum < I387_YMMENDH_REGNUM (tdep))
746 regclass = avxh;
747 else if (regnum >= I387_XMM0_REGNUM(tdep)
748 && regnum < I387_MXCSR_REGNUM (tdep))
749 regclass = sse;
750 else if (regnum >= I387_ST0_REGNUM (tdep)
751 && regnum < I387_FCTRL_REGNUM (tdep))
752 regclass = x87;
753 else
754 regclass = none;
755
756 if (regs != NULL && regclass != none)
757 {
758 /* Get `xstat_bv'. */
759 const gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs);
760
761 /* The supported bits in `xstat_bv' are 1 byte. Clear part in
762 vector registers if its bit in xstat_bv is zero. */
763 clear_bv = (~(*xstate_bv_p)) & tdep->xcr0;
764 }
765 else
766 clear_bv = I386_XSTATE_AVX_MASK;
767
768 switch (regclass)
769 {
770 case none:
771 break;
772
773 case avxh:
774 if ((clear_bv & I386_XSTATE_AVX))
775 p = NULL;
776 else
777 p = XSAVE_AVXH_ADDR (tdep, regs, regnum);
778 regcache_raw_supply (regcache, regnum, p);
779 return;
780
781 case sse:
782 if ((clear_bv & I386_XSTATE_SSE))
783 p = NULL;
784 else
785 p = FXSAVE_ADDR (tdep, regs, regnum);
786 regcache_raw_supply (regcache, regnum, p);
787 return;
788
789 case x87:
790 if ((clear_bv & I386_XSTATE_X87))
791 p = NULL;
792 else
793 p = FXSAVE_ADDR (tdep, regs, regnum);
794 regcache_raw_supply (regcache, regnum, p);
795 return;
796
797 case all:
798 /* Hanle the upper YMM registers. */
799 if ((tdep->xcr0 & I386_XSTATE_AVX))
800 {
801 if ((clear_bv & I386_XSTATE_AVX))
802 p = NULL;
803 else
804 p = regs;
805
806 for (i = I387_YMM0H_REGNUM (tdep);
807 i < I387_YMMENDH_REGNUM (tdep); i++)
808 {
809 if (p != NULL)
810 p = XSAVE_AVXH_ADDR (tdep, regs, i);
811 regcache_raw_supply (regcache, i, p);
812 }
813 }
814
815 /* Handle the XMM registers. */
816 if ((tdep->xcr0 & I386_XSTATE_SSE))
817 {
818 if ((clear_bv & I386_XSTATE_SSE))
819 p = NULL;
820 else
821 p = regs;
822
823 for (i = I387_XMM0_REGNUM (tdep);
824 i < I387_MXCSR_REGNUM (tdep); i++)
825 {
826 if (p != NULL)
827 p = FXSAVE_ADDR (tdep, regs, i);
828 regcache_raw_supply (regcache, i, p);
829 }
830 }
831
832 /* Handle the x87 registers. */
833 if ((tdep->xcr0 & I386_XSTATE_X87))
834 {
835 if ((clear_bv & I386_XSTATE_X87))
836 p = NULL;
837 else
838 p = regs;
839
840 for (i = I387_ST0_REGNUM (tdep);
841 i < I387_FCTRL_REGNUM (tdep); i++)
842 {
843 if (p != NULL)
844 p = FXSAVE_ADDR (tdep, regs, i);
845 regcache_raw_supply (regcache, i, p);
846 }
847 }
848 break;
849 }
850
851 /* Only handle x87 control registers. */
852 for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
853 if (regnum == -1 || regnum == i)
854 {
855 if (regs == NULL)
856 {
857 regcache_raw_supply (regcache, i, NULL);
858 continue;
859 }
860
861 /* Most of the FPU control registers occupy only 16 bits in
862 the xsave extended state. Give those a special treatment. */
863 if (i != I387_FIOFF_REGNUM (tdep)
864 && i != I387_FOOFF_REGNUM (tdep))
865 {
866 gdb_byte val[4];
867
868 memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
869 val[2] = val[3] = 0;
870 if (i == I387_FOP_REGNUM (tdep))
871 val[1] &= ((1 << 3) - 1);
872 else if (i== I387_FTAG_REGNUM (tdep))
873 {
874 /* The fxsave area contains a simplified version of
875 the tag word. We have to look at the actual 80-bit
876 FP data to recreate the traditional i387 tag word. */
877
878 unsigned long ftag = 0;
879 int fpreg;
880 int top;
881
882 top = ((FXSAVE_ADDR (tdep, regs,
883 I387_FSTAT_REGNUM (tdep)))[1] >> 3);
884 top &= 0x7;
885
886 for (fpreg = 7; fpreg >= 0; fpreg--)
887 {
888 int tag;
889
890 if (val[0] & (1 << fpreg))
891 {
e5b3d7d6 892 int thisreg = (fpreg + 8 - top) % 8
31aeac78 893 + I387_ST0_REGNUM (tdep);
e5b3d7d6 894 tag = i387_tag (FXSAVE_ADDR (tdep, regs, thisreg));
31aeac78
L
895 }
896 else
897 tag = 3; /* Empty */
898
899 ftag |= tag << (2 * fpreg);
900 }
901 val[0] = ftag & 0xff;
902 val[1] = (ftag >> 8) & 0xff;
903 }
904 regcache_raw_supply (regcache, i, val);
905 }
906 else
907 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
908 }
909
910 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
911 {
912 p = regs == NULL ? NULL : FXSAVE_MXCSR_ADDR (regs);
913 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), p);
914 }
915}
916
917/* Similar to i387_collect_fxsave, but use XSAVE extended state. */
918
919void
920i387_collect_xsave (const struct regcache *regcache, int regnum,
921 void *xsave, int gcore)
922{
923 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
924 gdb_byte *regs = xsave;
925 int i;
926 enum
927 {
928 none = 0x0,
929 check = 0x1,
930 x87 = 0x2 | check,
931 sse = 0x4 | check,
932 avxh = 0x8 | check,
933 all = x87 | sse | avxh
934 } regclass;
935
936 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
937 gdb_assert (tdep->num_xmm_regs > 0);
938
939 if (regnum == -1)
940 regclass = all;
941 else if (regnum >= I387_YMM0H_REGNUM (tdep)
942 && regnum < I387_YMMENDH_REGNUM (tdep))
943 regclass = avxh;
944 else if (regnum >= I387_XMM0_REGNUM(tdep)
945 && regnum < I387_MXCSR_REGNUM (tdep))
946 regclass = sse;
947 else if (regnum >= I387_ST0_REGNUM (tdep)
948 && regnum < I387_FCTRL_REGNUM (tdep))
949 regclass = x87;
950 else
951 regclass = none;
952
953 if (gcore)
954 {
955 /* Clear XSAVE extended state. */
956 memset (regs, 0, I386_XSTATE_SIZE (tdep->xcr0));
957
958 /* Update XCR0 and `xstate_bv' with XCR0 for gcore. */
959 if (tdep->xsave_xcr0_offset != -1)
960 memcpy (regs + tdep->xsave_xcr0_offset, &tdep->xcr0, 8);
961 memcpy (XSAVE_XSTATE_BV_ADDR (regs), &tdep->xcr0, 8);
962 }
963
964 if ((regclass & check))
965 {
966 gdb_byte raw[I386_MAX_REGISTER_SIZE];
967 gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs);
968 unsigned int xstate_bv = 0;
1777feb0 969 /* The supported bits in `xstat_bv' are 1 byte. */
31aeac78
L
970 unsigned int clear_bv = (~(*xstate_bv_p)) & tdep->xcr0;
971 gdb_byte *p;
972
973 /* Clear register set if its bit in xstat_bv is zero. */
974 if (clear_bv)
975 {
976 if ((clear_bv & I386_XSTATE_AVX))
977 for (i = I387_YMM0H_REGNUM (tdep);
978 i < I387_YMMENDH_REGNUM (tdep); i++)
979 memset (XSAVE_AVXH_ADDR (tdep, regs, i), 0, 16);
980
981 if ((clear_bv & I386_XSTATE_SSE))
982 for (i = I387_XMM0_REGNUM (tdep);
983 i < I387_MXCSR_REGNUM (tdep); i++)
984 memset (FXSAVE_ADDR (tdep, regs, i), 0, 16);
985
986 if ((clear_bv & I386_XSTATE_X87))
987 for (i = I387_ST0_REGNUM (tdep);
988 i < I387_FCTRL_REGNUM (tdep); i++)
989 memset (FXSAVE_ADDR (tdep, regs, i), 0, 10);
990 }
991
992 if (regclass == all)
993 {
994 /* Check if any upper YMM registers are changed. */
995 if ((tdep->xcr0 & I386_XSTATE_AVX))
996 for (i = I387_YMM0H_REGNUM (tdep);
997 i < I387_YMMENDH_REGNUM (tdep); i++)
998 {
999 regcache_raw_collect (regcache, i, raw);
1000 p = XSAVE_AVXH_ADDR (tdep, regs, i);
1001 if (memcmp (raw, p, 16))
1002 {
1003 xstate_bv |= I386_XSTATE_AVX;
1004 memcpy (p, raw, 16);
1005 }
1006 }
1007
1008 /* Check if any SSE registers are changed. */
1009 if ((tdep->xcr0 & I386_XSTATE_SSE))
1010 for (i = I387_XMM0_REGNUM (tdep);
1011 i < I387_MXCSR_REGNUM (tdep); i++)
1012 {
1013 regcache_raw_collect (regcache, i, raw);
1014 p = FXSAVE_ADDR (tdep, regs, i);
1015 if (memcmp (raw, p, 16))
1016 {
1017 xstate_bv |= I386_XSTATE_SSE;
1018 memcpy (p, raw, 16);
1019 }
1020 }
1021
1022 /* Check if any X87 registers are changed. */
1023 if ((tdep->xcr0 & I386_XSTATE_X87))
1024 for (i = I387_ST0_REGNUM (tdep);
1025 i < I387_FCTRL_REGNUM (tdep); i++)
1026 {
1027 regcache_raw_collect (regcache, i, raw);
1028 p = FXSAVE_ADDR (tdep, regs, i);
1029 if (memcmp (raw, p, 10))
1030 {
1031 xstate_bv |= I386_XSTATE_X87;
1032 memcpy (p, raw, 10);
1033 }
1034 }
1035 }
1036 else
1037 {
1038 /* Check if REGNUM is changed. */
1039 regcache_raw_collect (regcache, regnum, raw);
1040
1041 switch (regclass)
1042 {
1043 default:
4e4d8374
L
1044 internal_error (__FILE__, __LINE__,
1045 _("invalid i387 regclass"));
31aeac78 1046
40936b0d
L
1047 case avxh:
1048 /* This is an upper YMM register. */
1049 p = XSAVE_AVXH_ADDR (tdep, regs, regnum);
1050 if (memcmp (raw, p, 16))
31aeac78 1051 {
40936b0d
L
1052 xstate_bv |= I386_XSTATE_AVX;
1053 memcpy (p, raw, 16);
1054 }
1055 break;
31aeac78 1056
40936b0d
L
1057 case sse:
1058 /* This is an SSE register. */
1059 p = FXSAVE_ADDR (tdep, regs, regnum);
1060 if (memcmp (raw, p, 16))
1061 {
1062 xstate_bv |= I386_XSTATE_SSE;
1063 memcpy (p, raw, 16);
1064 }
1065 break;
31aeac78 1066
40936b0d
L
1067 case x87:
1068 /* This is an x87 register. */
1069 p = FXSAVE_ADDR (tdep, regs, regnum);
1070 if (memcmp (raw, p, 10))
1071 {
1072 xstate_bv |= I386_XSTATE_X87;
1073 memcpy (p, raw, 10);
31aeac78 1074 }
40936b0d 1075 break;
31aeac78 1076 }
40936b0d
L
1077 }
1078
1079 /* Update the corresponding bits in `xstate_bv' if any SSE/AVX
1080 registers are changed. */
1081 if (xstate_bv)
1082 {
1083 /* The supported bits in `xstat_bv' are 1 byte. */
1084 *xstate_bv_p |= (gdb_byte) xstate_bv;
1085
1086 switch (regclass)
31aeac78 1087 {
40936b0d 1088 default:
4e4d8374
L
1089 internal_error (__FILE__, __LINE__,
1090 _("invalid i387 regclass"));
40936b0d
L
1091
1092 case all:
1093 break;
1094
1095 case x87:
1096 case sse:
1097 case avxh:
1098 /* Register REGNUM has been updated. Return. */
1099 return;
31aeac78 1100 }
40936b0d
L
1101 }
1102 else
1103 {
1104 /* Return if REGNUM isn't changed. */
1105 if (regclass != all)
1106 return;
1107 }
31aeac78
L
1108 }
1109
1110 /* Only handle x87 control registers. */
1111 for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
1112 if (regnum == -1 || regnum == i)
1113 {
1114 /* Most of the FPU control registers occupy only 16 bits in
1115 the xsave extended state. Give those a special treatment. */
1116 if (i != I387_FIOFF_REGNUM (tdep)
1117 && i != I387_FOOFF_REGNUM (tdep))
1118 {
1119 gdb_byte buf[4];
1120
1121 regcache_raw_collect (regcache, i, buf);
1122
20a6ec49 1123 if (i == I387_FOP_REGNUM (tdep))
e750d25e
JT
1124 {
1125 /* The opcode occupies only 11 bits. Make sure we
40936b0d 1126 don't touch the other bits. */
e750d25e 1127 buf[1] &= ((1 << 3) - 1);
20a6ec49 1128 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
e750d25e 1129 }
20a6ec49 1130 else if (i == I387_FTAG_REGNUM (tdep))
e750d25e
JT
1131 {
1132 /* Converting back is much easier. */
1133
1134 unsigned short ftag;
1135 int fpreg;
1136
1137 ftag = (buf[1] << 8) | buf[0];
1138 buf[0] = 0;
1139 buf[1] = 0;
1140
1141 for (fpreg = 7; fpreg >= 0; fpreg--)
1142 {
1143 int tag = (ftag >> (fpreg * 2)) & 3;
1144
1145 if (tag != 3)
1146 buf[0] |= (1 << fpreg);
1147 }
1148 }
20a6ec49 1149 memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
e750d25e
JT
1150 }
1151 else
20a6ec49 1152 regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
e750d25e 1153 }
5716833c 1154
20a6ec49
MD
1155 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
1156 regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
5716833c 1157 FXSAVE_MXCSR_ADDR (regs));
e750d25e
JT
1158}
1159
1160/* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
1161 *RAW. */
1162
1163static int
b4ad899f 1164i387_tag (const gdb_byte *raw)
e750d25e
JT
1165{
1166 int integer;
1167 unsigned int exponent;
1168 unsigned long fraction[2];
1169
1170 integer = raw[7] & 0x80;
1171 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
1172 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
1173 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
1174 | (raw[5] << 8) | raw[4]);
1175
1176 if (exponent == 0x7fff)
1177 {
1178 /* Special. */
1179 return (2);
1180 }
1181 else if (exponent == 0x0000)
1182 {
1183 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
1184 {
1185 /* Zero. */
1186 return (1);
1187 }
1188 else
1189 {
1190 /* Special. */
1191 return (2);
1192 }
1193 }
1194 else
1195 {
1196 if (integer)
1197 {
1198 /* Valid. */
1199 return (0);
1200 }
1201 else
1202 {
1203 /* Special. */
1204 return (2);
1205 }
1206 }
1207}
efb1c01c
MK
1208
1209/* Prepare the FPU stack in REGCACHE for a function return. */
1210
1211void
1212i387_return_value (struct gdbarch *gdbarch, struct regcache *regcache)
1213{
1214 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1215 ULONGEST fstat;
1216
efb1c01c
MK
1217 /* Set the top of the floating-point register stack to 7. The
1218 actual value doesn't really matter, but 7 is what a normal
1219 function return would end up with if the program started out with
1220 a freshly initialized FPU. */
20a6ec49 1221 regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM (tdep), &fstat);
efb1c01c 1222 fstat |= (7 << 11);
20a6ec49 1223 regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM (tdep), fstat);
efb1c01c
MK
1224
1225 /* Mark %st(1) through %st(7) as empty. Since we set the top of the
1226 floating-point register stack to 7, the appropriate value for the
1227 tag word is 0x3fff. */
20a6ec49 1228 regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM (tdep), 0x3fff);
efb1c01c 1229
efb1c01c 1230}
This page took 0.913388 seconds and 4 git commands to generate.