dma: beautify queue listing output
[dragonfly.git] / contrib / gdb-6.2.1 / gdb / i387-tdep.c
blob0e60a13968b242396c81a885d8581ec7809f6ca8
1 /* Intel 387 floating point stuff.
3 Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000,
4 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
6 This file is part of GDB.
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.
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.
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. */
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"
33 #include "gdb_assert.h"
34 #include "gdb_string.h"
36 #include "i386-tdep.h"
37 #include "i387-tdep.h"
39 /* Implement the `info float' layout based on the register definitions
40 in `tm-i386.h'. */
42 /* Print the floating point number specified by RAW. */
44 static void
45 print_i387_value (char *raw, struct ui_file *file)
47 DOUBLEST value;
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);
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
66 /* Print the classification for the register contents RAW. */
68 static void
69 print_i387_ext (unsigned char *raw, struct ui_file *file)
71 int sign;
72 int integer;
73 unsigned int exponent;
74 unsigned long fraction[2];
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]);
83 if (exponent == 0x7fff && integer)
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);
98 else if (exponent < 0x7fff && exponent > 0x0000 && integer)
99 /* Normal. */
100 print_i387_value (raw, file);
101 else if (exponent == 0x0000)
103 /* Denormal or zero. */
104 print_i387_value (raw, file);
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);
113 else
114 /* Unsupported. */
115 fputs_filtered (" Unsupported", file);
118 /* Print the status word STATUS. */
120 static void
121 print_i387_status_word (unsigned int status, struct ui_file *file)
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" : " ");
142 fputs_filtered ("\n", file);
144 fprintf_filtered (file,
145 " TOP: %d\n", ((status >> 11) & 7));
148 /* Print the control word CONTROL. */
150 static void
151 print_i387_control_word (unsigned int control, struct ui_file *file)
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" : " ");
163 fputs_filtered ("\n", file);
165 fputs_filtered (" PC: ", file);
166 switch ((control >> 8) & 3)
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;
182 fputs_filtered (" RC: ", file);
183 switch ((control >> 10) & 3)
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;
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. */
204 void
205 i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
206 struct frame_info *frame, const char *args)
208 struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
209 char buf[4];
210 ULONGEST fctrl;
211 ULONGEST fstat;
212 ULONGEST ftag;
213 ULONGEST fiseg;
214 ULONGEST fioff;
215 ULONGEST foseg;
216 ULONGEST fooff;
217 ULONGEST fop;
218 int fpreg;
219 int top;
221 gdb_assert (gdbarch == get_frame_arch (frame));
223 /* Define I387_ST0_REGNUM such that we use the proper definitions
224 for FRAME's architecture. */
225 #define I387_ST0_REGNUM tdep->st0_regnum
227 fctrl = get_frame_register_unsigned (frame, I387_FCTRL_REGNUM);
228 fstat = get_frame_register_unsigned (frame, I387_FSTAT_REGNUM);
229 ftag = get_frame_register_unsigned (frame, I387_FTAG_REGNUM);
230 fiseg = get_frame_register_unsigned (frame, I387_FISEG_REGNUM);
231 fioff = get_frame_register_unsigned (frame, I387_FIOFF_REGNUM);
232 foseg = get_frame_register_unsigned (frame, I387_FOSEG_REGNUM);
233 fooff = get_frame_register_unsigned (frame, I387_FOOFF_REGNUM);
234 fop = get_frame_register_unsigned (frame, I387_FOP_REGNUM);
236 top = ((fstat >> 11) & 7);
238 for (fpreg = 7; fpreg >= 0; fpreg--)
240 unsigned char raw[I386_MAX_REGISTER_SIZE];
241 int tag = (ftag >> (fpreg * 2)) & 3;
242 int i;
244 fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg);
246 switch (tag)
248 case 0:
249 fputs_filtered ("Valid ", file);
250 break;
251 case 1:
252 fputs_filtered ("Zero ", file);
253 break;
254 case 2:
255 fputs_filtered ("Special ", file);
256 break;
257 case 3:
258 fputs_filtered ("Empty ", file);
259 break;
262 get_frame_register (frame, (fpreg + 8 - top) % 8 + I387_ST0_REGNUM, raw);
264 fputs_filtered ("0x", file);
265 for (i = 9; i >= 0; i--)
266 fprintf_filtered (file, "%02x", raw[i]);
268 if (tag != 3)
269 print_i387_ext (raw, file);
271 fputs_filtered ("\n", file);
274 fputs_filtered ("\n", file);
276 print_i387_status_word (fstat, file);
277 print_i387_control_word (fctrl, file);
278 fprintf_filtered (file, "Tag Word: %s\n",
279 local_hex_string_custom (ftag, "04"));
280 fprintf_filtered (file, "Instruction Pointer: %s:",
281 local_hex_string_custom (fiseg, "02"));
282 fprintf_filtered (file, "%s\n", local_hex_string_custom (fioff, "08"));
283 fprintf_filtered (file, "Operand Pointer: %s:",
284 local_hex_string_custom (foseg, "02"));
285 fprintf_filtered (file, "%s\n", local_hex_string_custom (fooff, "08"));
286 fprintf_filtered (file, "Opcode: %s\n",
287 local_hex_string_custom (fop ? (fop | 0xd800) : 0, "04"));
289 #undef I387_ST0_REGNUM
293 /* Read a value of type TYPE from register REGNUM in frame FRAME, and
294 return its contents in TO. */
296 void
297 i387_register_to_value (struct frame_info *frame, int regnum,
298 struct type *type, void *to)
300 char from[I386_MAX_REGISTER_SIZE];
302 gdb_assert (i386_fp_regnum_p (regnum));
304 /* We only support floating-point values. */
305 if (TYPE_CODE (type) != TYPE_CODE_FLT)
307 warning ("Cannot convert floating-point register value "
308 "to non-floating-point type.");
309 return;
312 /* Convert to TYPE. This should be a no-op if TYPE is equivalent to
313 the extended floating-point format used by the FPU. */
314 get_frame_register (frame, regnum, from);
315 convert_typed_floating (from, builtin_type_i387_ext, to, type);
318 /* Write the contents FROM of a value of type TYPE into register
319 REGNUM in frame FRAME. */
321 void
322 i387_value_to_register (struct frame_info *frame, int regnum,
323 struct type *type, const void *from)
325 char to[I386_MAX_REGISTER_SIZE];
327 gdb_assert (i386_fp_regnum_p (regnum));
329 /* We only support floating-point values. */
330 if (TYPE_CODE (type) != TYPE_CODE_FLT)
332 warning ("Cannot convert non-floating-point type "
333 "to floating-point register value.");
334 return;
337 /* Convert from TYPE. This should be a no-op if TYPE is equivalent
338 to the extended floating-point format used by the FPU. */
339 convert_typed_floating (from, type, to, builtin_type_i387_ext);
340 put_frame_register (frame, regnum, to);
344 /* Handle FSAVE and FXSAVE formats. */
346 /* FIXME: kettenis/20030927: The functions below should accept a
347 `regcache' argument, but I don't want to change the function
348 signature just yet. There's some band-aid in the functions below
349 in the form of the `regcache' local variables. This will ease the
350 transition later on. */
352 /* At fsave_offset[REGNUM] you'll find the offset to the location in
353 the data structure used by the "fsave" instruction where GDB
354 register REGNUM is stored. */
356 static int fsave_offset[] =
358 28 + 0 * 10, /* %st(0) ... */
359 28 + 1 * 10,
360 28 + 2 * 10,
361 28 + 3 * 10,
362 28 + 4 * 10,
363 28 + 5 * 10,
364 28 + 6 * 10,
365 28 + 7 * 10, /* ... %st(7). */
366 0, /* `fctrl' (16 bits). */
367 4, /* `fstat' (16 bits). */
368 8, /* `ftag' (16 bits). */
369 16, /* `fiseg' (16 bits). */
370 12, /* `fioff'. */
371 24, /* `foseg' (16 bits). */
372 20, /* `fooff'. */
373 18 /* `fop' (bottom 11 bits). */
376 #define FSAVE_ADDR(fsave, regnum) \
377 (fsave + fsave_offset[regnum - I387_ST0_REGNUM])
380 /* Fill register REGNUM in REGCACHE with the appropriate value from
381 *FSAVE. This function masks off any of the reserved bits in
382 *FSAVE. */
384 void
385 i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave)
387 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
388 const char *regs = fsave;
389 int i;
391 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
393 /* Define I387_ST0_REGNUM such that we use the proper definitions
394 for REGCACHE's architecture. */
395 #define I387_ST0_REGNUM tdep->st0_regnum
397 for (i = I387_ST0_REGNUM; i < I387_XMM0_REGNUM; i++)
398 if (regnum == -1 || regnum == i)
400 if (fsave == NULL)
402 regcache_raw_supply (regcache, i, NULL);
403 continue;
406 /* Most of the FPU control registers occupy only 16 bits in the
407 fsave area. Give those a special treatment. */
408 if (i >= I387_FCTRL_REGNUM
409 && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM)
411 unsigned char val[4];
413 memcpy (val, FSAVE_ADDR (regs, i), 2);
414 val[2] = val[3] = 0;
415 if (i == I387_FOP_REGNUM)
416 val[1] &= ((1 << 3) - 1);
417 regcache_raw_supply (regcache, i, val);
419 else
420 regcache_raw_supply (regcache, i, FSAVE_ADDR (regs, i));
422 #undef I387_ST0_REGNUM
425 /* Fill register REGNUM (if it is a floating-point register) in *FSAVE
426 with the value from REGCACHE. If REGNUM is -1, do this for all
427 registers. This function doesn't touch any of the reserved bits in
428 *FSAVE. */
430 void
431 i387_collect_fsave (const struct regcache *regcache, int regnum, void *fsave)
433 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
434 char *regs = fsave;
435 int i;
437 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
439 /* Define I387_ST0_REGNUM such that we use the proper definitions
440 for REGCACHE's architecture. */
441 #define I387_ST0_REGNUM tdep->st0_regnum
443 for (i = I387_ST0_REGNUM; i < I387_XMM0_REGNUM; i++)
444 if (regnum == -1 || regnum == i)
446 /* Most of the FPU control registers occupy only 16 bits in
447 the fsave area. Give those a special treatment. */
448 if (i >= I387_FCTRL_REGNUM
449 && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM)
451 unsigned char buf[4];
453 regcache_raw_collect (regcache, i, buf);
455 if (i == I387_FOP_REGNUM)
457 /* The opcode occupies only 11 bits. Make sure we
458 don't touch the other bits. */
459 buf[1] &= ((1 << 3) - 1);
460 buf[1] |= ((FSAVE_ADDR (regs, i))[1] & ~((1 << 3) - 1));
462 memcpy (FSAVE_ADDR (regs, i), buf, 2);
464 else
465 regcache_raw_collect (regcache, i, FSAVE_ADDR (regs, i));
467 #undef I387_ST0_REGNUM
470 /* Fill register REGNUM (if it is a floating-point register) in *FSAVE
471 with the value in GDB's register cache. If REGNUM is -1, do this
472 for all registers. This function doesn't touch any of the reserved
473 bits in *FSAVE. */
475 void
476 i387_fill_fsave (void *fsave, int regnum)
478 i387_collect_fsave (current_regcache, regnum, fsave);
482 /* At fxsave_offset[REGNUM] you'll find the offset to the location in
483 the data structure used by the "fxsave" instruction where GDB
484 register REGNUM is stored. */
486 static int fxsave_offset[] =
488 32, /* %st(0) through ... */
493 112,
494 128,
495 144, /* ... %st(7) (80 bits each). */
496 0, /* `fctrl' (16 bits). */
497 2, /* `fstat' (16 bits). */
498 4, /* `ftag' (16 bits). */
499 12, /* `fiseg' (16 bits). */
500 8, /* `fioff'. */
501 20, /* `foseg' (16 bits). */
502 16, /* `fooff'. */
503 6, /* `fop' (bottom 11 bits). */
504 160 + 0 * 16, /* %xmm0 through ... */
505 160 + 1 * 16,
506 160 + 2 * 16,
507 160 + 3 * 16,
508 160 + 4 * 16,
509 160 + 5 * 16,
510 160 + 6 * 16,
511 160 + 7 * 16,
512 160 + 8 * 16,
513 160 + 9 * 16,
514 160 + 10 * 16,
515 160 + 11 * 16,
516 160 + 12 * 16,
517 160 + 13 * 16,
518 160 + 14 * 16,
519 160 + 15 * 16, /* ... %xmm15 (128 bits each). */
522 #define FXSAVE_ADDR(fxsave, regnum) \
523 (fxsave + fxsave_offset[regnum - I387_ST0_REGNUM])
525 /* We made an unfortunate choice in putting %mxcsr after the SSE
526 registers %xmm0-%xmm7 instead of before, since it makes supporting
527 the registers %xmm8-%xmm15 on AMD64 a bit involved. Therefore we
528 don't include the offset for %mxcsr here above. */
530 #define FXSAVE_MXCSR_ADDR(fxsave) (fxsave + 24)
532 static int i387_tag (const unsigned char *raw);
535 /* Fill register REGNUM in REGCACHE with the appropriate
536 floating-point or SSE register value from *FXSAVE. This function
537 masks off any of the reserved bits in *FXSAVE. */
539 void
540 i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
542 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
543 const char *regs = fxsave;
544 int i;
546 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
547 gdb_assert (tdep->num_xmm_regs > 0);
549 /* Define I387_ST0_REGNUM and I387_NUM_XMM_REGS such that we use the
550 proper definitions for REGCACHE's architecture. */
552 #define I387_ST0_REGNUM tdep->st0_regnum
553 #define I387_NUM_XMM_REGS tdep->num_xmm_regs
555 for (i = I387_ST0_REGNUM; i < I387_MXCSR_REGNUM; i++)
556 if (regnum == -1 || regnum == i)
558 if (regs == NULL)
560 regcache_raw_supply (regcache, i, NULL);
561 continue;
564 /* Most of the FPU control registers occupy only 16 bits in
565 the fxsave area. Give those a special treatment. */
566 if (i >= I387_FCTRL_REGNUM && i < I387_XMM0_REGNUM
567 && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM)
569 unsigned char val[4];
571 memcpy (val, FXSAVE_ADDR (regs, i), 2);
572 val[2] = val[3] = 0;
573 if (i == I387_FOP_REGNUM)
574 val[1] &= ((1 << 3) - 1);
575 else if (i== I387_FTAG_REGNUM)
577 /* The fxsave area contains a simplified version of
578 the tag word. We have to look at the actual 80-bit
579 FP data to recreate the traditional i387 tag word. */
581 unsigned long ftag = 0;
582 int fpreg;
583 int top;
585 top = ((FXSAVE_ADDR (regs, I387_FSTAT_REGNUM))[1] >> 3);
586 top &= 0x7;
588 for (fpreg = 7; fpreg >= 0; fpreg--)
590 int tag;
592 if (val[0] & (1 << fpreg))
594 int regnum = (fpreg + 8 - top) % 8 + I387_ST0_REGNUM;
595 tag = i387_tag (FXSAVE_ADDR (regs, regnum));
597 else
598 tag = 3; /* Empty */
600 ftag |= tag << (2 * fpreg);
602 val[0] = ftag & 0xff;
603 val[1] = (ftag >> 8) & 0xff;
605 regcache_raw_supply (regcache, i, val);
607 else
608 regcache_raw_supply (regcache, i, FXSAVE_ADDR (regs, i));
611 if (regnum == I387_MXCSR_REGNUM || regnum == -1)
613 if (regs == NULL)
614 regcache_raw_supply (regcache, I387_MXCSR_REGNUM, NULL);
615 else
616 regcache_raw_supply (regcache, I387_MXCSR_REGNUM,
617 FXSAVE_MXCSR_ADDR (regs));
620 #undef I387_ST0_REGNUM
621 #undef I387_NUM_XMM_REGS
624 /* Fill register REGNUM (if it is a floating-point or SSE register) in
625 *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for
626 all registers. This function doesn't touch any of the reserved
627 bits in *FXSAVE. */
629 void
630 i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave)
632 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
633 char *regs = fxsave;
634 int i;
636 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
637 gdb_assert (tdep->num_xmm_regs > 0);
639 /* Define I387_ST0_REGNUM and I387_NUM_XMM_REGS such that we use the
640 proper definitions for REGCACHE's architecture. */
642 #define I387_ST0_REGNUM tdep->st0_regnum
643 #define I387_NUM_XMM_REGS tdep->num_xmm_regs
645 for (i = I387_ST0_REGNUM; i < I387_MXCSR_REGNUM; i++)
646 if (regnum == -1 || regnum == i)
648 /* Most of the FPU control registers occupy only 16 bits in
649 the fxsave area. Give those a special treatment. */
650 if (i >= I387_FCTRL_REGNUM && i < I387_XMM0_REGNUM
651 && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM)
653 unsigned char buf[4];
655 regcache_raw_collect (regcache, i, buf);
657 if (i == I387_FOP_REGNUM)
659 /* The opcode occupies only 11 bits. Make sure we
660 don't touch the other bits. */
661 buf[1] &= ((1 << 3) - 1);
662 buf[1] |= ((FXSAVE_ADDR (regs, i))[1] & ~((1 << 3) - 1));
664 else if (i == I387_FTAG_REGNUM)
666 /* Converting back is much easier. */
668 unsigned short ftag;
669 int fpreg;
671 ftag = (buf[1] << 8) | buf[0];
672 buf[0] = 0;
673 buf[1] = 0;
675 for (fpreg = 7; fpreg >= 0; fpreg--)
677 int tag = (ftag >> (fpreg * 2)) & 3;
679 if (tag != 3)
680 buf[0] |= (1 << fpreg);
683 memcpy (FXSAVE_ADDR (regs, i), buf, 2);
685 else
686 regcache_raw_collect (regcache, i, FXSAVE_ADDR (regs, i));
689 if (regnum == I387_MXCSR_REGNUM || regnum == -1)
690 regcache_raw_collect (regcache, I387_MXCSR_REGNUM,
691 FXSAVE_MXCSR_ADDR (regs));
693 #undef I387_ST0_REGNUM
694 #undef I387_NUM_XMM_REGS
697 /* Fill register REGNUM (if it is a floating-point or SSE register) in
698 *FXSAVE with the value in GDB's register cache. If REGNUM is -1, do
699 this for all registers. This function doesn't touch any of the
700 reserved bits in *FXSAVE. */
702 void
703 i387_fill_fxsave (void *fxsave, int regnum)
705 i387_collect_fxsave (current_regcache, regnum, fxsave);
708 /* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
709 *RAW. */
711 static int
712 i387_tag (const unsigned char *raw)
714 int integer;
715 unsigned int exponent;
716 unsigned long fraction[2];
718 integer = raw[7] & 0x80;
719 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
720 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
721 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
722 | (raw[5] << 8) | raw[4]);
724 if (exponent == 0x7fff)
726 /* Special. */
727 return (2);
729 else if (exponent == 0x0000)
731 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
733 /* Zero. */
734 return (1);
736 else
738 /* Special. */
739 return (2);
742 else
744 if (integer)
746 /* Valid. */
747 return (0);
749 else
751 /* Special. */
752 return (2);
757 /* Prepare the FPU stack in REGCACHE for a function return. */
759 void
760 i387_return_value (struct gdbarch *gdbarch, struct regcache *regcache)
762 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
763 ULONGEST fstat;
765 /* Define I387_ST0_REGNUM such that we use the proper
766 definitions for the architecture. */
767 #define I387_ST0_REGNUM tdep->st0_regnum
769 /* Set the top of the floating-point register stack to 7. The
770 actual value doesn't really matter, but 7 is what a normal
771 function return would end up with if the program started out with
772 a freshly initialized FPU. */
773 regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM, &fstat);
774 fstat |= (7 << 11);
775 regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM, fstat);
777 /* Mark %st(1) through %st(7) as empty. Since we set the top of the
778 floating-point register stack to 7, the appropriate value for the
779 tag word is 0x3fff. */
780 regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM, 0x3fff);
782 #undef I387_ST0_REGNUM