1 /* Intel 387 floating point stuff.
2 Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000, 2001
3 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"
34 #include "i386-tdep.h"
37 /* FIXME: Eliminate the next two functions when we have the time to
38 change all the callers. */
40 void i387_to_double (char *from
, char *to
);
41 void double_to_i387 (char *from
, char *to
);
44 i387_to_double (char *from
, char *to
)
46 floatformat_to_double (&floatformat_i387_ext
, from
, (double *) to
);
50 double_to_i387 (char *from
, char *to
)
52 floatformat_from_double (&floatformat_i387_ext
, (double *) from
, to
);
56 /* FIXME: The functions on this page are used by the old `info float'
57 implementations that a few of the i386 targets provide. These
58 functions should be removed if all of these have been converted to
59 use the generic implementation based on the new register file
62 static void print_387_control_bits (unsigned int control
);
63 static void print_387_status_bits (unsigned int status
);
66 print_387_control_bits (unsigned int control
)
68 switch ((control
>> 8) & 3)
71 puts_unfiltered (" 24 bit; ");
74 puts_unfiltered (" (bad); ");
77 puts_unfiltered (" 53 bit; ");
80 puts_unfiltered (" 64 bit; ");
83 switch ((control
>> 10) & 3)
86 puts_unfiltered ("NEAR; ");
89 puts_unfiltered ("DOWN; ");
92 puts_unfiltered ("UP; ");
95 puts_unfiltered ("CHOP; ");
100 puts_unfiltered ("mask");
101 if (control
& 0x0001)
102 puts_unfiltered (" INVAL");
103 if (control
& 0x0002)
104 puts_unfiltered (" DENOR");
105 if (control
& 0x0004)
106 puts_unfiltered (" DIVZ");
107 if (control
& 0x0008)
108 puts_unfiltered (" OVERF");
109 if (control
& 0x0010)
110 puts_unfiltered (" UNDER");
111 if (control
& 0x0020)
112 puts_unfiltered (" LOS");
113 puts_unfiltered (";");
116 if (control
& 0xe080)
117 warning ("\nreserved bits on: %s",
118 local_hex_string (control
& 0xe080));
122 print_387_control_word (unsigned int control
)
124 printf_filtered ("control %s:", local_hex_string(control
& 0xffff));
125 print_387_control_bits (control
);
126 puts_unfiltered ("\n");
130 print_387_status_bits (unsigned int status
)
132 printf_unfiltered (" flags %d%d%d%d; ",
133 (status
& 0x4000) != 0,
134 (status
& 0x0400) != 0,
135 (status
& 0x0200) != 0,
136 (status
& 0x0100) != 0);
137 printf_unfiltered ("top %d; ", (status
>> 11) & 7);
140 puts_unfiltered ("excep");
141 if (status
& 0x0001) puts_unfiltered (" INVAL");
142 if (status
& 0x0002) puts_unfiltered (" DENOR");
143 if (status
& 0x0004) puts_unfiltered (" DIVZ");
144 if (status
& 0x0008) puts_unfiltered (" OVERF");
145 if (status
& 0x0010) puts_unfiltered (" UNDER");
146 if (status
& 0x0020) puts_unfiltered (" LOS");
147 if (status
& 0x0040) puts_unfiltered (" STACK");
152 print_387_status_word (unsigned int status
)
154 printf_filtered ("status %s:", local_hex_string (status
& 0xffff));
155 print_387_status_bits (status
);
156 puts_unfiltered ("\n");
160 /* Implement the `info float' layout based on the register definitions
163 /* Print the floating point number specified by RAW. */
165 print_i387_value (char *raw
)
169 /* Using extract_typed_floating here might affect the representation
170 of certain numbers such as NaNs, even if GDB is running natively.
171 This is fine since our caller already detects such special
172 numbers and we print the hexadecimal representation anyway. */
173 value
= extract_typed_floating (raw
, builtin_type_i387_ext
);
175 /* We try to print 19 digits. The last digit may or may not contain
176 garbage, but we'd better print one too many. We need enough room
177 to print the value, 1 position for the sign, 1 for the decimal
178 point, 19 for the digits and 6 for the exponent adds up to 27. */
179 #ifdef PRINTF_HAS_LONG_DOUBLE
180 printf_filtered (" %-+27.19Lg", (long double) value
);
182 printf_filtered (" %-+27.19g", (double) value
);
186 /* Print the classification for the register contents RAW. */
188 print_i387_ext (unsigned char *raw
)
192 unsigned int exponent
;
193 unsigned long fraction
[2];
195 sign
= raw
[9] & 0x80;
196 integer
= raw
[7] & 0x80;
197 exponent
= (((raw
[9] & 0x7f) << 8) | raw
[8]);
198 fraction
[0] = ((raw
[3] << 24) | (raw
[2] << 16) | (raw
[1] << 8) | raw
[0]);
199 fraction
[1] = (((raw
[7] & 0x7f) << 24) | (raw
[6] << 16)
200 | (raw
[5] << 8) | raw
[4]);
202 if (exponent
== 0x7fff && integer
)
204 if (fraction
[0] == 0x00000000 && fraction
[1] == 0x00000000)
206 printf_filtered (" %cInf", (sign
? '-' : '+'));
207 else if (sign
&& fraction
[0] == 0x00000000 && fraction
[1] == 0x40000000)
208 /* Real Indefinite (QNaN). */
209 puts_unfiltered (" Real Indefinite (QNaN)");
210 else if (fraction
[1] & 0x40000000)
212 puts_filtered (" QNaN");
215 puts_filtered (" SNaN");
217 else if (exponent
< 0x7fff && exponent
> 0x0000 && integer
)
219 print_i387_value (raw
);
220 else if (exponent
== 0x0000)
222 /* Denormal or zero. */
223 print_i387_value (raw
);
226 /* Pseudo-denormal. */
227 puts_filtered (" Pseudo-denormal");
228 else if (fraction
[0] || fraction
[1])
230 puts_filtered (" Denormal");
234 puts_filtered (" Unsupported");
237 /* Print the status word STATUS. */
239 print_i387_status_word (unsigned int status
)
241 printf_filtered ("Status Word: %s",
242 local_hex_string_custom (status
, "04"));
244 printf_filtered (" %s", (status
& 0x0001) ? "IE" : " ");
245 printf_filtered (" %s", (status
& 0x0002) ? "DE" : " ");
246 printf_filtered (" %s", (status
& 0x0004) ? "ZE" : " ");
247 printf_filtered (" %s", (status
& 0x0008) ? "OE" : " ");
248 printf_filtered (" %s", (status
& 0x0010) ? "UE" : " ");
249 printf_filtered (" %s", (status
& 0x0020) ? "PE" : " ");
251 printf_filtered (" %s", (status
& 0x0080) ? "ES" : " ");
253 printf_filtered (" %s", (status
& 0x0040) ? "SF" : " ");
255 printf_filtered (" %s", (status
& 0x0100) ? "C0" : " ");
256 printf_filtered (" %s", (status
& 0x0200) ? "C1" : " ");
257 printf_filtered (" %s", (status
& 0x0400) ? "C2" : " ");
258 printf_filtered (" %s", (status
& 0x4000) ? "C3" : " ");
260 puts_filtered ("\n");
262 printf_filtered (" TOP: %d\n", ((status
>> 11) & 7));
265 /* Print the control word CONTROL. */
267 print_i387_control_word (unsigned int control
)
269 printf_filtered ("Control Word: %s",
270 local_hex_string_custom (control
, "04"));
272 printf_filtered (" %s", (control
& 0x0001) ? "IM" : " ");
273 printf_filtered (" %s", (control
& 0x0002) ? "DM" : " ");
274 printf_filtered (" %s", (control
& 0x0004) ? "ZM" : " ");
275 printf_filtered (" %s", (control
& 0x0008) ? "OM" : " ");
276 printf_filtered (" %s", (control
& 0x0010) ? "UM" : " ");
277 printf_filtered (" %s", (control
& 0x0020) ? "PM" : " ");
279 puts_filtered ("\n");
281 puts_filtered (" PC: ");
282 switch ((control
>> 8) & 3)
285 puts_filtered ("Single Precision (24-bits)\n");
288 puts_filtered ("Reserved\n");
291 puts_filtered ("Double Precision (53-bits)\n");
294 puts_filtered ("Extended Precision (64-bits)\n");
298 puts_filtered (" RC: ");
299 switch ((control
>> 10) & 3)
302 puts_filtered ("Round to nearest\n");
305 puts_filtered ("Round down\n");
308 puts_filtered ("Round up\n");
311 puts_filtered ("Round toward zero\n");
316 /* Print out the i387 floating poin state. */
318 i387_float_info (void)
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 printf_filtered ("%sR%d: ", fpreg
== top
? "=>" : " ", fpreg
);
353 puts_filtered ("Valid ");
356 puts_filtered ("Zero ");
359 puts_filtered ("Special ");
362 puts_filtered ("Empty ");
366 read_register_gen ((fpreg
+ 8 - top
) % 8 + FP0_REGNUM
, raw
);
368 puts_filtered ("0x");
369 for (i
= 9; i
>= 0; i
--)
370 printf_filtered ("%02x", raw
[i
]);
373 print_i387_ext (raw
);
375 puts_filtered ("\n");
378 puts_filtered ("\n");
380 print_i387_status_word (fstat
);
381 print_i387_control_word (fctrl
);
382 printf_filtered ("Tag Word: %s\n",
383 local_hex_string_custom (ftag
, "04"));
384 printf_filtered ("Instruction Pointer: %s:",
385 local_hex_string_custom (fiseg
, "02"));
386 printf_filtered ("%s\n", local_hex_string_custom (fioff
, "08"));
387 printf_filtered ("Operand Pointer: %s:",
388 local_hex_string_custom (foseg
, "02"));
389 printf_filtered ("%s\n", local_hex_string_custom (fooff
, "08"));
390 printf_filtered ("Opcode: %s\n",
391 local_hex_string_custom (fop
? (fop
| 0xd800) : 0, "04"));
This page took 0.037569 seconds and 4 git commands to generate.