* utils.c (fputs_maybe_filtered): Check if there's already a top
[deliverable/binutils-gdb.git] / gdb / i387-tdep.c
1 /* Intel 387 floating point stuff.
2
3 Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000, 2001,
4 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
5 Free Software Foundation, Inc.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
22 #include "defs.h"
23 #include "doublest.h"
24 #include "floatformat.h"
25 #include "frame.h"
26 #include "gdbcore.h"
27 #include "inferior.h"
28 #include "language.h"
29 #include "regcache.h"
30 #include "value.h"
31
32 #include "gdb_assert.h"
33 #include "gdb_string.h"
34
35 #include "i386-tdep.h"
36 #include "i387-tdep.h"
37
38 /* Print the floating point number specified by RAW. */
39
40 static void
41 print_i387_value (struct gdbarch *gdbarch,
42 const gdb_byte *raw, struct ui_file *file)
43 {
44 DOUBLEST value;
45
46 /* Using extract_typed_floating here might affect the representation
47 of certain numbers such as NaNs, even if GDB is running natively.
48 This is fine since our caller already detects such special
49 numbers and we print the hexadecimal representation anyway. */
50 value = extract_typed_floating (raw, i387_ext_type (gdbarch));
51
52 /* We try to print 19 digits. The last digit may or may not contain
53 garbage, but we'd better print one too many. We need enough room
54 to print the value, 1 position for the sign, 1 for the decimal
55 point, 19 for the digits and 6 for the exponent adds up to 27. */
56 #ifdef PRINTF_HAS_LONG_DOUBLE
57 fprintf_filtered (file, " %-+27.19Lg", (long double) value);
58 #else
59 fprintf_filtered (file, " %-+27.19g", (double) value);
60 #endif
61 }
62
63 /* Print the classification for the register contents RAW. */
64
65 static void
66 print_i387_ext (struct gdbarch *gdbarch,
67 const gdb_byte *raw, struct ui_file *file)
68 {
69 int sign;
70 int integer;
71 unsigned int exponent;
72 unsigned long fraction[2];
73
74 sign = raw[9] & 0x80;
75 integer = raw[7] & 0x80;
76 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
77 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
78 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
79 | (raw[5] << 8) | raw[4]);
80
81 if (exponent == 0x7fff && integer)
82 {
83 if (fraction[0] == 0x00000000 && fraction[1] == 0x00000000)
84 /* Infinity. */
85 fprintf_filtered (file, " %cInf", (sign ? '-' : '+'));
86 else if (sign && fraction[0] == 0x00000000 && fraction[1] == 0x40000000)
87 /* Real Indefinite (QNaN). */
88 fputs_unfiltered (" Real Indefinite (QNaN)", file);
89 else if (fraction[1] & 0x40000000)
90 /* QNaN. */
91 fputs_filtered (" QNaN", file);
92 else
93 /* SNaN. */
94 fputs_filtered (" SNaN", file);
95 }
96 else if (exponent < 0x7fff && exponent > 0x0000 && integer)
97 /* Normal. */
98 print_i387_value (gdbarch, raw, file);
99 else if (exponent == 0x0000)
100 {
101 /* Denormal or zero. */
102 print_i387_value (gdbarch, raw, file);
103
104 if (integer)
105 /* Pseudo-denormal. */
106 fputs_filtered (" Pseudo-denormal", file);
107 else if (fraction[0] || fraction[1])
108 /* Denormal. */
109 fputs_filtered (" Denormal", file);
110 }
111 else
112 /* Unsupported. */
113 fputs_filtered (" Unsupported", file);
114 }
115
116 /* Print the status word STATUS. */
117
118 static void
119 print_i387_status_word (unsigned int status, struct ui_file *file)
120 {
121 fprintf_filtered (file, "Status Word: %s",
122 hex_string_custom (status, 4));
123 fputs_filtered (" ", file);
124 fprintf_filtered (file, " %s", (status & 0x0001) ? "IE" : " ");
125 fprintf_filtered (file, " %s", (status & 0x0002) ? "DE" : " ");
126 fprintf_filtered (file, " %s", (status & 0x0004) ? "ZE" : " ");
127 fprintf_filtered (file, " %s", (status & 0x0008) ? "OE" : " ");
128 fprintf_filtered (file, " %s", (status & 0x0010) ? "UE" : " ");
129 fprintf_filtered (file, " %s", (status & 0x0020) ? "PE" : " ");
130 fputs_filtered (" ", file);
131 fprintf_filtered (file, " %s", (status & 0x0080) ? "ES" : " ");
132 fputs_filtered (" ", file);
133 fprintf_filtered (file, " %s", (status & 0x0040) ? "SF" : " ");
134 fputs_filtered (" ", file);
135 fprintf_filtered (file, " %s", (status & 0x0100) ? "C0" : " ");
136 fprintf_filtered (file, " %s", (status & 0x0200) ? "C1" : " ");
137 fprintf_filtered (file, " %s", (status & 0x0400) ? "C2" : " ");
138 fprintf_filtered (file, " %s", (status & 0x4000) ? "C3" : " ");
139
140 fputs_filtered ("\n", file);
141
142 fprintf_filtered (file,
143 " TOP: %d\n", ((status >> 11) & 7));
144 }
145
146 /* Print the control word CONTROL. */
147
148 static void
149 print_i387_control_word (unsigned int control, struct ui_file *file)
150 {
151 fprintf_filtered (file, "Control Word: %s",
152 hex_string_custom (control, 4));
153 fputs_filtered (" ", file);
154 fprintf_filtered (file, " %s", (control & 0x0001) ? "IM" : " ");
155 fprintf_filtered (file, " %s", (control & 0x0002) ? "DM" : " ");
156 fprintf_filtered (file, " %s", (control & 0x0004) ? "ZM" : " ");
157 fprintf_filtered (file, " %s", (control & 0x0008) ? "OM" : " ");
158 fprintf_filtered (file, " %s", (control & 0x0010) ? "UM" : " ");
159 fprintf_filtered (file, " %s", (control & 0x0020) ? "PM" : " ");
160
161 fputs_filtered ("\n", file);
162
163 fputs_filtered (" PC: ", file);
164 switch ((control >> 8) & 3)
165 {
166 case 0:
167 fputs_filtered ("Single Precision (24-bits)\n", file);
168 break;
169 case 1:
170 fputs_filtered ("Reserved\n", file);
171 break;
172 case 2:
173 fputs_filtered ("Double Precision (53-bits)\n", file);
174 break;
175 case 3:
176 fputs_filtered ("Extended Precision (64-bits)\n", file);
177 break;
178 }
179
180 fputs_filtered (" RC: ", file);
181 switch ((control >> 10) & 3)
182 {
183 case 0:
184 fputs_filtered ("Round to nearest\n", file);
185 break;
186 case 1:
187 fputs_filtered ("Round down\n", file);
188 break;
189 case 2:
190 fputs_filtered ("Round up\n", file);
191 break;
192 case 3:
193 fputs_filtered ("Round toward zero\n", file);
194 break;
195 }
196 }
197
198 /* Print out the i387 floating point state. Note that we ignore FRAME
199 in the code below. That's OK since floating-point registers are
200 never saved on the stack. */
201
202 void
203 i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
204 struct frame_info *frame, const char *args)
205 {
206 struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
207 gdb_byte buf[4];
208 ULONGEST fctrl;
209 ULONGEST fstat;
210 ULONGEST ftag;
211 ULONGEST fiseg;
212 ULONGEST fioff;
213 ULONGEST foseg;
214 ULONGEST fooff;
215 ULONGEST fop;
216 int fpreg;
217 int top;
218
219 gdb_assert (gdbarch == get_frame_arch (frame));
220
221 fctrl = get_frame_register_unsigned (frame, I387_FCTRL_REGNUM (tdep));
222 fstat = get_frame_register_unsigned (frame, I387_FSTAT_REGNUM (tdep));
223 ftag = get_frame_register_unsigned (frame, I387_FTAG_REGNUM (tdep));
224 fiseg = get_frame_register_unsigned (frame, I387_FISEG_REGNUM (tdep));
225 fioff = get_frame_register_unsigned (frame, I387_FIOFF_REGNUM (tdep));
226 foseg = get_frame_register_unsigned (frame, I387_FOSEG_REGNUM (tdep));
227 fooff = get_frame_register_unsigned (frame, I387_FOOFF_REGNUM (tdep));
228 fop = get_frame_register_unsigned (frame, I387_FOP_REGNUM (tdep));
229
230 top = ((fstat >> 11) & 7);
231
232 for (fpreg = 7; fpreg >= 0; fpreg--)
233 {
234 gdb_byte raw[I386_MAX_REGISTER_SIZE];
235 int tag = (ftag >> (fpreg * 2)) & 3;
236 int i;
237
238 fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg);
239
240 switch (tag)
241 {
242 case 0:
243 fputs_filtered ("Valid ", file);
244 break;
245 case 1:
246 fputs_filtered ("Zero ", file);
247 break;
248 case 2:
249 fputs_filtered ("Special ", file);
250 break;
251 case 3:
252 fputs_filtered ("Empty ", file);
253 break;
254 }
255
256 get_frame_register (frame, (fpreg + 8 - top) % 8 + I387_ST0_REGNUM (tdep),
257 raw);
258
259 fputs_filtered ("0x", file);
260 for (i = 9; i >= 0; i--)
261 fprintf_filtered (file, "%02x", raw[i]);
262
263 if (tag != 3)
264 print_i387_ext (gdbarch, raw, file);
265
266 fputs_filtered ("\n", file);
267 }
268
269 fputs_filtered ("\n", file);
270
271 print_i387_status_word (fstat, file);
272 print_i387_control_word (fctrl, file);
273 fprintf_filtered (file, "Tag Word: %s\n",
274 hex_string_custom (ftag, 4));
275 fprintf_filtered (file, "Instruction Pointer: %s:",
276 hex_string_custom (fiseg, 2));
277 fprintf_filtered (file, "%s\n", hex_string_custom (fioff, 8));
278 fprintf_filtered (file, "Operand Pointer: %s:",
279 hex_string_custom (foseg, 2));
280 fprintf_filtered (file, "%s\n", hex_string_custom (fooff, 8));
281 fprintf_filtered (file, "Opcode: %s\n",
282 hex_string_custom (fop ? (fop | 0xd800) : 0, 4));
283 }
284 \f
285
286 /* Return nonzero if a value of type TYPE stored in register REGNUM
287 needs any special handling. */
288
289 int
290 i387_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type)
291 {
292 if (i386_fp_regnum_p (gdbarch, regnum))
293 {
294 /* Floating point registers must be converted unless we are
295 accessing them in their hardware type. */
296 if (type == i387_ext_type (gdbarch))
297 return 0;
298 else
299 return 1;
300 }
301
302 return 0;
303 }
304
305 /* Read a value of type TYPE from register REGNUM in frame FRAME, and
306 return its contents in TO. */
307
308 void
309 i387_register_to_value (struct frame_info *frame, int regnum,
310 struct type *type, gdb_byte *to)
311 {
312 struct gdbarch *gdbarch = get_frame_arch (frame);
313 gdb_byte from[I386_MAX_REGISTER_SIZE];
314
315 gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
316
317 /* We only support floating-point values. */
318 if (TYPE_CODE (type) != TYPE_CODE_FLT)
319 {
320 warning (_("Cannot convert floating-point register value "
321 "to non-floating-point type."));
322 return;
323 }
324
325 /* Convert to TYPE. */
326 get_frame_register (frame, regnum, from);
327 convert_typed_floating (from, i387_ext_type (gdbarch), to, type);
328 }
329
330 /* Write the contents FROM of a value of type TYPE into register
331 REGNUM in frame FRAME. */
332
333 void
334 i387_value_to_register (struct frame_info *frame, int regnum,
335 struct type *type, const gdb_byte *from)
336 {
337 struct gdbarch *gdbarch = get_frame_arch (frame);
338 gdb_byte to[I386_MAX_REGISTER_SIZE];
339
340 gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
341
342 /* We only support floating-point values. */
343 if (TYPE_CODE (type) != TYPE_CODE_FLT)
344 {
345 warning (_("Cannot convert non-floating-point type "
346 "to floating-point register value."));
347 return;
348 }
349
350 /* Convert from TYPE. */
351 convert_typed_floating (from, type, to, i387_ext_type (gdbarch));
352 put_frame_register (frame, regnum, to);
353 }
354 \f
355
356 /* Handle FSAVE and FXSAVE formats. */
357
358 /* At fsave_offset[REGNUM] you'll find the offset to the location in
359 the data structure used by the "fsave" instruction where GDB
360 register REGNUM is stored. */
361
362 static int fsave_offset[] =
363 {
364 28 + 0 * 10, /* %st(0) ... */
365 28 + 1 * 10,
366 28 + 2 * 10,
367 28 + 3 * 10,
368 28 + 4 * 10,
369 28 + 5 * 10,
370 28 + 6 * 10,
371 28 + 7 * 10, /* ... %st(7). */
372 0, /* `fctrl' (16 bits). */
373 4, /* `fstat' (16 bits). */
374 8, /* `ftag' (16 bits). */
375 16, /* `fiseg' (16 bits). */
376 12, /* `fioff'. */
377 24, /* `foseg' (16 bits). */
378 20, /* `fooff'. */
379 18 /* `fop' (bottom 11 bits). */
380 };
381
382 #define FSAVE_ADDR(tdep, fsave, regnum) \
383 (fsave + fsave_offset[regnum - I387_ST0_REGNUM (tdep)])
384 \f
385
386 /* Fill register REGNUM in REGCACHE with the appropriate value from
387 *FSAVE. This function masks off any of the reserved bits in
388 *FSAVE. */
389
390 void
391 i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave)
392 {
393 struct gdbarch *gdbarch = get_regcache_arch (regcache);
394 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
395 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
396 const gdb_byte *regs = fsave;
397 int i;
398
399 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
400
401 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
402 if (regnum == -1 || regnum == i)
403 {
404 if (fsave == NULL)
405 {
406 regcache_raw_supply (regcache, i, NULL);
407 continue;
408 }
409
410 /* Most of the FPU control registers occupy only 16 bits in the
411 fsave area. Give those a special treatment. */
412 if (i >= I387_FCTRL_REGNUM (tdep)
413 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
414 {
415 gdb_byte val[4];
416
417 memcpy (val, FSAVE_ADDR (tdep, regs, i), 2);
418 val[2] = val[3] = 0;
419 if (i == I387_FOP_REGNUM (tdep))
420 val[1] &= ((1 << 3) - 1);
421 regcache_raw_supply (regcache, i, val);
422 }
423 else
424 regcache_raw_supply (regcache, i, FSAVE_ADDR (tdep, regs, i));
425 }
426
427 /* Provide dummy values for the SSE registers. */
428 for (i = I387_XMM0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
429 if (regnum == -1 || regnum == i)
430 regcache_raw_supply (regcache, i, NULL);
431 if (regnum == -1 || regnum == I387_MXCSR_REGNUM (tdep))
432 {
433 gdb_byte buf[4];
434
435 store_unsigned_integer (buf, 4, byte_order, 0x1f80);
436 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), buf);
437 }
438 }
439
440 /* Fill register REGNUM (if it is a floating-point register) in *FSAVE
441 with the value from REGCACHE. If REGNUM is -1, do this for all
442 registers. This function doesn't touch any of the reserved bits in
443 *FSAVE. */
444
445 void
446 i387_collect_fsave (const struct regcache *regcache, int regnum, void *fsave)
447 {
448 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
449 gdb_byte *regs = fsave;
450 int i;
451
452 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
453
454 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
455 if (regnum == -1 || regnum == i)
456 {
457 /* Most of the FPU control registers occupy only 16 bits in
458 the fsave area. Give those a special treatment. */
459 if (i >= I387_FCTRL_REGNUM (tdep)
460 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
461 {
462 gdb_byte buf[4];
463
464 regcache_raw_collect (regcache, i, buf);
465
466 if (i == I387_FOP_REGNUM (tdep))
467 {
468 /* The opcode occupies only 11 bits. Make sure we
469 don't touch the other bits. */
470 buf[1] &= ((1 << 3) - 1);
471 buf[1] |= ((FSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
472 }
473 memcpy (FSAVE_ADDR (tdep, regs, i), buf, 2);
474 }
475 else
476 regcache_raw_collect (regcache, i, FSAVE_ADDR (tdep, regs, i));
477 }
478 }
479 \f
480
481 /* At fxsave_offset[REGNUM] you'll find the offset to the location in
482 the data structure used by the "fxsave" instruction where GDB
483 register REGNUM is stored. */
484
485 static int fxsave_offset[] =
486 {
487 32, /* %st(0) through ... */
488 48,
489 64,
490 80,
491 96,
492 112,
493 128,
494 144, /* ... %st(7) (80 bits each). */
495 0, /* `fctrl' (16 bits). */
496 2, /* `fstat' (16 bits). */
497 4, /* `ftag' (16 bits). */
498 12, /* `fiseg' (16 bits). */
499 8, /* `fioff'. */
500 20, /* `foseg' (16 bits). */
501 16, /* `fooff'. */
502 6, /* `fop' (bottom 11 bits). */
503 160 + 0 * 16, /* %xmm0 through ... */
504 160 + 1 * 16,
505 160 + 2 * 16,
506 160 + 3 * 16,
507 160 + 4 * 16,
508 160 + 5 * 16,
509 160 + 6 * 16,
510 160 + 7 * 16,
511 160 + 8 * 16,
512 160 + 9 * 16,
513 160 + 10 * 16,
514 160 + 11 * 16,
515 160 + 12 * 16,
516 160 + 13 * 16,
517 160 + 14 * 16,
518 160 + 15 * 16, /* ... %xmm15 (128 bits each). */
519 };
520
521 #define FXSAVE_ADDR(tdep, fxsave, regnum) \
522 (fxsave + fxsave_offset[regnum - I387_ST0_REGNUM (tdep)])
523
524 /* We made an unfortunate choice in putting %mxcsr after the SSE
525 registers %xmm0-%xmm7 instead of before, since it makes supporting
526 the registers %xmm8-%xmm15 on AMD64 a bit involved. Therefore we
527 don't include the offset for %mxcsr here above. */
528
529 #define FXSAVE_MXCSR_ADDR(fxsave) (fxsave + 24)
530
531 static int i387_tag (const gdb_byte *raw);
532 \f
533
534 /* Fill register REGNUM in REGCACHE with the appropriate
535 floating-point or SSE register value from *FXSAVE. This function
536 masks off any of the reserved bits in *FXSAVE. */
537
538 void
539 i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
540 {
541 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
542 const gdb_byte *regs = fxsave;
543 int i;
544
545 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
546 gdb_assert (tdep->num_xmm_regs > 0);
547
548 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
549 if (regnum == -1 || regnum == i)
550 {
551 if (regs == NULL)
552 {
553 regcache_raw_supply (regcache, i, NULL);
554 continue;
555 }
556
557 /* Most of the FPU control registers occupy only 16 bits in
558 the fxsave area. Give those a special treatment. */
559 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
560 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
561 {
562 gdb_byte val[4];
563
564 memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
565 val[2] = val[3] = 0;
566 if (i == I387_FOP_REGNUM (tdep))
567 val[1] &= ((1 << 3) - 1);
568 else if (i== I387_FTAG_REGNUM (tdep))
569 {
570 /* The fxsave area contains a simplified version of
571 the tag word. We have to look at the actual 80-bit
572 FP data to recreate the traditional i387 tag word. */
573
574 unsigned long ftag = 0;
575 int fpreg;
576 int top;
577
578 top = ((FXSAVE_ADDR (tdep, regs,
579 I387_FSTAT_REGNUM (tdep)))[1] >> 3);
580 top &= 0x7;
581
582 for (fpreg = 7; fpreg >= 0; fpreg--)
583 {
584 int tag;
585
586 if (val[0] & (1 << fpreg))
587 {
588 int regnum = (fpreg + 8 - top) % 8
589 + I387_ST0_REGNUM (tdep);
590 tag = i387_tag (FXSAVE_ADDR (tdep, regs, regnum));
591 }
592 else
593 tag = 3; /* Empty */
594
595 ftag |= tag << (2 * fpreg);
596 }
597 val[0] = ftag & 0xff;
598 val[1] = (ftag >> 8) & 0xff;
599 }
600 regcache_raw_supply (regcache, i, val);
601 }
602 else
603 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
604 }
605
606 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
607 {
608 if (regs == NULL)
609 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), NULL);
610 else
611 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep),
612 FXSAVE_MXCSR_ADDR (regs));
613 }
614 }
615
616 /* Fill register REGNUM (if it is a floating-point or SSE register) in
617 *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for
618 all registers. This function doesn't touch any of the reserved
619 bits in *FXSAVE. */
620
621 void
622 i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave)
623 {
624 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
625 gdb_byte *regs = fxsave;
626 int i;
627
628 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
629 gdb_assert (tdep->num_xmm_regs > 0);
630
631 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
632 if (regnum == -1 || regnum == i)
633 {
634 /* Most of the FPU control registers occupy only 16 bits in
635 the fxsave area. Give those a special treatment. */
636 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
637 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
638 {
639 gdb_byte buf[4];
640
641 regcache_raw_collect (regcache, i, buf);
642
643 if (i == I387_FOP_REGNUM (tdep))
644 {
645 /* The opcode occupies only 11 bits. Make sure we
646 don't touch the other bits. */
647 buf[1] &= ((1 << 3) - 1);
648 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
649 }
650 else if (i == I387_FTAG_REGNUM (tdep))
651 {
652 /* Converting back is much easier. */
653
654 unsigned short ftag;
655 int fpreg;
656
657 ftag = (buf[1] << 8) | buf[0];
658 buf[0] = 0;
659 buf[1] = 0;
660
661 for (fpreg = 7; fpreg >= 0; fpreg--)
662 {
663 int tag = (ftag >> (fpreg * 2)) & 3;
664
665 if (tag != 3)
666 buf[0] |= (1 << fpreg);
667 }
668 }
669 memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
670 }
671 else
672 regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
673 }
674
675 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
676 regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
677 FXSAVE_MXCSR_ADDR (regs));
678 }
679
680 /* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
681 *RAW. */
682
683 static int
684 i387_tag (const gdb_byte *raw)
685 {
686 int integer;
687 unsigned int exponent;
688 unsigned long fraction[2];
689
690 integer = raw[7] & 0x80;
691 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
692 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
693 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
694 | (raw[5] << 8) | raw[4]);
695
696 if (exponent == 0x7fff)
697 {
698 /* Special. */
699 return (2);
700 }
701 else if (exponent == 0x0000)
702 {
703 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
704 {
705 /* Zero. */
706 return (1);
707 }
708 else
709 {
710 /* Special. */
711 return (2);
712 }
713 }
714 else
715 {
716 if (integer)
717 {
718 /* Valid. */
719 return (0);
720 }
721 else
722 {
723 /* Special. */
724 return (2);
725 }
726 }
727 }
728
729 /* Prepare the FPU stack in REGCACHE for a function return. */
730
731 void
732 i387_return_value (struct gdbarch *gdbarch, struct regcache *regcache)
733 {
734 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
735 ULONGEST fstat;
736
737 /* Set the top of the floating-point register stack to 7. The
738 actual value doesn't really matter, but 7 is what a normal
739 function return would end up with if the program started out with
740 a freshly initialized FPU. */
741 regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM (tdep), &fstat);
742 fstat |= (7 << 11);
743 regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM (tdep), fstat);
744
745 /* Mark %st(1) through %st(7) as empty. Since we set the top of the
746 floating-point register stack to 7, the appropriate value for the
747 tag word is 0x3fff. */
748 regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM (tdep), 0x3fff);
749
750 }
This page took 0.045805 seconds and 4 git commands to generate.