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] x86-64: fix ZMM register state tracking


The three AVX512 state components are entirely independent - one being
in its "init state" has no implication whatsoever on either of the other
two. Fully separate X86_XSTATE_ZMM_H and X86_XSTATE_ZMM handling, to
prevent upper halves of the upper 16 ZMM registers to display as if they
were zero (when they aren't) after e.g. VZEROALL/VZEROUPPER.

gdb/
2018-09-05  Jan Beulich  <jbeulich@suse.com>

	* i387-tdep.c (i387_supply_xsave): Split handling of
	X86_XSTATE_ZMM_H and X86_XSTATE_ZMM.
	(i387_collect_xsave): Likewise.

--- a/gdb/i387-tdep.c
+++ b/gdb/i387-tdep.c
@@ -923,7 +923,8 @@ i387_supply_xsave (struct regcache *regc
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   const gdb_byte *regs = (const gdb_byte *) xsave;
-  int i;
+  int i, zmm_endlo_regnum = I387_ZMM0H_REGNUM (tdep)
+			    + std::min (tdep->num_zmm_regs, 16);
   ULONGEST clear_bv;
   static const gdb_byte zero[I386_MAX_REGISTER_SIZE] = { 0 };
   enum
@@ -1002,7 +1003,8 @@ i387_supply_xsave (struct regcache *regc
       return;
 
     case avx512_zmm_h:
-      if ((clear_bv & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
+      if ((clear_bv & (regnum < zmm_endlo_regnum ? X86_XSTATE_ZMM_H
+						 : X86_XSTATE_ZMM)))
 	regcache->raw_supply (regnum, zero);
       else
 	regcache->raw_supply (regnum,
@@ -1080,21 +1082,17 @@ i387_supply_xsave (struct regcache *regc
 	    }
 	}
 
-      /* Handle the upper ZMM registers.  */
-      if ((tdep->xcr0 & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
+      /* Handle the upper halves of the low 8/16 ZMM registers.  */
+      if ((tdep->xcr0 & X86_XSTATE_ZMM_H))
 	{
-	  if ((clear_bv & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
+	  if ((clear_bv & X86_XSTATE_ZMM_H))
 	    {
-	      for (i = I387_ZMM0H_REGNUM (tdep);
-		   i < I387_ZMMENDH_REGNUM (tdep);
-		   i++)
+	      for (i = I387_ZMM0H_REGNUM (tdep); i < zmm_endlo_regnum; i++)
 		regcache->raw_supply (i, zero);
 	    }
 	  else
 	    {
-	      for (i = I387_ZMM0H_REGNUM (tdep);
-		   i < I387_ZMMENDH_REGNUM (tdep);
-		   i++)
+	      for (i = I387_ZMM0H_REGNUM (tdep); i < zmm_endlo_regnum; i++)
 		regcache->raw_supply (i,
 				      XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i));
 	    }
@@ -1119,11 +1117,13 @@ i387_supply_xsave (struct regcache *regc
 	    }
 	}
 
-      /* Handle the YMM_AVX512 registers.  */
+      /* Handle the upper 16 ZMM/YMM/XMM registers (if any).  */
       if ((tdep->xcr0 & X86_XSTATE_ZMM))
 	{
 	  if ((clear_bv & X86_XSTATE_ZMM))
 	    {
+	      for (i = zmm_endlo_regnum; i < I387_ZMMENDH_REGNUM (tdep); i++)
+		regcache->raw_supply (i, zero);
 	      for (i = I387_YMM16H_REGNUM (tdep);
 		   i < I387_YMMH_AVX512_END_REGNUM (tdep);
 		   i++)
@@ -1135,6 +1135,9 @@ i387_supply_xsave (struct regcache *regc
 	    }
 	  else
 	    {
+	      for (i = zmm_endlo_regnum; i < I387_ZMMENDH_REGNUM (tdep); i++)
+		regcache->raw_supply (i,
+				      XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i));
 	      for (i = I387_YMM16H_REGNUM (tdep);
 		   i < I387_YMMH_AVX512_END_REGNUM (tdep);
 		   i++)
@@ -1340,7 +1343,8 @@ i387_collect_xsave (const struct regcach
   gdb_byte *p, *regs = (gdb_byte *) xsave;
   gdb_byte raw[I386_MAX_REGISTER_SIZE];
   ULONGEST initial_xstate_bv, clear_bv, xstate_bv = 0;
-  unsigned int i;
+  unsigned int i, zmm_endlo_regnum = I387_ZMM0H_REGNUM (tdep)
+				     + std::min (tdep->num_zmm_regs, 16);
   enum
     {
       x87_ctrl_or_mxcsr = 0x1,
@@ -1441,9 +1445,8 @@ i387_collect_xsave (const struct regcach
 	     i < I387_MPXEND_REGNUM (tdep); i++)
 	  memset (XSAVE_MPX_ADDR (tdep, regs, i), 0, 8);
 
-      if ((clear_bv & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
-	for (i = I387_ZMM0H_REGNUM (tdep);
-	     i < I387_ZMMENDH_REGNUM (tdep); i++)
+      if ((clear_bv & X86_XSTATE_ZMM_H))
+	for (i = I387_ZMM0H_REGNUM (tdep); i < zmm_endlo_regnum; i++)
 	  memset (XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i), 0, 32);
 
       if ((clear_bv & X86_XSTATE_K))
@@ -1453,6 +1456,8 @@ i387_collect_xsave (const struct regcach
 
       if ((clear_bv & X86_XSTATE_ZMM))
 	{
+	  for (i = zmm_endlo_regnum; i < I387_ZMMENDH_REGNUM (tdep); i++)
+	    memset (XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i), 0, 32);
 	  for (i = I387_YMM16H_REGNUM (tdep);
 	       i < I387_YMMH_AVX512_END_REGNUM (tdep); i++)
 	    memset (XSAVE_YMM_AVX512_ADDR (tdep, regs, i), 0, 16);




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