From patchwork Wed Sep 5 13:22:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 29204 Received: (qmail 27049 invoked by alias); 5 Sep 2018 13:23:04 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 27040 invoked by uid 89); 5 Sep 2018 13:23:04 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=whatsoever X-HELO: prv1-mh.provo.novell.com Received: from prv1-mh.provo.novell.com (HELO prv1-mh.provo.novell.com) (137.65.248.33) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 05 Sep 2018 13:23:02 +0000 Received: from INET-PRV1-MTA by prv1-mh.provo.novell.com with Novell_GroupWise; Wed, 05 Sep 2018 07:23:01 -0600 Message-Id: <5B8FD8B302000078001E5940@prv1-mh.provo.novell.com> Date: Wed, 05 Sep 2018 07:22:59 -0600 From: "Jan Beulich" To: "GDB" Subject: [PATCH] x86-64: fix ZMM register state tracking Mime-Version: 1.0 Content-Disposition: inline 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 * 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);