daf1c6ff6ce78278159e335c04680b7e29a1eb28
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 point state. Note that we ignore FRAME
316 in the code below. That's OK since floating-point registers are
317 never saved on the stack. */
320 i387_print_float_info (struct gdbarch
*gdbarch
, struct ui_file
*file
,
321 struct frame_info
*frame
, const char *args
)
334 fctrl
= read_register (FCTRL_REGNUM
);
335 fstat
= read_register (FSTAT_REGNUM
);
336 ftag
= read_register (FTAG_REGNUM
);
337 fiseg
= read_register (FCS_REGNUM
);
338 fioff
= read_register (FCOFF_REGNUM
);
339 foseg
= read_register (FDS_REGNUM
);
340 fooff
= read_register (FDOFF_REGNUM
);
341 fop
= read_register (FOP_REGNUM
);
343 top
= ((fstat
>> 11) & 7);
345 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
347 unsigned char raw
[FPU_REG_RAW_SIZE
];
348 int tag
= (ftag
>> (fpreg
* 2)) & 3;
351 fprintf_filtered (file
, "%sR%d: ", fpreg
== top
? "=>" : " ", fpreg
);
356 fputs_filtered ("Valid ", file
);
359 fputs_filtered ("Zero ", file
);
362 fputs_filtered ("Special ", file
);
365 fputs_filtered ("Empty ", file
);
369 read_register_gen ((fpreg
+ 8 - top
) % 8 + FP0_REGNUM
, raw
);
371 fputs_filtered ("0x", file
);
372 for (i
= 9; i
>= 0; i
--)
373 fprintf_filtered (file
, "%02x", raw
[i
]);
376 print_i387_ext (raw
, file
);
378 fputs_filtered ("\n", file
);
381 puts_filtered ("\n");
383 print_i387_status_word (fstat
, file
);
384 print_i387_control_word (fctrl
, file
);
385 fprintf_filtered (file
, "Tag Word: %s\n",
386 local_hex_string_custom (ftag
, "04"));
387 fprintf_filtered (file
, "Instruction Pointer: %s:",
388 local_hex_string_custom (fiseg
, "02"));
389 fprintf_filtered (file
, "%s\n", local_hex_string_custom (fioff
, "08"));
390 fprintf_filtered (file
, "Operand Pointer: %s:",
391 local_hex_string_custom (foseg
, "02"));
392 fprintf_filtered (file
, "%s\n", local_hex_string_custom (fooff
, "08"));
393 fprintf_filtered (file
, "Opcode: %s\n",
394 local_hex_string_custom (fop
? (fop
| 0xd800) : 0, "04"));
397 /* FIXME: kettenis/2000-05-21: Right now more than a few i386 targets
398 define their own routines to manage the floating-point registers in
399 GDB's register array. Most (if not all) of these targets use the
400 format used by the "fsave" instruction in their communication with
401 the OS. They should all be converted to use the routines below. */
403 /* At fsave_offset[REGNUM] you'll find the offset to the location in
404 the data structure used by the "fsave" instruction where GDB
405 register REGNUM is stored. */
407 static int fsave_offset
[] =
409 28 + 0 * FPU_REG_RAW_SIZE
, /* FP0_REGNUM through ... */
410 28 + 1 * FPU_REG_RAW_SIZE
,
411 28 + 2 * FPU_REG_RAW_SIZE
,
412 28 + 3 * FPU_REG_RAW_SIZE
,
413 28 + 4 * FPU_REG_RAW_SIZE
,
414 28 + 5 * FPU_REG_RAW_SIZE
,
415 28 + 6 * FPU_REG_RAW_SIZE
,
416 28 + 7 * FPU_REG_RAW_SIZE
, /* ... FP7_REGNUM. */
417 0, /* FCTRL_REGNUM (16 bits). */
418 4, /* FSTAT_REGNUM (16 bits). */
419 8, /* FTAG_REGNUM (16 bits). */
420 16, /* FISEG_REGNUM (16 bits). */
421 12, /* FIOFF_REGNUM. */
422 24, /* FOSEG_REGNUM. */
423 20, /* FOOFF_REGNUM. */
424 18 /* FOP_REGNUM (bottom 11 bits). */
427 #define FSAVE_ADDR(fsave, regnum) (fsave + fsave_offset[regnum - FP0_REGNUM])
430 /* Fill register REGNUM in GDB's register array with the appropriate
431 value from *FSAVE. This function masks off any of the reserved
435 i387_supply_register (int regnum
, char *fsave
)
437 /* Most of the FPU control registers occupy only 16 bits in
438 the fsave area. Give those a special treatment. */
439 if (regnum
>= FPC_REGNUM
440 && regnum
!= FIOFF_REGNUM
&& regnum
!= FOOFF_REGNUM
)
442 unsigned char val
[4];
444 memcpy (val
, FSAVE_ADDR (fsave
, regnum
), 2);
446 if (regnum
== FOP_REGNUM
)
447 val
[1] &= ((1 << 3) - 1);
448 supply_register (regnum
, val
);
451 supply_register (regnum
, FSAVE_ADDR (fsave
, regnum
));
454 /* Fill GDB's register array with the floating-point register values
455 in *FSAVE. This function masks off any of the reserved
459 i387_supply_fsave (char *fsave
)
463 for (i
= FP0_REGNUM
; i
< XMM0_REGNUM
; i
++)
464 i387_supply_register (i
, fsave
);
467 /* Fill register REGNUM (if it is a floating-point register) in *FSAVE
468 with the value in GDB's register array. If REGNUM is -1, do this
469 for all registers. This function doesn't touch any of the reserved
473 i387_fill_fsave (char *fsave
, int regnum
)
477 for (i
= FP0_REGNUM
; i
< XMM0_REGNUM
; i
++)
478 if (regnum
== -1 || regnum
== i
)
480 /* Most of the FPU control registers occupy only 16 bits in
481 the fsave area. Give those a special treatment. */
483 && i
!= FIOFF_REGNUM
&& i
!= FOOFF_REGNUM
)
485 unsigned char buf
[4];
487 regcache_collect (i
, buf
);
491 /* The opcode occupies only 11 bits. Make sure we
492 don't touch the other bits. */
493 buf
[1] &= ((1 << 3) - 1);
494 buf
[1] |= ((FSAVE_ADDR (fsave
, i
))[1] & ~((1 << 3) - 1));
496 memcpy (FSAVE_ADDR (fsave
, i
), buf
, 2);
499 regcache_collect (i
, FSAVE_ADDR (fsave
, i
));
504 /* At fxsave_offset[REGNUM] you'll find the offset to the location in
505 the data structure used by the "fxsave" instruction where GDB
506 register REGNUM is stored. */
508 static int fxsave_offset
[] =
510 32, /* FP0_REGNUM through ... */
517 144, /* ... FP7_REGNUM (80 bits each). */
518 0, /* FCTRL_REGNUM (16 bits). */
519 2, /* FSTAT_REGNUM (16 bits). */
520 4, /* FTAG_REGNUM (16 bits). */
521 12, /* FISEG_REGNUM (16 bits). */
522 8, /* FIOFF_REGNUM. */
523 20, /* FOSEG_REGNUM (16 bits). */
524 16, /* FOOFF_REGNUM. */
525 6, /* FOP_REGNUM (bottom 11 bits). */
526 160, /* XMM0_REGNUM through ... */
533 272, /* ... XMM7_REGNUM (128 bits each). */
534 24, /* MXCSR_REGNUM. */
537 #define FXSAVE_ADDR(fxsave, regnum) \
538 (fxsave + fxsave_offset[regnum - FP0_REGNUM])
540 static int i387_tag (unsigned char *raw
);
543 /* Fill GDB's register array with the floating-point and SSE register
544 values in *FXSAVE. This function masks off any of the reserved
548 i387_supply_fxsave (char *fxsave
)
550 int i
, last_regnum
= MXCSR_REGNUM
;
552 if (gdbarch_tdep (current_gdbarch
)->num_xmm_regs
== 0)
553 last_regnum
= FOP_REGNUM
;
555 for (i
= FP0_REGNUM
; i
<= last_regnum
; i
++)
557 /* Most of the FPU control registers occupy only 16 bits in
558 the fxsave area. Give those a special treatment. */
559 if (i
>= FPC_REGNUM
&& i
< XMM0_REGNUM
560 && i
!= FIOFF_REGNUM
&& i
!= FOOFF_REGNUM
)
562 unsigned char val
[4];
564 memcpy (val
, FXSAVE_ADDR (fxsave
, i
), 2);
567 val
[1] &= ((1 << 3) - 1);
568 else if (i
== FTAG_REGNUM
)
570 /* The fxsave area contains a simplified version of the
571 tag word. We have to look at the actual 80-bit FP
572 data to recreate the traditional i387 tag word. */
574 unsigned long ftag
= 0;
578 top
= (((FXSAVE_ADDR (fxsave
, FSTAT_REGNUM
))[1] >> 3) & 0x7);
580 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
584 if (val
[0] & (1 << fpreg
))
586 int regnum
= (fpreg
+ 8 - top
) % 8 + FP0_REGNUM
;
587 tag
= i387_tag (FXSAVE_ADDR (fxsave
, regnum
));
592 ftag
|= tag
<< (2 * fpreg
);
594 val
[0] = ftag
& 0xff;
595 val
[1] = (ftag
>> 8) & 0xff;
597 supply_register (i
, val
);
600 supply_register (i
, FXSAVE_ADDR (fxsave
, i
));
604 /* Fill register REGNUM (if it is a floating-point or SSE register) in
605 *FXSAVE with the value in GDB's register array. If REGNUM is -1, do
606 this for all registers. This function doesn't touch any of the
607 reserved bits in *FXSAVE. */
610 i387_fill_fxsave (char *fxsave
, int regnum
)
612 int i
, last_regnum
= MXCSR_REGNUM
;
614 if (gdbarch_tdep (current_gdbarch
)->num_xmm_regs
== 0)
615 last_regnum
= FOP_REGNUM
;
617 for (i
= FP0_REGNUM
; i
<= last_regnum
; i
++)
618 if (regnum
== -1 || regnum
== i
)
620 /* Most of the FPU control registers occupy only 16 bits in
621 the fxsave area. Give those a special treatment. */
622 if (i
>= FPC_REGNUM
&& i
< XMM0_REGNUM
623 && i
!= FIOFF_REGNUM
&& i
!= FDOFF_REGNUM
)
625 unsigned char buf
[4];
627 regcache_collect (i
, buf
);
631 /* The opcode occupies only 11 bits. Make sure we
632 don't touch the other bits. */
633 buf
[1] &= ((1 << 3) - 1);
634 buf
[1] |= ((FXSAVE_ADDR (fxsave
, i
))[1] & ~((1 << 3) - 1));
636 else if (i
== FTAG_REGNUM
)
638 /* Converting back is much easier. */
643 ftag
= (buf
[1] << 8) | buf
[0];
647 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
649 int tag
= (ftag
>> (fpreg
* 2)) & 3;
652 buf
[0] |= (1 << fpreg
);
655 memcpy (FXSAVE_ADDR (fxsave
, i
), buf
, 2);
658 regcache_collect (i
, FXSAVE_ADDR (fxsave
, i
));
662 /* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
666 i387_tag (unsigned char *raw
)
669 unsigned int exponent
;
670 unsigned long fraction
[2];
672 integer
= raw
[7] & 0x80;
673 exponent
= (((raw
[9] & 0x7f) << 8) | raw
[8]);
674 fraction
[0] = ((raw
[3] << 24) | (raw
[2] << 16) | (raw
[1] << 8) | raw
[0]);
675 fraction
[1] = (((raw
[7] & 0x7f) << 24) | (raw
[6] << 16)
676 | (raw
[5] << 8) | raw
[4]);
678 if (exponent
== 0x7fff)
683 else if (exponent
== 0x0000)
685 if (fraction
[0] == 0x0000 && fraction
[1] == 0x0000 && !integer
)