1 /* Intel 387 floating point stuff.
2 
3    Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000,
4    2001, 2002, 2003, 2004, 2005 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., 59 Temple Place - Suite 330,
21    Boston, MA 02111-1307, 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
print_i387_value(const gdb_byte * raw,struct ui_file * file)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
print_i387_ext(const gdb_byte * raw,struct ui_file * file)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
print_i387_status_word(unsigned int status,struct ui_file * file)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
print_i387_control_word(unsigned int control,struct ui_file * file)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
i387_print_float_info(struct gdbarch * gdbarch,struct ui_file * file,struct frame_info * frame,const char * args)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 
289 
290 /* Read a value of type TYPE from register REGNUM in frame FRAME, and
291    return its contents in TO.  */
292 
293 void
i387_register_to_value(struct frame_info * frame,int regnum,struct type * type,gdb_byte * to)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
i387_value_to_register(struct frame_info * frame,int regnum,struct type * type,const gdb_byte * from)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 
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 
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
i387_supply_fsave(struct regcache * regcache,int regnum,const void * fsave)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
i387_collect_fsave(const struct regcache * regcache,int regnum,void * fsave)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
i387_fill_fsave(void * fsave,int regnum)483 i387_fill_fsave (void *fsave, int regnum)
484 {
485   i387_collect_fsave (current_regcache, regnum, fsave);
486 }
487 
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 
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
i387_supply_fxsave(struct regcache * regcache,int regnum,const void * fxsave)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
i387_collect_fxsave(const struct regcache * regcache,int regnum,void * fxsave)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
i387_fill_fxsave(void * fxsave,int regnum)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
i387_tag(const gdb_byte * raw)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
i387_return_value(struct gdbarch * gdbarch,struct regcache * regcache)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 }
791