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
)
168 int len
= TARGET_LONG_DOUBLE_BIT
/ TARGET_CHAR_BIT
;
169 char *tmp
= alloca (len
);
171 /* This code only works on targets where ... */
172 gdb_assert (TARGET_LONG_DOUBLE_FORMAT
== &floatformat_i387_ext
);
174 /* Take care of the padding. FP reg is 80 bits. The same value in
175 memory is 96 bits. */
176 gdb_assert (FPU_REG_RAW_SIZE
< len
);
177 memcpy (tmp
, raw
, FPU_REG_RAW_SIZE
);
178 memset (tmp
+ FPU_REG_RAW_SIZE
, 0, len
- FPU_REG_RAW_SIZE
);
180 /* Extract the value as a DOUBLEST. */
181 /* Use extract_floating() rather than floatformat_to_doublest().
182 The latter is lossy in nature. Once GDB gets a host/target
183 independent and non-lossy FP it will become possible to bypass
184 extract_floating() and call floatformat*() directly. Note also
185 the assumptions about TARGET_LONG_DOUBLE above. */
186 value
= extract_floating (tmp
, len
);
188 /* We try to print 19 digits. The last digit may or may not contain
189 garbage, but we'd better print one too many. We need enough room
190 to print the value, 1 position for the sign, 1 for the decimal
191 point, 19 for the digits and 6 for the exponent adds up to 27. */
192 #ifdef PRINTF_HAS_LONG_DOUBLE
193 printf_filtered (" %-+27.19Lg", (long double) value
);
195 printf_filtered (" %-+27.19g", (double) value
);
199 /* Print the classification for the register contents RAW. */
201 print_i387_ext (unsigned char *raw
)
205 unsigned int exponent
;
206 unsigned long fraction
[2];
208 sign
= raw
[9] & 0x80;
209 integer
= raw
[7] & 0x80;
210 exponent
= (((raw
[9] & 0x7f) << 8) | raw
[8]);
211 fraction
[0] = ((raw
[3] << 24) | (raw
[2] << 16) | (raw
[1] << 8) | raw
[0]);
212 fraction
[1] = (((raw
[7] & 0x7f) << 24) | (raw
[6] << 16)
213 | (raw
[5] << 8) | raw
[4]);
215 if (exponent
== 0x7fff && integer
)
217 if (fraction
[0] == 0x00000000 && fraction
[1] == 0x00000000)
219 printf_filtered (" %cInf", (sign
? '-' : '+'));
220 else if (sign
&& fraction
[0] == 0x00000000 && fraction
[1] == 0x40000000)
221 /* Real Indefinite (QNaN). */
222 puts_unfiltered (" Real Indefinite (QNaN)");
223 else if (fraction
[1] & 0x40000000)
225 puts_filtered (" QNaN");
228 puts_filtered (" SNaN");
230 else if (exponent
< 0x7fff && exponent
> 0x0000 && integer
)
232 print_i387_value (raw
);
233 else if (exponent
== 0x0000)
235 /* Denormal or zero. */
236 print_i387_value (raw
);
239 /* Pseudo-denormal. */
240 puts_filtered (" Pseudo-denormal");
241 else if (fraction
[0] || fraction
[1])
243 puts_filtered (" Denormal");
247 puts_filtered (" Unsupported");
250 /* Print the status word STATUS. */
252 print_i387_status_word (unsigned int status
)
254 printf_filtered ("Status Word: %s",
255 local_hex_string_custom (status
, "04"));
257 printf_filtered (" %s", (status
& 0x0001) ? "IE" : " ");
258 printf_filtered (" %s", (status
& 0x0002) ? "DE" : " ");
259 printf_filtered (" %s", (status
& 0x0004) ? "ZE" : " ");
260 printf_filtered (" %s", (status
& 0x0008) ? "OE" : " ");
261 printf_filtered (" %s", (status
& 0x0010) ? "UE" : " ");
262 printf_filtered (" %s", (status
& 0x0020) ? "PE" : " ");
264 printf_filtered (" %s", (status
& 0x0080) ? "ES" : " ");
266 printf_filtered (" %s", (status
& 0x0040) ? "SF" : " ");
268 printf_filtered (" %s", (status
& 0x0100) ? "C0" : " ");
269 printf_filtered (" %s", (status
& 0x0200) ? "C1" : " ");
270 printf_filtered (" %s", (status
& 0x0400) ? "C2" : " ");
271 printf_filtered (" %s", (status
& 0x4000) ? "C3" : " ");
273 puts_filtered ("\n");
275 printf_filtered (" TOP: %d\n", ((status
>> 11) & 7));
278 /* Print the control word CONTROL. */
280 print_i387_control_word (unsigned int control
)
282 printf_filtered ("Control Word: %s",
283 local_hex_string_custom (control
, "04"));
285 printf_filtered (" %s", (control
& 0x0001) ? "IM" : " ");
286 printf_filtered (" %s", (control
& 0x0002) ? "DM" : " ");
287 printf_filtered (" %s", (control
& 0x0004) ? "ZM" : " ");
288 printf_filtered (" %s", (control
& 0x0008) ? "OM" : " ");
289 printf_filtered (" %s", (control
& 0x0010) ? "UM" : " ");
290 printf_filtered (" %s", (control
& 0x0020) ? "PM" : " ");
292 puts_filtered ("\n");
294 puts_filtered (" PC: ");
295 switch ((control
>> 8) & 3)
298 puts_filtered ("Single Precision (24-bits)\n");
301 puts_filtered ("Reserved\n");
304 puts_filtered ("Double Precision (53-bits)\n");
307 puts_filtered ("Extended Precision (64-bits)\n");
311 puts_filtered (" RC: ");
312 switch ((control
>> 10) & 3)
315 puts_filtered ("Round to nearest\n");
318 puts_filtered ("Round down\n");
321 puts_filtered ("Round up\n");
324 puts_filtered ("Round toward zero\n");
329 /* Print out the i387 floating poin state. */
331 i387_float_info (void)
344 fctrl
= read_register (FCTRL_REGNUM
);
345 fstat
= read_register (FSTAT_REGNUM
);
346 ftag
= read_register (FTAG_REGNUM
);
347 fiseg
= read_register (FCS_REGNUM
);
348 fioff
= read_register (FCOFF_REGNUM
);
349 foseg
= read_register (FDS_REGNUM
);
350 fooff
= read_register (FDOFF_REGNUM
);
351 fop
= read_register (FOP_REGNUM
);
353 top
= ((fstat
>> 11) & 7);
355 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
357 unsigned char raw
[FPU_REG_RAW_SIZE
];
358 int tag
= (ftag
>> (fpreg
* 2)) & 3;
361 printf_filtered ("%sR%d: ", fpreg
== top
? "=>" : " ", fpreg
);
366 puts_filtered ("Valid ");
369 puts_filtered ("Zero ");
372 puts_filtered ("Special ");
375 puts_filtered ("Empty ");
379 read_register_gen ((fpreg
+ 8 - top
) % 8 + FP0_REGNUM
, raw
);
381 puts_filtered ("0x");
382 for (i
= 9; i
>= 0; i
--)
383 printf_filtered ("%02x", raw
[i
]);
386 print_i387_ext (raw
);
388 puts_filtered ("\n");
391 puts_filtered ("\n");
393 print_i387_status_word (fstat
);
394 print_i387_control_word (fctrl
);
395 printf_filtered ("Tag Word: %s\n",
396 local_hex_string_custom (ftag
, "04"));
397 printf_filtered ("Instruction Pointer: %s:",
398 local_hex_string_custom (fiseg
, "02"));
399 printf_filtered ("%s\n", local_hex_string_custom (fioff
, "08"));
400 printf_filtered ("Operand Pointer: %s:",
401 local_hex_string_custom (foseg
, "02"));
402 printf_filtered ("%s\n", local_hex_string_custom (fooff
, "08"));
403 printf_filtered ("Opcode: %s\n",
404 local_hex_string_custom (fop
? (fop
| 0xd800) : 0, "04"));