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