OSDN Git Service

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