ee550c6d06e4111308407ee5b2eef2ff7bb675ce
1 /* Intel 387 floating point stuff.
3 Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000,
4 2001, 2002, 2003 Free Software Foundation, Inc.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
29 #include "floatformat.h"
31 #include "gdb_assert.h"
32 #include "gdb_string.h"
35 #include "i386-tdep.h"
36 #include "i387-tdep.h"
38 /* Implement the `info float' layout based on the register definitions
41 /* Print the floating point number specified by RAW. */
43 print_i387_value (char *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
, builtin_type_i387_ext
);
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. */
66 print_i387_ext (unsigned char *raw
, struct ui_file
*file
)
70 unsigned int exponent
;
71 unsigned long fraction
[2];
74 integer
= raw
[7] & 0x80;
75 exponent
= (((raw
[9] & 0x7f) << 8) | raw
[8]);
76 fraction
[0] = ((raw
[3] << 24) | (raw
[2] << 16) | (raw
[1] << 8) | raw
[0]);
77 fraction
[1] = (((raw
[7] & 0x7f) << 24) | (raw
[6] << 16)
78 | (raw
[5] << 8) | raw
[4]);
80 if (exponent
== 0x7fff && integer
)
82 if (fraction
[0] == 0x00000000 && fraction
[1] == 0x00000000)
84 fprintf_filtered (file
, " %cInf", (sign
? '-' : '+'));
85 else if (sign
&& fraction
[0] == 0x00000000 && fraction
[1] == 0x40000000)
86 /* Real Indefinite (QNaN). */
87 fputs_unfiltered (" Real Indefinite (QNaN)", file
);
88 else if (fraction
[1] & 0x40000000)
90 fputs_filtered (" QNaN", file
);
93 fputs_filtered (" SNaN", file
);
95 else if (exponent
< 0x7fff && exponent
> 0x0000 && integer
)
97 print_i387_value (raw
, file
);
98 else if (exponent
== 0x0000)
100 /* Denormal or zero. */
101 print_i387_value (raw
, file
);
104 /* Pseudo-denormal. */
105 fputs_filtered (" Pseudo-denormal", file
);
106 else if (fraction
[0] || fraction
[1])
108 fputs_filtered (" Denormal", file
);
112 fputs_filtered (" Unsupported", file
);
115 /* Print the status word STATUS. */
117 print_i387_status_word (unsigned int status
, struct ui_file
*file
)
119 fprintf_filtered (file
, "Status Word: %s",
120 local_hex_string_custom (status
, "04"));
121 fputs_filtered (" ", file
);
122 fprintf_filtered (file
, " %s", (status
& 0x0001) ? "IE" : " ");
123 fprintf_filtered (file
, " %s", (status
& 0x0002) ? "DE" : " ");
124 fprintf_filtered (file
, " %s", (status
& 0x0004) ? "ZE" : " ");
125 fprintf_filtered (file
, " %s", (status
& 0x0008) ? "OE" : " ");
126 fprintf_filtered (file
, " %s", (status
& 0x0010) ? "UE" : " ");
127 fprintf_filtered (file
, " %s", (status
& 0x0020) ? "PE" : " ");
128 fputs_filtered (" ", file
);
129 fprintf_filtered (file
, " %s", (status
& 0x0080) ? "ES" : " ");
130 fputs_filtered (" ", file
);
131 fprintf_filtered (file
, " %s", (status
& 0x0040) ? "SF" : " ");
132 fputs_filtered (" ", file
);
133 fprintf_filtered (file
, " %s", (status
& 0x0100) ? "C0" : " ");
134 fprintf_filtered (file
, " %s", (status
& 0x0200) ? "C1" : " ");
135 fprintf_filtered (file
, " %s", (status
& 0x0400) ? "C2" : " ");
136 fprintf_filtered (file
, " %s", (status
& 0x4000) ? "C3" : " ");
138 fputs_filtered ("\n", file
);
140 fprintf_filtered (file
,
141 " TOP: %d\n", ((status
>> 11) & 7));
144 /* Print the control word CONTROL. */
146 print_i387_control_word (unsigned int control
, struct ui_file
*file
)
148 fprintf_filtered (file
, "Control Word: %s",
149 local_hex_string_custom (control
, "04"));
150 fputs_filtered (" ", file
);
151 fprintf_filtered (file
, " %s", (control
& 0x0001) ? "IM" : " ");
152 fprintf_filtered (file
, " %s", (control
& 0x0002) ? "DM" : " ");
153 fprintf_filtered (file
, " %s", (control
& 0x0004) ? "ZM" : " ");
154 fprintf_filtered (file
, " %s", (control
& 0x0008) ? "OM" : " ");
155 fprintf_filtered (file
, " %s", (control
& 0x0010) ? "UM" : " ");
156 fprintf_filtered (file
, " %s", (control
& 0x0020) ? "PM" : " ");
158 fputs_filtered ("\n", file
);
160 fputs_filtered (" PC: ", file
);
161 switch ((control
>> 8) & 3)
164 fputs_filtered ("Single Precision (24-bits)\n", file
);
167 fputs_filtered ("Reserved\n", file
);
170 fputs_filtered ("Double Precision (53-bits)\n", file
);
173 fputs_filtered ("Extended Precision (64-bits)\n", file
);
177 fputs_filtered (" RC: ", file
);
178 switch ((control
>> 10) & 3)
181 fputs_filtered ("Round to nearest\n", file
);
184 fputs_filtered ("Round down\n", file
);
187 fputs_filtered ("Round up\n", file
);
190 fputs_filtered ("Round toward zero\n", file
);
195 /* Print out the i387 floating point state. Note that we ignore FRAME
196 in the code below. That's OK since floating-point registers are
197 never saved on the stack. */
200 i387_print_float_info (struct gdbarch
*gdbarch
, struct ui_file
*file
,
201 struct frame_info
*frame
, const char *args
)
215 frame_register_read (frame
, FCTRL_REGNUM
, buf
);
216 fctrl
= extract_unsigned_integer (buf
, 4);
217 frame_register_read (frame
, FSTAT_REGNUM
, buf
);
218 fstat
= extract_unsigned_integer (buf
, 4);
219 frame_register_read (frame
, FTAG_REGNUM
, buf
);
220 ftag
= extract_unsigned_integer (buf
, 4);
221 frame_register_read (frame
, FISEG_REGNUM
, buf
);
222 fiseg
= extract_unsigned_integer (buf
, 4);
223 frame_register_read (frame
, FIOFF_REGNUM
, buf
);
224 fioff
= extract_unsigned_integer (buf
, 4);
225 frame_register_read (frame
, FOSEG_REGNUM
, buf
);
226 foseg
= extract_unsigned_integer (buf
, 4);
227 frame_register_read (frame
, FOOFF_REGNUM
, buf
);
228 fooff
= extract_unsigned_integer (buf
, 4);
229 frame_register_read (frame
, FOP_REGNUM
, buf
);
230 fop
= extract_unsigned_integer (buf
, 4);
232 top
= ((fstat
>> 11) & 7);
234 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
236 unsigned char raw
[FPU_REG_RAW_SIZE
];
237 int tag
= (ftag
>> (fpreg
* 2)) & 3;
240 fprintf_filtered (file
, "%sR%d: ", fpreg
== top
? "=>" : " ", fpreg
);
245 fputs_filtered ("Valid ", file
);
248 fputs_filtered ("Zero ", file
);
251 fputs_filtered ("Special ", file
);
254 fputs_filtered ("Empty ", file
);
258 frame_register_read (frame
, (fpreg
+ 8 - top
) % 8 + FP0_REGNUM
, raw
);
260 fputs_filtered ("0x", file
);
261 for (i
= 9; i
>= 0; i
--)
262 fprintf_filtered (file
, "%02x", raw
[i
]);
265 print_i387_ext (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 local_hex_string_custom (ftag
, "04"));
276 fprintf_filtered (file
, "Instruction Pointer: %s:",
277 local_hex_string_custom (fiseg
, "02"));
278 fprintf_filtered (file
, "%s\n", local_hex_string_custom (fioff
, "08"));
279 fprintf_filtered (file
, "Operand Pointer: %s:",
280 local_hex_string_custom (foseg
, "02"));
281 fprintf_filtered (file
, "%s\n", local_hex_string_custom (fooff
, "08"));
282 fprintf_filtered (file
, "Opcode: %s\n",
283 local_hex_string_custom (fop
? (fop
| 0xd800) : 0, "04"));
287 /* Read a value of type TYPE from register REGNUM in frame FRAME, and
288 return its contents in TO. */
291 i387_register_to_value (struct frame_info
*frame
, int regnum
,
292 struct type
*type
, void *to
)
294 char from
[I386_MAX_REGISTER_SIZE
];
296 gdb_assert (i386_fp_regnum_p (regnum
));
298 /* We only support floating-point values. */
299 if (TYPE_CODE (type
) != TYPE_CODE_FLT
)
301 warning ("Cannot convert floating-point register value "
302 "to non-floating-point type.");
306 /* Convert to TYPE. This should be a no-op if TYPE is equivalent to
307 the extended floating-point format used by the FPU. */
308 frame_read_register (frame
, regnum
, from
);
309 convert_typed_floating (from
, builtin_type_i387_ext
, to
, type
);
312 /* Write the contents FROM of a value of type TYPE into register
313 REGNUM in frame FRAME. */
316 i387_value_to_register (struct frame_info
*frame
, int regnum
,
317 struct type
*type
, const void *from
)
319 char to
[I386_MAX_REGISTER_SIZE
];
321 gdb_assert (i386_fp_regnum_p (regnum
));
323 /* We only support floating-point values. */
324 if (TYPE_CODE (type
) != TYPE_CODE_FLT
)
326 warning ("Cannot convert non-floating-point type "
327 "to floating-point register value.");
331 /* Convert from TYPE. This should be a no-op if TYPE is equivalent
332 to the extended floating-point format used by the FPU. */
333 convert_typed_floating (from
, type
, to
, builtin_type_i387_ext
);
334 put_frame_register (frame
, regnum
, to
);
338 /* FIXME: kettenis/2000-05-21: Right now more than a few i386 targets
339 define their own routines to manage the floating-point registers in
340 GDB's register array. Most (if not all) of these targets use the
341 format used by the "fsave" instruction in their communication with
342 the OS. They should all be converted to use the routines below. */
344 /* At fsave_offset[REGNUM] you'll find the offset to the location in
345 the data structure used by the "fsave" instruction where GDB
346 register REGNUM is stored. */
348 static int fsave_offset
[] =
350 28 + 0 * FPU_REG_RAW_SIZE
, /* FP0_REGNUM through ... */
351 28 + 1 * FPU_REG_RAW_SIZE
,
352 28 + 2 * FPU_REG_RAW_SIZE
,
353 28 + 3 * FPU_REG_RAW_SIZE
,
354 28 + 4 * FPU_REG_RAW_SIZE
,
355 28 + 5 * FPU_REG_RAW_SIZE
,
356 28 + 6 * FPU_REG_RAW_SIZE
,
357 28 + 7 * FPU_REG_RAW_SIZE
, /* ... FP7_REGNUM. */
358 0, /* FCTRL_REGNUM (16 bits). */
359 4, /* FSTAT_REGNUM (16 bits). */
360 8, /* FTAG_REGNUM (16 bits). */
361 16, /* FISEG_REGNUM (16 bits). */
362 12, /* FIOFF_REGNUM. */
363 24, /* FOSEG_REGNUM. */
364 20, /* FOOFF_REGNUM. */
365 18 /* FOP_REGNUM (bottom 11 bits). */
368 #define FSAVE_ADDR(fsave, regnum) (fsave + fsave_offset[regnum - FP0_REGNUM])
371 /* Fill register REGNUM in GDB's register array with the appropriate
372 value from *FSAVE. This function masks off any of the reserved
376 i387_supply_register (int regnum
, char *fsave
)
380 supply_register (regnum
, NULL
);
384 /* Most of the FPU control registers occupy only 16 bits in
385 the fsave area. Give those a special treatment. */
386 if (regnum
>= FPC_REGNUM
387 && regnum
!= FIOFF_REGNUM
&& regnum
!= FOOFF_REGNUM
)
389 unsigned char val
[4];
391 memcpy (val
, FSAVE_ADDR (fsave
, regnum
), 2);
393 if (regnum
== FOP_REGNUM
)
394 val
[1] &= ((1 << 3) - 1);
395 supply_register (regnum
, val
);
398 supply_register (regnum
, FSAVE_ADDR (fsave
, regnum
));
401 /* Fill GDB's register array with the floating-point register values
402 in *FSAVE. This function masks off any of the reserved
406 i387_supply_fsave (char *fsave
)
410 for (i
= FP0_REGNUM
; i
< XMM0_REGNUM
; i
++)
411 i387_supply_register (i
, fsave
);
414 /* Fill register REGNUM (if it is a floating-point register) in *FSAVE
415 with the value in GDB's register array. If REGNUM is -1, do this
416 for all registers. This function doesn't touch any of the reserved
420 i387_fill_fsave (char *fsave
, int regnum
)
424 for (i
= FP0_REGNUM
; i
< XMM0_REGNUM
; i
++)
425 if (regnum
== -1 || regnum
== i
)
427 /* Most of the FPU control registers occupy only 16 bits in
428 the fsave area. Give those a special treatment. */
430 && i
!= FIOFF_REGNUM
&& i
!= FOOFF_REGNUM
)
432 unsigned char buf
[4];
434 regcache_collect (i
, buf
);
438 /* The opcode occupies only 11 bits. Make sure we
439 don't touch the other bits. */
440 buf
[1] &= ((1 << 3) - 1);
441 buf
[1] |= ((FSAVE_ADDR (fsave
, i
))[1] & ~((1 << 3) - 1));
443 memcpy (FSAVE_ADDR (fsave
, i
), buf
, 2);
446 regcache_collect (i
, FSAVE_ADDR (fsave
, i
));
451 /* At fxsave_offset[REGNUM] you'll find the offset to the location in
452 the data structure used by the "fxsave" instruction where GDB
453 register REGNUM is stored. */
455 static int fxsave_offset
[] =
457 32, /* FP0_REGNUM through ... */
464 144, /* ... FP7_REGNUM (80 bits each). */
465 0, /* FCTRL_REGNUM (16 bits). */
466 2, /* FSTAT_REGNUM (16 bits). */
467 4, /* FTAG_REGNUM (16 bits). */
468 12, /* FISEG_REGNUM (16 bits). */
469 8, /* FIOFF_REGNUM. */
470 20, /* FOSEG_REGNUM (16 bits). */
471 16, /* FOOFF_REGNUM. */
472 6, /* FOP_REGNUM (bottom 11 bits). */
473 160 + 0 * 16, /* XMM0_REGNUM through ... */
488 160 + 15 * 16, /* ... XMM15_REGNUM (128 bits each). */
489 24 /* MXCSR_REGNUM. */
492 /* FIXME: kettenis/20030430: We made an unfortunate choice in putting
493 %mxcsr after the SSE registers %xmm0-%xmm7 instead of before, since
494 it makes supporting the registers %xmm8-%xmm15 on x86-64 a bit
495 involved. Hack around it by explicitly overriding the offset for
498 #define FXSAVE_ADDR(fxsave, regnum) \
499 ((regnum == MXCSR_REGNUM) ? (fxsave + 24) : \
500 (fxsave + fxsave_offset[regnum - FP0_REGNUM]))
502 static int i387_tag (unsigned char *raw
);
505 /* Fill GDB's register array with the floating-point and SSE register
506 values in *FXSAVE. This function masks off any of the reserved
510 i387_supply_fxsave (char *fxsave
)
512 int i
, last_regnum
= MXCSR_REGNUM
;
514 if (gdbarch_tdep (current_gdbarch
)->num_xmm_regs
== 0)
515 last_regnum
= FOP_REGNUM
;
517 for (i
= FP0_REGNUM
; i
<= last_regnum
; i
++)
521 supply_register (i
, NULL
);
525 /* Most of the FPU control registers occupy only 16 bits in
526 the fxsave area. Give those a special treatment. */
527 if (i
>= FPC_REGNUM
&& i
< XMM0_REGNUM
528 && i
!= FIOFF_REGNUM
&& i
!= FOOFF_REGNUM
)
530 unsigned char val
[4];
532 memcpy (val
, FXSAVE_ADDR (fxsave
, i
), 2);
535 val
[1] &= ((1 << 3) - 1);
536 else if (i
== FTAG_REGNUM
)
538 /* The fxsave area contains a simplified version of the
539 tag word. We have to look at the actual 80-bit FP
540 data to recreate the traditional i387 tag word. */
542 unsigned long ftag
= 0;
546 top
= (((FXSAVE_ADDR (fxsave
, FSTAT_REGNUM
))[1] >> 3) & 0x7);
548 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
552 if (val
[0] & (1 << fpreg
))
554 int regnum
= (fpreg
+ 8 - top
) % 8 + FP0_REGNUM
;
555 tag
= i387_tag (FXSAVE_ADDR (fxsave
, regnum
));
560 ftag
|= tag
<< (2 * fpreg
);
562 val
[0] = ftag
& 0xff;
563 val
[1] = (ftag
>> 8) & 0xff;
565 supply_register (i
, val
);
568 supply_register (i
, FXSAVE_ADDR (fxsave
, i
));
572 /* Fill register REGNUM (if it is a floating-point or SSE register) in
573 *FXSAVE with the value in GDB's register array. If REGNUM is -1, do
574 this for all registers. This function doesn't touch any of the
575 reserved bits in *FXSAVE. */
578 i387_fill_fxsave (char *fxsave
, int regnum
)
580 int i
, last_regnum
= MXCSR_REGNUM
;
582 if (gdbarch_tdep (current_gdbarch
)->num_xmm_regs
== 0)
583 last_regnum
= FOP_REGNUM
;
585 for (i
= FP0_REGNUM
; i
<= last_regnum
; i
++)
586 if (regnum
== -1 || regnum
== i
)
588 /* Most of the FPU control registers occupy only 16 bits in
589 the fxsave area. Give those a special treatment. */
590 if (i
>= FPC_REGNUM
&& i
< XMM0_REGNUM
591 && i
!= FIOFF_REGNUM
&& i
!= FOOFF_REGNUM
)
593 unsigned char buf
[4];
595 regcache_collect (i
, buf
);
599 /* The opcode occupies only 11 bits. Make sure we
600 don't touch the other bits. */
601 buf
[1] &= ((1 << 3) - 1);
602 buf
[1] |= ((FXSAVE_ADDR (fxsave
, i
))[1] & ~((1 << 3) - 1));
604 else if (i
== FTAG_REGNUM
)
606 /* Converting back is much easier. */
611 ftag
= (buf
[1] << 8) | buf
[0];
615 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
617 int tag
= (ftag
>> (fpreg
* 2)) & 3;
620 buf
[0] |= (1 << fpreg
);
623 memcpy (FXSAVE_ADDR (fxsave
, i
), buf
, 2);
626 regcache_collect (i
, FXSAVE_ADDR (fxsave
, i
));
630 /* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
634 i387_tag (unsigned char *raw
)
637 unsigned int exponent
;
638 unsigned long fraction
[2];
640 integer
= raw
[7] & 0x80;
641 exponent
= (((raw
[9] & 0x7f) << 8) | raw
[8]);
642 fraction
[0] = ((raw
[3] << 24) | (raw
[2] << 16) | (raw
[1] << 8) | raw
[0]);
643 fraction
[1] = (((raw
[7] & 0x7f) << 24) | (raw
[6] << 16)
644 | (raw
[5] << 8) | raw
[4]);
646 if (exponent
== 0x7fff)
651 else if (exponent
== 0x0000)
653 if (fraction
[0] == 0x0000 && fraction
[1] == 0x0000 && !integer
)
This page took 0.047797 seconds and 4 git commands to generate.