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
44static void
45print_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
68static void
69print_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
120static void
121print_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
150static void
151print_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
204void
205i387_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
296void
297i387_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
321void
322i387_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
356static 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
384void
385i387_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
446void
447i387_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
491void
492i387_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
502static 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
548static 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
555void
556i387_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
645void
646i387_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
718void
719i387_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
727static int
728i387_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
775void
776i387_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