1 /* Intel 387 floating point stuff.
3 Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000, 2001,
4 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
5 Free Software Foundation, Inc.
7 This file is part of GDB.
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
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
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.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include "floatformat.h"
32 #include "gdb_assert.h"
33 #include "gdb_string.h"
35 #include "i386-tdep.h"
36 #include "i387-tdep.h"
37 #include "i386-xstate.h"
39 /* Print the floating point number specified by RAW. */
42 print_i387_value (struct gdbarch
*gdbarch
,
43 const gdb_byte
*raw
, struct ui_file
*file
)
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. */
51 value
= extract_typed_floating (raw
, i387_ext_type (gdbarch
));
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
58 fprintf_filtered (file
, " %-+27.19Lg", (long double) value
);
60 fprintf_filtered (file
, " %-+27.19g", (double) value
);
64 /* Print the classification for the register contents RAW. */
67 print_i387_ext (struct gdbarch
*gdbarch
,
68 const gdb_byte
*raw
, struct ui_file
*file
)
72 unsigned int exponent
;
73 unsigned long fraction
[2];
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]);
82 if (exponent
== 0x7fff && integer
)
84 if (fraction
[0] == 0x00000000 && fraction
[1] == 0x00000000)
86 fprintf_filtered (file
, " %cInf", (sign
? '-' : '+'));
87 else if (sign
&& fraction
[0] == 0x00000000 && fraction
[1] == 0x40000000)
88 /* Real Indefinite (QNaN). */
89 fputs_unfiltered (" Real Indefinite (QNaN)", file
);
90 else if (fraction
[1] & 0x40000000)
92 fputs_filtered (" QNaN", file
);
95 fputs_filtered (" SNaN", file
);
97 else if (exponent
< 0x7fff && exponent
> 0x0000 && integer
)
99 print_i387_value (gdbarch
, raw
, file
);
100 else if (exponent
== 0x0000)
102 /* Denormal or zero. */
103 print_i387_value (gdbarch
, raw
, file
);
106 /* Pseudo-denormal. */
107 fputs_filtered (" Pseudo-denormal", file
);
108 else if (fraction
[0] || fraction
[1])
110 fputs_filtered (" Denormal", file
);
114 fputs_filtered (" Unsupported", file
);
117 /* Print the status word STATUS. */
120 print_i387_status_word (unsigned int status
, struct ui_file
*file
)
122 fprintf_filtered (file
, "Status Word: %s",
123 hex_string_custom (status
, 4));
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" : " ");
141 fputs_filtered ("\n", file
);
143 fprintf_filtered (file
,
144 " TOP: %d\n", ((status
>> 11) & 7));
147 /* Print the control word CONTROL. */
150 print_i387_control_word (unsigned int control
, struct ui_file
*file
)
152 fprintf_filtered (file
, "Control Word: %s",
153 hex_string_custom (control
, 4));
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" : " ");
162 fputs_filtered ("\n", file
);
164 fputs_filtered (" PC: ", file
);
165 switch ((control
>> 8) & 3)
168 fputs_filtered ("Single Precision (24-bits)\n", file
);
171 fputs_filtered ("Reserved\n", file
);
174 fputs_filtered ("Double Precision (53-bits)\n", file
);
177 fputs_filtered ("Extended Precision (64-bits)\n", file
);
181 fputs_filtered (" RC: ", file
);
182 switch ((control
>> 10) & 3)
185 fputs_filtered ("Round to nearest\n", file
);
188 fputs_filtered ("Round down\n", file
);
191 fputs_filtered ("Round up\n", file
);
194 fputs_filtered ("Round toward zero\n", file
);
199 /* Print out the i387 floating point state. Note that we ignore FRAME
200 in the code below. That's OK since floating-point registers are
201 never saved on the stack. */
204 i387_print_float_info (struct gdbarch
*gdbarch
, struct ui_file
*file
,
205 struct frame_info
*frame
, const char *args
)
207 struct gdbarch_tdep
*tdep
= gdbarch_tdep (get_frame_arch (frame
));
220 gdb_assert (gdbarch
== get_frame_arch (frame
));
222 fctrl
= get_frame_register_unsigned (frame
, I387_FCTRL_REGNUM (tdep
));
223 fstat
= get_frame_register_unsigned (frame
, I387_FSTAT_REGNUM (tdep
));
224 ftag
= get_frame_register_unsigned (frame
, I387_FTAG_REGNUM (tdep
));
225 fiseg
= get_frame_register_unsigned (frame
, I387_FISEG_REGNUM (tdep
));
226 fioff
= get_frame_register_unsigned (frame
, I387_FIOFF_REGNUM (tdep
));
227 foseg
= get_frame_register_unsigned (frame
, I387_FOSEG_REGNUM (tdep
));
228 fooff
= get_frame_register_unsigned (frame
, I387_FOOFF_REGNUM (tdep
));
229 fop
= get_frame_register_unsigned (frame
, I387_FOP_REGNUM (tdep
));
231 top
= ((fstat
>> 11) & 7);
233 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
235 gdb_byte raw
[I386_MAX_REGISTER_SIZE
];
236 int tag
= (ftag
>> (fpreg
* 2)) & 3;
239 fprintf_filtered (file
, "%sR%d: ", fpreg
== top
? "=>" : " ", fpreg
);
244 fputs_filtered ("Valid ", file
);
247 fputs_filtered ("Zero ", file
);
250 fputs_filtered ("Special ", file
);
253 fputs_filtered ("Empty ", file
);
257 get_frame_register (frame
, (fpreg
+ 8 - top
) % 8 + I387_ST0_REGNUM (tdep
),
260 fputs_filtered ("0x", file
);
261 for (i
= 9; i
>= 0; i
--)
262 fprintf_filtered (file
, "%02x", raw
[i
]);
265 print_i387_ext (gdbarch
, raw
, file
);
267 fputs_filtered ("\n", file
);
270 fputs_filtered ("\n", file
);
272 print_i387_status_word (fstat
, file
);
273 print_i387_control_word (fctrl
, file
);
274 fprintf_filtered (file
, "Tag Word: %s\n",
275 hex_string_custom (ftag
, 4));
276 fprintf_filtered (file
, "Instruction Pointer: %s:",
277 hex_string_custom (fiseg
, 2));
278 fprintf_filtered (file
, "%s\n", hex_string_custom (fioff
, 8));
279 fprintf_filtered (file
, "Operand Pointer: %s:",
280 hex_string_custom (foseg
, 2));
281 fprintf_filtered (file
, "%s\n", hex_string_custom (fooff
, 8));
282 fprintf_filtered (file
, "Opcode: %s\n",
283 hex_string_custom (fop
? (fop
| 0xd800) : 0, 4));
287 /* Return nonzero if a value of type TYPE stored in register REGNUM
288 needs any special handling. */
291 i387_convert_register_p (struct gdbarch
*gdbarch
, int regnum
, struct type
*type
)
293 if (i386_fp_regnum_p (gdbarch
, regnum
))
295 /* Floating point registers must be converted unless we are
296 accessing them in their hardware type. */
297 if (type
== i387_ext_type (gdbarch
))
306 /* Read a value of type TYPE from register REGNUM in frame FRAME, and
307 return its contents in TO. */
310 i387_register_to_value (struct frame_info
*frame
, int regnum
,
311 struct type
*type
, gdb_byte
*to
)
313 struct gdbarch
*gdbarch
= get_frame_arch (frame
);
314 gdb_byte from
[I386_MAX_REGISTER_SIZE
];
316 gdb_assert (i386_fp_regnum_p (gdbarch
, regnum
));
318 /* We only support floating-point values. */
319 if (TYPE_CODE (type
) != TYPE_CODE_FLT
)
321 warning (_("Cannot convert floating-point register value "
322 "to non-floating-point type."));
326 /* Convert to TYPE. */
327 get_frame_register (frame
, regnum
, from
);
328 convert_typed_floating (from
, i387_ext_type (gdbarch
), to
, type
);
331 /* Write the contents FROM of a value of type TYPE into register
332 REGNUM in frame FRAME. */
335 i387_value_to_register (struct frame_info
*frame
, int regnum
,
336 struct type
*type
, const gdb_byte
*from
)
338 struct gdbarch
*gdbarch
= get_frame_arch (frame
);
339 gdb_byte to
[I386_MAX_REGISTER_SIZE
];
341 gdb_assert (i386_fp_regnum_p (gdbarch
, regnum
));
343 /* We only support floating-point values. */
344 if (TYPE_CODE (type
) != TYPE_CODE_FLT
)
346 warning (_("Cannot convert non-floating-point type "
347 "to floating-point register value."));
351 /* Convert from TYPE. */
352 convert_typed_floating (from
, type
, to
, i387_ext_type (gdbarch
));
353 put_frame_register (frame
, regnum
, to
);
357 /* Handle FSAVE and FXSAVE formats. */
359 /* At fsave_offset[REGNUM] you'll find the offset to the location in
360 the data structure used by the "fsave" instruction where GDB
361 register REGNUM is stored. */
363 static int fsave_offset
[] =
365 28 + 0 * 10, /* %st(0) ... */
372 28 + 7 * 10, /* ... %st(7). */
373 0, /* `fctrl' (16 bits). */
374 4, /* `fstat' (16 bits). */
375 8, /* `ftag' (16 bits). */
376 16, /* `fiseg' (16 bits). */
378 24, /* `foseg' (16 bits). */
380 18 /* `fop' (bottom 11 bits). */
383 #define FSAVE_ADDR(tdep, fsave, regnum) \
384 (fsave + fsave_offset[regnum - I387_ST0_REGNUM (tdep)])
387 /* Fill register REGNUM in REGCACHE with the appropriate value from
388 *FSAVE. This function masks off any of the reserved bits in
392 i387_supply_fsave (struct regcache
*regcache
, int regnum
, const void *fsave
)
394 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
395 struct gdbarch_tdep
*tdep
= gdbarch_tdep (gdbarch
);
396 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
397 const gdb_byte
*regs
= fsave
;
400 gdb_assert (tdep
->st0_regnum
>= I386_ST0_REGNUM
);
402 for (i
= I387_ST0_REGNUM (tdep
); i
< I387_XMM0_REGNUM (tdep
); i
++)
403 if (regnum
== -1 || regnum
== i
)
407 regcache_raw_supply (regcache
, i
, NULL
);
411 /* Most of the FPU control registers occupy only 16 bits in the
412 fsave area. Give those a special treatment. */
413 if (i
>= I387_FCTRL_REGNUM (tdep
)
414 && i
!= I387_FIOFF_REGNUM (tdep
) && i
!= I387_FOOFF_REGNUM (tdep
))
418 memcpy (val
, FSAVE_ADDR (tdep
, regs
, i
), 2);
420 if (i
== I387_FOP_REGNUM (tdep
))
421 val
[1] &= ((1 << 3) - 1);
422 regcache_raw_supply (regcache
, i
, val
);
425 regcache_raw_supply (regcache
, i
, FSAVE_ADDR (tdep
, regs
, i
));
428 /* Provide dummy values for the SSE registers. */
429 for (i
= I387_XMM0_REGNUM (tdep
); i
< I387_MXCSR_REGNUM (tdep
); i
++)
430 if (regnum
== -1 || regnum
== i
)
431 regcache_raw_supply (regcache
, i
, NULL
);
432 if (regnum
== -1 || regnum
== I387_MXCSR_REGNUM (tdep
))
436 store_unsigned_integer (buf
, 4, byte_order
, 0x1f80);
437 regcache_raw_supply (regcache
, I387_MXCSR_REGNUM (tdep
), buf
);
441 /* Fill register REGNUM (if it is a floating-point register) in *FSAVE
442 with the value from REGCACHE. If REGNUM is -1, do this for all
443 registers. This function doesn't touch any of the reserved bits in
447 i387_collect_fsave (const struct regcache
*regcache
, int regnum
, void *fsave
)
449 struct gdbarch_tdep
*tdep
= gdbarch_tdep (get_regcache_arch (regcache
));
450 gdb_byte
*regs
= fsave
;
453 gdb_assert (tdep
->st0_regnum
>= I386_ST0_REGNUM
);
455 for (i
= I387_ST0_REGNUM (tdep
); i
< I387_XMM0_REGNUM (tdep
); i
++)
456 if (regnum
== -1 || regnum
== i
)
458 /* Most of the FPU control registers occupy only 16 bits in
459 the fsave area. Give those a special treatment. */
460 if (i
>= I387_FCTRL_REGNUM (tdep
)
461 && i
!= I387_FIOFF_REGNUM (tdep
) && i
!= I387_FOOFF_REGNUM (tdep
))
465 regcache_raw_collect (regcache
, i
, buf
);
467 if (i
== I387_FOP_REGNUM (tdep
))
469 /* The opcode occupies only 11 bits. Make sure we
470 don't touch the other bits. */
471 buf
[1] &= ((1 << 3) - 1);
472 buf
[1] |= ((FSAVE_ADDR (tdep
, regs
, i
))[1] & ~((1 << 3) - 1));
474 memcpy (FSAVE_ADDR (tdep
, regs
, i
), buf
, 2);
477 regcache_raw_collect (regcache
, i
, FSAVE_ADDR (tdep
, regs
, i
));
482 /* At fxsave_offset[REGNUM] you'll find the offset to the location in
483 the data structure used by the "fxsave" instruction where GDB
484 register REGNUM is stored. */
486 static int fxsave_offset
[] =
488 32, /* %st(0) through ... */
495 144, /* ... %st(7) (80 bits each). */
496 0, /* `fctrl' (16 bits). */
497 2, /* `fstat' (16 bits). */
498 4, /* `ftag' (16 bits). */
499 12, /* `fiseg' (16 bits). */
501 20, /* `foseg' (16 bits). */
503 6, /* `fop' (bottom 11 bits). */
504 160 + 0 * 16, /* %xmm0 through ... */
519 160 + 15 * 16, /* ... %xmm15 (128 bits each). */
522 #define FXSAVE_ADDR(tdep, fxsave, regnum) \
523 (fxsave + fxsave_offset[regnum - I387_ST0_REGNUM (tdep)])
525 /* We made an unfortunate choice in putting %mxcsr after the SSE
526 registers %xmm0-%xmm7 instead of before, since it makes supporting
527 the registers %xmm8-%xmm15 on AMD64 a bit involved. Therefore we
528 don't include the offset for %mxcsr here above. */
530 #define FXSAVE_MXCSR_ADDR(fxsave) (fxsave + 24)
532 static int i387_tag (const gdb_byte
*raw
);
535 /* Fill register REGNUM in REGCACHE with the appropriate
536 floating-point or SSE register value from *FXSAVE. This function
537 masks off any of the reserved bits in *FXSAVE. */
540 i387_supply_fxsave (struct regcache
*regcache
, int regnum
, const void *fxsave
)
542 struct gdbarch_tdep
*tdep
= gdbarch_tdep (get_regcache_arch (regcache
));
543 const gdb_byte
*regs
= fxsave
;
546 gdb_assert (tdep
->st0_regnum
>= I386_ST0_REGNUM
);
547 gdb_assert (tdep
->num_xmm_regs
> 0);
549 for (i
= I387_ST0_REGNUM (tdep
); i
< I387_MXCSR_REGNUM (tdep
); i
++)
550 if (regnum
== -1 || regnum
== i
)
554 regcache_raw_supply (regcache
, i
, NULL
);
558 /* Most of the FPU control registers occupy only 16 bits in
559 the fxsave area. Give those a special treatment. */
560 if (i
>= I387_FCTRL_REGNUM (tdep
) && i
< I387_XMM0_REGNUM (tdep
)
561 && i
!= I387_FIOFF_REGNUM (tdep
) && i
!= I387_FOOFF_REGNUM (tdep
))
565 memcpy (val
, FXSAVE_ADDR (tdep
, regs
, i
), 2);
567 if (i
== I387_FOP_REGNUM (tdep
))
568 val
[1] &= ((1 << 3) - 1);
569 else if (i
== I387_FTAG_REGNUM (tdep
))
571 /* The fxsave area contains a simplified version of
572 the tag word. We have to look at the actual 80-bit
573 FP data to recreate the traditional i387 tag word. */
575 unsigned long ftag
= 0;
579 top
= ((FXSAVE_ADDR (tdep
, regs
,
580 I387_FSTAT_REGNUM (tdep
)))[1] >> 3);
583 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
587 if (val
[0] & (1 << fpreg
))
589 int regnum
= (fpreg
+ 8 - top
) % 8
590 + I387_ST0_REGNUM (tdep
);
591 tag
= i387_tag (FXSAVE_ADDR (tdep
, regs
, regnum
));
596 ftag
|= tag
<< (2 * fpreg
);
598 val
[0] = ftag
& 0xff;
599 val
[1] = (ftag
>> 8) & 0xff;
601 regcache_raw_supply (regcache
, i
, val
);
604 regcache_raw_supply (regcache
, i
, FXSAVE_ADDR (tdep
, regs
, i
));
607 if (regnum
== I387_MXCSR_REGNUM (tdep
) || regnum
== -1)
610 regcache_raw_supply (regcache
, I387_MXCSR_REGNUM (tdep
), NULL
);
612 regcache_raw_supply (regcache
, I387_MXCSR_REGNUM (tdep
),
613 FXSAVE_MXCSR_ADDR (regs
));
617 /* Fill register REGNUM (if it is a floating-point or SSE register) in
618 *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for
619 all registers. This function doesn't touch any of the reserved
623 i387_collect_fxsave (const struct regcache
*regcache
, int regnum
, void *fxsave
)
625 struct gdbarch_tdep
*tdep
= gdbarch_tdep (get_regcache_arch (regcache
));
626 gdb_byte
*regs
= fxsave
;
629 gdb_assert (tdep
->st0_regnum
>= I386_ST0_REGNUM
);
630 gdb_assert (tdep
->num_xmm_regs
> 0);
632 for (i
= I387_ST0_REGNUM (tdep
); i
< I387_MXCSR_REGNUM (tdep
); i
++)
633 if (regnum
== -1 || regnum
== i
)
635 /* Most of the FPU control registers occupy only 16 bits in
636 the fxsave area. Give those a special treatment. */
637 if (i
>= I387_FCTRL_REGNUM (tdep
) && i
< I387_XMM0_REGNUM (tdep
)
638 && i
!= I387_FIOFF_REGNUM (tdep
) && i
!= I387_FOOFF_REGNUM (tdep
))
642 regcache_raw_collect (regcache
, i
, buf
);
644 if (i
== I387_FOP_REGNUM (tdep
))
646 /* The opcode occupies only 11 bits. Make sure we
647 don't touch the other bits. */
648 buf
[1] &= ((1 << 3) - 1);
649 buf
[1] |= ((FXSAVE_ADDR (tdep
, regs
, i
))[1] & ~((1 << 3) - 1));
651 else if (i
== I387_FTAG_REGNUM (tdep
))
653 /* Converting back is much easier. */
658 ftag
= (buf
[1] << 8) | buf
[0];
662 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
664 int tag
= (ftag
>> (fpreg
* 2)) & 3;
667 buf
[0] |= (1 << fpreg
);
670 memcpy (FXSAVE_ADDR (tdep
, regs
, i
), buf
, 2);
673 regcache_raw_collect (regcache
, i
, FXSAVE_ADDR (tdep
, regs
, i
));
676 if (regnum
== I387_MXCSR_REGNUM (tdep
) || regnum
== -1)
677 regcache_raw_collect (regcache
, I387_MXCSR_REGNUM (tdep
),
678 FXSAVE_MXCSR_ADDR (regs
));
681 /* `xstate_bv' is at byte offset 512. */
682 #define XSAVE_XSTATE_BV_ADDR(xsave) (xsave + 512)
684 /* At xsave_avxh_offset[REGNUM] you'll find the offset to the location in
685 the upper 128bit of AVX register data structure used by the "xsave"
686 instruction where GDB register REGNUM is stored. */
688 static int xsave_avxh_offset
[] =
690 576 + 0 * 16, /* Upper 128bit of %ymm0 through ... */
705 576 + 15 * 16 /* Upper 128bit of ... %ymm15 (128 bits each). */
708 #define XSAVE_AVXH_ADDR(tdep, xsave, regnum) \
709 (xsave + xsave_avxh_offset[regnum - I387_YMM0H_REGNUM (tdep)])
711 /* Similar to i387_supply_fxsave, but use XSAVE extended state. */
714 i387_supply_xsave (struct regcache
*regcache
, int regnum
,
717 struct gdbarch_tdep
*tdep
= gdbarch_tdep (get_regcache_arch (regcache
));
718 const gdb_byte
*regs
= xsave
;
720 unsigned int clear_bv
;
728 all
= x87
| sse
| avxh
731 gdb_assert (tdep
->st0_regnum
>= I386_ST0_REGNUM
);
732 gdb_assert (tdep
->num_xmm_regs
> 0);
736 else if (regnum
>= I387_YMM0H_REGNUM (tdep
)
737 && regnum
< I387_YMMENDH_REGNUM (tdep
))
739 else if (regnum
>= I387_XMM0_REGNUM(tdep
)
740 && regnum
< I387_MXCSR_REGNUM (tdep
))
742 else if (regnum
>= I387_ST0_REGNUM (tdep
)
743 && regnum
< I387_FCTRL_REGNUM (tdep
))
748 if (regs
!= NULL
&& regclass
!= none
)
750 /* Get `xstat_bv'. */
751 const gdb_byte
*xstate_bv_p
= XSAVE_XSTATE_BV_ADDR (regs
);
753 /* The supported bits in `xstat_bv' are 1 byte. Clear part in
754 vector registers if its bit in xstat_bv is zero. */
755 clear_bv
= (~(*xstate_bv_p
)) & tdep
->xcr0
;
758 clear_bv
= I386_XSTATE_AVX_MASK
;
766 if ((clear_bv
& I386_XSTATE_AVX
))
769 p
= XSAVE_AVXH_ADDR (tdep
, regs
, regnum
);
770 regcache_raw_supply (regcache
, regnum
, p
);
774 if ((clear_bv
& I386_XSTATE_SSE
))
777 p
= FXSAVE_ADDR (tdep
, regs
, regnum
);
778 regcache_raw_supply (regcache
, regnum
, p
);
782 if ((clear_bv
& I386_XSTATE_X87
))
785 p
= FXSAVE_ADDR (tdep
, regs
, regnum
);
786 regcache_raw_supply (regcache
, regnum
, p
);
790 /* Hanle the upper YMM registers. */
791 if ((tdep
->xcr0
& I386_XSTATE_AVX
))
793 if ((clear_bv
& I386_XSTATE_AVX
))
798 for (i
= I387_YMM0H_REGNUM (tdep
);
799 i
< I387_YMMENDH_REGNUM (tdep
); i
++)
802 p
= XSAVE_AVXH_ADDR (tdep
, regs
, i
);
803 regcache_raw_supply (regcache
, i
, p
);
807 /* Handle the XMM registers. */
808 if ((tdep
->xcr0
& I386_XSTATE_SSE
))
810 if ((clear_bv
& I386_XSTATE_SSE
))
815 for (i
= I387_XMM0_REGNUM (tdep
);
816 i
< I387_MXCSR_REGNUM (tdep
); i
++)
819 p
= FXSAVE_ADDR (tdep
, regs
, i
);
820 regcache_raw_supply (regcache
, i
, p
);
824 /* Handle the x87 registers. */
825 if ((tdep
->xcr0
& I386_XSTATE_X87
))
827 if ((clear_bv
& I386_XSTATE_X87
))
832 for (i
= I387_ST0_REGNUM (tdep
);
833 i
< I387_FCTRL_REGNUM (tdep
); i
++)
836 p
= FXSAVE_ADDR (tdep
, regs
, i
);
837 regcache_raw_supply (regcache
, i
, p
);
843 /* Only handle x87 control registers. */
844 for (i
= I387_FCTRL_REGNUM (tdep
); i
< I387_XMM0_REGNUM (tdep
); i
++)
845 if (regnum
== -1 || regnum
== i
)
849 regcache_raw_supply (regcache
, i
, NULL
);
853 /* Most of the FPU control registers occupy only 16 bits in
854 the xsave extended state. Give those a special treatment. */
855 if (i
!= I387_FIOFF_REGNUM (tdep
)
856 && i
!= I387_FOOFF_REGNUM (tdep
))
860 memcpy (val
, FXSAVE_ADDR (tdep
, regs
, i
), 2);
862 if (i
== I387_FOP_REGNUM (tdep
))
863 val
[1] &= ((1 << 3) - 1);
864 else if (i
== I387_FTAG_REGNUM (tdep
))
866 /* The fxsave area contains a simplified version of
867 the tag word. We have to look at the actual 80-bit
868 FP data to recreate the traditional i387 tag word. */
870 unsigned long ftag
= 0;
874 top
= ((FXSAVE_ADDR (tdep
, regs
,
875 I387_FSTAT_REGNUM (tdep
)))[1] >> 3);
878 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
882 if (val
[0] & (1 << fpreg
))
884 int regnum
= (fpreg
+ 8 - top
) % 8
885 + I387_ST0_REGNUM (tdep
);
886 tag
= i387_tag (FXSAVE_ADDR (tdep
, regs
, regnum
));
891 ftag
|= tag
<< (2 * fpreg
);
893 val
[0] = ftag
& 0xff;
894 val
[1] = (ftag
>> 8) & 0xff;
896 regcache_raw_supply (regcache
, i
, val
);
899 regcache_raw_supply (regcache
, i
, FXSAVE_ADDR (tdep
, regs
, i
));
902 if (regnum
== I387_MXCSR_REGNUM (tdep
) || regnum
== -1)
904 p
= regs
== NULL
? NULL
: FXSAVE_MXCSR_ADDR (regs
);
905 regcache_raw_supply (regcache
, I387_MXCSR_REGNUM (tdep
), p
);
909 /* Similar to i387_collect_fxsave, but use XSAVE extended state. */
912 i387_collect_xsave (const struct regcache
*regcache
, int regnum
,
913 void *xsave
, int gcore
)
915 struct gdbarch_tdep
*tdep
= gdbarch_tdep (get_regcache_arch (regcache
));
916 gdb_byte
*regs
= xsave
;
925 all
= x87
| sse
| avxh
928 gdb_assert (tdep
->st0_regnum
>= I386_ST0_REGNUM
);
929 gdb_assert (tdep
->num_xmm_regs
> 0);
933 else if (regnum
>= I387_YMM0H_REGNUM (tdep
)
934 && regnum
< I387_YMMENDH_REGNUM (tdep
))
936 else if (regnum
>= I387_XMM0_REGNUM(tdep
)
937 && regnum
< I387_MXCSR_REGNUM (tdep
))
939 else if (regnum
>= I387_ST0_REGNUM (tdep
)
940 && regnum
< I387_FCTRL_REGNUM (tdep
))
947 /* Clear XSAVE extended state. */
948 memset (regs
, 0, I386_XSTATE_SIZE (tdep
->xcr0
));
950 /* Update XCR0 and `xstate_bv' with XCR0 for gcore. */
951 if (tdep
->xsave_xcr0_offset
!= -1)
952 memcpy (regs
+ tdep
->xsave_xcr0_offset
, &tdep
->xcr0
, 8);
953 memcpy (XSAVE_XSTATE_BV_ADDR (regs
), &tdep
->xcr0
, 8);
956 if ((regclass
& check
))
958 gdb_byte raw
[I386_MAX_REGISTER_SIZE
];
959 gdb_byte
*xstate_bv_p
= XSAVE_XSTATE_BV_ADDR (regs
);
960 unsigned int xstate_bv
= 0;
961 /* The supported bits in `xstat_bv' are 1 byte. */
962 unsigned int clear_bv
= (~(*xstate_bv_p
)) & tdep
->xcr0
;
965 /* Clear register set if its bit in xstat_bv is zero. */
968 if ((clear_bv
& I386_XSTATE_AVX
))
969 for (i
= I387_YMM0H_REGNUM (tdep
);
970 i
< I387_YMMENDH_REGNUM (tdep
); i
++)
971 memset (XSAVE_AVXH_ADDR (tdep
, regs
, i
), 0, 16);
973 if ((clear_bv
& I386_XSTATE_SSE
))
974 for (i
= I387_XMM0_REGNUM (tdep
);
975 i
< I387_MXCSR_REGNUM (tdep
); i
++)
976 memset (FXSAVE_ADDR (tdep
, regs
, i
), 0, 16);
978 if ((clear_bv
& I386_XSTATE_X87
))
979 for (i
= I387_ST0_REGNUM (tdep
);
980 i
< I387_FCTRL_REGNUM (tdep
); i
++)
981 memset (FXSAVE_ADDR (tdep
, regs
, i
), 0, 10);
986 /* Check if any upper YMM registers are changed. */
987 if ((tdep
->xcr0
& I386_XSTATE_AVX
))
988 for (i
= I387_YMM0H_REGNUM (tdep
);
989 i
< I387_YMMENDH_REGNUM (tdep
); i
++)
991 regcache_raw_collect (regcache
, i
, raw
);
992 p
= XSAVE_AVXH_ADDR (tdep
, regs
, i
);
993 if (memcmp (raw
, p
, 16))
995 xstate_bv
|= I386_XSTATE_AVX
;
1000 /* Check if any SSE registers are changed. */
1001 if ((tdep
->xcr0
& I386_XSTATE_SSE
))
1002 for (i
= I387_XMM0_REGNUM (tdep
);
1003 i
< I387_MXCSR_REGNUM (tdep
); i
++)
1005 regcache_raw_collect (regcache
, i
, raw
);
1006 p
= FXSAVE_ADDR (tdep
, regs
, i
);
1007 if (memcmp (raw
, p
, 16))
1009 xstate_bv
|= I386_XSTATE_SSE
;
1010 memcpy (p
, raw
, 16);
1014 /* Check if any X87 registers are changed. */
1015 if ((tdep
->xcr0
& I386_XSTATE_X87
))
1016 for (i
= I387_ST0_REGNUM (tdep
);
1017 i
< I387_FCTRL_REGNUM (tdep
); i
++)
1019 regcache_raw_collect (regcache
, i
, raw
);
1020 p
= FXSAVE_ADDR (tdep
, regs
, i
);
1021 if (memcmp (raw
, p
, 10))
1023 xstate_bv
|= I386_XSTATE_X87
;
1024 memcpy (p
, raw
, 10);
1030 /* Check if REGNUM is changed. */
1031 regcache_raw_collect (regcache
, regnum
, raw
);
1036 internal_error (__FILE__
, __LINE__
,
1037 _("invalid i387 regclass"));
1040 /* This is an upper YMM register. */
1041 p
= XSAVE_AVXH_ADDR (tdep
, regs
, regnum
);
1042 if (memcmp (raw
, p
, 16))
1044 xstate_bv
|= I386_XSTATE_AVX
;
1045 memcpy (p
, raw
, 16);
1050 /* This is an SSE register. */
1051 p
= FXSAVE_ADDR (tdep
, regs
, regnum
);
1052 if (memcmp (raw
, p
, 16))
1054 xstate_bv
|= I386_XSTATE_SSE
;
1055 memcpy (p
, raw
, 16);
1060 /* This is an x87 register. */
1061 p
= FXSAVE_ADDR (tdep
, regs
, regnum
);
1062 if (memcmp (raw
, p
, 10))
1064 xstate_bv
|= I386_XSTATE_X87
;
1065 memcpy (p
, raw
, 10);
1071 /* Update the corresponding bits in `xstate_bv' if any SSE/AVX
1072 registers are changed. */
1075 /* The supported bits in `xstat_bv' are 1 byte. */
1076 *xstate_bv_p
|= (gdb_byte
) xstate_bv
;
1081 internal_error (__FILE__
, __LINE__
,
1082 _("invalid i387 regclass"));
1090 /* Register REGNUM has been updated. Return. */
1096 /* Return if REGNUM isn't changed. */
1097 if (regclass
!= all
)
1102 /* Only handle x87 control registers. */
1103 for (i
= I387_FCTRL_REGNUM (tdep
); i
< I387_XMM0_REGNUM (tdep
); i
++)
1104 if (regnum
== -1 || regnum
== i
)
1106 /* Most of the FPU control registers occupy only 16 bits in
1107 the xsave extended state. Give those a special treatment. */
1108 if (i
!= I387_FIOFF_REGNUM (tdep
)
1109 && i
!= I387_FOOFF_REGNUM (tdep
))
1113 regcache_raw_collect (regcache
, i
, buf
);
1115 if (i
== I387_FOP_REGNUM (tdep
))
1117 /* The opcode occupies only 11 bits. Make sure we
1118 don't touch the other bits. */
1119 buf
[1] &= ((1 << 3) - 1);
1120 buf
[1] |= ((FXSAVE_ADDR (tdep
, regs
, i
))[1] & ~((1 << 3) - 1));
1122 else if (i
== I387_FTAG_REGNUM (tdep
))
1124 /* Converting back is much easier. */
1126 unsigned short ftag
;
1129 ftag
= (buf
[1] << 8) | buf
[0];
1133 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
1135 int tag
= (ftag
>> (fpreg
* 2)) & 3;
1138 buf
[0] |= (1 << fpreg
);
1141 memcpy (FXSAVE_ADDR (tdep
, regs
, i
), buf
, 2);
1144 regcache_raw_collect (regcache
, i
, FXSAVE_ADDR (tdep
, regs
, i
));
1147 if (regnum
== I387_MXCSR_REGNUM (tdep
) || regnum
== -1)
1148 regcache_raw_collect (regcache
, I387_MXCSR_REGNUM (tdep
),
1149 FXSAVE_MXCSR_ADDR (regs
));
1152 /* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
1156 i387_tag (const gdb_byte
*raw
)
1159 unsigned int exponent
;
1160 unsigned long fraction
[2];
1162 integer
= raw
[7] & 0x80;
1163 exponent
= (((raw
[9] & 0x7f) << 8) | raw
[8]);
1164 fraction
[0] = ((raw
[3] << 24) | (raw
[2] << 16) | (raw
[1] << 8) | raw
[0]);
1165 fraction
[1] = (((raw
[7] & 0x7f) << 24) | (raw
[6] << 16)
1166 | (raw
[5] << 8) | raw
[4]);
1168 if (exponent
== 0x7fff)
1173 else if (exponent
== 0x0000)
1175 if (fraction
[0] == 0x0000 && fraction
[1] == 0x0000 && !integer
)
1201 /* Prepare the FPU stack in REGCACHE for a function return. */
1204 i387_return_value (struct gdbarch
*gdbarch
, struct regcache
*regcache
)
1206 struct gdbarch_tdep
*tdep
= gdbarch_tdep (gdbarch
);
1209 /* Set the top of the floating-point register stack to 7. The
1210 actual value doesn't really matter, but 7 is what a normal
1211 function return would end up with if the program started out with
1212 a freshly initialized FPU. */
1213 regcache_raw_read_unsigned (regcache
, I387_FSTAT_REGNUM (tdep
), &fstat
);
1215 regcache_raw_write_unsigned (regcache
, I387_FSTAT_REGNUM (tdep
), fstat
);
1217 /* Mark %st(1) through %st(7) as empty. Since we set the top of the
1218 floating-point register stack to 7, the appropriate value for the
1219 tag word is 0x3fff. */
1220 regcache_raw_write_unsigned (regcache
, I387_FTAG_REGNUM (tdep
), 0x3fff);
This page took 0.055127 seconds and 4 git commands to generate.