forked from Imagelibrary/binutils-gdb
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
This commit is contained in:
130
gdb/i387-tdep.c
130
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user