1 /* Intel 387 floating point stuff.
2 Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000,
3 2001, 2002 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
28 #include "floatformat.h"
30 #include "gdb_assert.h"
33 #include "i386-tdep.h"
35 /* FIXME: Eliminate the next two functions when we have the time to
36 change all the callers. */
38 void i387_to_double (char *from
, char *to
);
39 void double_to_i387 (char *from
, char *to
);
42 i387_to_double (char *from
, char *to
)
44 floatformat_to_double (&floatformat_i387_ext
, from
, (double *) to
);
48 double_to_i387 (char *from
, char *to
)
50 floatformat_from_double (&floatformat_i387_ext
, (double *) from
, to
);
54 /* FIXME: The functions on this page are used by the old `info float'
55 implementations that a few of the i386 targets provide. These
56 functions should be removed if all of these have been converted to
57 use the generic implementation based on the new register file
60 static void print_387_control_bits (unsigned int control
);
61 static void print_387_status_bits (unsigned int status
);
64 print_387_control_bits (unsigned int control
)
66 switch ((control
>> 8) & 3)
69 puts_unfiltered (" 24 bit; ");
72 puts_unfiltered (" (bad); ");
75 puts_unfiltered (" 53 bit; ");
78 puts_unfiltered (" 64 bit; ");
81 switch ((control
>> 10) & 3)
84 puts_unfiltered ("NEAR; ");
87 puts_unfiltered ("DOWN; ");
90 puts_unfiltered ("UP; ");
93 puts_unfiltered ("CHOP; ");
98 puts_unfiltered ("mask");
100 puts_unfiltered (" INVAL");
101 if (control
& 0x0002)
102 puts_unfiltered (" DENOR");
103 if (control
& 0x0004)
104 puts_unfiltered (" DIVZ");
105 if (control
& 0x0008)
106 puts_unfiltered (" OVERF");
107 if (control
& 0x0010)
108 puts_unfiltered (" UNDER");
109 if (control
& 0x0020)
110 puts_unfiltered (" LOS");
111 puts_unfiltered (";");
114 if (control
& 0xe080)
115 warning ("\nreserved bits on: %s",
116 local_hex_string (control
& 0xe080));
120 print_387_control_word (unsigned int control
)
122 printf_filtered ("control %s:", local_hex_string(control
& 0xffff));
123 print_387_control_bits (control
);
124 puts_unfiltered ("\n");
128 print_387_status_bits (unsigned int status
)
130 printf_unfiltered (" flags %d%d%d%d; ",
131 (status
& 0x4000) != 0,
132 (status
& 0x0400) != 0,
133 (status
& 0x0200) != 0,
134 (status
& 0x0100) != 0);
135 printf_unfiltered ("top %d; ", (status
>> 11) & 7);
138 puts_unfiltered ("excep");
139 if (status
& 0x0001) puts_unfiltered (" INVAL");
140 if (status
& 0x0002) puts_unfiltered (" DENOR");
141 if (status
& 0x0004) puts_unfiltered (" DIVZ");
142 if (status
& 0x0008) puts_unfiltered (" OVERF");
143 if (status
& 0x0010) puts_unfiltered (" UNDER");
144 if (status
& 0x0020) puts_unfiltered (" LOS");
145 if (status
& 0x0040) puts_unfiltered (" STACK");
150 print_387_status_word (unsigned int status
)
152 printf_filtered ("status %s:", local_hex_string (status
& 0xffff));
153 print_387_status_bits (status
);
154 puts_unfiltered ("\n");
158 /* Implement the `info float' layout based on the register definitions
161 /* Print the floating point number specified by RAW. */
163 print_i387_value (char *raw
, struct ui_file
*file
)
167 /* Using extract_typed_floating here might affect the representation
168 of certain numbers such as NaNs, even if GDB is running natively.
169 This is fine since our caller already detects such special
170 numbers and we print the hexadecimal representation anyway. */
171 value
= extract_typed_floating (raw
, builtin_type_i387_ext
);
173 /* We try to print 19 digits. The last digit may or may not contain
174 garbage, but we'd better print one too many. We need enough room
175 to print the value, 1 position for the sign, 1 for the decimal
176 point, 19 for the digits and 6 for the exponent adds up to 27. */
177 #ifdef PRINTF_HAS_LONG_DOUBLE
178 fprintf_filtered (file
, " %-+27.19Lg", (long double) value
);
180 fprintf_filtered (file
, " %-+27.19g", (double) value
);
184 /* Print the classification for the register contents RAW. */
186 print_i387_ext (unsigned char *raw
, struct ui_file
*file
)
190 unsigned int exponent
;
191 unsigned long fraction
[2];
193 sign
= raw
[9] & 0x80;
194 integer
= raw
[7] & 0x80;
195 exponent
= (((raw
[9] & 0x7f) << 8) | raw
[8]);
196 fraction
[0] = ((raw
[3] << 24) | (raw
[2] << 16) | (raw
[1] << 8) | raw
[0]);
197 fraction
[1] = (((raw
[7] & 0x7f) << 24) | (raw
[6] << 16)
198 | (raw
[5] << 8) | raw
[4]);
200 if (exponent
== 0x7fff && integer
)
202 if (fraction
[0] == 0x00000000 && fraction
[1] == 0x00000000)
204 fprintf_filtered (file
, " %cInf", (sign
? '-' : '+'));
205 else if (sign
&& fraction
[0] == 0x00000000 && fraction
[1] == 0x40000000)
206 /* Real Indefinite (QNaN). */
207 fputs_unfiltered (" Real Indefinite (QNaN)", file
);
208 else if (fraction
[1] & 0x40000000)
210 fputs_filtered (" QNaN", file
);
213 fputs_filtered (" SNaN", file
);
215 else if (exponent
< 0x7fff && exponent
> 0x0000 && integer
)
217 print_i387_value (raw
, file
);
218 else if (exponent
== 0x0000)
220 /* Denormal or zero. */
221 print_i387_value (raw
, file
);
224 /* Pseudo-denormal. */
225 fputs_filtered (" Pseudo-denormal", file
);
226 else if (fraction
[0] || fraction
[1])
228 fputs_filtered (" Denormal", file
);
232 fputs_filtered (" Unsupported", file
);
235 /* Print the status word STATUS. */
237 print_i387_status_word (unsigned int status
, struct ui_file
*file
)
239 fprintf_filtered (file
, "Status Word: %s",
240 local_hex_string_custom (status
, "04"));
241 fputs_filtered (" ", file
);
242 fprintf_filtered (file
, " %s", (status
& 0x0001) ? "IE" : " ");
243 fprintf_filtered (file
, " %s", (status
& 0x0002) ? "DE" : " ");
244 fprintf_filtered (file
, " %s", (status
& 0x0004) ? "ZE" : " ");
245 fprintf_filtered (file
, " %s", (status
& 0x0008) ? "OE" : " ");
246 fprintf_filtered (file
, " %s", (status
& 0x0010) ? "UE" : " ");
247 fprintf_filtered (file
, " %s", (status
& 0x0020) ? "PE" : " ");
248 fputs_filtered (" ", file
);
249 fprintf_filtered (file
, " %s", (status
& 0x0080) ? "ES" : " ");
250 fputs_filtered (" ", file
);
251 fprintf_filtered (file
, " %s", (status
& 0x0040) ? "SF" : " ");
252 fputs_filtered (" ", file
);
253 fprintf_filtered (file
, " %s", (status
& 0x0100) ? "C0" : " ");
254 fprintf_filtered (file
, " %s", (status
& 0x0200) ? "C1" : " ");
255 fprintf_filtered (file
, " %s", (status
& 0x0400) ? "C2" : " ");
256 fprintf_filtered (file
, " %s", (status
& 0x4000) ? "C3" : " ");
258 fputs_filtered ("\n", file
);
260 fprintf_filtered (file
,
261 " TOP: %d\n", ((status
>> 11) & 7));
264 /* Print the control word CONTROL. */
266 print_i387_control_word (unsigned int control
, struct ui_file
*file
)
268 fprintf_filtered (file
, "Control Word: %s",
269 local_hex_string_custom (control
, "04"));
270 fputs_filtered (" ", file
);
271 fprintf_filtered (file
, " %s", (control
& 0x0001) ? "IM" : " ");
272 fprintf_filtered (file
, " %s", (control
& 0x0002) ? "DM" : " ");
273 fprintf_filtered (file
, " %s", (control
& 0x0004) ? "ZM" : " ");
274 fprintf_filtered (file
, " %s", (control
& 0x0008) ? "OM" : " ");
275 fprintf_filtered (file
, " %s", (control
& 0x0010) ? "UM" : " ");
276 fprintf_filtered (file
, " %s", (control
& 0x0020) ? "PM" : " ");
278 fputs_filtered ("\n", file
);
280 fputs_filtered (" PC: ", file
);
281 switch ((control
>> 8) & 3)
284 fputs_filtered ("Single Precision (24-bits)\n", file
);
287 fputs_filtered ("Reserved\n", file
);
290 fputs_filtered ("Double Precision (53-bits)\n", file
);
293 fputs_filtered ("Extended Precision (64-bits)\n", file
);
297 fputs_filtered (" RC: ", file
);
298 switch ((control
>> 10) & 3)
301 fputs_filtered ("Round to nearest\n", file
);
304 fputs_filtered ("Round down\n", file
);
307 fputs_filtered ("Round up\n", file
);
310 fputs_filtered ("Round toward zero\n", file
);
315 /* Print out the i387 floating poin state. */
317 i387_print_float_info (struct gdbarch
*gdbarch
, struct ui_file
*file
,
318 struct frame_info
*frame
)
331 fctrl
= read_register (FCTRL_REGNUM
);
332 fstat
= read_register (FSTAT_REGNUM
);
333 ftag
= read_register (FTAG_REGNUM
);
334 fiseg
= read_register (FCS_REGNUM
);
335 fioff
= read_register (FCOFF_REGNUM
);
336 foseg
= read_register (FDS_REGNUM
);
337 fooff
= read_register (FDOFF_REGNUM
);
338 fop
= read_register (FOP_REGNUM
);
340 top
= ((fstat
>> 11) & 7);
342 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
344 unsigned char raw
[FPU_REG_RAW_SIZE
];
345 int tag
= (ftag
>> (fpreg
* 2)) & 3;
348 fprintf_filtered (file
, "%sR%d: ", fpreg
== top
? "=>" : " ", fpreg
);
353 fputs_filtered ("Valid ", file
);
356 fputs_filtered ("Zero ", file
);
359 fputs_filtered ("Special ", file
);
362 fputs_filtered ("Empty ", file
);
366 read_register_gen ((fpreg
+ 8 - top
) % 8 + FP0_REGNUM
, raw
);
368 fputs_filtered ("0x", file
);
369 for (i
= 9; i
>= 0; i
--)
370 fprintf_filtered (file
, "%02x", raw
[i
]);
373 print_i387_ext (raw
, file
);
375 fputs_filtered ("\n", file
);
378 puts_filtered ("\n");
380 print_i387_status_word (fstat
, file
);
381 print_i387_control_word (fctrl
, file
);
382 fprintf_filtered (file
, "Tag Word: %s\n",
383 local_hex_string_custom (ftag
, "04"));
384 fprintf_filtered (file
, "Instruction Pointer: %s:",
385 local_hex_string_custom (fiseg
, "02"));
386 fprintf_filtered (file
, "%s\n", local_hex_string_custom (fioff
, "08"));
387 fprintf_filtered (file
, "Operand Pointer: %s:",
388 local_hex_string_custom (foseg
, "02"));
389 fprintf_filtered (file
, "%s\n", local_hex_string_custom (fooff
, "08"));
390 fprintf_filtered (file
, "Opcode: %s\n",
391 local_hex_string_custom (fop
? (fop
| 0xd800) : 0, "04"));
394 /* FIXME: kettenis/2000-05-21: Right now more than a few i386 targets
395 define their own routines to manage the floating-point registers in
396 GDB's register array. Most (if not all) of these targets use the
397 format used by the "fsave" instruction in their communication with
398 the OS. They should all be converted to use the routines below. */
400 /* At fsave_offset[REGNUM] you'll find the offset to the location in
401 the data structure used by the "fsave" instruction where GDB
402 register REGNUM is stored. */
404 static int fsave_offset
[] =
406 28 + 0 * FPU_REG_RAW_SIZE
, /* FP0_REGNUM through ... */
407 28 + 1 * FPU_REG_RAW_SIZE
,
408 28 + 2 * FPU_REG_RAW_SIZE
,
409 28 + 3 * FPU_REG_RAW_SIZE
,
410 28 + 4 * FPU_REG_RAW_SIZE
,
411 28 + 5 * FPU_REG_RAW_SIZE
,
412 28 + 6 * FPU_REG_RAW_SIZE
,
413 28 + 7 * FPU_REG_RAW_SIZE
, /* ... FP7_REGNUM. */
414 0, /* FCTRL_REGNUM (16 bits). */
415 4, /* FSTAT_REGNUM (16 bits). */
416 8, /* FTAG_REGNUM (16 bits). */
417 16, /* FISEG_REGNUM (16 bits). */
418 12, /* FIOFF_REGNUM. */
419 24, /* FOSEG_REGNUM. */
420 20, /* FOOFF_REGNUM. */
421 18 /* FOP_REGNUM (bottom 11 bits). */
424 #define FSAVE_ADDR(fsave, regnum) (fsave + fsave_offset[regnum - FP0_REGNUM])
427 /* Fill register REGNUM in GDB's register array with the appropriate
428 value from *FSAVE. This function masks off any of the reserved
432 i387_supply_register (int regnum
, char *fsave
)
434 /* Most of the FPU control registers occupy only 16 bits in
435 the fsave area. Give those a special treatment. */
436 if (regnum
>= FPC_REGNUM
437 && regnum
!= FIOFF_REGNUM
&& regnum
!= FOOFF_REGNUM
)
439 unsigned char val
[4];
441 memcpy (val
, FSAVE_ADDR (fsave
, regnum
), 2);
443 if (regnum
== FOP_REGNUM
)
444 val
[1] &= ((1 << 3) - 1);
445 supply_register (regnum
, val
);
448 supply_register (regnum
, FSAVE_ADDR (fsave
, regnum
));
451 /* Fill GDB's register array with the floating-point register values
452 in *FSAVE. This function masks off any of the reserved
456 i387_supply_fsave (char *fsave
)
460 for (i
= FP0_REGNUM
; i
< XMM0_REGNUM
; i
++)
461 i387_supply_register (i
, fsave
);
464 /* Fill register REGNUM (if it is a floating-point register) in *FSAVE
465 with the value in GDB's register array. If REGNUM is -1, do this
466 for all registers. This function doesn't touch any of the reserved
470 i387_fill_fsave (char *fsave
, int regnum
)
474 for (i
= FP0_REGNUM
; i
< XMM0_REGNUM
; i
++)
475 if (regnum
== -1 || regnum
== i
)
477 /* Most of the FPU control registers occupy only 16 bits in
478 the fsave area. Give those a special treatment. */
480 && i
!= FIOFF_REGNUM
&& i
!= FOOFF_REGNUM
)
482 unsigned char buf
[4];
484 regcache_collect (i
, buf
);
488 /* The opcode occupies only 11 bits. Make sure we
489 don't touch the other bits. */
490 buf
[1] &= ((1 << 3) - 1);
491 buf
[1] |= ((FSAVE_ADDR (fsave
, i
))[1] & ~((1 << 3) - 1));
493 memcpy (FSAVE_ADDR (fsave
, i
), buf
, 2);
496 regcache_collect (i
, FSAVE_ADDR (fsave
, i
));
501 /* At fxsave_offset[REGNUM] you'll find the offset to the location in
502 the data structure used by the "fxsave" instruction where GDB
503 register REGNUM is stored. */
505 static int fxsave_offset
[] =
507 32, /* FP0_REGNUM through ... */
514 144, /* ... FP7_REGNUM (80 bits each). */
515 0, /* FCTRL_REGNUM (16 bits). */
516 2, /* FSTAT_REGNUM (16 bits). */
517 4, /* FTAG_REGNUM (16 bits). */
518 12, /* FISEG_REGNUM (16 bits). */
519 8, /* FIOFF_REGNUM. */
520 20, /* FOSEG_REGNUM (16 bits). */
521 16, /* FOOFF_REGNUM. */
522 6, /* FOP_REGNUM (bottom 11 bits). */
523 160, /* XMM0_REGNUM through ... */
530 272, /* ... XMM7_REGNUM (128 bits each). */
531 24, /* MXCSR_REGNUM. */
534 #define FXSAVE_ADDR(fxsave, regnum) \
535 (fxsave + fxsave_offset[regnum - FP0_REGNUM])
537 static int i387_tag (unsigned char *raw
);
540 /* Fill GDB's register array with the floating-point and SSE register
541 values in *FXSAVE. This function masks off any of the reserved
545 i387_supply_fxsave (char *fxsave
)
547 int i
, last_regnum
= MXCSR_REGNUM
;
549 if (gdbarch_tdep (current_gdbarch
)->num_xmm_regs
== 0)
550 last_regnum
= FOP_REGNUM
;
552 for (i
= FP0_REGNUM
; i
<= last_regnum
; i
++)
554 /* Most of the FPU control registers occupy only 16 bits in
555 the fxsave area. Give those a special treatment. */
556 if (i
>= FPC_REGNUM
&& i
< XMM0_REGNUM
557 && i
!= FIOFF_REGNUM
&& i
!= FOOFF_REGNUM
)
559 unsigned char val
[4];
561 memcpy (val
, FXSAVE_ADDR (fxsave
, i
), 2);
564 val
[1] &= ((1 << 3) - 1);
565 else if (i
== FTAG_REGNUM
)
567 /* The fxsave area contains a simplified version of the
568 tag word. We have to look at the actual 80-bit FP
569 data to recreate the traditional i387 tag word. */
571 unsigned long ftag
= 0;
575 top
= (((FXSAVE_ADDR (fxsave
, FSTAT_REGNUM
))[1] >> 3) & 0x7);
577 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
581 if (val
[0] & (1 << fpreg
))
583 int regnum
= (fpreg
+ 8 - top
) % 8 + FP0_REGNUM
;
584 tag
= i387_tag (FXSAVE_ADDR (fxsave
, regnum
));
589 ftag
|= tag
<< (2 * fpreg
);
591 val
[0] = ftag
& 0xff;
592 val
[1] = (ftag
>> 8) & 0xff;
594 supply_register (i
, val
);
597 supply_register (i
, FXSAVE_ADDR (fxsave
, i
));
601 /* Fill register REGNUM (if it is a floating-point or SSE register) in
602 *FXSAVE with the value in GDB's register array. If REGNUM is -1, do
603 this for all registers. This function doesn't touch any of the
604 reserved bits in *FXSAVE. */
607 i387_fill_fxsave (char *fxsave
, int regnum
)
609 int i
, last_regnum
= MXCSR_REGNUM
;
611 if (gdbarch_tdep (current_gdbarch
)->num_xmm_regs
== 0)
612 last_regnum
= FOP_REGNUM
;
614 for (i
= FP0_REGNUM
; i
<= last_regnum
; i
++)
615 if (regnum
== -1 || regnum
== i
)
617 /* Most of the FPU control registers occupy only 16 bits in
618 the fxsave area. Give those a special treatment. */
619 if (i
>= FPC_REGNUM
&& i
< XMM0_REGNUM
620 && i
!= FIOFF_REGNUM
&& i
!= FDOFF_REGNUM
)
622 unsigned char buf
[4];
624 regcache_collect (i
, buf
);
628 /* The opcode occupies only 11 bits. Make sure we
629 don't touch the other bits. */
630 buf
[1] &= ((1 << 3) - 1);
631 buf
[1] |= ((FXSAVE_ADDR (fxsave
, i
))[1] & ~((1 << 3) - 1));
633 else if (i
== FTAG_REGNUM
)
635 /* Converting back is much easier. */
640 ftag
= (buf
[1] << 8) | buf
[0];
644 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
646 int tag
= (ftag
>> (fpreg
* 2)) & 3;
649 buf
[0] |= (1 << fpreg
);
652 memcpy (FXSAVE_ADDR (fxsave
, i
), buf
, 2);
655 regcache_collect (i
, FXSAVE_ADDR (fxsave
, i
));
659 /* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
663 i387_tag (unsigned char *raw
)
666 unsigned int exponent
;
667 unsigned long fraction
[2];
669 integer
= raw
[7] & 0x80;
670 exponent
= (((raw
[9] & 0x7f) << 8) | raw
[8]);
671 fraction
[0] = ((raw
[3] << 24) | (raw
[2] << 16) | (raw
[1] << 8) | raw
[0]);
672 fraction
[1] = (((raw
[7] & 0x7f) << 24) | (raw
[6] << 16)
673 | (raw
[5] << 8) | raw
[4]);
675 if (exponent
== 0x7fff)
680 else if (exponent
== 0x0000)
682 if (fraction
[0] == 0x0000 && fraction
[1] == 0x0000 && !integer
)
This page took 0.04545 seconds and 5 git commands to generate.