OSDN Git Service

Copyright updates for 2007.
[pf3gnuchains/pf3gnuchains3x.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 Free Software Foundation, Inc.
5
6    This file is part of GDB.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor,
21    Boston, MA 02110-1301, USA.  */
22
23 #include "defs.h"
24 #include "doublest.h"
25 #include "floatformat.h"
26 #include "frame.h"
27 #include "gdbcore.h"
28 #include "inferior.h"
29 #include "language.h"
30 #include "regcache.h"
31 #include "value.h"
32
33 #include "gdb_assert.h"
34 #include "gdb_string.h"
35
36 #include "i386-tdep.h"
37 #include "i387-tdep.h"
38
39 /* Print the floating point number specified by RAW.  */
40
41 static void
42 print_i387_value (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, builtin_type_i387_ext);
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 (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 (raw, file);
98   else if (exponent == 0x0000)
99     {
100       /* Denormal or zero.  */
101       print_i387_value (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   /* Define I387_ST0_REGNUM such that we use the proper definitions
221      for FRAME's architecture.  */
222 #define I387_ST0_REGNUM tdep->st0_regnum
223
224   fctrl = get_frame_register_unsigned (frame, I387_FCTRL_REGNUM);
225   fstat = get_frame_register_unsigned (frame, I387_FSTAT_REGNUM);
226   ftag = get_frame_register_unsigned (frame, I387_FTAG_REGNUM);
227   fiseg = get_frame_register_unsigned (frame, I387_FISEG_REGNUM);
228   fioff = get_frame_register_unsigned (frame, I387_FIOFF_REGNUM);
229   foseg = get_frame_register_unsigned (frame, I387_FOSEG_REGNUM);
230   fooff = get_frame_register_unsigned (frame, I387_FOOFF_REGNUM);
231   fop = get_frame_register_unsigned (frame, I387_FOP_REGNUM);
232
233   top = ((fstat >> 11) & 7);
234
235   for (fpreg = 7; fpreg >= 0; fpreg--)
236     {
237       gdb_byte raw[I386_MAX_REGISTER_SIZE];
238       int tag = (ftag >> (fpreg * 2)) & 3;
239       int i;
240
241       fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : "  ", fpreg);
242
243       switch (tag)
244         {
245         case 0:
246           fputs_filtered ("Valid   ", file);
247           break;
248         case 1:
249           fputs_filtered ("Zero    ", file);
250           break;
251         case 2:
252           fputs_filtered ("Special ", file);
253           break;
254         case 3:
255           fputs_filtered ("Empty   ", file);
256           break;
257         }
258
259       get_frame_register (frame, (fpreg + 8 - top) % 8 + I387_ST0_REGNUM, raw);
260
261       fputs_filtered ("0x", file);
262       for (i = 9; i >= 0; i--)
263         fprintf_filtered (file, "%02x", raw[i]);
264
265       if (tag != 3)
266         print_i387_ext (raw, file);
267
268       fputs_filtered ("\n", file);
269     }
270
271   fputs_filtered ("\n", file);
272
273   print_i387_status_word (fstat, file);
274   print_i387_control_word (fctrl, file);
275   fprintf_filtered (file, "Tag Word:            %s\n",
276                     hex_string_custom (ftag, 4));
277   fprintf_filtered (file, "Instruction Pointer: %s:",
278                     hex_string_custom (fiseg, 2));
279   fprintf_filtered (file, "%s\n", hex_string_custom (fioff, 8));
280   fprintf_filtered (file, "Operand Pointer:     %s:",
281                     hex_string_custom (foseg, 2));
282   fprintf_filtered (file, "%s\n", hex_string_custom (fooff, 8));
283   fprintf_filtered (file, "Opcode:              %s\n",
284                     hex_string_custom (fop ? (fop | 0xd800) : 0, 4));
285
286 #undef I387_ST0_REGNUM
287 }
288 \f
289
290 /* Read a value of type TYPE from register REGNUM in frame FRAME, and
291    return its contents in TO.  */
292
293 void
294 i387_register_to_value (struct frame_info *frame, int regnum,
295                         struct type *type, gdb_byte *to)
296 {
297   gdb_byte from[I386_MAX_REGISTER_SIZE];
298
299   gdb_assert (i386_fp_regnum_p (regnum));
300
301   /* We only support floating-point values.  */
302   if (TYPE_CODE (type) != TYPE_CODE_FLT)
303     {
304       warning (_("Cannot convert floating-point register value "
305                "to non-floating-point type."));
306       return;
307     }
308
309   /* Convert to TYPE.  This should be a no-op if TYPE is equivalent to
310      the extended floating-point format used by the FPU.  */
311   get_frame_register (frame, regnum, from);
312   convert_typed_floating (from, builtin_type_i387_ext, to, type);
313 }
314
315 /* Write the contents FROM of a value of type TYPE into register
316    REGNUM in frame FRAME.  */
317
318 void
319 i387_value_to_register (struct frame_info *frame, int regnum,
320                         struct type *type, const gdb_byte *from)
321 {
322   gdb_byte to[I386_MAX_REGISTER_SIZE];
323
324   gdb_assert (i386_fp_regnum_p (regnum));
325
326   /* We only support floating-point values.  */
327   if (TYPE_CODE (type) != TYPE_CODE_FLT)
328     {
329       warning (_("Cannot convert non-floating-point type "
330                "to floating-point register value."));
331       return;
332     }
333
334   /* Convert from TYPE.  This should be a no-op if TYPE is equivalent
335      to the extended floating-point format used by the FPU.  */
336   convert_typed_floating (from, type, to, builtin_type_i387_ext);
337   put_frame_register (frame, regnum, to);
338 }
339 \f
340
341 /* Handle FSAVE and FXSAVE formats.  */
342
343 /* At fsave_offset[REGNUM] you'll find the offset to the location in
344    the data structure used by the "fsave" instruction where GDB
345    register REGNUM is stored.  */
346
347 static int fsave_offset[] =
348 {
349   28 + 0 * 10,                  /* %st(0) ...  */
350   28 + 1 * 10,
351   28 + 2 * 10,
352   28 + 3 * 10,
353   28 + 4 * 10,
354   28 + 5 * 10,
355   28 + 6 * 10,
356   28 + 7 * 10,                  /* ... %st(7).  */
357   0,                            /* `fctrl' (16 bits).  */
358   4,                            /* `fstat' (16 bits).  */
359   8,                            /* `ftag' (16 bits).  */
360   16,                           /* `fiseg' (16 bits).  */
361   12,                           /* `fioff'.  */
362   24,                           /* `foseg' (16 bits).  */
363   20,                           /* `fooff'.  */
364   18                            /* `fop' (bottom 11 bits).  */
365 };
366
367 #define FSAVE_ADDR(fsave, regnum) \
368   (fsave + fsave_offset[regnum - I387_ST0_REGNUM])
369 \f
370
371 /* Fill register REGNUM in REGCACHE with the appropriate value from
372    *FSAVE.  This function masks off any of the reserved bits in
373    *FSAVE.  */
374
375 void
376 i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave)
377 {
378   struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
379   const gdb_byte *regs = fsave;
380   int i;
381
382   gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
383
384   /* Define I387_ST0_REGNUM and I387_NUM_XMM_REGS such that we use the
385      proper definitions for REGCACHE's architecture.  */
386
387 #define I387_ST0_REGNUM tdep->st0_regnum
388 #define I387_NUM_XMM_REGS tdep->num_xmm_regs
389
390   for (i = I387_ST0_REGNUM; i < I387_XMM0_REGNUM; i++)
391     if (regnum == -1 || regnum == i)
392       {
393         if (fsave == NULL)
394           {
395             regcache_raw_supply (regcache, i, NULL);
396             continue;
397           }
398
399         /* Most of the FPU control registers occupy only 16 bits in the
400            fsave area.  Give those a special treatment.  */
401         if (i >= I387_FCTRL_REGNUM
402             && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM)
403           {
404             gdb_byte val[4];
405
406             memcpy (val, FSAVE_ADDR (regs, i), 2);
407             val[2] = val[3] = 0;
408             if (i == I387_FOP_REGNUM)
409               val[1] &= ((1 << 3) - 1);
410             regcache_raw_supply (regcache, i, val);
411           }
412         else
413           regcache_raw_supply (regcache, i, FSAVE_ADDR (regs, i));
414       }
415
416   /* Provide dummy values for the SSE registers.  */
417   for (i = I387_XMM0_REGNUM; i < I387_MXCSR_REGNUM; i++)
418     if (regnum == -1 || regnum == i)
419       regcache_raw_supply (regcache, i, NULL);
420   if (regnum == -1 || regnum == I387_MXCSR_REGNUM)
421     {
422       gdb_byte buf[4];
423
424       store_unsigned_integer (buf, 4, 0x1f80);
425       regcache_raw_supply (regcache, I387_MXCSR_REGNUM, buf);
426     }
427
428 #undef I387_ST0_REGNUM
429 #undef I387_NUM_XMM_REGS
430 }
431
432 /* Fill register REGNUM (if it is a floating-point register) in *FSAVE
433    with the value from REGCACHE.  If REGNUM is -1, do this for all
434    registers.  This function doesn't touch any of the reserved bits in
435    *FSAVE.  */
436
437 void
438 i387_collect_fsave (const struct regcache *regcache, int regnum, void *fsave)
439 {
440   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
441   gdb_byte *regs = fsave;
442   int i;
443
444   gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
445
446   /* Define I387_ST0_REGNUM such that we use the proper definitions
447      for REGCACHE's architecture.  */
448 #define I387_ST0_REGNUM tdep->st0_regnum
449
450   for (i = I387_ST0_REGNUM; i < I387_XMM0_REGNUM; i++)
451     if (regnum == -1 || regnum == i)
452       {
453         /* Most of the FPU control registers occupy only 16 bits in
454            the fsave area.  Give those a special treatment.  */
455         if (i >= I387_FCTRL_REGNUM
456             && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM)
457           {
458             gdb_byte buf[4];
459
460             regcache_raw_collect (regcache, i, buf);
461
462             if (i == I387_FOP_REGNUM)
463               {
464                 /* The opcode occupies only 11 bits.  Make sure we
465                    don't touch the other bits.  */
466                 buf[1] &= ((1 << 3) - 1);
467                 buf[1] |= ((FSAVE_ADDR (regs, i))[1] & ~((1 << 3) - 1));
468               }
469             memcpy (FSAVE_ADDR (regs, i), buf, 2);
470           }
471         else
472           regcache_raw_collect (regcache, i, FSAVE_ADDR (regs, i));
473       }
474 #undef I387_ST0_REGNUM
475 }
476
477 /* Fill register REGNUM (if it is a floating-point register) in *FSAVE
478    with the value in GDB's register cache.  If REGNUM is -1, do this
479    for all registers.  This function doesn't touch any of the reserved
480    bits in *FSAVE.  */
481
482 void
483 i387_fill_fsave (void *fsave, int regnum)
484 {
485   i387_collect_fsave (current_regcache, regnum, fsave);
486 }
487 \f
488
489 /* At fxsave_offset[REGNUM] you'll find the offset to the location in
490    the data structure used by the "fxsave" instruction where GDB
491    register REGNUM is stored.  */
492
493 static int fxsave_offset[] =
494 {
495   32,                           /* %st(0) through ...  */
496   48,
497   64,
498   80,
499   96,
500   112,
501   128,
502   144,                          /* ... %st(7) (80 bits each).  */
503   0,                            /* `fctrl' (16 bits).  */
504   2,                            /* `fstat' (16 bits).  */
505   4,                            /* `ftag' (16 bits).  */
506   12,                           /* `fiseg' (16 bits).  */
507   8,                            /* `fioff'.  */
508   20,                           /* `foseg' (16 bits).  */
509   16,                           /* `fooff'.  */
510   6,                            /* `fop' (bottom 11 bits).  */
511   160 + 0 * 16,                 /* %xmm0 through ...  */
512   160 + 1 * 16,
513   160 + 2 * 16,
514   160 + 3 * 16,
515   160 + 4 * 16,
516   160 + 5 * 16,
517   160 + 6 * 16,
518   160 + 7 * 16,
519   160 + 8 * 16,
520   160 + 9 * 16,
521   160 + 10 * 16,
522   160 + 11 * 16,
523   160 + 12 * 16,
524   160 + 13 * 16,
525   160 + 14 * 16,
526   160 + 15 * 16,                /* ... %xmm15 (128 bits each).  */
527 };
528
529 #define FXSAVE_ADDR(fxsave, regnum) \
530   (fxsave + fxsave_offset[regnum - I387_ST0_REGNUM])
531
532 /* We made an unfortunate choice in putting %mxcsr after the SSE
533    registers %xmm0-%xmm7 instead of before, since it makes supporting
534    the registers %xmm8-%xmm15 on AMD64 a bit involved.  Therefore we
535    don't include the offset for %mxcsr here above.  */
536
537 #define FXSAVE_MXCSR_ADDR(fxsave) (fxsave + 24)
538
539 static int i387_tag (const gdb_byte *raw);
540 \f
541
542 /* Fill register REGNUM in REGCACHE with the appropriate
543    floating-point or SSE register value from *FXSAVE.  This function
544    masks off any of the reserved bits in *FXSAVE.  */
545
546 void
547 i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
548 {
549   struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
550   const gdb_byte *regs = fxsave;
551   int i;
552
553   gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
554   gdb_assert (tdep->num_xmm_regs > 0);
555
556   /* Define I387_ST0_REGNUM and I387_NUM_XMM_REGS such that we use the
557      proper definitions for REGCACHE's architecture.  */
558
559 #define I387_ST0_REGNUM tdep->st0_regnum
560 #define I387_NUM_XMM_REGS tdep->num_xmm_regs
561
562   for (i = I387_ST0_REGNUM; i < I387_MXCSR_REGNUM; i++)
563     if (regnum == -1 || regnum == i)
564       {
565         if (regs == NULL)
566           {
567             regcache_raw_supply (regcache, i, NULL);
568             continue;
569           }
570
571         /* Most of the FPU control registers occupy only 16 bits in
572            the fxsave area.  Give those a special treatment.  */
573         if (i >= I387_FCTRL_REGNUM && i < I387_XMM0_REGNUM
574             && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM)
575           {
576             gdb_byte val[4];
577
578             memcpy (val, FXSAVE_ADDR (regs, i), 2);
579             val[2] = val[3] = 0;
580             if (i == I387_FOP_REGNUM)
581               val[1] &= ((1 << 3) - 1);
582             else if (i== I387_FTAG_REGNUM)
583               {
584                 /* The fxsave area contains a simplified version of
585                    the tag word.  We have to look at the actual 80-bit
586                    FP data to recreate the traditional i387 tag word.  */
587
588                 unsigned long ftag = 0;
589                 int fpreg;
590                 int top;
591
592                 top = ((FXSAVE_ADDR (regs, I387_FSTAT_REGNUM))[1] >> 3);
593                 top &= 0x7;
594
595                 for (fpreg = 7; fpreg >= 0; fpreg--)
596                   {
597                     int tag;
598
599                     if (val[0] & (1 << fpreg))
600                       {
601                         int regnum = (fpreg + 8 - top) % 8 + I387_ST0_REGNUM;
602                         tag = i387_tag (FXSAVE_ADDR (regs, regnum));
603                       }
604                     else
605                       tag = 3;          /* Empty */
606
607                     ftag |= tag << (2 * fpreg);
608                   }
609                 val[0] = ftag & 0xff;
610                 val[1] = (ftag >> 8) & 0xff;
611               }
612             regcache_raw_supply (regcache, i, val);
613           }
614         else
615           regcache_raw_supply (regcache, i, FXSAVE_ADDR (regs, i));
616       }
617
618   if (regnum == I387_MXCSR_REGNUM || regnum == -1)
619     {
620       if (regs == NULL)
621         regcache_raw_supply (regcache, I387_MXCSR_REGNUM, NULL);
622       else
623         regcache_raw_supply (regcache, I387_MXCSR_REGNUM,
624                              FXSAVE_MXCSR_ADDR (regs));
625     }
626
627 #undef I387_ST0_REGNUM
628 #undef I387_NUM_XMM_REGS
629 }
630
631 /* Fill register REGNUM (if it is a floating-point or SSE register) in
632    *FXSAVE with the value from REGCACHE.  If REGNUM is -1, do this for
633    all registers.  This function doesn't touch any of the reserved
634    bits in *FXSAVE.  */
635
636 void
637 i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave)
638 {
639   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
640   gdb_byte *regs = fxsave;
641   int i;
642
643   gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
644   gdb_assert (tdep->num_xmm_regs > 0);
645
646   /* Define I387_ST0_REGNUM and I387_NUM_XMM_REGS such that we use the
647      proper definitions for REGCACHE's architecture.  */
648
649 #define I387_ST0_REGNUM tdep->st0_regnum
650 #define I387_NUM_XMM_REGS tdep->num_xmm_regs
651
652   for (i = I387_ST0_REGNUM; i < I387_MXCSR_REGNUM; i++)
653     if (regnum == -1 || regnum == i)
654       {
655         /* Most of the FPU control registers occupy only 16 bits in
656            the fxsave area.  Give those a special treatment.  */
657         if (i >= I387_FCTRL_REGNUM && i < I387_XMM0_REGNUM
658             && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM)
659           {
660             gdb_byte buf[4];
661
662             regcache_raw_collect (regcache, i, buf);
663
664             if (i == I387_FOP_REGNUM)
665               {
666                 /* The opcode occupies only 11 bits.  Make sure we
667                    don't touch the other bits.  */
668                 buf[1] &= ((1 << 3) - 1);
669                 buf[1] |= ((FXSAVE_ADDR (regs, i))[1] & ~((1 << 3) - 1));
670               }
671             else if (i == I387_FTAG_REGNUM)
672               {
673                 /* Converting back is much easier.  */
674
675                 unsigned short ftag;
676                 int fpreg;
677
678                 ftag = (buf[1] << 8) | buf[0];
679                 buf[0] = 0;
680                 buf[1] = 0;
681
682                 for (fpreg = 7; fpreg >= 0; fpreg--)
683                   {
684                     int tag = (ftag >> (fpreg * 2)) & 3;
685
686                     if (tag != 3)
687                       buf[0] |= (1 << fpreg);
688                   }
689               }
690             memcpy (FXSAVE_ADDR (regs, i), buf, 2);
691           }
692         else
693           regcache_raw_collect (regcache, i, FXSAVE_ADDR (regs, i));
694       }
695
696   if (regnum == I387_MXCSR_REGNUM || regnum == -1)
697     regcache_raw_collect (regcache, I387_MXCSR_REGNUM,
698                           FXSAVE_MXCSR_ADDR (regs));
699
700 #undef I387_ST0_REGNUM
701 #undef I387_NUM_XMM_REGS
702 }
703
704 /* Fill register REGNUM (if it is a floating-point or SSE register) in
705    *FXSAVE with the value in GDB's register cache.  If REGNUM is -1, do
706    this for all registers.  This function doesn't touch any of the
707    reserved bits in *FXSAVE.  */
708
709 void
710 i387_fill_fxsave (void *fxsave, int regnum)
711 {
712   i387_collect_fxsave (current_regcache, regnum, fxsave);
713 }
714
715 /* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
716    *RAW.  */
717
718 static int
719 i387_tag (const gdb_byte *raw)
720 {
721   int integer;
722   unsigned int exponent;
723   unsigned long fraction[2];
724
725   integer = raw[7] & 0x80;
726   exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
727   fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
728   fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
729                  | (raw[5] << 8) | raw[4]);
730
731   if (exponent == 0x7fff)
732     {
733       /* Special.  */
734       return (2);
735     }
736   else if (exponent == 0x0000)
737     {
738       if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
739         {
740           /* Zero.  */
741           return (1);
742         }
743       else
744         {
745           /* Special.  */
746           return (2);
747         }
748     }
749   else
750     {
751       if (integer)
752         {
753           /* Valid.  */
754           return (0);
755         }
756       else
757         {
758           /* Special.  */
759           return (2);
760         }
761     }
762 }
763
764 /* Prepare the FPU stack in REGCACHE for a function return.  */
765
766 void
767 i387_return_value (struct gdbarch *gdbarch, struct regcache *regcache)
768 {
769   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
770   ULONGEST fstat;
771
772   /* Define I387_ST0_REGNUM such that we use the proper
773      definitions for the architecture.  */
774 #define I387_ST0_REGNUM tdep->st0_regnum
775
776   /* Set the top of the floating-point register stack to 7.  The
777      actual value doesn't really matter, but 7 is what a normal
778      function return would end up with if the program started out with
779      a freshly initialized FPU.  */
780   regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM, &fstat);
781   fstat |= (7 << 11);
782   regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM, fstat);
783
784   /* Mark %st(1) through %st(7) as empty.  Since we set the top of the
785      floating-point register stack to 7, the appropriate value for the
786      tag word is 0x3fff.  */
787   regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM, 0x3fff);
788
789 #undef I387_ST0_REGNUM
790 }