]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/i387-tdep.c
* i387-tdep.c (i387_register_to_value): Use get_frame_register
[thirdparty/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 "doublest.h"
25 #include "floatformat.h"
26 #include "frame.h"
27 #include "gdbcore.h"
28 #include "inferior.h"
29 #include "language.h"
30 #include "regcache.h"
31 #include "value.h"
32
33 #include "gdb_assert.h"
34 #include "gdb_string.h"
35
36 #include "i386-tdep.h"
37 #include "i387-tdep.h"
38
39 /* Implement the `info float' layout based on the register definitions
40 in `tm-i386.h'. */
41
42 /* Print the floating point number specified by RAW. */
43
44 static void
45 print_i387_value (char *raw, struct ui_file *file)
46 {
47 DOUBLEST value;
48
49 /* Using extract_typed_floating here might affect the representation
50 of certain numbers such as NaNs, even if GDB is running natively.
51 This is fine since our caller already detects such special
52 numbers and we print the hexadecimal representation anyway. */
53 value = extract_typed_floating (raw, builtin_type_i387_ext);
54
55 /* We try to print 19 digits. The last digit may or may not contain
56 garbage, but we'd better print one too many. We need enough room
57 to print the value, 1 position for the sign, 1 for the decimal
58 point, 19 for the digits and 6 for the exponent adds up to 27. */
59 #ifdef PRINTF_HAS_LONG_DOUBLE
60 fprintf_filtered (file, " %-+27.19Lg", (long double) value);
61 #else
62 fprintf_filtered (file, " %-+27.19g", (double) value);
63 #endif
64 }
65
66 /* Print the classification for the register contents RAW. */
67
68 static void
69 print_i387_ext (unsigned char *raw, struct ui_file *file)
70 {
71 int sign;
72 int integer;
73 unsigned int exponent;
74 unsigned long fraction[2];
75
76 sign = raw[9] & 0x80;
77 integer = raw[7] & 0x80;
78 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
79 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
80 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
81 | (raw[5] << 8) | raw[4]);
82
83 if (exponent == 0x7fff && integer)
84 {
85 if (fraction[0] == 0x00000000 && fraction[1] == 0x00000000)
86 /* Infinity. */
87 fprintf_filtered (file, " %cInf", (sign ? '-' : '+'));
88 else if (sign && fraction[0] == 0x00000000 && fraction[1] == 0x40000000)
89 /* Real Indefinite (QNaN). */
90 fputs_unfiltered (" Real Indefinite (QNaN)", file);
91 else if (fraction[1] & 0x40000000)
92 /* QNaN. */
93 fputs_filtered (" QNaN", file);
94 else
95 /* SNaN. */
96 fputs_filtered (" SNaN", file);
97 }
98 else if (exponent < 0x7fff && exponent > 0x0000 && integer)
99 /* Normal. */
100 print_i387_value (raw, file);
101 else if (exponent == 0x0000)
102 {
103 /* Denormal or zero. */
104 print_i387_value (raw, file);
105
106 if (integer)
107 /* Pseudo-denormal. */
108 fputs_filtered (" Pseudo-denormal", file);
109 else if (fraction[0] || fraction[1])
110 /* Denormal. */
111 fputs_filtered (" Denormal", file);
112 }
113 else
114 /* Unsupported. */
115 fputs_filtered (" Unsupported", file);
116 }
117
118 /* Print the status word STATUS. */
119
120 static void
121 print_i387_status_word (unsigned int status, struct ui_file *file)
122 {
123 fprintf_filtered (file, "Status Word: %s",
124 local_hex_string_custom (status, "04"));
125 fputs_filtered (" ", file);
126 fprintf_filtered (file, " %s", (status & 0x0001) ? "IE" : " ");
127 fprintf_filtered (file, " %s", (status & 0x0002) ? "DE" : " ");
128 fprintf_filtered (file, " %s", (status & 0x0004) ? "ZE" : " ");
129 fprintf_filtered (file, " %s", (status & 0x0008) ? "OE" : " ");
130 fprintf_filtered (file, " %s", (status & 0x0010) ? "UE" : " ");
131 fprintf_filtered (file, " %s", (status & 0x0020) ? "PE" : " ");
132 fputs_filtered (" ", file);
133 fprintf_filtered (file, " %s", (status & 0x0080) ? "ES" : " ");
134 fputs_filtered (" ", file);
135 fprintf_filtered (file, " %s", (status & 0x0040) ? "SF" : " ");
136 fputs_filtered (" ", file);
137 fprintf_filtered (file, " %s", (status & 0x0100) ? "C0" : " ");
138 fprintf_filtered (file, " %s", (status & 0x0200) ? "C1" : " ");
139 fprintf_filtered (file, " %s", (status & 0x0400) ? "C2" : " ");
140 fprintf_filtered (file, " %s", (status & 0x4000) ? "C3" : " ");
141
142 fputs_filtered ("\n", file);
143
144 fprintf_filtered (file,
145 " TOP: %d\n", ((status >> 11) & 7));
146 }
147
148 /* Print the control word CONTROL. */
149
150 static void
151 print_i387_control_word (unsigned int control, struct ui_file *file)
152 {
153 fprintf_filtered (file, "Control Word: %s",
154 local_hex_string_custom (control, "04"));
155 fputs_filtered (" ", file);
156 fprintf_filtered (file, " %s", (control & 0x0001) ? "IM" : " ");
157 fprintf_filtered (file, " %s", (control & 0x0002) ? "DM" : " ");
158 fprintf_filtered (file, " %s", (control & 0x0004) ? "ZM" : " ");
159 fprintf_filtered (file, " %s", (control & 0x0008) ? "OM" : " ");
160 fprintf_filtered (file, " %s", (control & 0x0010) ? "UM" : " ");
161 fprintf_filtered (file, " %s", (control & 0x0020) ? "PM" : " ");
162
163 fputs_filtered ("\n", file);
164
165 fputs_filtered (" PC: ", file);
166 switch ((control >> 8) & 3)
167 {
168 case 0:
169 fputs_filtered ("Single Precision (24-bits)\n", file);
170 break;
171 case 1:
172 fputs_filtered ("Reserved\n", file);
173 break;
174 case 2:
175 fputs_filtered ("Double Precision (53-bits)\n", file);
176 break;
177 case 3:
178 fputs_filtered ("Extended Precision (64-bits)\n", file);
179 break;
180 }
181
182 fputs_filtered (" RC: ", file);
183 switch ((control >> 10) & 3)
184 {
185 case 0:
186 fputs_filtered ("Round to nearest\n", file);
187 break;
188 case 1:
189 fputs_filtered ("Round down\n", file);
190 break;
191 case 2:
192 fputs_filtered ("Round up\n", file);
193 break;
194 case 3:
195 fputs_filtered ("Round toward zero\n", file);
196 break;
197 }
198 }
199
200 /* Print out the i387 floating point state. Note that we ignore FRAME
201 in the code below. That's OK since floating-point registers are
202 never saved on the stack. */
203
204 void
205 i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
206 struct frame_info *frame, const char *args)
207 {
208 char buf[4];
209 ULONGEST fctrl;
210 ULONGEST fstat;
211 ULONGEST ftag;
212 ULONGEST fiseg;
213 ULONGEST fioff;
214 ULONGEST foseg;
215 ULONGEST fooff;
216 ULONGEST fop;
217 int fpreg;
218 int top;
219
220 fctrl = get_frame_register_unsigned (frame, FCTRL_REGNUM);
221 fstat = get_frame_register_unsigned (frame, FSTAT_REGNUM);
222 ftag = get_frame_register_unsigned (frame, FTAG_REGNUM);
223 fiseg = get_frame_register_unsigned (frame, FISEG_REGNUM);
224 fioff = get_frame_register_unsigned (frame, FIOFF_REGNUM);
225 foseg = get_frame_register_unsigned (frame, FOSEG_REGNUM);
226 fooff = get_frame_register_unsigned (frame, FOOFF_REGNUM);
227 fop = get_frame_register_unsigned (frame, FOP_REGNUM);
228
229 top = ((fstat >> 11) & 7);
230
231 for (fpreg = 7; fpreg >= 0; fpreg--)
232 {
233 unsigned char raw[FPU_REG_RAW_SIZE];
234 int tag = (ftag >> (fpreg * 2)) & 3;
235 int i;
236
237 fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg);
238
239 switch (tag)
240 {
241 case 0:
242 fputs_filtered ("Valid ", file);
243 break;
244 case 1:
245 fputs_filtered ("Zero ", file);
246 break;
247 case 2:
248 fputs_filtered ("Special ", file);
249 break;
250 case 3:
251 fputs_filtered ("Empty ", file);
252 break;
253 }
254
255 get_frame_register (frame, (fpreg + 8 - top) % 8 + FP0_REGNUM, raw);
256
257 fputs_filtered ("0x", file);
258 for (i = 9; i >= 0; i--)
259 fprintf_filtered (file, "%02x", raw[i]);
260
261 if (tag != 3)
262 print_i387_ext (raw, file);
263
264 fputs_filtered ("\n", file);
265 }
266
267 fputs_filtered ("\n", file);
268
269 print_i387_status_word (fstat, file);
270 print_i387_control_word (fctrl, file);
271 fprintf_filtered (file, "Tag Word: %s\n",
272 local_hex_string_custom (ftag, "04"));
273 fprintf_filtered (file, "Instruction Pointer: %s:",
274 local_hex_string_custom (fiseg, "02"));
275 fprintf_filtered (file, "%s\n", local_hex_string_custom (fioff, "08"));
276 fprintf_filtered (file, "Operand Pointer: %s:",
277 local_hex_string_custom (foseg, "02"));
278 fprintf_filtered (file, "%s\n", local_hex_string_custom (fooff, "08"));
279 fprintf_filtered (file, "Opcode: %s\n",
280 local_hex_string_custom (fop ? (fop | 0xd800) : 0, "04"));
281 }
282 \f
283
284 /* Read a value of type TYPE from register REGNUM in frame FRAME, and
285 return its contents in TO. */
286
287 void
288 i387_register_to_value (struct frame_info *frame, int regnum,
289 struct type *type, void *to)
290 {
291 char from[I386_MAX_REGISTER_SIZE];
292
293 gdb_assert (i386_fp_regnum_p (regnum));
294
295 /* We only support floating-point values. */
296 if (TYPE_CODE (type) != TYPE_CODE_FLT)
297 {
298 warning ("Cannot convert floating-point register value "
299 "to non-floating-point type.");
300 return;
301 }
302
303 /* Convert to TYPE. This should be a no-op if TYPE is equivalent to
304 the extended floating-point format used by the FPU. */
305 get_frame_register (frame, regnum, from);
306 convert_typed_floating (from, builtin_type_i387_ext, to, type);
307 }
308
309 /* Write the contents FROM of a value of type TYPE into register
310 REGNUM in frame FRAME. */
311
312 void
313 i387_value_to_register (struct frame_info *frame, int regnum,
314 struct type *type, const void *from)
315 {
316 char to[I386_MAX_REGISTER_SIZE];
317
318 gdb_assert (i386_fp_regnum_p (regnum));
319
320 /* We only support floating-point values. */
321 if (TYPE_CODE (type) != TYPE_CODE_FLT)
322 {
323 warning ("Cannot convert non-floating-point type "
324 "to floating-point register value.");
325 return;
326 }
327
328 /* Convert from TYPE. This should be a no-op if TYPE is equivalent
329 to the extended floating-point format used by the FPU. */
330 convert_typed_floating (from, type, to, builtin_type_i387_ext);
331 put_frame_register (frame, regnum, to);
332 }
333 \f
334
335 /* Handle FSAVE and FXSAVE formats. */
336
337 /* At fsave_offset[REGNUM] you'll find the offset to the location in
338 the data structure used by the "fsave" instruction where GDB
339 register REGNUM is stored. */
340
341 static int fsave_offset[] =
342 {
343 28 + 0 * FPU_REG_RAW_SIZE, /* FP0_REGNUM through ... */
344 28 + 1 * FPU_REG_RAW_SIZE,
345 28 + 2 * FPU_REG_RAW_SIZE,
346 28 + 3 * FPU_REG_RAW_SIZE,
347 28 + 4 * FPU_REG_RAW_SIZE,
348 28 + 5 * FPU_REG_RAW_SIZE,
349 28 + 6 * FPU_REG_RAW_SIZE,
350 28 + 7 * FPU_REG_RAW_SIZE, /* ... FP7_REGNUM. */
351 0, /* FCTRL_REGNUM (16 bits). */
352 4, /* FSTAT_REGNUM (16 bits). */
353 8, /* FTAG_REGNUM (16 bits). */
354 16, /* FISEG_REGNUM (16 bits). */
355 12, /* FIOFF_REGNUM. */
356 24, /* FOSEG_REGNUM. */
357 20, /* FOOFF_REGNUM. */
358 18 /* FOP_REGNUM (bottom 11 bits). */
359 };
360
361 #define FSAVE_ADDR(fsave, regnum) (fsave + fsave_offset[regnum - FP0_REGNUM])
362 \f
363
364 /* Fill register REGNUM in GDB's register array with the appropriate
365 value from *FSAVE. This function masks off any of the reserved
366 bits in *FSAVE. */
367
368 void
369 i387_supply_register (int regnum, char *fsave)
370 {
371 if (fsave == NULL)
372 {
373 supply_register (regnum, NULL);
374 return;
375 }
376
377 /* Most of the FPU control registers occupy only 16 bits in
378 the fsave area. Give those a special treatment. */
379 if (regnum >= FPC_REGNUM
380 && regnum != FIOFF_REGNUM && regnum != FOOFF_REGNUM)
381 {
382 unsigned char val[4];
383
384 memcpy (val, FSAVE_ADDR (fsave, regnum), 2);
385 val[2] = val[3] = 0;
386 if (regnum == FOP_REGNUM)
387 val[1] &= ((1 << 3) - 1);
388 supply_register (regnum, val);
389 }
390 else
391 supply_register (regnum, FSAVE_ADDR (fsave, regnum));
392 }
393
394 /* Fill GDB's register array with the floating-point register values
395 in *FSAVE. This function masks off any of the reserved
396 bits in *FSAVE. */
397
398 void
399 i387_supply_fsave (char *fsave)
400 {
401 int i;
402
403 for (i = FP0_REGNUM; i < XMM0_REGNUM; i++)
404 i387_supply_register (i, fsave);
405 }
406
407 /* Fill register REGNUM (if it is a floating-point register) in *FSAVE
408 with the value in GDB's register array. If REGNUM is -1, do this
409 for all registers. This function doesn't touch any of the reserved
410 bits in *FSAVE. */
411
412 void
413 i387_fill_fsave (char *fsave, int regnum)
414 {
415 int i;
416
417 for (i = FP0_REGNUM; i < XMM0_REGNUM; i++)
418 if (regnum == -1 || regnum == i)
419 {
420 /* Most of the FPU control registers occupy only 16 bits in
421 the fsave area. Give those a special treatment. */
422 if (i >= FPC_REGNUM
423 && i != FIOFF_REGNUM && i != FOOFF_REGNUM)
424 {
425 unsigned char buf[4];
426
427 regcache_collect (i, buf);
428
429 if (i == FOP_REGNUM)
430 {
431 /* The opcode occupies only 11 bits. Make sure we
432 don't touch the other bits. */
433 buf[1] &= ((1 << 3) - 1);
434 buf[1] |= ((FSAVE_ADDR (fsave, i))[1] & ~((1 << 3) - 1));
435 }
436 memcpy (FSAVE_ADDR (fsave, i), buf, 2);
437 }
438 else
439 regcache_collect (i, FSAVE_ADDR (fsave, i));
440 }
441 }
442 \f
443
444 /* At fxsave_offset[REGNUM] you'll find the offset to the location in
445 the data structure used by the "fxsave" instruction where GDB
446 register REGNUM is stored. */
447
448 static int fxsave_offset[] =
449 {
450 32, /* FP0_REGNUM through ... */
451 48,
452 64,
453 80,
454 96,
455 112,
456 128,
457 144, /* ... FP7_REGNUM (80 bits each). */
458 0, /* FCTRL_REGNUM (16 bits). */
459 2, /* FSTAT_REGNUM (16 bits). */
460 4, /* FTAG_REGNUM (16 bits). */
461 12, /* FISEG_REGNUM (16 bits). */
462 8, /* FIOFF_REGNUM. */
463 20, /* FOSEG_REGNUM (16 bits). */
464 16, /* FOOFF_REGNUM. */
465 6, /* FOP_REGNUM (bottom 11 bits). */
466 160 + 0 * 16, /* XMM0_REGNUM through ... */
467 160 + 1 * 16,
468 160 + 2 * 16,
469 160 + 3 * 16,
470 160 + 4 * 16,
471 160 + 5 * 16,
472 160 + 6 * 16,
473 160 + 7 * 16,
474 160 + 8 * 16,
475 160 + 9 * 16,
476 160 + 10 * 16,
477 160 + 11 * 16,
478 160 + 12 * 16,
479 160 + 13 * 16,
480 160 + 14 * 16,
481 160 + 15 * 16, /* ... XMM15_REGNUM (128 bits each). */
482 24 /* MXCSR_REGNUM. */
483 };
484
485 /* FIXME: kettenis/20030430: We made an unfortunate choice in putting
486 %mxcsr after the SSE registers %xmm0-%xmm7 instead of before, since
487 it makes supporting the registers %xmm8-%xmm15 on x86-64 a bit
488 involved. Hack around it by explicitly overriding the offset for
489 %mxcsr here. */
490
491 #define FXSAVE_ADDR(fxsave, regnum) \
492 ((regnum == MXCSR_REGNUM) ? (fxsave + 24) : \
493 (fxsave + fxsave_offset[regnum - FP0_REGNUM]))
494
495 static int i387_tag (unsigned char *raw);
496 \f
497
498 /* Fill GDB's register array with the floating-point and SSE register
499 values in *FXSAVE. This function masks off any of the reserved
500 bits in *FXSAVE. */
501
502 void
503 i387_supply_fxsave (char *fxsave)
504 {
505 int i, last_regnum = MXCSR_REGNUM;
506
507 if (gdbarch_tdep (current_gdbarch)->num_xmm_regs == 0)
508 last_regnum = FOP_REGNUM;
509
510 for (i = FP0_REGNUM; i <= last_regnum; i++)
511 {
512 if (fxsave == NULL)
513 {
514 supply_register (i, NULL);
515 continue;
516 }
517
518 /* Most of the FPU control registers occupy only 16 bits in
519 the fxsave area. Give those a special treatment. */
520 if (i >= FPC_REGNUM && i < XMM0_REGNUM
521 && i != FIOFF_REGNUM && i != FOOFF_REGNUM)
522 {
523 unsigned char val[4];
524
525 memcpy (val, FXSAVE_ADDR (fxsave, i), 2);
526 val[2] = val[3] = 0;
527 if (i == FOP_REGNUM)
528 val[1] &= ((1 << 3) - 1);
529 else if (i== FTAG_REGNUM)
530 {
531 /* The fxsave area contains a simplified version of the
532 tag word. We have to look at the actual 80-bit FP
533 data to recreate the traditional i387 tag word. */
534
535 unsigned long ftag = 0;
536 int fpreg;
537 int top;
538
539 top = (((FXSAVE_ADDR (fxsave, FSTAT_REGNUM))[1] >> 3) & 0x7);
540
541 for (fpreg = 7; fpreg >= 0; fpreg--)
542 {
543 int tag;
544
545 if (val[0] & (1 << fpreg))
546 {
547 int regnum = (fpreg + 8 - top) % 8 + FP0_REGNUM;
548 tag = i387_tag (FXSAVE_ADDR (fxsave, regnum));
549 }
550 else
551 tag = 3; /* Empty */
552
553 ftag |= tag << (2 * fpreg);
554 }
555 val[0] = ftag & 0xff;
556 val[1] = (ftag >> 8) & 0xff;
557 }
558 supply_register (i, val);
559 }
560 else
561 supply_register (i, FXSAVE_ADDR (fxsave, i));
562 }
563 }
564
565 /* Fill register REGNUM (if it is a floating-point or SSE register) in
566 *FXSAVE with the value in GDB's register array. If REGNUM is -1, do
567 this for all registers. This function doesn't touch any of the
568 reserved bits in *FXSAVE. */
569
570 void
571 i387_fill_fxsave (char *fxsave, int regnum)
572 {
573 int i, last_regnum = MXCSR_REGNUM;
574
575 if (gdbarch_tdep (current_gdbarch)->num_xmm_regs == 0)
576 last_regnum = FOP_REGNUM;
577
578 for (i = FP0_REGNUM; i <= last_regnum; i++)
579 if (regnum == -1 || regnum == i)
580 {
581 /* Most of the FPU control registers occupy only 16 bits in
582 the fxsave area. Give those a special treatment. */
583 if (i >= FPC_REGNUM && i < XMM0_REGNUM
584 && i != FIOFF_REGNUM && i != FOOFF_REGNUM)
585 {
586 unsigned char buf[4];
587
588 regcache_collect (i, buf);
589
590 if (i == FOP_REGNUM)
591 {
592 /* The opcode occupies only 11 bits. Make sure we
593 don't touch the other bits. */
594 buf[1] &= ((1 << 3) - 1);
595 buf[1] |= ((FXSAVE_ADDR (fxsave, i))[1] & ~((1 << 3) - 1));
596 }
597 else if (i == FTAG_REGNUM)
598 {
599 /* Converting back is much easier. */
600
601 unsigned short ftag;
602 int fpreg;
603
604 ftag = (buf[1] << 8) | buf[0];
605 buf[0] = 0;
606 buf[1] = 0;
607
608 for (fpreg = 7; fpreg >= 0; fpreg--)
609 {
610 int tag = (ftag >> (fpreg * 2)) & 3;
611
612 if (tag != 3)
613 buf[0] |= (1 << fpreg);
614 }
615 }
616 memcpy (FXSAVE_ADDR (fxsave, i), buf, 2);
617 }
618 else
619 regcache_collect (i, FXSAVE_ADDR (fxsave, i));
620 }
621 }
622
623 /* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
624 *RAW. */
625
626 static int
627 i387_tag (unsigned char *raw)
628 {
629 int integer;
630 unsigned int exponent;
631 unsigned long fraction[2];
632
633 integer = raw[7] & 0x80;
634 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
635 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
636 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
637 | (raw[5] << 8) | raw[4]);
638
639 if (exponent == 0x7fff)
640 {
641 /* Special. */
642 return (2);
643 }
644 else if (exponent == 0x0000)
645 {
646 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
647 {
648 /* Zero. */
649 return (1);
650 }
651 else
652 {
653 /* Special. */
654 return (2);
655 }
656 }
657 else
658 {
659 if (integer)
660 {
661 /* Valid. */
662 return (0);
663 }
664 else
665 {
666 /* Special. */
667 return (2);
668 }
669 }
670 }