Delete add_minsym_to_demangled_hash_table from symtabs.h. Static function.
[deliverable/binutils-gdb.git] / gdb / i387-tdep.c
CommitLineData
c906108c 1/* Intel 387 floating point stuff.
ac27f131 2 Copyright (C) 1988, 89, 91, 98, 99, 2000 Free Software Foundation, Inc.
c906108c 3
c5aa993b 4 This file is part of GDB.
c906108c 5
c5aa993b
JM
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
c906108c 10
c5aa993b
JM
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
c906108c 15
c5aa993b
JM
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
c906108c
SS
20
21#include "defs.h"
22#include "frame.h"
23#include "inferior.h"
24#include "language.h"
d4f3574e 25#include "value.h"
c906108c
SS
26#include "gdbcore.h"
27#include "floatformat.h"
28
c906108c 29
de57eccd
JM
30/* FIXME: Eliminate the next two functions when we have the time to
31 change all the callers. */
d4f3574e 32
de57eccd
JM
33void i387_to_double PARAMS ((char *from, char *to));
34void double_to_i387 PARAMS ((char *from, char *to));
c906108c
SS
35
36void
37i387_to_double (from, to)
38 char *from;
39 char *to;
40{
c5aa993b 41 floatformat_to_double (&floatformat_i387_ext, from, (double *) to);
c906108c
SS
42}
43
44void
45double_to_i387 (from, to)
46 char *from;
47 char *to;
48{
c5aa993b 49 floatformat_from_double (&floatformat_i387_ext, (double *) from, to);
c906108c
SS
50}
51
de57eccd
JM
52\f
53/* FIXME: The functions on this page are used by the old `info float'
54 implementations that a few of the i386 targets provide. These
55 functions should be removed if all of these have been converted to
56 use the generic implementation based on the new register file
57 layout. */
58
59static void print_387_control_bits PARAMS ((unsigned int control));
60static void print_387_status_bits PARAMS ((unsigned int status));
61
d4f3574e
SS
62static void
63print_387_control_bits (control)
c906108c
SS
64 unsigned int control;
65{
c5aa993b 66 switch ((control >> 8) & 3)
c906108c 67 {
c5aa993b 68 case 0:
d4f3574e 69 puts_unfiltered (" 24 bit; ");
c5aa993b
JM
70 break;
71 case 1:
d4f3574e 72 puts_unfiltered (" (bad); ");
c5aa993b
JM
73 break;
74 case 2:
d4f3574e 75 puts_unfiltered (" 53 bit; ");
c5aa993b
JM
76 break;
77 case 3:
d4f3574e 78 puts_unfiltered (" 64 bit; ");
c5aa993b 79 break;
c906108c 80 }
c5aa993b 81 switch ((control >> 10) & 3)
c906108c 82 {
c5aa993b 83 case 0:
d4f3574e 84 puts_unfiltered ("NEAR; ");
c5aa993b
JM
85 break;
86 case 1:
d4f3574e 87 puts_unfiltered ("DOWN; ");
c5aa993b
JM
88 break;
89 case 2:
d4f3574e 90 puts_unfiltered ("UP; ");
c5aa993b
JM
91 break;
92 case 3:
d4f3574e 93 puts_unfiltered ("CHOP; ");
c5aa993b 94 break;
c906108c 95 }
c5aa993b 96 if (control & 0x3f)
c906108c 97 {
d4f3574e 98 puts_unfiltered ("mask");
c5aa993b 99 if (control & 0x0001)
d4f3574e 100 puts_unfiltered (" INVAL");
c5aa993b 101 if (control & 0x0002)
d4f3574e 102 puts_unfiltered (" DENOR");
c5aa993b 103 if (control & 0x0004)
d4f3574e 104 puts_unfiltered (" DIVZ");
c5aa993b 105 if (control & 0x0008)
d4f3574e 106 puts_unfiltered (" OVERF");
c5aa993b 107 if (control & 0x0010)
d4f3574e 108 puts_unfiltered (" UNDER");
c5aa993b 109 if (control & 0x0020)
d4f3574e
SS
110 puts_unfiltered (" LOS");
111 puts_unfiltered (";");
c906108c 112 }
cff3e48b 113
c5aa993b 114 if (control & 0xe080)
d4f3574e 115 warning ("\nreserved bits on: %s",
c5aa993b 116 local_hex_string (control & 0xe080));
c906108c
SS
117}
118
119void
d4f3574e
SS
120print_387_control_word (control)
121 unsigned int control;
122{
123 printf_filtered ("control %s:", local_hex_string(control & 0xffff));
124 print_387_control_bits (control);
125 puts_unfiltered ("\n");
126}
127
128static void
129print_387_status_bits (status)
c906108c
SS
130 unsigned int status;
131{
d4f3574e 132 printf_unfiltered (" flags %d%d%d%d; ",
c5aa993b
JM
133 (status & 0x4000) != 0,
134 (status & 0x0400) != 0,
135 (status & 0x0200) != 0,
136 (status & 0x0100) != 0);
d4f3574e
SS
137 printf_unfiltered ("top %d; ", (status >> 11) & 7);
138 if (status & 0xff)
139 {
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");
148 }
149}
150
151void
152print_387_status_word (status)
153 unsigned int status;
154{
155 printf_filtered ("status %s:", local_hex_string (status & 0xffff));
156 print_387_status_bits (status);
157 puts_unfiltered ("\n");
158}
159
de57eccd
JM
160\f
161/* Implement the `info float' layout based on the register definitions
162 in `tm-i386.h'. */
163
164/* Print the floating point number specified by RAW. */
165static void
166print_i387_value (char *raw)
167{
168 DOUBLEST value;
169
170 floatformat_to_doublest (&floatformat_i387_ext, raw, &value);
171
172 /* We try to print 19 digits. The last digit may or may not contain
173 garbage, but we'd better print one too many. We need enough room
174 to print the value, 1 position for the sign, 1 for the decimal
175 point, 19 for the digits and 6 for the exponent adds up to 27. */
176#ifdef PRINTF_HAS_LONG_DOUBLE
177 printf_filtered (" %-+27.19Lg", (long double) value);
178#else
179 printf_filtered (" %-+27.19g", (double) value);
180#endif
181}
182
183/* Print the classification for the register contents RAW. */
184static void
185print_i387_ext (unsigned char *raw)
186{
187 int sign;
188 int integer;
189 unsigned int exponent;
190 unsigned long fraction[2];
191
192 sign = raw[9] & 0x80;
193 integer = raw[7] & 0x80;
194 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
195 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
196 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
197 | (raw[5] << 8) | raw[4]);
198
199 if (exponent == 0x7fff && integer)
200 {
201 if (fraction[0] == 0x00000000 && fraction[1] == 0x00000000)
202 /* Infinity. */
203 printf_filtered (" %cInf", (sign ? '-' : '+'));
204 else if (sign && fraction[0] == 0x00000000 && fraction[1] == 0x40000000)
205 /* Real Indefinite (QNaN). */
206 puts_unfiltered (" Real Indefinite (QNaN)");
207 else if (fraction[1] & 0x40000000)
208 /* QNaN. */
209 puts_filtered (" QNaN");
210 else
211 /* SNaN. */
212 puts_filtered (" SNaN");
213 }
214 else if (exponent < 0x7fff && exponent > 0x0000 && integer)
215 /* Normal. */
216 print_i387_value (raw);
217 else if (exponent == 0x0000)
218 {
219 /* Denormal or zero. */
220 print_i387_value (raw);
221
222 if (integer)
223 /* Pseudo-denormal. */
224 puts_filtered (" Pseudo-denormal");
225 else if (fraction[0] || fraction[1])
226 /* Denormal. */
227 puts_filtered (" Denormal");
228 }
229 else
230 /* Unsupported. */
231 puts_filtered (" Unsupported");
232}
233
234/* Print the status word STATUS. */
235static void
236print_i387_status_word (unsigned int status)
237{
238 printf_filtered ("Status Word: %s",
239 local_hex_string_custom (status, "04"));
240 puts_filtered (" ");
241 printf_filtered (" %s", (status & 0x0001) ? "IE" : " ");
242 printf_filtered (" %s", (status & 0x0002) ? "DE" : " ");
243 printf_filtered (" %s", (status & 0x0004) ? "ZE" : " ");
244 printf_filtered (" %s", (status & 0x0008) ? "OE" : " ");
245 printf_filtered (" %s", (status & 0x0010) ? "UE" : " ");
246 printf_filtered (" %s", (status & 0x0020) ? "PE" : " ");
247 puts_filtered (" ");
248 printf_filtered (" %s", (status & 0x0080) ? "ES" : " ");
249 puts_filtered (" ");
250 printf_filtered (" %s", (status & 0x0080) ? "SF" : " ");
251 puts_filtered (" ");
252 printf_filtered (" %s", (status & 0x0100) ? "C0" : " ");
253 printf_filtered (" %s", (status & 0x0200) ? "C1" : " ");
254 printf_filtered (" %s", (status & 0x0400) ? "C2" : " ");
255 printf_filtered (" %s", (status & 0x4000) ? "C3" : " ");
256
257 puts_filtered ("\n");
258
259 printf_filtered (" TOP: %d\n", ((status >> 11) & 7));
260}
261
262/* Print the control word CONTROL. */
263static void
264print_i387_control_word (unsigned int control)
265{
266 printf_filtered ("Control Word: %s",
267 local_hex_string_custom (control, "04"));
268 puts_filtered (" ");
269 printf_filtered (" %s", (control & 0x0001) ? "IM" : " ");
270 printf_filtered (" %s", (control & 0x0002) ? "DM" : " ");
271 printf_filtered (" %s", (control & 0x0004) ? "ZM" : " ");
272 printf_filtered (" %s", (control & 0x0008) ? "OM" : " ");
273 printf_filtered (" %s", (control & 0x0010) ? "UM" : " ");
274 printf_filtered (" %s", (control & 0x0020) ? "PM" : " ");
275
276 puts_filtered ("\n");
277
278 puts_filtered (" PC: ");
279 switch ((control >> 8) & 3)
280 {
281 case 0:
282 puts_filtered ("Single Precision (24-bits)\n");
283 break;
284 case 1:
285 puts_filtered ("Reserved\n");
286 break;
287 case 2:
288 puts_filtered ("Double Precision (53-bits)\n");
289 break;
290 case 3:
291 puts_filtered ("Extended Precision (64-bits)\n");
292 break;
293 }
294
295 puts_filtered (" RC: ");
296 switch ((control >> 10) & 3)
297 {
298 case 0:
299 puts_filtered ("Round to nearest\n");
300 break;
301 case 1:
302 puts_filtered ("Round down\n");
303 break;
304 case 2:
305 puts_filtered ("Round up\n");
306 break;
307 case 3:
308 puts_filtered ("Round toward zero\n");
309 break;
310 }
311}
312
313/* Print out the i387 floating poin state. */
314void
315i387_float_info (void)
316{
317 unsigned int fctrl;
318 unsigned int fstat;
319 unsigned int ftag;
320 unsigned int fiseg;
321 unsigned int fioff;
322 unsigned int foseg;
323 unsigned int fooff;
324 unsigned int fop;
325 int fpreg;
326 int top;
327
328 fctrl = read_register (FCTRL_REGNUM);
329 fstat = read_register (FSTAT_REGNUM);
330 ftag = read_register (FTAG_REGNUM);
331 fiseg = read_register (FCS_REGNUM);
332 fioff = read_register (FCOFF_REGNUM);
333 foseg = read_register (FDS_REGNUM);
334 fooff = read_register (FDOFF_REGNUM);
335 fop = read_register (FOP_REGNUM);
336
337 top = ((fstat >> 11) & 7);
338
339 for (fpreg = 7; fpreg >= 0; fpreg--)
340 {
341 unsigned char raw[FPU_REG_RAW_SIZE];
342 int tag = (ftag >> (fpreg * 2)) & 3;
343 int i;
344
345 printf_filtered ("%sR%d: ", fpreg == top ? "=>" : " ", fpreg);
346
347 switch (tag)
348 {
349 case 0:
350 puts_filtered ("Valid ");
351 break;
352 case 1:
353 puts_filtered ("Zero ");
354 break;
355 case 2:
356 puts_filtered ("Special ");
357 break;
358 case 3:
359 puts_filtered ("Empty ");
360 break;
361 }
362
363 read_register_gen ((fpreg + 8 - top) % 8 + FP0_REGNUM, raw);
364
365 puts_filtered ("0x");
366 for (i = 9; i >= 0; i--)
367 printf_filtered ("%02x", raw[i]);
368
369 if (tag != 3)
370 print_i387_ext (raw);
371
372 puts_filtered ("\n");
373 }
374
375 puts_filtered ("\n");
376
377 print_i387_status_word (fstat);
378 print_i387_control_word (fctrl);
379 printf_filtered ("Tag Word: %s\n",
380 local_hex_string_custom (ftag, "04"));
381 printf_filtered ("Instruction Pointer: %s:",
382 local_hex_string_custom (fiseg, "02"));
383 printf_filtered ("%s\n", local_hex_string_custom (fioff, "08"));
384 printf_filtered ("Operand Pointer: %s:",
385 local_hex_string_custom (foseg, "02"));
386 printf_filtered ("%s\n", local_hex_string_custom (fooff, "08"));
387 printf_filtered ("Opcode: %s\n",
388 local_hex_string_custom (fop ? (fop | 0xd800) : 0, "04"));
389}
This page took 0.061828 seconds and 4 git commands to generate.