diff options
author | Walfred Tedeschi <walfred.tedeschi@intel.com> | 2013-11-20 13:02:00 +0100 |
---|---|---|
committer | Walfred Tedeschi <walfred.tedeschi@intel.com> | 2013-11-20 14:42:50 +0100 |
commit | 1dbcd68cf12168c359df2da36b5b612100310a30 (patch) | |
tree | 7ff900d7ed9b933c214ef9c686bc509e884b9e85 /gdb/i387-tdep.c | |
parent | ccc42043f7a34784560e08553bbf51ce3044785e (diff) | |
download | gdb-1dbcd68cf12168c359df2da36b5b612100310a30.zip gdb-1dbcd68cf12168c359df2da36b5b612100310a30.tar.gz gdb-1dbcd68cf12168c359df2da36b5b612100310a30.tar.bz2 |
Add MPX support for i386
2013-11-20 Walfred Tedeschi <walfred.tedeschi@intel.com>
* i386-linux-nat.c (GETXSTATEREGS_SUPPLIES): Add MPX
registers on the range of registers to be read from
xsave buffer.
(i386_linux_read_description): Add case for MPX.
* i386-linux-tdep.c: Include features/i386/i386-mpx-linux.c.
(i386_linux_gregset_reg_offset): Add MPX registers.
(i386_linux_core_read_description): Initialize also MPX.
(_initialize_i386_linux_tdep): Add mpx initialization.
* i386-tdep.h (gdbarch_tdep): Add fields bnd0r_regnum, bnd0_regnum,
mpx_register_names.
(i386_regnum): Add MPX registers.
(I386_MPX_NUM_REGS): New macro.
(i386_bnd_regnum_p): New function.
* i386-linux-tdep.h (I386_LINUX_NUM_REGS): Set
number of registers to be the number of BNDSTATUS.
(tdesc_i386_mpx_linux): Add description for MPX Linux registers.
* i386-tdep.c: Include features/i386/i386-mpx.c.
(i386_mpx_names): Add MPX register names array.
(i386_bnd_names): Add bnd pseudo register names array.
(i386_bndr_regnum_p): Lookup register numbers for bnd raw
registers.
(i386_bndr_regnum_p): Lookup register numbers for bnd raw registers.
(386_mpx_ctrl_regnum_p): Lookup register numbers for MPX control
registers.
(i386_bnd_type): New function.
(i386_pseudo_register_type): Use i386_bnd_type for bnd pseudo
register types.
(i386_pseudo_register_read_into_value): Add bnd case.
(i386_pseudo_register_write): Add bnd pseudo registers.
(i386_register_reggroup_p): Add MPX register to the group all.
(i386_validate_tdesc_p): Add MPX to the target description
validation.
(i386_pseudo_register_name): Add bnd pseudo registers.
(i386_gdbarch_init): Add MPX for architecture initialization.
(_initia_initialize_i386_tdep): Add mpx initialization.
* i387-tdep.c (xsave_mpx_offset): New vector for MPX offsets on
XSAVE buffer.
(XSAVE_MPX_ADDR): New macro.
(i387_supply_xsave): Add MPX case.
(i387_collect_xsave): Add MPX case.
* i387-tdep.h (I387_BND0R_REGNUM): New macro.
(I387_BNDCFGU_REGNUM): New macro.
(I387_NUM_MPX_REGS): New macro.
(I387_NUM_BND_REGS): New macro.
(I387_NUM_MPX_CTRL_REGS): New macro.
(I387_MPXEND_REGNUM): New macro.
* common/i386-xstate.h (I386_XSTATE_BNDREGS): New macro.
(I386_XSTATE_BNDCFG): Likewise.
(I386_XSTATE_MPX_MASK): Likewise.
(I386_XSTATE_ALL_MASK): New macro represents flags for all states.
(I386_XSTATE_BNDREGS_SIZE): New macro.
(I386_XSTATE_BNDCFG_SIZE): Likewise.
(I386_XSTATE_SIZE): Adapt for MPX.
(I386_XSTATE_MAX_SIZE): Likewise.
Change-Id: I9ddb7d49434d86fa18eb6b99515203d7c567aefd
Signed-off-by: Walfred Tedeschi <walfred.tedeschi@intel.com>
Conflicts:
gdb/ChangeLog
Diffstat (limited to 'gdb/i387-tdep.c')
-rw-r--r-- | gdb/i387-tdep.c | 130 |
1 files changed, 126 insertions, 4 deletions
diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c index fd44386..1bf1485 100644 --- a/gdb/i387-tdep.c +++ b/gdb/i387-tdep.c @@ -763,9 +763,22 @@ static int xsave_avxh_offset[] = 576 + 15 * 16 /* Upper 128bit of ... %ymm15 (128 bits each). */ }; +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, +}; + #define XSAVE_AVXH_ADDR(tdep, xsave, regnum) \ (xsave + xsave_avxh_offset[regnum - I387_YMM0H_REGNUM (tdep)]) +#define XSAVE_MPX_ADDR(tdep, xsave, regnum) \ + (xsave + xsave_mpx_offset[regnum - I387_BND0R_REGNUM (tdep)]) + /* Similar to i387_supply_fxsave, but use XSAVE extended state. */ void @@ -783,7 +796,8 @@ i387_supply_xsave (struct regcache *regcache, int regnum, x87 = 0x1, sse = 0x2, avxh = 0x4, - all = x87 | sse | avxh + mpx = 0x8, + all = x87 | sse | avxh | mpx } regclass; gdb_assert (regs != NULL); @@ -795,6 +809,9 @@ i387_supply_xsave (struct regcache *regcache, int regnum, else if (regnum >= I387_YMM0H_REGNUM (tdep) && regnum < I387_YMMENDH_REGNUM (tdep)) regclass = avxh; + else if (regnum >= I387_BND0R_REGNUM (tdep) + && regnum < I387_MPXEND_REGNUM (tdep)) + regclass = mpx; else if (regnum >= I387_XMM0_REGNUM(tdep) && regnum < I387_MXCSR_REGNUM (tdep)) regclass = sse; @@ -814,7 +831,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum, clear_bv = (~(*xstate_bv_p)) & tdep->xcr0; } else - clear_bv = I386_XSTATE_AVX_MASK; + clear_bv = I386_XSTATE_ALL_MASK; /* With the delayed xsave mechanism, in between the program starting, and the program accessing the vector registers for the @@ -838,6 +855,14 @@ i387_supply_xsave (struct regcache *regcache, int regnum, XSAVE_AVXH_ADDR (tdep, regs, regnum)); return; + case mpx: + if ((clear_bv & I386_XSTATE_BNDREGS)) + regcache_raw_supply (regcache, regnum, zero); + else + regcache_raw_supply (regcache, regnum, + XSAVE_MPX_ADDR (tdep, regs, regnum)); + return; + case sse: if ((clear_bv & I386_XSTATE_SSE)) regcache_raw_supply (regcache, regnum, zero); @@ -875,6 +900,42 @@ i387_supply_xsave (struct regcache *regcache, int regnum, } } + /* Handle the MPX registers. */ + if ((tdep->xcr0 & I386_XSTATE_BNDREGS)) + { + if (clear_bv & I386_XSTATE_BNDREGS) + { + for (i = I387_BND0R_REGNUM (tdep); + i < I387_BNDCFGU_REGNUM (tdep); i++) + regcache_raw_supply (regcache, i, zero); + } + else + { + for (i = I387_BND0R_REGNUM (tdep); + i < I387_BNDCFGU_REGNUM (tdep); i++) + regcache_raw_supply (regcache, i, + XSAVE_MPX_ADDR (tdep, regs, i)); + } + } + + /* Handle the MPX registers. */ + if ((tdep->xcr0 & I386_XSTATE_BNDCFG)) + { + if (clear_bv & I386_XSTATE_BNDCFG) + { + for (i = I387_BNDCFGU_REGNUM (tdep); + i < I387_MPXEND_REGNUM (tdep); i++) + regcache_raw_supply (regcache, i, zero); + } + else + { + for (i = I387_BNDCFGU_REGNUM (tdep); + i < I387_MPXEND_REGNUM (tdep); i++) + regcache_raw_supply (regcache, i, + XSAVE_MPX_ADDR (tdep, regs, i)); + } + } + /* Handle the XMM registers. */ if ((tdep->xcr0 & I386_XSTATE_SSE)) { @@ -989,7 +1050,8 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, x87 = 0x2 | check, sse = 0x4 | check, avxh = 0x8 | check, - all = x87 | sse | avxh + mpx = 0x10 | check, + all = x87 | sse | avxh | mpx } regclass; gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); @@ -1000,7 +1062,10 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, else if (regnum >= I387_YMM0H_REGNUM (tdep) && regnum < I387_YMMENDH_REGNUM (tdep)) regclass = avxh; - else if (regnum >= I387_XMM0_REGNUM(tdep) + else if (regnum >= I387_BND0R_REGNUM (tdep) + && regnum < I387_MPXEND_REGNUM (tdep)) + regclass = mpx; + else if (regnum >= I387_XMM0_REGNUM (tdep) && regnum < I387_MXCSR_REGNUM (tdep)) regclass = sse; else if (regnum >= I387_ST0_REGNUM (tdep) @@ -1032,6 +1097,16 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, /* Clear register set if its bit in xstat_bv is zero. */ if (clear_bv) { + if ((clear_bv & I386_XSTATE_BNDREGS)) + for (i = I387_BND0R_REGNUM (tdep); + i < I387_BNDCFGU_REGNUM (tdep); i++) + memset (XSAVE_MPX_ADDR (tdep, regs, i), 0, 16); + + if ((clear_bv & I386_XSTATE_BNDCFG)) + for (i = I387_BNDCFGU_REGNUM (tdep); + i < I387_MPXEND_REGNUM (tdep); i++) + memset (XSAVE_MPX_ADDR (tdep, regs, i), 0, 8); + if ((clear_bv & I386_XSTATE_AVX)) for (i = I387_YMM0H_REGNUM (tdep); i < I387_YMMENDH_REGNUM (tdep); i++) @@ -1063,6 +1138,33 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, memcpy (p, raw, 16); } } + /* Check if any upper MPX registers are changed. */ + if ((tdep->xcr0 & I386_XSTATE_BNDREGS)) + for (i = I387_BND0R_REGNUM (tdep); + i < I387_BNDCFGU_REGNUM (tdep); i++) + { + regcache_raw_collect (regcache, i, raw); + p = XSAVE_MPX_ADDR (tdep, regs, i); + if (memcmp (raw, p, 16)) + { + xstate_bv |= I386_XSTATE_BNDREGS; + memcpy (p, raw, 16); + } + } + + /* Check if any upper MPX registers are changed. */ + if ((tdep->xcr0 & I386_XSTATE_BNDCFG)) + for (i = I387_BNDCFGU_REGNUM (tdep); + i < I387_MPXEND_REGNUM (tdep); i++) + { + regcache_raw_collect (regcache, i, raw); + p = XSAVE_MPX_ADDR (tdep, regs, i); + if (memcmp (raw, p, 8)) + { + xstate_bv |= I386_XSTATE_BNDCFG; + memcpy (p, raw, 8); + } + } /* Check if any SSE registers are changed. */ if ((tdep->xcr0 & I386_XSTATE_SSE)) @@ -1113,6 +1215,25 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, } break; + case mpx: + if (regnum < I387_BNDCFGU_REGNUM (tdep)) + { + regcache_raw_collect (regcache, regnum, raw); + p = XSAVE_MPX_ADDR (tdep, regs, regnum); + if (memcmp (raw, p, 16)) + { + xstate_bv |= I386_XSTATE_BNDREGS; + memcpy (p, raw, 16); + } + } + else + { + p = XSAVE_MPX_ADDR (tdep, regs, regnum); + xstate_bv |= I386_XSTATE_BNDCFG; + memcpy (p, raw, 8); + } + break; + case sse: /* This is an SSE register. */ p = FXSAVE_ADDR (tdep, regs, regnum); @@ -1154,6 +1275,7 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, case x87: case sse: case avxh: + case mpx: /* Register REGNUM has been updated. Return. */ return; } |