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