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