2003-06-14 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / i387-tdep.c
1 /* Intel 387 floating point stuff.
2
3 Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000,
4 2001, 2002, 2003 Free Software Foundation, Inc.
5
6 This file is part of GDB.
7
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.
12
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.
17
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. */
22
23 #include "defs.h"
24 #include "frame.h"
25 #include "inferior.h"
26 #include "language.h"
27 #include "value.h"
28 #include "gdbcore.h"
29 #include "floatformat.h"
30 #include "regcache.h"
31 #include "gdb_assert.h"
32 #include "gdb_string.h"
33 #include "doublest.h"
34
35 #include "i386-tdep.h"
36 #include "i387-tdep.h"
37
38 /* Implement the `info float' layout based on the register definitions
39 in `tm-i386.h'. */
40
41 /* Print the floating point number specified by RAW. */
42 static void
43 print_i387_value (char *raw, struct ui_file *file)
44 {
45 DOUBLEST value;
46
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);
52
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);
59 #else
60 fprintf_filtered (file, " %-+27.19g", (double) value);
61 #endif
62 }
63
64 /* Print the classification for the register contents RAW. */
65 static void
66 print_i387_ext (unsigned char *raw, struct ui_file *file)
67 {
68 int sign;
69 int integer;
70 unsigned int exponent;
71 unsigned long fraction[2];
72
73 sign = raw[9] & 0x80;
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]);
79
80 if (exponent == 0x7fff && integer)
81 {
82 if (fraction[0] == 0x00000000 && fraction[1] == 0x00000000)
83 /* Infinity. */
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)
89 /* QNaN. */
90 fputs_filtered (" QNaN", file);
91 else
92 /* SNaN. */
93 fputs_filtered (" SNaN", file);
94 }
95 else if (exponent < 0x7fff && exponent > 0x0000 && integer)
96 /* Normal. */
97 print_i387_value (raw, file);
98 else if (exponent == 0x0000)
99 {
100 /* Denormal or zero. */
101 print_i387_value (raw, file);
102
103 if (integer)
104 /* Pseudo-denormal. */
105 fputs_filtered (" Pseudo-denormal", file);
106 else if (fraction[0] || fraction[1])
107 /* Denormal. */
108 fputs_filtered (" Denormal", file);
109 }
110 else
111 /* Unsupported. */
112 fputs_filtered (" Unsupported", file);
113 }
114
115 /* Print the status word STATUS. */
116 static void
117 print_i387_status_word (unsigned int status, struct ui_file *file)
118 {
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" : " ");
137
138 fputs_filtered ("\n", file);
139
140 fprintf_filtered (file,
141 " TOP: %d\n", ((status >> 11) & 7));
142 }
143
144 /* Print the control word CONTROL. */
145 static void
146 print_i387_control_word (unsigned int control, struct ui_file *file)
147 {
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" : " ");
157
158 fputs_filtered ("\n", file);
159
160 fputs_filtered (" PC: ", file);
161 switch ((control >> 8) & 3)
162 {
163 case 0:
164 fputs_filtered ("Single Precision (24-bits)\n", file);
165 break;
166 case 1:
167 fputs_filtered ("Reserved\n", file);
168 break;
169 case 2:
170 fputs_filtered ("Double Precision (53-bits)\n", file);
171 break;
172 case 3:
173 fputs_filtered ("Extended Precision (64-bits)\n", file);
174 break;
175 }
176
177 fputs_filtered (" RC: ", file);
178 switch ((control >> 10) & 3)
179 {
180 case 0:
181 fputs_filtered ("Round to nearest\n", file);
182 break;
183 case 1:
184 fputs_filtered ("Round down\n", file);
185 break;
186 case 2:
187 fputs_filtered ("Round up\n", file);
188 break;
189 case 3:
190 fputs_filtered ("Round toward zero\n", file);
191 break;
192 }
193 }
194
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. */
198
199 void
200 i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
201 struct frame_info *frame, const char *args)
202 {
203 char buf[4];
204 ULONGEST fctrl;
205 ULONGEST fstat;
206 ULONGEST ftag;
207 ULONGEST fiseg;
208 ULONGEST fioff;
209 ULONGEST foseg;
210 ULONGEST fooff;
211 ULONGEST fop;
212 int fpreg;
213 int top;
214
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);
231
232 top = ((fstat >> 11) & 7);
233
234 for (fpreg = 7; fpreg >= 0; fpreg--)
235 {
236 unsigned char raw[FPU_REG_RAW_SIZE];
237 int tag = (ftag >> (fpreg * 2)) & 3;
238 int i;
239
240 fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg);
241
242 switch (tag)
243 {
244 case 0:
245 fputs_filtered ("Valid ", file);
246 break;
247 case 1:
248 fputs_filtered ("Zero ", file);
249 break;
250 case 2:
251 fputs_filtered ("Special ", file);
252 break;
253 case 3:
254 fputs_filtered ("Empty ", file);
255 break;
256 }
257
258 frame_register_read (frame, (fpreg + 8 - top) % 8 + FP0_REGNUM, raw);
259
260 fputs_filtered ("0x", file);
261 for (i = 9; i >= 0; i--)
262 fprintf_filtered (file, "%02x", raw[i]);
263
264 if (tag != 3)
265 print_i387_ext (raw, file);
266
267 fputs_filtered ("\n", file);
268 }
269
270 fputs_filtered ("\n", file);
271
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"));
284 }
285
286 /* FIXME: kettenis/2000-05-21: Right now more than a few i386 targets
287 define their own routines to manage the floating-point registers in
288 GDB's register array. Most (if not all) of these targets use the
289 format used by the "fsave" instruction in their communication with
290 the OS. They should all be converted to use the routines below. */
291
292 /* At fsave_offset[REGNUM] you'll find the offset to the location in
293 the data structure used by the "fsave" instruction where GDB
294 register REGNUM is stored. */
295
296 static int fsave_offset[] =
297 {
298 28 + 0 * FPU_REG_RAW_SIZE, /* FP0_REGNUM through ... */
299 28 + 1 * FPU_REG_RAW_SIZE,
300 28 + 2 * FPU_REG_RAW_SIZE,
301 28 + 3 * FPU_REG_RAW_SIZE,
302 28 + 4 * FPU_REG_RAW_SIZE,
303 28 + 5 * FPU_REG_RAW_SIZE,
304 28 + 6 * FPU_REG_RAW_SIZE,
305 28 + 7 * FPU_REG_RAW_SIZE, /* ... FP7_REGNUM. */
306 0, /* FCTRL_REGNUM (16 bits). */
307 4, /* FSTAT_REGNUM (16 bits). */
308 8, /* FTAG_REGNUM (16 bits). */
309 16, /* FISEG_REGNUM (16 bits). */
310 12, /* FIOFF_REGNUM. */
311 24, /* FOSEG_REGNUM. */
312 20, /* FOOFF_REGNUM. */
313 18 /* FOP_REGNUM (bottom 11 bits). */
314 };
315
316 #define FSAVE_ADDR(fsave, regnum) (fsave + fsave_offset[regnum - FP0_REGNUM])
317 \f
318
319 /* Fill register REGNUM in GDB's register array with the appropriate
320 value from *FSAVE. This function masks off any of the reserved
321 bits in *FSAVE. */
322
323 void
324 i387_supply_register (int regnum, char *fsave)
325 {
326 if (fsave == NULL)
327 {
328 supply_register (regnum, NULL);
329 return;
330 }
331
332 /* Most of the FPU control registers occupy only 16 bits in
333 the fsave area. Give those a special treatment. */
334 if (regnum >= FPC_REGNUM
335 && regnum != FIOFF_REGNUM && regnum != FOOFF_REGNUM)
336 {
337 unsigned char val[4];
338
339 memcpy (val, FSAVE_ADDR (fsave, regnum), 2);
340 val[2] = val[3] = 0;
341 if (regnum == FOP_REGNUM)
342 val[1] &= ((1 << 3) - 1);
343 supply_register (regnum, val);
344 }
345 else
346 supply_register (regnum, FSAVE_ADDR (fsave, regnum));
347 }
348
349 /* Fill GDB's register array with the floating-point register values
350 in *FSAVE. This function masks off any of the reserved
351 bits in *FSAVE. */
352
353 void
354 i387_supply_fsave (char *fsave)
355 {
356 int i;
357
358 for (i = FP0_REGNUM; i < XMM0_REGNUM; i++)
359 i387_supply_register (i, fsave);
360 }
361
362 /* Fill register REGNUM (if it is a floating-point register) in *FSAVE
363 with the value in GDB's register array. If REGNUM is -1, do this
364 for all registers. This function doesn't touch any of the reserved
365 bits in *FSAVE. */
366
367 void
368 i387_fill_fsave (char *fsave, int regnum)
369 {
370 int i;
371
372 for (i = FP0_REGNUM; i < XMM0_REGNUM; i++)
373 if (regnum == -1 || regnum == i)
374 {
375 /* Most of the FPU control registers occupy only 16 bits in
376 the fsave area. Give those a special treatment. */
377 if (i >= FPC_REGNUM
378 && i != FIOFF_REGNUM && i != FOOFF_REGNUM)
379 {
380 unsigned char buf[4];
381
382 regcache_collect (i, buf);
383
384 if (i == FOP_REGNUM)
385 {
386 /* The opcode occupies only 11 bits. Make sure we
387 don't touch the other bits. */
388 buf[1] &= ((1 << 3) - 1);
389 buf[1] |= ((FSAVE_ADDR (fsave, i))[1] & ~((1 << 3) - 1));
390 }
391 memcpy (FSAVE_ADDR (fsave, i), buf, 2);
392 }
393 else
394 regcache_collect (i, FSAVE_ADDR (fsave, i));
395 }
396 }
397 \f
398
399 /* At fxsave_offset[REGNUM] you'll find the offset to the location in
400 the data structure used by the "fxsave" instruction where GDB
401 register REGNUM is stored. */
402
403 static int fxsave_offset[] =
404 {
405 32, /* FP0_REGNUM through ... */
406 48,
407 64,
408 80,
409 96,
410 112,
411 128,
412 144, /* ... FP7_REGNUM (80 bits each). */
413 0, /* FCTRL_REGNUM (16 bits). */
414 2, /* FSTAT_REGNUM (16 bits). */
415 4, /* FTAG_REGNUM (16 bits). */
416 12, /* FISEG_REGNUM (16 bits). */
417 8, /* FIOFF_REGNUM. */
418 20, /* FOSEG_REGNUM (16 bits). */
419 16, /* FOOFF_REGNUM. */
420 6, /* FOP_REGNUM (bottom 11 bits). */
421 160 + 0 * 16, /* XMM0_REGNUM through ... */
422 160 + 1 * 16,
423 160 + 2 * 16,
424 160 + 3 * 16,
425 160 + 4 * 16,
426 160 + 5 * 16,
427 160 + 6 * 16,
428 160 + 7 * 16,
429 160 + 8 * 16,
430 160 + 9 * 16,
431 160 + 10 * 16,
432 160 + 11 * 16,
433 160 + 12 * 16,
434 160 + 13 * 16,
435 160 + 14 * 16,
436 160 + 15 * 16, /* ... XMM15_REGNUM (128 bits each). */
437 24 /* MXCSR_REGNUM. */
438 };
439
440 /* FIXME: kettenis/20030430: We made an unfortunate choice in putting
441 %mxcsr after the SSE registers %xmm0-%xmm7 instead of before, since
442 it makes supporting the registers %xmm8-%xmm15 on x86-64 a bit
443 involved. Hack around it by explicitly overriding the offset for
444 %mxcsr here. */
445
446 #define FXSAVE_ADDR(fxsave, regnum) \
447 ((regnum == MXCSR_REGNUM) ? (fxsave + 24) : \
448 (fxsave + fxsave_offset[regnum - FP0_REGNUM]))
449
450 static int i387_tag (unsigned char *raw);
451 \f
452
453 /* Fill GDB's register array with the floating-point and SSE register
454 values in *FXSAVE. This function masks off any of the reserved
455 bits in *FXSAVE. */
456
457 void
458 i387_supply_fxsave (char *fxsave)
459 {
460 int i, last_regnum = MXCSR_REGNUM;
461
462 if (gdbarch_tdep (current_gdbarch)->num_xmm_regs == 0)
463 last_regnum = FOP_REGNUM;
464
465 for (i = FP0_REGNUM; i <= last_regnum; i++)
466 {
467 if (fxsave == NULL)
468 {
469 supply_register (i, NULL);
470 continue;
471 }
472
473 /* Most of the FPU control registers occupy only 16 bits in
474 the fxsave area. Give those a special treatment. */
475 if (i >= FPC_REGNUM && i < XMM0_REGNUM
476 && i != FIOFF_REGNUM && i != FOOFF_REGNUM)
477 {
478 unsigned char val[4];
479
480 memcpy (val, FXSAVE_ADDR (fxsave, i), 2);
481 val[2] = val[3] = 0;
482 if (i == FOP_REGNUM)
483 val[1] &= ((1 << 3) - 1);
484 else if (i== FTAG_REGNUM)
485 {
486 /* The fxsave area contains a simplified version of the
487 tag word. We have to look at the actual 80-bit FP
488 data to recreate the traditional i387 tag word. */
489
490 unsigned long ftag = 0;
491 int fpreg;
492 int top;
493
494 top = (((FXSAVE_ADDR (fxsave, FSTAT_REGNUM))[1] >> 3) & 0x7);
495
496 for (fpreg = 7; fpreg >= 0; fpreg--)
497 {
498 int tag;
499
500 if (val[0] & (1 << fpreg))
501 {
502 int regnum = (fpreg + 8 - top) % 8 + FP0_REGNUM;
503 tag = i387_tag (FXSAVE_ADDR (fxsave, regnum));
504 }
505 else
506 tag = 3; /* Empty */
507
508 ftag |= tag << (2 * fpreg);
509 }
510 val[0] = ftag & 0xff;
511 val[1] = (ftag >> 8) & 0xff;
512 }
513 supply_register (i, val);
514 }
515 else
516 supply_register (i, FXSAVE_ADDR (fxsave, i));
517 }
518 }
519
520 /* Fill register REGNUM (if it is a floating-point or SSE register) in
521 *FXSAVE with the value in GDB's register array. If REGNUM is -1, do
522 this for all registers. This function doesn't touch any of the
523 reserved bits in *FXSAVE. */
524
525 void
526 i387_fill_fxsave (char *fxsave, int regnum)
527 {
528 int i, last_regnum = MXCSR_REGNUM;
529
530 if (gdbarch_tdep (current_gdbarch)->num_xmm_regs == 0)
531 last_regnum = FOP_REGNUM;
532
533 for (i = FP0_REGNUM; i <= last_regnum; i++)
534 if (regnum == -1 || regnum == i)
535 {
536 /* Most of the FPU control registers occupy only 16 bits in
537 the fxsave area. Give those a special treatment. */
538 if (i >= FPC_REGNUM && i < XMM0_REGNUM
539 && i != FIOFF_REGNUM && i != FOOFF_REGNUM)
540 {
541 unsigned char buf[4];
542
543 regcache_collect (i, buf);
544
545 if (i == FOP_REGNUM)
546 {
547 /* The opcode occupies only 11 bits. Make sure we
548 don't touch the other bits. */
549 buf[1] &= ((1 << 3) - 1);
550 buf[1] |= ((FXSAVE_ADDR (fxsave, i))[1] & ~((1 << 3) - 1));
551 }
552 else if (i == FTAG_REGNUM)
553 {
554 /* Converting back is much easier. */
555
556 unsigned short ftag;
557 int fpreg;
558
559 ftag = (buf[1] << 8) | buf[0];
560 buf[0] = 0;
561 buf[1] = 0;
562
563 for (fpreg = 7; fpreg >= 0; fpreg--)
564 {
565 int tag = (ftag >> (fpreg * 2)) & 3;
566
567 if (tag != 3)
568 buf[0] |= (1 << fpreg);
569 }
570 }
571 memcpy (FXSAVE_ADDR (fxsave, i), buf, 2);
572 }
573 else
574 regcache_collect (i, FXSAVE_ADDR (fxsave, i));
575 }
576 }
577
578 /* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
579 *RAW. */
580
581 static int
582 i387_tag (unsigned char *raw)
583 {
584 int integer;
585 unsigned int exponent;
586 unsigned long fraction[2];
587
588 integer = raw[7] & 0x80;
589 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
590 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
591 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
592 | (raw[5] << 8) | raw[4]);
593
594 if (exponent == 0x7fff)
595 {
596 /* Special. */
597 return (2);
598 }
599 else if (exponent == 0x0000)
600 {
601 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
602 {
603 /* Zero. */
604 return (1);
605 }
606 else
607 {
608 /* Special. */
609 return (2);
610 }
611 }
612 else
613 {
614 if (integer)
615 {
616 /* Valid. */
617 return (0);
618 }
619 else
620 {
621 /* Special. */
622 return (2);
623 }
624 }
625 }
This page took 0.06388 seconds and 5 git commands to generate.