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
)
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 printf_filtered (" %-+27.19Lg", (long double) value
);
180 printf_filtered (" %-+27.19g", (double) value
);
184 /* Print the classification for the register contents RAW. */
186 print_i387_ext (unsigned char *raw
)
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 printf_filtered (" %cInf", (sign
? '-' : '+'));
205 else if (sign
&& fraction
[0] == 0x00000000 && fraction
[1] == 0x40000000)
206 /* Real Indefinite (QNaN). */
207 puts_unfiltered (" Real Indefinite (QNaN)");
208 else if (fraction
[1] & 0x40000000)
210 puts_filtered (" QNaN");
213 puts_filtered (" SNaN");
215 else if (exponent
< 0x7fff && exponent
> 0x0000 && integer
)
217 print_i387_value (raw
);
218 else if (exponent
== 0x0000)
220 /* Denormal or zero. */
221 print_i387_value (raw
);
224 /* Pseudo-denormal. */
225 puts_filtered (" Pseudo-denormal");
226 else if (fraction
[0] || fraction
[1])
228 puts_filtered (" Denormal");
232 puts_filtered (" Unsupported");
235 /* Print the status word STATUS. */
237 print_i387_status_word (unsigned int status
)
239 printf_filtered ("Status Word: %s",
240 local_hex_string_custom (status
, "04"));
242 printf_filtered (" %s", (status
& 0x0001) ? "IE" : " ");
243 printf_filtered (" %s", (status
& 0x0002) ? "DE" : " ");
244 printf_filtered (" %s", (status
& 0x0004) ? "ZE" : " ");
245 printf_filtered (" %s", (status
& 0x0008) ? "OE" : " ");
246 printf_filtered (" %s", (status
& 0x0010) ? "UE" : " ");
247 printf_filtered (" %s", (status
& 0x0020) ? "PE" : " ");
249 printf_filtered (" %s", (status
& 0x0080) ? "ES" : " ");
251 printf_filtered (" %s", (status
& 0x0040) ? "SF" : " ");
253 printf_filtered (" %s", (status
& 0x0100) ? "C0" : " ");
254 printf_filtered (" %s", (status
& 0x0200) ? "C1" : " ");
255 printf_filtered (" %s", (status
& 0x0400) ? "C2" : " ");
256 printf_filtered (" %s", (status
& 0x4000) ? "C3" : " ");
258 puts_filtered ("\n");
260 printf_filtered (" TOP: %d\n", ((status
>> 11) & 7));
263 /* Print the control word CONTROL. */
265 print_i387_control_word (unsigned int control
)
267 printf_filtered ("Control Word: %s",
268 local_hex_string_custom (control
, "04"));
270 printf_filtered (" %s", (control
& 0x0001) ? "IM" : " ");
271 printf_filtered (" %s", (control
& 0x0002) ? "DM" : " ");
272 printf_filtered (" %s", (control
& 0x0004) ? "ZM" : " ");
273 printf_filtered (" %s", (control
& 0x0008) ? "OM" : " ");
274 printf_filtered (" %s", (control
& 0x0010) ? "UM" : " ");
275 printf_filtered (" %s", (control
& 0x0020) ? "PM" : " ");
277 puts_filtered ("\n");
279 puts_filtered (" PC: ");
280 switch ((control
>> 8) & 3)
283 puts_filtered ("Single Precision (24-bits)\n");
286 puts_filtered ("Reserved\n");
289 puts_filtered ("Double Precision (53-bits)\n");
292 puts_filtered ("Extended Precision (64-bits)\n");
296 puts_filtered (" RC: ");
297 switch ((control
>> 10) & 3)
300 puts_filtered ("Round to nearest\n");
303 puts_filtered ("Round down\n");
306 puts_filtered ("Round up\n");
309 puts_filtered ("Round toward zero\n");
314 /* Print out the i387 floating poin state. */
316 i387_float_info (void)
329 fctrl
= read_register (FCTRL_REGNUM
);
330 fstat
= read_register (FSTAT_REGNUM
);
331 ftag
= read_register (FTAG_REGNUM
);
332 fiseg
= read_register (FCS_REGNUM
);
333 fioff
= read_register (FCOFF_REGNUM
);
334 foseg
= read_register (FDS_REGNUM
);
335 fooff
= read_register (FDOFF_REGNUM
);
336 fop
= read_register (FOP_REGNUM
);
338 top
= ((fstat
>> 11) & 7);
340 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
342 unsigned char raw
[FPU_REG_RAW_SIZE
];
343 int tag
= (ftag
>> (fpreg
* 2)) & 3;
346 printf_filtered ("%sR%d: ", fpreg
== top
? "=>" : " ", fpreg
);
351 puts_filtered ("Valid ");
354 puts_filtered ("Zero ");
357 puts_filtered ("Special ");
360 puts_filtered ("Empty ");
364 read_register_gen ((fpreg
+ 8 - top
) % 8 + FP0_REGNUM
, raw
);
366 puts_filtered ("0x");
367 for (i
= 9; i
>= 0; i
--)
368 printf_filtered ("%02x", raw
[i
]);
371 print_i387_ext (raw
);
373 puts_filtered ("\n");
376 puts_filtered ("\n");
378 print_i387_status_word (fstat
);
379 print_i387_control_word (fctrl
);
380 printf_filtered ("Tag Word: %s\n",
381 local_hex_string_custom (ftag
, "04"));
382 printf_filtered ("Instruction Pointer: %s:",
383 local_hex_string_custom (fiseg
, "02"));
384 printf_filtered ("%s\n", local_hex_string_custom (fioff
, "08"));
385 printf_filtered ("Operand Pointer: %s:",
386 local_hex_string_custom (foseg
, "02"));
387 printf_filtered ("%s\n", local_hex_string_custom (fooff
, "08"));
388 printf_filtered ("Opcode: %s\n",
389 local_hex_string_custom (fop
? (fop
| 0xd800) : 0, "04"));
392 /* FIXME: kettenis/2000-05-21: Right now more than a few i386 targets
393 define their own routines to manage the floating-point registers in
394 GDB's register array. Most (if not all) of these targets use the
395 format used by the "fsave" instruction in their communication with
396 the OS. They should all be converted to use the routines below. */
398 /* At fsave_offset[REGNUM] you'll find the offset to the location in
399 the data structure used by the "fsave" instruction where GDB
400 register REGNUM is stored. */
402 static int fsave_offset
[] =
404 28 + 0 * FPU_REG_RAW_SIZE
, /* FP0_REGNUM through ... */
405 28 + 1 * FPU_REG_RAW_SIZE
,
406 28 + 2 * FPU_REG_RAW_SIZE
,
407 28 + 3 * FPU_REG_RAW_SIZE
,
408 28 + 4 * FPU_REG_RAW_SIZE
,
409 28 + 5 * FPU_REG_RAW_SIZE
,
410 28 + 6 * FPU_REG_RAW_SIZE
,
411 28 + 7 * FPU_REG_RAW_SIZE
, /* ... FP7_REGNUM. */
412 0, /* FCTRL_REGNUM (16 bits). */
413 4, /* FSTAT_REGNUM (16 bits). */
414 8, /* FTAG_REGNUM (16 bits). */
415 16, /* FISEG_REGNUM (16 bits). */
416 12, /* FIOFF_REGNUM. */
417 24, /* FOSEG_REGNUM. */
418 20, /* FOOFF_REGNUM. */
419 18 /* FOP_REGNUM (bottom 11 bits). */
422 #define FSAVE_ADDR(fsave, regnum) (fsave + fsave_offset[regnum - FP0_REGNUM])
425 /* Fill register REGNUM in GDB's register array with the appropriate
426 value from *FSAVE. This function masks off any of the reserved
430 i387_supply_register (int regnum
, char *fsave
)
432 /* Most of the FPU control registers occupy only 16 bits in
433 the fsave area. Give those a special treatment. */
434 if (regnum
>= FPC_REGNUM
435 && regnum
!= FIOFF_REGNUM
&& regnum
!= FOOFF_REGNUM
)
437 unsigned char val
[4];
439 memcpy (val
, FSAVE_ADDR (fsave
, regnum
), 2);
441 if (regnum
== FOP_REGNUM
)
442 val
[1] &= ((1 << 3) - 1);
443 supply_register (regnum
, val
);
446 supply_register (regnum
, FSAVE_ADDR (fsave
, regnum
));
449 /* Fill GDB's register array with the floating-point register values
450 in *FSAVE. This function masks off any of the reserved
454 i387_supply_fsave (char *fsave
)
458 for (i
= FP0_REGNUM
; i
< XMM0_REGNUM
; i
++)
459 i387_supply_register (i
, fsave
);
462 /* Fill register REGNUM (if it is a floating-point register) in *FSAVE
463 with the value in GDB's register array. If REGNUM is -1, do this
464 for all registers. This function doesn't touch any of the reserved
468 i387_fill_fsave (char *fsave
, int regnum
)
472 for (i
= FP0_REGNUM
; i
< XMM0_REGNUM
; i
++)
473 if (regnum
== -1 || regnum
== i
)
475 /* Most of the FPU control registers occupy only 16 bits in
476 the fsave area. Give those a special treatment. */
478 && i
!= FIOFF_REGNUM
&& i
!= FOOFF_REGNUM
)
480 unsigned char buf
[4];
482 regcache_collect (i
, buf
);
486 /* The opcode occupies only 11 bits. Make sure we
487 don't touch the other bits. */
488 buf
[1] &= ((1 << 3) - 1);
489 buf
[1] |= ((FSAVE_ADDR (fsave
, i
))[1] & ~((1 << 3) - 1));
491 memcpy (FSAVE_ADDR (fsave
, i
), buf
, 2);
494 regcache_collect (i
, FSAVE_ADDR (fsave
, i
));
499 /* At fxsave_offset[REGNUM] you'll find the offset to the location in
500 the data structure used by the "fxsave" instruction where GDB
501 register REGNUM is stored. */
503 static int fxsave_offset
[] =
505 32, /* FP0_REGNUM through ... */
512 144, /* ... FP7_REGNUM (80 bits each). */
513 0, /* FCTRL_REGNUM (16 bits). */
514 2, /* FSTAT_REGNUM (16 bits). */
515 4, /* FTAG_REGNUM (16 bits). */
516 12, /* FISEG_REGNUM (16 bits). */
517 8, /* FIOFF_REGNUM. */
518 20, /* FOSEG_REGNUM (16 bits). */
519 16, /* FOOFF_REGNUM. */
520 6, /* FOP_REGNUM (bottom 11 bits). */
521 160, /* XMM0_REGNUM through ... */
528 272, /* ... XMM7_REGNUM (128 bits each). */
529 24, /* MXCSR_REGNUM. */
532 #define FXSAVE_ADDR(fxsave, regnum) \
533 (fxsave + fxsave_offset[regnum - FP0_REGNUM])
535 static int i387_tag (unsigned char *raw
);
538 /* Fill GDB's register array with the floating-point and SSE register
539 values in *FXSAVE. This function masks off any of the reserved
543 i387_supply_fxsave (char *fxsave
)
545 int i
, last_regnum
= MXCSR_REGNUM
;
547 if (gdbarch_tdep (current_gdbarch
)->num_xmm_regs
== 0)
548 last_regnum
= FOP_REGNUM
;
550 for (i
= FP0_REGNUM
; i
<= last_regnum
; i
++)
552 /* Most of the FPU control registers occupy only 16 bits in
553 the fxsave area. Give those a special treatment. */
554 if (i
>= FPC_REGNUM
&& i
< XMM0_REGNUM
555 && i
!= FIOFF_REGNUM
&& i
!= FOOFF_REGNUM
)
557 unsigned char val
[4];
559 memcpy (val
, FXSAVE_ADDR (fxsave
, i
), 2);
562 val
[1] &= ((1 << 3) - 1);
563 else if (i
== FTAG_REGNUM
)
565 /* The fxsave area contains a simplified version of the
566 tag word. We have to look at the actual 80-bit FP
567 data to recreate the traditional i387 tag word. */
569 unsigned long ftag
= 0;
573 top
= (((FXSAVE_ADDR (fxsave
, FSTAT_REGNUM
))[1] >> 3) & 0x7);
575 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
579 if (val
[0] & (1 << fpreg
))
581 int regnum
= (fpreg
+ 8 - top
) % 8 + FP0_REGNUM
;
582 tag
= i387_tag (FXSAVE_ADDR (fxsave
, regnum
));
587 ftag
|= tag
<< (2 * fpreg
);
589 val
[0] = ftag
& 0xff;
590 val
[1] = (ftag
>> 8) & 0xff;
592 supply_register (i
, val
);
595 supply_register (i
, FXSAVE_ADDR (fxsave
, i
));
599 /* Fill register REGNUM (if it is a floating-point or SSE register) in
600 *FXSAVE with the value in GDB's register array. If REGNUM is -1, do
601 this for all registers. This function doesn't touch any of the
602 reserved bits in *FXSAVE. */
605 i387_fill_fxsave (char *fxsave
, int regnum
)
607 int i
, last_regnum
= MXCSR_REGNUM
;
609 if (gdbarch_tdep (current_gdbarch
)->num_xmm_regs
== 0)
610 last_regnum
= FOP_REGNUM
;
612 for (i
= FP0_REGNUM
; i
<= last_regnum
; i
++)
613 if (regnum
== -1 || regnum
== i
)
615 /* Most of the FPU control registers occupy only 16 bits in
616 the fxsave area. Give those a special treatment. */
617 if (i
>= FPC_REGNUM
&& i
< XMM0_REGNUM
618 && i
!= FIOFF_REGNUM
&& i
!= FDOFF_REGNUM
)
620 unsigned char buf
[4];
622 regcache_collect (i
, buf
);
626 /* The opcode occupies only 11 bits. Make sure we
627 don't touch the other bits. */
628 buf
[1] &= ((1 << 3) - 1);
629 buf
[1] |= ((FXSAVE_ADDR (fxsave
, i
))[1] & ~((1 << 3) - 1));
631 else if (i
== FTAG_REGNUM
)
633 /* Converting back is much easier. */
638 ftag
= (buf
[1] << 8) | buf
[0];
642 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
644 int tag
= (ftag
>> (fpreg
* 2)) & 3;
647 buf
[0] |= (1 << fpreg
);
650 memcpy (FXSAVE_ADDR (fxsave
, i
), buf
, 2);
653 regcache_collect (i
, FXSAVE_ADDR (fxsave
, i
));
657 /* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
661 i387_tag (unsigned char *raw
)
664 unsigned int exponent
;
665 unsigned long fraction
[2];
667 integer
= raw
[7] & 0x80;
668 exponent
= (((raw
[9] & 0x7f) << 8) | raw
[8]);
669 fraction
[0] = ((raw
[3] << 24) | (raw
[2] << 16) | (raw
[1] << 8) | raw
[0]);
670 fraction
[1] = (((raw
[7] & 0x7f) << 24) | (raw
[6] << 16)
671 | (raw
[5] << 8) | raw
[4]);
673 if (exponent
== 0x7fff)
678 else if (exponent
== 0x0000)
680 if (fraction
[0] == 0x0000 && fraction
[1] == 0x0000 && !integer
)
This page took 0.044914 seconds and 4 git commands to generate.