This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: 5/6: Add AVX support (i387 changes)


Hi,

Here are i387 changes to support AVX.  OK to install?

Thanks.


H.J.
---
2010-03-03  H.J. Lu  <hongjiu.lu@intel.com>

	* i387-tdep.c: Include "i386-xstate.h".
	(i387_supply_fsave): Replace I387_XMM0_REGNUM with
	I387_VECTOR0_REGNUM.
	(i387_collect_fsave): Likewise.
	(i387_supply_fxsave): Replace I387_XMM0_REGNUM with
	I387_VECTOR0_REGNUM.  Replace num_xmm_regs with num_vector_regs.
	Check tdep->xcr0 for AVX.
	(i387_collect_fxsave): Likewise.
	(xsave_sse_offset): New.
	(XSAVE_XSTATE_BV_ADDR): Likewise.
	(XSAVE_SSE_ADDR): Likewise.
	(xsave_avxh_offset): Likewise.
	(XSAVE_AVXH_ADDR): Likewise.
	(i387_supply_xsave): Likewise.
	(i387_collect_xsave): Likewise.

	* i387-tdep.h (I387_NUM_XMM_REGS): Renamed to ...
	(I387_NUM_VECTOR_REGS): This.
	(I387_XMM0_REGNUM): Renamed to ...
	(I387_VECTOR0_REGNUM): This.
	(I387_MXCSR_REGNUM): Updated.
	(i387_supply_xsave): New.
	(i387_collect_xsave): Likewise.

diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
index 3fb5b56..1f4547d 100644
--- a/gdb/i387-tdep.c
+++ b/gdb/i387-tdep.c
@@ -34,6 +34,7 @@
 
 #include "i386-tdep.h"
 #include "i387-tdep.h"
+#include "i386-xstate.h"
 
 /* Print the floating point number specified by RAW.  */
 
@@ -398,7 +399,7 @@ i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave)
 
   gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
 
-  for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
+  for (i = I387_ST0_REGNUM (tdep); i < I387_VECTOR0_REGNUM (tdep); i++)
     if (regnum == -1 || regnum == i)
       {
 	if (fsave == NULL)
@@ -425,7 +426,7 @@ i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave)
       }
 
   /* Provide dummy values for the SSE registers.  */
-  for (i = I387_XMM0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
+  for (i = I387_VECTOR0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
     if (regnum == -1 || regnum == i)
       regcache_raw_supply (regcache, i, NULL);
   if (regnum == -1 || regnum == I387_MXCSR_REGNUM (tdep))
@@ -451,7 +452,7 @@ i387_collect_fsave (const struct regcache *regcache, int regnum, void *fsave)
 
   gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
 
-  for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
+  for (i = I387_ST0_REGNUM (tdep); i < I387_VECTOR0_REGNUM (tdep); i++)
     if (regnum == -1 || regnum == i)
       {
 	/* Most of the FPU control registers occupy only 16 bits in
@@ -541,9 +542,11 @@ i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
   struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
   const gdb_byte *regs = fxsave;
   int i;
+  gdb_byte raw[I386_MAX_REGISTER_SIZE];
+  const gdb_byte *xmm;
 
   gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
-  gdb_assert (tdep->num_xmm_regs > 0);
+  gdb_assert (tdep->num_vector_regs > 0);
 
   for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
     if (regnum == -1 || regnum == i)
@@ -556,7 +559,7 @@ i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
 
 	/* Most of the FPU control registers occupy only 16 bits in
 	   the fxsave area.  Give those a special treatment.  */
-	if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
+	if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_VECTOR0_REGNUM (tdep)
 	    && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
 	  {
 	    gdb_byte val[4];
@@ -600,7 +603,17 @@ i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
 	    regcache_raw_supply (regcache, i, val);
 	  }
 	else
-	  regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
+	  {
+	    if ((tdep->xcr0 & I386_XSTATE_AVX_MASK)
+		== I386_XSTATE_AVX_MASK)
+	      {
+		memcpy (raw, FXSAVE_ADDR (tdep, regs, i), 16);
+		xmm = raw;
+	      }
+	    else
+	      xmm = FXSAVE_ADDR (tdep, regs, i);
+	    regcache_raw_supply (regcache, i, xmm);
+	  }
       }
 
   if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
@@ -624,16 +637,18 @@ i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave)
   struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
   gdb_byte *regs = fxsave;
   int i;
+  gdb_byte raw[I386_MAX_REGISTER_SIZE];
+  gdb_byte *xmm;
 
   gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
-  gdb_assert (tdep->num_xmm_regs > 0);
+  gdb_assert (tdep->num_vector_regs > 0);
 
   for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
     if (regnum == -1 || regnum == i)
       {
 	/* Most of the FPU control registers occupy only 16 bits in
            the fxsave area.  Give those a special treatment.  */
-	if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
+	if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_VECTOR0_REGNUM (tdep)
 	    && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
 	  {
 	    gdb_byte buf[4];
@@ -669,7 +684,465 @@ i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave)
 	    memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
 	  }
 	else
+	  {
+	    if ((tdep->xcr0 & I386_XSTATE_AVX_MASK)
+		== I386_XSTATE_AVX_MASK)
+	      {
+		memcpy (raw, FXSAVE_ADDR (tdep, regs, i), 16);
+		xmm = raw;
+	      }
+	    else
+	      xmm = FXSAVE_ADDR (tdep, regs, i);
+	    regcache_raw_collect (regcache, i, xmm);
+	  }
+      }
+
+  if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
+    regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
+			  FXSAVE_MXCSR_ADDR (regs));
+}
+
+/* At xsave_sse_offset[REGNUM] you'll find the offset to the location in
+   the SSE register data structure used by the "xsave" instruction where
+   GDB register REGNUM is stored.  */
+
+static int xsave_sse_offset[] =
+{
+  160 + 0 * 16,		/* %xmm0 through ...  */
+  160 + 1 * 16,
+  160 + 2 * 16,
+  160 + 3 * 16,
+  160 + 4 * 16,
+  160 + 5 * 16,
+  160 + 6 * 16,
+  160 + 7 * 16,
+  160 + 8 * 16,
+  160 + 9 * 16,
+  160 + 10 * 16,
+  160 + 11 * 16,
+  160 + 12 * 16,
+  160 + 13 * 16,
+  160 + 14 * 16,
+  160 + 15 * 16,	/* ... %xmm15 (128 bits each).  */
+};
+
+/* `xstate_bv' is at byte offset 512.  */
+#define XSAVE_XSTATE_BV_ADDR(xsave) (xsave + 512)
+
+#define XSAVE_SSE_ADDR(tdep, xsave, regnum) \
+  (xsave + xsave_sse_offset[regnum - I387_VECTOR0_REGNUM (tdep)])
+
+/* At xsave_avxh_offset[REGNUM] you'll find the offset to the location in
+   the upper 128bit of AVX register data structure used by the "xsave"
+   instruction where GDB register REGNUM is stored.  */
+
+static int xsave_avxh_offset[] =
+{
+  576 + 0 * 16,		/* Upper 128bit of %ymm0 through ...  */
+  576 + 1 * 16,
+  576 + 2 * 16,
+  576 + 3 * 16,
+  576 + 4 * 16,
+  576 + 5 * 16,
+  576 + 6 * 16,
+  576 + 7 * 16,
+  576 + 8 * 16,
+  576 + 9 * 16,
+  576 + 10 * 16,
+  576 + 11 * 16,
+  576 + 12 * 16,
+  576 + 13 * 16,
+  576 + 14 * 16,
+  576 + 15 * 16,	/* Upper 128bit of ... %ymm15 (128 bits each).  */
+};
+
+#define XSAVE_AVXH_ADDR(tdep, xsave, regnum) \
+  (xsave + xsave_avxh_offset[regnum - I387_VECTOR0_REGNUM (tdep)])
+
+/* Similar to i387_supply_fxsave, but use XSAVE extended state.  */
+
+void
+i387_supply_xsave (struct regcache *regcache, int regnum,
+		   const void *xsave)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
+  const gdb_byte *regs = xsave;
+  int i;
+  unsigned int clear_bv;
+  gdb_byte raw[I386_MAX_REGISTER_SIZE];
+  const gdb_byte *p;
+
+  gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
+  gdb_assert (tdep->num_vector_regs > 0);
+
+  if (regs != NULL
+      && (regnum == -1
+	  || (regnum >= I387_VECTOR0_REGNUM(tdep)
+	      && regnum < I387_MXCSR_REGNUM (tdep))
+	  || (regnum >= I387_ST0_REGNUM (tdep)
+	      && regnum < I387_FCTRL_REGNUM (tdep))))
+    {
+      /* Get `xstat_bv'.  */
+      const gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs);
+
+      /* The supported bits in `xstat_bv' are 1 byte.  Clear part in
+	 vector registers if its bit in xstat_bv is zero.  */
+      clear_bv = (~(*xstate_bv_p)) & tdep->xcr0;
+    }
+  else
+    clear_bv = 0;
+
+  for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
+    if (regnum == -1 || regnum == i)
+      {
+	if (regs == NULL)
+	  {
+	    regcache_raw_supply (regcache, i, NULL);
+	    continue;
+	  }
+
+	/* Most of the FPU control registers occupy only 16 bits in
+	   the xsave extended state.  Give those a special treatment.  */
+	if (i >= I387_FCTRL_REGNUM (tdep)
+	    && i < I387_VECTOR0_REGNUM (tdep)
+	    && i != I387_FIOFF_REGNUM (tdep)
+	    && i != I387_FOOFF_REGNUM (tdep))
+	  {
+	    gdb_byte val[4];
+
+	    memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
+	    val[2] = val[3] = 0;
+	    if (i == I387_FOP_REGNUM (tdep))
+	      val[1] &= ((1 << 3) - 1);
+	    else if (i== I387_FTAG_REGNUM (tdep))
+	      {
+		/* The fxsave area contains a simplified version of
+		   the tag word.  We have to look at the actual 80-bit
+		   FP data to recreate the traditional i387 tag word.  */
+
+		unsigned long ftag = 0;
+		int fpreg;
+		int top;
+
+		top = ((FXSAVE_ADDR (tdep, regs,
+				     I387_FSTAT_REGNUM (tdep)))[1] >> 3);
+		top &= 0x7;
+
+		for (fpreg = 7; fpreg >= 0; fpreg--)
+		  {
+		    int tag;
+
+		    if (val[0] & (1 << fpreg))
+		      {
+			int regnum = (fpreg + 8 - top) % 8 
+				       + I387_ST0_REGNUM (tdep);
+			tag = i387_tag (FXSAVE_ADDR (tdep, regs, regnum));
+		      }
+		    else
+		      tag = 3;		/* Empty */
+
+		    ftag |= tag << (2 * fpreg);
+		  }
+		val[0] = ftag & 0xff;
+		val[1] = (ftag >> 8) & 0xff;
+	      }
+	    regcache_raw_supply (regcache, i, val);
+	  }
+	else if (i < I387_VECTOR0_REGNUM (tdep))
+	  {
+	    if (i < I387_FCTRL_REGNUM (tdep)
+		&& (clear_bv & bit_I386_XSTATE_X87))
+	      p = NULL;
+	    else
+	      p = FXSAVE_ADDR (tdep, regs, i);
+	    regcache_raw_supply (regcache, i, p);
+	  }
+	else
+	  {
+	    if ((tdep->xcr0 & I386_XSTATE_AVX_MASK)
+		== I386_XSTATE_AVX_MASK)
+	      {
+		if ((clear_bv & (bit_I386_XSTATE_SSE | bit_I386_XSTATE_AVX))
+		    == (bit_I386_XSTATE_SSE | bit_I386_XSTATE_AVX))
+		  p = NULL;
+		else
+		  {
+		    p = raw;
+		    if ((clear_bv & bit_I386_XSTATE_SSE))
+		      memset (raw, 0, 16);
+		    else
+		      memcpy (raw, XSAVE_SSE_ADDR (tdep, regs, i), 16);
+		    if ((clear_bv & bit_I386_XSTATE_AVX))
+		      memset (raw + 16, 0, 16);
+		    else
+		      memcpy (raw + 16, XSAVE_AVXH_ADDR (tdep, regs, i),
+			      16);
+		  }
+	      }
+	    else
+	      {
+		if ((clear_bv & bit_I386_XSTATE_SSE))
+		  p = NULL;
+		else
+		  p = XSAVE_SSE_ADDR (tdep, regs, i);
+	      }
+	    regcache_raw_supply (regcache, i, p);
+	  }
+      }
+
+  if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
+    {
+      if (regs == NULL)
+	regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), NULL);
+      else
+	regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep),
+			     FXSAVE_MXCSR_ADDR (regs));
+    }
+}
+
+/* Similar to i387_collect_fxsave, but use XSAVE extended state.  */
+
+void
+i387_collect_xsave (const struct regcache *regcache, int regnum,
+		    void *xsave, int gcore)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
+  gdb_byte *regs = xsave;
+  int i;
+  gdb_byte raw[I386_MAX_REGISTER_SIZE];
+
+  gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
+  gdb_assert (tdep->num_vector_regs > 0);
+
+  if (gcore)
+    {
+      /* Update XCR0 and `xstate_bv' with XCR0 for gcore.  */
+      if (tdep->xsave_xcr0_offset != -1)
+	memcpy (regs + tdep->xsave_xcr0_offset, &tdep->xcr0, 8);
+      memcpy (XSAVE_XSTATE_BV_ADDR (regs), &tdep->xcr0, 8);
+    }
+  else
+    {
+      enum
+	{
+	  none = 0x0,
+	  check = 0x1,
+	  x87 = 0x2 | check,
+	  vector = 0x4 | check,
+	  all = 0x8 | check
+	} regclass;
+
+      if (regnum == -1)
+	regclass = all;
+      else if (regnum >= I387_VECTOR0_REGNUM(tdep)
+	       && regnum < I387_MXCSR_REGNUM (tdep))
+	regclass = vector;
+      else if (regnum >= I387_ST0_REGNUM (tdep)
+	       && regnum < I387_FCTRL_REGNUM (tdep))
+	regclass = x87;
+      else
+	regclass = none;
+
+      if ((regclass & check))
+	{
+	  gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs);
+	  int num_vector_regs;
+	  unsigned int xstate_bv = 0;
+	  /* The supported bits in `xstat_bv' are 1 byte. */
+	  unsigned int clear_bv = (~(*xstate_bv_p)) & tdep->xcr0;
+
+	  /* Clear part in vector registers if its bit in xstat_bv is
+	     zero.  */
+	  if (clear_bv)
+	    {
+	      i = I387_VECTOR0_REGNUM (tdep);
+	      num_vector_regs = I387_NUM_VECTOR_REGS(tdep);
+	      for (; num_vector_regs; num_vector_regs--, i++)
+		{
+		  if ((clear_bv & bit_I386_XSTATE_AVX))
+		    memset (XSAVE_AVXH_ADDR (tdep, regs, i), 0, 16);
+		  if ((clear_bv & bit_I386_XSTATE_SSE))
+		    memset (XSAVE_SSE_ADDR (tdep, regs, i), 0, 16);
+		}
+
+	      if ((clear_bv & bit_I386_XSTATE_X87))
+		for (i = I387_ST0_REGNUM (tdep);
+		     i < I387_FCTRL_REGNUM (tdep); i++)
+		  memset (FXSAVE_ADDR (tdep, regs, i), 0, 10);
+	    }
+
+	  if (regclass == all)
+	    {
+	      i = I387_VECTOR0_REGNUM (tdep);
+	      num_vector_regs = I387_NUM_VECTOR_REGS(tdep);
+
+	      if ((tdep->xcr0 & I386_XSTATE_AVX_MASK)
+		  == I386_XSTATE_AVX_MASK)
+		{
+		  /* Check if any AVX registers are changed.  */
+		  for (; num_vector_regs; num_vector_regs--, i++)
+		    {
+		      regcache_raw_read ((struct regcache *) regcache,
+					 i, raw);
+		      if (memcmp (raw + 16,
+				  XSAVE_AVXH_ADDR (tdep, regs, i), 16))
+			xstate_bv |= bit_I386_XSTATE_AVX;
+		      if (memcmp (raw, XSAVE_SSE_ADDR (tdep, regs, i), 16))
+			xstate_bv |= bit_I386_XSTATE_SSE;
+
+		      if (xstate_bv
+			  == (bit_I386_XSTATE_AVX | bit_I386_XSTATE_SSE))
+			break;
+		    }
+		}
+	      else
+		{
+		  /* Check if any SSE registers are changed.  */
+		  for (; num_vector_regs; num_vector_regs--, i++)
+		    {
+		      regcache_raw_read ((struct regcache *) regcache,
+					 i, raw);
+		      if (memcmp (raw, XSAVE_SSE_ADDR (tdep, regs, i), 16))
+			{
+			  xstate_bv |= bit_I386_XSTATE_SSE;
+			  break;
+			}
+		    }
+		}
+
+	      /* Check if any X87 registers are changed.  */
+	      for (i = I387_ST0_REGNUM (tdep);
+		   i < I387_FCTRL_REGNUM (tdep); i++)
+		{
+		  regcache_raw_read ((struct regcache *) regcache, i, raw);
+		  if (memcmp (raw, FXSAVE_ADDR (tdep, regs, i), 10))
+		    {
+		      xstate_bv |= bit_I386_XSTATE_X87;
+		      break;
+		    }
+		}
+	    }
+	  else
+	    {
+	      /* Check if REGNUM is changed.  */
+	      regcache_raw_read ((struct regcache *) regcache, regnum, raw);
+
+	      if (regclass == x87)
+		{
+		  /* This is an x87 register.  */
+		  if (memcmp (raw, FXSAVE_ADDR (tdep, regs, regnum), 10))
+		    xstate_bv |= bit_I386_XSTATE_X87;
+		}
+	      else
+		{
+		  /* This is an SSE/AVX register.  */
+		  if ((tdep->xcr0 & I386_XSTATE_AVX_MASK)
+		      == I386_XSTATE_AVX_MASK)
+		    {
+		      if (memcmp (raw + 16,
+				  XSAVE_AVXH_ADDR (tdep, regs, regnum), 16))
+			xstate_bv |= bit_I386_XSTATE_AVX;
+		    }
+
+		  if (memcmp (raw, XSAVE_SSE_ADDR (tdep, regs, regnum), 16))
+		    xstate_bv |= bit_I386_XSTATE_SSE;
+		}
+	    }
+
+	  /* Update the corresponding bits in `xstate_bv' if any SSE/AVX
+	     registers are changed.  */
+	  if (xstate_bv)
+	    {
+	      /* The supported bits in `xstat_bv' are 1 byte.  */
+	      *xstate_bv_p |= (gdb_byte) xstate_bv;
+
+	      /* Update REGNUM and return.  */
+	      if (regclass != all)
+		{
+		  if (regclass == x87)
+		    {
+		      /* x87 register.  */
+		      memcpy (FXSAVE_ADDR (tdep, regs, regnum), raw, 10);
+		    }
+		  else
+		    {
+		      /* SSE/AVX register.  */
+		      if ((xstate_bv & bit_I386_XSTATE_AVX))
+			memcpy (XSAVE_AVXH_ADDR (tdep, regs, regnum),
+				raw + 16, 16);
+		      if ((xstate_bv & bit_I386_XSTATE_SSE))
+			memcpy (XSAVE_SSE_ADDR (tdep, regs, regnum), raw, 16);
+		    }
+		  return;
+		}
+	    }
+	  else
+	    {
+	      /* Return if REGNUM isn't changed.  */
+	      if (regclass != all)
+		return;
+	    }
+	}
+    }
+
+  for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
+    if (regnum == -1 || regnum == i)
+      {
+	/* Most of the FPU control registers occupy only 16 bits in
+	   the xsave extended state.  Give those a special treatment.  */
+	if (i >= I387_FCTRL_REGNUM (tdep)
+	    && i < I387_VECTOR0_REGNUM (tdep)
+	    && i != I387_FIOFF_REGNUM (tdep)
+	    && i != I387_FOOFF_REGNUM (tdep))
+	  {
+	    gdb_byte buf[4];
+
+	    regcache_raw_collect (regcache, i, buf);
+
+	    if (i == I387_FOP_REGNUM (tdep))
+	      {
+		/* The opcode occupies only 11 bits.  Make sure we
+                   don't touch the other bits.  */
+		buf[1] &= ((1 << 3) - 1);
+		buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
+	      }
+	    else if (i == I387_FTAG_REGNUM (tdep))
+	      {
+		/* Converting back is much easier.  */
+
+		unsigned short ftag;
+		int fpreg;
+
+		ftag = (buf[1] << 8) | buf[0];
+		buf[0] = 0;
+		buf[1] = 0;
+
+		for (fpreg = 7; fpreg >= 0; fpreg--)
+		  {
+		    int tag = (ftag >> (fpreg * 2)) & 3;
+
+		    if (tag != 3)
+		      buf[0] |= (1 << fpreg);
+		  }
+	      }
+	    memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
+	  }
+	else if (i < I387_VECTOR0_REGNUM (tdep))
 	  regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
+	else
+	  {
+	    if ((tdep->xcr0 & I386_XSTATE_AVX_MASK)
+		== I386_XSTATE_AVX_MASK)
+	      {
+		regcache_raw_collect (regcache, i, raw);
+		memcpy (XSAVE_SSE_ADDR (tdep, regs, i), raw, 16);
+		memcpy (XSAVE_AVXH_ADDR (tdep, regs, i),
+			raw + 16, 16);
+	      }
+	    else
+	      regcache_raw_collect (regcache, i,
+				    XSAVE_SSE_ADDR (tdep, regs, i));
+	  }
       }
 
   if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
diff --git a/gdb/i387-tdep.h b/gdb/i387-tdep.h
index 645eb91..f867a1f 100644
--- a/gdb/i387-tdep.h
+++ b/gdb/i387-tdep.h
@@ -31,7 +31,7 @@ struct ui_file;
 #define I387_NUM_REGS	16
 
 #define I387_ST0_REGNUM(tdep) ((tdep)->st0_regnum)
-#define I387_NUM_XMM_REGS(tdep) ((tdep)->num_xmm_regs)
+#define I387_NUM_VECTOR_REGS(tdep) ((tdep)->num_vector_regs)
 #define I387_MM0_REGNUM(tdep) ((tdep)->mm0_regnum)
 
 #define I387_FCTRL_REGNUM(tdep) (I387_ST0_REGNUM (tdep) + 8)
@@ -42,9 +42,9 @@ struct ui_file;
 #define I387_FOSEG_REGNUM(tdep) (I387_FCTRL_REGNUM (tdep) + 5)
 #define I387_FOOFF_REGNUM(tdep) (I387_FCTRL_REGNUM (tdep) + 6)
 #define I387_FOP_REGNUM(tdep) (I387_FCTRL_REGNUM (tdep) + 7)
-#define I387_XMM0_REGNUM(tdep) (I387_ST0_REGNUM (tdep) + 16)
+#define I387_VECTOR0_REGNUM(tdep) (I387_ST0_REGNUM (tdep) + 16)
 #define I387_MXCSR_REGNUM(tdep) \
-  (I387_XMM0_REGNUM (tdep) + I387_NUM_XMM_REGS (tdep))
+  (I387_VECTOR0_REGNUM (tdep) + I387_NUM_VECTOR_REGS (tdep))
 
 /* Print out the i387 floating point state.  */
 
@@ -99,6 +99,11 @@ extern void i387_collect_fsave (const struct regcache *regcache, int regnum,
 extern void i387_supply_fxsave (struct regcache *regcache, int regnum,
 				const void *fxsave);
 
+/* Similar to i387_supply_fxsave, but use XSAVE extended state.  */
+
+extern void i387_supply_xsave (struct regcache *regcache, int regnum,
+			       const void *xsave);
+
 /* Fill register REGNUM (if it is a floating-point or SSE register) in
    *FXSAVE with the value from REGCACHE.  If REGNUM is -1, do this for
    all registers.  This function doesn't touch any of the reserved
@@ -107,6 +112,11 @@ extern void i387_supply_fxsave (struct regcache *regcache, int regnum,
 extern void i387_collect_fxsave (const struct regcache *regcache, int regnum,
 				 void *fxsave);
 
+/* Similar to i387_collect_fxsave, but use XSAVE extended state.  */
+
+extern void i387_collect_xsave (const struct regcache *regcache,
+				int regnum, void *xsave, int gcore);
+
 /* Prepare the FPU stack in REGCACHE for a function return.  */
 
 extern void i387_return_value (struct gdbarch *gdbarch,


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]