From patchwork Thu Apr 27 21:01:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Baldwin X-Patchwork-Id: 68417 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3BF0D3882667 for ; Thu, 27 Apr 2023 21:02:58 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail.baldwin.cx (bigwig.baldwin.cx [IPv6:2607:f138:0:13::2]) by sourceware.org (Postfix) with ESMTPS id 2A42B3857733 for ; Thu, 27 Apr 2023 21:01:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2A42B3857733 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=FreeBSD.org Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=FreeBSD.org Received: from ralph.baldwin.net (c-98-35-126-114.hsd1.ca.comcast.net [98.35.126.114]) by mail.baldwin.cx (Postfix) with ESMTPSA id 808331A84E38 for ; Thu, 27 Apr 2023 17:01:35 -0400 (EDT) From: John Baldwin To: gdb-patches@sourceware.org Subject: [PATCH v5 13/19] gdb: Use x86_xstate_layout to parse the XSAVE extended state area. Date: Thu, 27 Apr 2023 14:01:07 -0700 Message-Id: <20230427210113.45380-14-jhb@FreeBSD.org> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230427210113.45380-1-jhb@FreeBSD.org> References: <20230427210113.45380-1-jhb@FreeBSD.org> MIME-Version: 1.0 X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.6.4 (mail.baldwin.cx [0.0.0.0]); Thu, 27 Apr 2023 17:01:36 -0400 (EDT) X-Virus-Scanned: clamav-milter 0.103.1 at mail.baldwin.cx X-Virus-Status: Clean X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, FORGED_SPF_HELO, GIT_PATCH_0, KAM_DMARC_STATUS, KHOP_HELO_FCRDNS, SCC_10_SHORT_WORD_LINES, SCC_5_SHORT_WORD_LINES, SPF_HELO_PASS, SPF_SOFTFAIL, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" All of the tables describing the offsets of individual registers for XSAVE state components now hold relative offsets rather than absolute offsets. Some tables (those for MPX registers and ZMMH registers) had to be split into separate tables as they held entries that spanned multiple state components. --- gdb/i387-tdep.c | 467 ++++++++++++++++++++++++++++-------------------- gdb/i387-tdep.h | 1 + 2 files changed, 278 insertions(+), 190 deletions(-) diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c index f25579c1a9a..389cf11bfbd 100644 --- a/gdb/i387-tdep.c +++ b/gdb/i387-tdep.c @@ -732,170 +732,204 @@ i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave) /* `xstate_bv' is at byte offset 512. */ #define XSAVE_XSTATE_BV_ADDR(xsave) (xsave + 512) -/* 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. */ +/* At xsave_avxh_offset[REGNUM] you'll find the relative offset within + the AVX region of the XSAVE extended state where the upper 128bits + of GDB register YMM0 + 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). */ + 0 * 16, /* Upper 128bit of %ymm0 through ... */ + 1 * 16, + 2 * 16, + 3 * 16, + 4 * 16, + 5 * 16, + 6 * 16, + 7 * 16, + 8 * 16, + 9 * 16, + 10 * 16, + 11 * 16, + 12 * 16, + 13 * 16, + 14 * 16, + 15 * 16 /* Upper 128bit of ... %ymm15 (128 bits each). */ }; -#define XSAVE_AVXH_ADDR(tdep, xsave, regnum) \ - (xsave + xsave_avxh_offset[regnum - I387_YMM0H_REGNUM (tdep)]) +#define XSAVE_AVXH_ADDR(tdep, xsave, regnum) \ + (xsave + (tdep)->xsave_layout.avx_offset \ + + xsave_avxh_offset[regnum - I387_YMM0H_REGNUM (tdep)]) -/* At xsave_ymm_avx512_offset[REGNUM] you'll find the offset to the location in - the upper 128bit of ZMM register data structure used by the "xsave" - instruction where GDB register REGNUM is stored. */ +/* At xsave_ymm_avx512_offset[REGNUM] you'll find the relative offset + within the ZMM region of the XSAVE extended state where the second + 128bits of GDB register YMM16 + REGNUM is stored. */ static int xsave_ymm_avx512_offset[] = { - /* HI16_ZMM_area + 16 bytes + regnum* 64 bytes. */ - 1664 + 16 + 0 * 64, /* %ymm16 through... */ - 1664 + 16 + 1 * 64, - 1664 + 16 + 2 * 64, - 1664 + 16 + 3 * 64, - 1664 + 16 + 4 * 64, - 1664 + 16 + 5 * 64, - 1664 + 16 + 6 * 64, - 1664 + 16 + 7 * 64, - 1664 + 16 + 8 * 64, - 1664 + 16 + 9 * 64, - 1664 + 16 + 10 * 64, - 1664 + 16 + 11 * 64, - 1664 + 16 + 12 * 64, - 1664 + 16 + 13 * 64, - 1664 + 16 + 14 * 64, - 1664 + 16 + 15 * 64 /* ... %ymm31 (128 bits each). */ + 16 + 0 * 64, /* %ymm16 through... */ + 16 + 1 * 64, + 16 + 2 * 64, + 16 + 3 * 64, + 16 + 4 * 64, + 16 + 5 * 64, + 16 + 6 * 64, + 16 + 7 * 64, + 16 + 8 * 64, + 16 + 9 * 64, + 16 + 10 * 64, + 16 + 11 * 64, + 16 + 12 * 64, + 16 + 13 * 64, + 16 + 14 * 64, + 16 + 15 * 64 /* ... %ymm31 (128 bits each). */ }; -#define XSAVE_YMM_AVX512_ADDR(tdep, xsave, regnum) \ - (xsave + xsave_ymm_avx512_offset[regnum - I387_YMM16H_REGNUM (tdep)]) +#define XSAVE_YMM_AVX512_ADDR(tdep, xsave, regnum) \ + (xsave + (tdep)->xsave_layout.zmm_offset \ + + xsave_ymm_avx512_offset[regnum - I387_YMM16H_REGNUM (tdep)]) + +/* At xsave_xmm_avx512_offset[REGNUM] you'll find the relative offset + within the ZMM region of the XSAVE extended state where the first + 128bits of GDB register XMM16 + REGNUM is stored. */ static int xsave_xmm_avx512_offset[] = { - 1664 + 0 * 64, /* %ymm16 through... */ - 1664 + 1 * 64, - 1664 + 2 * 64, - 1664 + 3 * 64, - 1664 + 4 * 64, - 1664 + 5 * 64, - 1664 + 6 * 64, - 1664 + 7 * 64, - 1664 + 8 * 64, - 1664 + 9 * 64, - 1664 + 10 * 64, - 1664 + 11 * 64, - 1664 + 12 * 64, - 1664 + 13 * 64, - 1664 + 14 * 64, - 1664 + 15 * 64 /* ... %ymm31 (128 bits each). */ + 0 * 64, /* %xmm16 through... */ + 1 * 64, + 2 * 64, + 3 * 64, + 4 * 64, + 5 * 64, + 6 * 64, + 7 * 64, + 8 * 64, + 9 * 64, + 10 * 64, + 11 * 64, + 12 * 64, + 13 * 64, + 14 * 64, + 15 * 64 /* ... %xmm31 (128 bits each). */ }; -#define XSAVE_XMM_AVX512_ADDR(tdep, xsave, regnum) \ - (xsave + xsave_xmm_avx512_offset[regnum - I387_XMM16_REGNUM (tdep)]) +#define XSAVE_XMM_AVX512_ADDR(tdep, xsave, regnum) \ + (xsave + (tdep)->xsave_layout.zmm_offset \ + + xsave_xmm_avx512_offset[regnum - I387_XMM16_REGNUM (tdep)]) -static int xsave_mpx_offset[] = { - 960 + 0 * 16, /* bnd0r...bnd3r registers. */ - 960 + 1 * 16, - 960 + 2 * 16, - 960 + 3 * 16, - 1024 + 0 * 8, /* bndcfg ... bndstatus. */ - 1024 + 1 * 8, +/* At xsave_bndregs_offset[REGNUM] you'll find the relative offset + within the BNDREGS region of the XSAVE extended state where the GDB + register BND0R + REGNUM is stored. */ + +static int xsave_bndregs_offset[] = { + 0 * 16, /* bnd0r...bnd3r registers. */ + 1 * 16, + 2 * 16, + 3 * 16 +}; + +#define XSAVE_BNDREGS_ADDR(tdep, xsave, regnum) \ + (xsave + (tdep)->xsave_layout.bndregs_offset \ + + xsave_bndregs_offset[regnum - I387_BND0R_REGNUM (tdep)]) + +static int xsave_bndcfg_offset[] = { + 0 * 8, /* bndcfg ... bndstatus. */ + 1 * 8, }; -#define XSAVE_MPX_ADDR(tdep, xsave, regnum) \ - (xsave + xsave_mpx_offset[regnum - I387_BND0R_REGNUM (tdep)]) +#define XSAVE_BNDCFG_ADDR(tdep, xsave, regnum) \ + (xsave + (tdep)->xsave_layout.bndcfg_offset \ + + xsave_bndcfg_offset[regnum - I387_BNDCFGU_REGNUM (tdep)]) - /* At xsave_avx512__h_offset[REGNUM] you find the offset to the location - of the AVX512 opmask register data structure used by the "xsave" - instruction where GDB register REGNUM is stored. */ +/* At xsave_avx512_k_offset[REGNUM] you'll find the relative offset + within the K region of the XSAVE extended state where the AVX512 + opmask register K0 + REGNUM is stored. */ static int xsave_avx512_k_offset[] = { - 1088 + 0 * 8, /* %k0 through... */ - 1088 + 1 * 8, - 1088 + 2 * 8, - 1088 + 3 * 8, - 1088 + 4 * 8, - 1088 + 5 * 8, - 1088 + 6 * 8, - 1088 + 7 * 8 /* %k7 (64 bits each). */ + 0 * 8, /* %k0 through... */ + 1 * 8, + 2 * 8, + 3 * 8, + 4 * 8, + 5 * 8, + 6 * 8, + 7 * 8 /* %k7 (64 bits each). */ }; -#define XSAVE_AVX512_K_ADDR(tdep, xsave, regnum) \ - (xsave + xsave_avx512_k_offset[regnum - I387_K0_REGNUM (tdep)]) +#define XSAVE_AVX512_K_ADDR(tdep, xsave, regnum) \ + (xsave + (tdep)->xsave_layout.k_offset \ + + xsave_avx512_k_offset[regnum - I387_K0_REGNUM (tdep)]) -/* At xsave_avx512_zmm_h_offset[REGNUM] you find the offset to the location in - the upper 256bit of AVX512 ZMMH register data structure used by the "xsave" - instruction where GDB register REGNUM is stored. */ -static int xsave_avx512_zmm_h_offset[] = +/* At xsave_avx512_zmm0_h_offset[REGNUM] you find the relative offset + within the ZMM_H region of the XSAVE extended state where the upper + 256bits of the GDB register ZMM0 + REGNUM is stored. */ + +static int xsave_avx512_zmm0_h_offset[] = +{ + 0 * 32, /* Upper 256bit of %zmmh0 through... */ + 1 * 32, + 2 * 32, + 3 * 32, + 4 * 32, + 5 * 32, + 6 * 32, + 7 * 32, + 8 * 32, + 9 * 32, + 10 * 32, + 11 * 32, + 12 * 32, + 13 * 32, + 14 * 32, + 15 * 32 /* Upper 256bit of... %zmmh15 (256 bits each). */ +}; + +#define XSAVE_AVX512_ZMM0_H_ADDR(tdep, xsave, regnum) \ + (xsave + (tdep)->xsave_layout.zmm_h_offset \ + + xsave_avx512_zmm0_h_offset[regnum - I387_ZMM0H_REGNUM (tdep)]) + +/* At xsave_avx512_zmm16_h_offset[REGNUM] you find the relative offset + within the ZMM_H region of the XSAVE extended state where the upper + 256bits of the GDB register ZMM16 + REGNUM is stored. */ + +static int xsave_avx512_zmm16_h_offset[] = { - 1152 + 0 * 32, - 1152 + 1 * 32, /* Upper 256bit of %zmmh0 through... */ - 1152 + 2 * 32, - 1152 + 3 * 32, - 1152 + 4 * 32, - 1152 + 5 * 32, - 1152 + 6 * 32, - 1152 + 7 * 32, - 1152 + 8 * 32, - 1152 + 9 * 32, - 1152 + 10 * 32, - 1152 + 11 * 32, - 1152 + 12 * 32, - 1152 + 13 * 32, - 1152 + 14 * 32, - 1152 + 15 * 32, /* Upper 256bit of... %zmmh15 (256 bits each). */ - 1664 + 32 + 0 * 64, /* Upper 256bit of... %zmmh16 (256 bits each). */ - 1664 + 32 + 1 * 64, - 1664 + 32 + 2 * 64, - 1664 + 32 + 3 * 64, - 1664 + 32 + 4 * 64, - 1664 + 32 + 5 * 64, - 1664 + 32 + 6 * 64, - 1664 + 32 + 7 * 64, - 1664 + 32 + 8 * 64, - 1664 + 32 + 9 * 64, - 1664 + 32 + 10 * 64, - 1664 + 32 + 11 * 64, - 1664 + 32 + 12 * 64, - 1664 + 32 + 13 * 64, - 1664 + 32 + 14 * 64, - 1664 + 32 + 15 * 64 /* Upper 256bit of... %zmmh31 (256 bits each). */ + 32 + 0 * 64, /* Upper 256bit of... %zmmh16 (256 bits each). */ + 32 + 1 * 64, + 32 + 2 * 64, + 32 + 3 * 64, + 32 + 4 * 64, + 32 + 5 * 64, + 32 + 6 * 64, + 32 + 7 * 64, + 32 + 8 * 64, + 32 + 9 * 64, + 32 + 10 * 64, + 32 + 11 * 64, + 32 + 12 * 64, + 32 + 13 * 64, + 32 + 14 * 64, + 32 + 15 * 64 /* Upper 256bit of... %zmmh31 (256 bits each). */ }; -#define XSAVE_AVX512_ZMM_H_ADDR(tdep, xsave, regnum) \ - (xsave + xsave_avx512_zmm_h_offset[regnum - I387_ZMM0H_REGNUM (tdep)]) +#define XSAVE_AVX512_ZMM16_H_ADDR(tdep, xsave, regnum) \ + (xsave + (tdep)->xsave_layout.zmm_offset \ + + xsave_avx512_zmm16_h_offset[regnum - I387_ZMM16H_REGNUM (tdep)]) -/* At xsave_pkeys_offset[REGNUM] you find the offset to the location - of the PKRU register data structure used by the "xsave" - instruction where GDB register REGNUM is stored. */ +/* At xsave_pkeys_offset[REGNUM] you'll find the relative offset + within the PKEYS region of the XSAVE extended state where the PKRU + register is stored. */ static int xsave_pkeys_offset[] = { -2688 + 0 * 8 /* %pkru (64 bits in XSTATE, 32-bit actually used by + 0 * 8 /* %pkru (64 bits in XSTATE, 32-bit actually used by instructions and applications). */ }; -#define XSAVE_PKEYS_ADDR(tdep, xsave, regnum) \ - (xsave + xsave_pkeys_offset[regnum - I387_PKRU_REGNUM (tdep)]) +#define XSAVE_PKEYS_ADDR(tdep, xsave, regnum) \ + (xsave + (tdep)->xsave_layout.pkru_offset \ + + xsave_pkeys_offset[regnum - I387_PKRU_REGNUM (tdep)]) /* See i387-tdep.h. */ @@ -998,14 +1032,16 @@ i387_supply_xsave (struct regcache *regcache, int regnum, x87 = 0x1, sse = 0x2, avxh = 0x4, - mpx = 0x8, - avx512_k = 0x10, - avx512_zmm_h = 0x20, - avx512_ymmh_avx512 = 0x40, - avx512_xmm_avx512 = 0x80, - pkeys = 0x100, - all = x87 | sse | avxh | mpx | avx512_k | avx512_zmm_h - | avx512_ymmh_avx512 | avx512_xmm_avx512 | pkeys + bndregs = 0x8, + bndcfg = 0x10, + avx512_k = 0x20, + avx512_zmm0_h = 0x40, + avx512_zmm16_h = 0x80, + avx512_ymmh_avx512 = 0x100, + avx512_xmm_avx512 = 0x200, + pkeys = 0x400, + all = x87 | sse | avxh | bndregs | bndcfg | avx512_k | avx512_zmm0_h + | avx512_zmm16_h | avx512_ymmh_avx512 | avx512_xmm_avx512 | pkeys } regclass; gdb_assert (regs != NULL); @@ -1018,8 +1054,11 @@ i387_supply_xsave (struct regcache *regcache, int regnum, && regnum < I387_PKEYSEND_REGNUM (tdep)) regclass = pkeys; else if (regnum >= I387_ZMM0H_REGNUM (tdep) + && regnum < I387_ZMM16H_REGNUM (tdep)) + regclass = avx512_zmm0_h; + else if (regnum >= I387_ZMM16H_REGNUM (tdep) && regnum < I387_ZMMENDH_REGNUM (tdep)) - regclass = avx512_zmm_h; + regclass = avx512_zmm16_h; else if (regnum >= I387_K0_REGNUM (tdep) && regnum < I387_KEND_REGNUM (tdep)) regclass = avx512_k; @@ -1033,8 +1072,11 @@ i387_supply_xsave (struct regcache *regcache, int regnum, && regnum < I387_YMMENDH_REGNUM (tdep)) regclass = avxh; else if (regnum >= I387_BND0R_REGNUM (tdep) + && regnum < I387_BNDCFGU_REGNUM (tdep)) + regclass = bndregs; + else if (regnum >= I387_BNDCFGU_REGNUM (tdep) && regnum < I387_MPXEND_REGNUM (tdep)) - regclass = mpx; + regclass = bndcfg; else if (regnum >= I387_XMM0_REGNUM (tdep) && regnum < I387_MXCSR_REGNUM (tdep)) regclass = sse; @@ -1067,13 +1109,20 @@ i387_supply_xsave (struct regcache *regcache, int regnum, regcache->raw_supply (regnum, XSAVE_PKEYS_ADDR (tdep, regs, regnum)); return; - case avx512_zmm_h: - if ((clear_bv & (regnum < zmm_endlo_regnum ? X86_XSTATE_ZMM_H - : X86_XSTATE_ZMM))) + case avx512_zmm0_h: + if ((clear_bv & X86_XSTATE_ZMM_H)) regcache->raw_supply (regnum, zero); else regcache->raw_supply (regnum, - XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, regnum)); + XSAVE_AVX512_ZMM0_H_ADDR (tdep, regs, regnum)); + return; + + case avx512_zmm16_h: + if ((clear_bv & X86_XSTATE_ZMM)) + regcache->raw_supply (regnum, zero); + else + regcache->raw_supply (regnum, + XSAVE_AVX512_ZMM16_H_ADDR (tdep, regs, regnum)); return; case avx512_k: @@ -1106,11 +1155,18 @@ i387_supply_xsave (struct regcache *regcache, int regnum, regcache->raw_supply (regnum, XSAVE_AVXH_ADDR (tdep, regs, regnum)); return; - case mpx: + case bndcfg: + if ((clear_bv & X86_XSTATE_BNDCFG)) + regcache->raw_supply (regnum, zero); + else + regcache->raw_supply (regnum, XSAVE_BNDCFG_ADDR (tdep, regs, regnum)); + return; + + case bndregs: if ((clear_bv & X86_XSTATE_BNDREGS)) regcache->raw_supply (regnum, zero); else - regcache->raw_supply (regnum, XSAVE_MPX_ADDR (tdep, regs, regnum)); + regcache->raw_supply (regnum, XSAVE_BNDREGS_ADDR (tdep, regs, regnum)); return; case sse: @@ -1159,7 +1215,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum, { for (i = I387_ZMM0H_REGNUM (tdep); i < zmm_endlo_regnum; i++) regcache->raw_supply (i, - XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i)); + XSAVE_AVX512_ZMM0_H_ADDR (tdep, regs, i)); } } @@ -1187,7 +1243,8 @@ i387_supply_xsave (struct regcache *regcache, int regnum, { if ((clear_bv & X86_XSTATE_ZMM)) { - for (i = zmm_endlo_regnum; i < I387_ZMMENDH_REGNUM (tdep); i++) + for (i = I387_ZMM16H_REGNUM (tdep); + i < I387_ZMMENDH_REGNUM (tdep); i++) regcache->raw_supply (i, zero); for (i = I387_YMM16H_REGNUM (tdep); i < I387_YMMH_AVX512_END_REGNUM (tdep); @@ -1200,9 +1257,10 @@ i387_supply_xsave (struct regcache *regcache, int regnum, } else { - for (i = zmm_endlo_regnum; i < I387_ZMMENDH_REGNUM (tdep); i++) + for (i = I387_ZMM16H_REGNUM (tdep); + i < I387_ZMMENDH_REGNUM (tdep); i++) regcache->raw_supply (i, - XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i)); + XSAVE_AVX512_ZMM16_H_ADDR (tdep, regs, i)); for (i = I387_YMM16H_REGNUM (tdep); i < I387_YMMH_AVX512_END_REGNUM (tdep); i++) @@ -1245,7 +1303,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum, { for (i = I387_BND0R_REGNUM (tdep); i < I387_BNDCFGU_REGNUM (tdep); i++) - regcache->raw_supply (i, XSAVE_MPX_ADDR (tdep, regs, i)); + regcache->raw_supply (i, XSAVE_BNDREGS_ADDR (tdep, regs, i)); } } @@ -1262,7 +1320,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum, { for (i = I387_BNDCFGU_REGNUM (tdep); i < I387_MPXEND_REGNUM (tdep); i++) - regcache->raw_supply (i, XSAVE_MPX_ADDR (tdep, regs, i)); + regcache->raw_supply (i, XSAVE_BNDCFG_ADDR (tdep, regs, i)); } } @@ -1418,14 +1476,16 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, x87 = 0x2, sse = 0x4, avxh = 0x8, - mpx = 0x10, - avx512_k = 0x20, - avx512_zmm_h = 0x40, - avx512_ymmh_avx512 = 0x80, - avx512_xmm_avx512 = 0x100, - pkeys = 0x200, - all = x87 | sse | avxh | mpx | avx512_k | avx512_zmm_h - | avx512_ymmh_avx512 | avx512_xmm_avx512 | pkeys + bndregs = 0x10, + bndcfg = 0x20, + avx512_k = 0x40, + avx512_zmm0_h = 0x80, + avx512_zmm16_h = 0x100, + avx512_ymmh_avx512 = 0x200, + avx512_xmm_avx512 = 0x400, + pkeys = 0x800, + all = x87 | sse | avxh | bndregs | bndcfg | avx512_k | avx512_zmm0_h + | avx512_zmm16_h | avx512_ymmh_avx512 | avx512_xmm_avx512 | pkeys } regclass; gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); @@ -1437,8 +1497,11 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, && regnum < I387_PKEYSEND_REGNUM (tdep)) regclass = pkeys; else if (regnum >= I387_ZMM0H_REGNUM (tdep) + && regnum < I387_ZMM16H_REGNUM (tdep)) + regclass = avx512_zmm0_h; + else if (regnum >= I387_ZMM16H_REGNUM (tdep) && regnum < I387_ZMMENDH_REGNUM (tdep)) - regclass = avx512_zmm_h; + regclass = avx512_zmm16_h; else if (regnum >= I387_K0_REGNUM (tdep) && regnum < I387_KEND_REGNUM (tdep)) regclass = avx512_k; @@ -1452,8 +1515,11 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, && regnum < I387_YMMENDH_REGNUM (tdep)) regclass = avxh; else if (regnum >= I387_BND0R_REGNUM (tdep) + && regnum < I387_BNDCFGU_REGNUM (tdep)) + regclass = bndregs; + else if (regnum >= I387_BNDCFGU_REGNUM (tdep) && regnum < I387_MPXEND_REGNUM (tdep)) - regclass = mpx; + regclass = bndcfg; else if (regnum >= I387_XMM0_REGNUM (tdep) && regnum < I387_MXCSR_REGNUM (tdep)) regclass = sse; @@ -1470,7 +1536,7 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, if (gcore) { /* Clear XSAVE extended state. */ - memset (regs, 0, X86_XSTATE_SIZE (tdep->xcr0)); + memset (regs, 0, tdep->xsave_layout.sizeof_xsave); /* Update XCR0 and `xstate_bv' with XCR0 for gcore. */ if (tdep->xsave_xcr0_offset != -1) @@ -1505,16 +1571,16 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, if ((clear_bv & X86_XSTATE_BNDREGS)) for (i = I387_BND0R_REGNUM (tdep); i < I387_BNDCFGU_REGNUM (tdep); i++) - memset (XSAVE_MPX_ADDR (tdep, regs, i), 0, 16); + memset (XSAVE_BNDREGS_ADDR (tdep, regs, i), 0, 16); if ((clear_bv & X86_XSTATE_BNDCFG)) for (i = I387_BNDCFGU_REGNUM (tdep); i < I387_MPXEND_REGNUM (tdep); i++) - memset (XSAVE_MPX_ADDR (tdep, regs, i), 0, 8); + memset (XSAVE_BNDCFG_ADDR (tdep, regs, i), 0, 8); 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); + memset (XSAVE_AVX512_ZMM0_H_ADDR (tdep, regs, i), 0, 32); if ((clear_bv & X86_XSTATE_K)) for (i = I387_K0_REGNUM (tdep); @@ -1523,8 +1589,9 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, 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_ZMM16H_REGNUM (tdep); i < I387_ZMMENDH_REGNUM (tdep); + i++) + memset (XSAVE_AVX512_ZMM16_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); @@ -1587,15 +1654,27 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, } /* Check if any ZMMH registers are changed. */ - if ((tdep->xcr0 & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM))) - for (i = I387_ZMM0H_REGNUM (tdep); + if ((tdep->xcr0 & X86_XSTATE_ZMM)) + for (i = I387_ZMM16H_REGNUM (tdep); i < I387_ZMMENDH_REGNUM (tdep); i++) { regcache->raw_collect (i, raw); - p = XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i); + p = XSAVE_AVX512_ZMM16_H_ADDR (tdep, regs, i); if (memcmp (raw, p, 32) != 0) { - xstate_bv |= (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM); + xstate_bv |= X86_XSTATE_ZMM; + memcpy (p, raw, 32); + } + } + + if ((tdep->xcr0 & X86_XSTATE_ZMM_H)) + for (i = I387_ZMM0H_REGNUM (tdep); i < zmm_endlo_regnum; i++) + { + regcache->raw_collect (i, raw); + p = XSAVE_AVX512_ZMM0_H_ADDR (tdep, regs, i); + if (memcmp (raw, p, 32) != 0) + { + xstate_bv |= X86_XSTATE_ZMM_H; memcpy (p, raw, 32); } } @@ -1647,7 +1726,7 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, i < I387_BNDCFGU_REGNUM (tdep); i++) { regcache->raw_collect (i, raw); - p = XSAVE_MPX_ADDR (tdep, regs, i); + p = XSAVE_BNDREGS_ADDR (tdep, regs, i); if (memcmp (raw, p, 16)) { xstate_bv |= X86_XSTATE_BNDREGS; @@ -1661,7 +1740,7 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, i < I387_MPXEND_REGNUM (tdep); i++) { regcache->raw_collect (i, raw); - p = XSAVE_MPX_ADDR (tdep, regs, i); + p = XSAVE_BNDCFG_ADDR (tdep, regs, i); if (memcmp (raw, p, 8)) { xstate_bv |= X86_XSTATE_BNDCFG; @@ -1750,15 +1829,26 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, } break; - case avx512_zmm_h: - /* This is a ZMM register. */ - p = XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, regnum); + case avx512_zmm16_h: + /* This is a ZMM16-31 register. */ + p = XSAVE_AVX512_ZMM16_H_ADDR (tdep, regs, regnum); if (memcmp (raw, p, 32) != 0) { - xstate_bv |= (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM); + xstate_bv |= X86_XSTATE_ZMM; memcpy (p, raw, 32); } break; + + case avx512_zmm0_h: + /* This is a ZMM0-15 register. */ + p = XSAVE_AVX512_ZMM0_H_ADDR (tdep, regs, regnum); + if (memcmp (raw, p, 32) != 0) + { + xstate_bv |= X86_XSTATE_ZMM_H; + memcpy (p, raw, 32); + } + break; + case avx512_k: /* This is a AVX512 mask register. */ p = XSAVE_AVX512_K_ADDR (tdep, regs, regnum); @@ -1799,25 +1889,22 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, } break; - case mpx: - if (regnum < I387_BNDCFGU_REGNUM (tdep)) + case bndregs: + regcache->raw_collect (regnum, raw); + p = XSAVE_BNDREGS_ADDR (tdep, regs, regnum); + if (memcmp (raw, p, 16)) { - regcache->raw_collect (regnum, raw); - p = XSAVE_MPX_ADDR (tdep, regs, regnum); - if (memcmp (raw, p, 16)) - { - xstate_bv |= X86_XSTATE_BNDREGS; - memcpy (p, raw, 16); - } - } - else - { - p = XSAVE_MPX_ADDR (tdep, regs, regnum); - xstate_bv |= X86_XSTATE_BNDCFG; - memcpy (p, raw, 8); + xstate_bv |= X86_XSTATE_BNDREGS; + memcpy (p, raw, 16); } break; + case bndcfg: + p = XSAVE_BNDCFG_ADDR (tdep, regs, regnum); + xstate_bv |= X86_XSTATE_BNDCFG; + memcpy (p, raw, 8); + break; + case sse: /* This is an SSE register. */ p = FXSAVE_ADDR (tdep, regs, regnum); diff --git a/gdb/i387-tdep.h b/gdb/i387-tdep.h index b7674155255..55651a497df 100644 --- a/gdb/i387-tdep.h +++ b/gdb/i387-tdep.h @@ -51,6 +51,7 @@ struct x86_xsave_layout; #define I387_K0_REGNUM(tdep) ((tdep)->k0_regnum) #define I387_NUM_ZMMH_REGS(tdep) ((tdep)->num_zmm_regs) #define I387_ZMM0H_REGNUM(tdep) ((tdep)->zmm0h_regnum) +#define I387_ZMM16H_REGNUM(tdep) ((tdep)->zmm0h_regnum + 16) #define I387_NUM_YMM_AVX512_REGS(tdep) ((tdep)->num_ymm_avx512_regs) #define I387_YMM16H_REGNUM(tdep) ((tdep)->ymm16h_regnum)