| Index: gdb/i387-tdep.c
|
| diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
|
| index 97bd5f65540b894086ff8a4038ded200381810c2..1bf14856b11da447745e8c412f78c395e7f00344 100644
|
| --- a/gdb/i387-tdep.c
|
| +++ b/gdb/i387-tdep.c
|
| @@ -1,7 +1,6 @@
|
| /* Intel 387 floating point stuff.
|
|
|
| - Copyright (C) 1988-1989, 1991-1994, 1998-2005, 2007-2012 Free
|
| - Software Foundation, Inc.
|
| + Copyright (C) 1988-2013 Free Software Foundation, Inc.
|
|
|
| This file is part of GDB.
|
|
|
| @@ -29,7 +28,7 @@
|
| #include "value.h"
|
|
|
| #include "gdb_assert.h"
|
| -#include "gdb_string.h"
|
| +#include <string.h>
|
|
|
| #include "i386-tdep.h"
|
| #include "i387-tdep.h"
|
| @@ -299,7 +298,7 @@ i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
|
|
|
| if (value_entirely_available (regval))
|
| {
|
| - const char *raw = value_contents (regval);
|
| + const gdb_byte *raw = value_contents (regval);
|
|
|
| fputs_filtered ("0x", file);
|
| for (i = 9; i >= 0; i--)
|
| @@ -764,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
|
| @@ -784,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);
|
| @@ -796,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;
|
| @@ -815,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
|
| @@ -839,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);
|
| @@ -876,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))
|
| {
|
| @@ -990,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);
|
| @@ -1001,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)
|
| @@ -1033,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++)
|
| @@ -1064,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))
|
| @@ -1114,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);
|
| @@ -1155,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;
|
| }
|
|
|