/* i387-specific utility functions, for the remote server for GDB.
- Copyright (C) 2000, 2001, 2002, 2005, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
This file is part of GDB.
#include "i387-fp.h"
#include "i386-xstate.h"
-int num_xmm_registers = 8;
+static const int num_mpx_bnd_registers = 4;
+static const int num_mpx_cfg_registers = 2;
/* Note: These functions preserve the reserved bits in control registers.
However, gdbserver promptly throws away that information. */
/* Space for eight upper 128-bit YMM values, or 16 on x86-64. */
unsigned char ymmh_space[256];
+
+ unsigned char reserved4[128];
+
+ /* Space for 4 bound registers values of 128 bits. */
+ unsigned char mpx_bnd_space[64];
+
+ /* Space for 2 MPX configuration registers of 64 bits
+ plus reserved space. */
+ unsigned char mpx_cfg_space[16];
};
void
{
struct i387_fsave *fp = (struct i387_fsave *) buf;
int i;
- int st0_regnum = find_regno ("st0");
+ int st0_regnum = find_regno (regcache->tdesc, "st0");
unsigned long val, val2;
for (i = 0; i < 8; i++)
{
struct i387_fsave *fp = (struct i387_fsave *) buf;
int i;
- int st0_regnum = find_regno ("st0");
+ int st0_regnum = find_regno (regcache->tdesc, "st0");
unsigned long val;
for (i = 0; i < 8; i++)
{
struct i387_fxsave *fp = (struct i387_fxsave *) buf;
int i;
- int st0_regnum = find_regno ("st0");
- int xmm0_regnum = find_regno ("xmm0");
+ int st0_regnum = find_regno (regcache->tdesc, "st0");
+ int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
unsigned long val, val2;
+ /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
+ int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
for (i = 0; i < 8; i++)
collect_register (regcache, i + st0_regnum,
unsigned long long xstate_bv = 0;
char raw[16];
char *p;
+ /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
+ int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
/* The supported bits in `xstat_bv' are 1 byte. Clear part in
vector registers if its bit in xstat_bv is zero. */
if ((clear_bv & I386_XSTATE_AVX))
for (i = 0; i < num_xmm_registers; i++)
memset (((char *) &fp->ymmh_space[0]) + i * 16, 0, 16);
+
+ if ((clear_bv & I386_XSTATE_BNDREGS))
+ for (i = 0; i < num_mpx_bnd_registers; i++)
+ memset (((char *) &fp->mpx_bnd_space[0]) + i * 16, 0, 16);
+
+ if ((clear_bv & I386_XSTATE_BNDCFG))
+ for (i = 0; i < num_mpx_cfg_registers; i++)
+ memset (((char *) &fp->mpx_cfg_space[0]) + i * 8, 0, 8);
}
/* Check if any x87 registers are changed. */
if ((x86_xcr0 & I386_XSTATE_X87))
{
- int st0_regnum = find_regno ("st0");
+ int st0_regnum = find_regno (regcache->tdesc, "st0");
for (i = 0; i < 8; i++)
{
/* Check if any SSE registers are changed. */
if ((x86_xcr0 & I386_XSTATE_SSE))
{
- int xmm0_regnum = find_regno ("xmm0");
+ int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
for (i = 0; i < num_xmm_registers; i++)
{
/* Check if any AVX registers are changed. */
if ((x86_xcr0 & I386_XSTATE_AVX))
{
- int ymm0h_regnum = find_regno ("ymm0h");
+ int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
for (i = 0; i < num_xmm_registers; i++)
{
}
}
+ /* Check if any bound register has changed. */
+ if ((x86_xcr0 & I386_XSTATE_BNDREGS))
+ {
+ int bnd0r_regnum = find_regno (regcache->tdesc, "bnd0raw");
+
+ for (i = 0; i < num_mpx_bnd_registers; i++)
+ {
+ collect_register (regcache, i + bnd0r_regnum, raw);
+ p = ((char *) &fp->mpx_bnd_space[0]) + i * 16;
+ if (memcmp (raw, p, 16))
+ {
+ xstate_bv |= I386_XSTATE_BNDREGS;
+ memcpy (p, raw, 16);
+ }
+ }
+ }
+
+ /* Check if any status register has changed. */
+ if ((x86_xcr0 & I386_XSTATE_BNDCFG))
+ {
+ int bndcfg_regnum = find_regno (regcache->tdesc, "bndcfgu");
+
+ for (i = 0; i < num_mpx_cfg_registers; i++)
+ {
+ collect_register (regcache, i + bndcfg_regnum, raw);
+ p = ((char *) &fp->mpx_cfg_space[0]) + i * 8;
+ if (memcmp (raw, p, 8))
+ {
+ xstate_bv |= I386_XSTATE_BNDCFG;
+ memcpy (p, raw, 8);
+ }
+ }
+ }
+
/* Update the corresponding bits in xstate_bv if any SSE/AVX
registers are changed. */
fp->xstate_bv |= xstate_bv;
{
struct i387_fxsave *fp = (struct i387_fxsave *) buf;
int i, top;
- int st0_regnum = find_regno ("st0");
- int xmm0_regnum = find_regno ("xmm0");
+ int st0_regnum = find_regno (regcache->tdesc, "st0");
+ int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
unsigned long val;
+ /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
+ int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
for (i = 0; i < 8; i++)
supply_register (regcache, i + st0_regnum,
int i, top;
unsigned long val;
unsigned int clear_bv;
- char *p;
+ gdb_byte *p;
+ /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
+ int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
/* The supported bits in `xstat_bv' are 1 byte. Clear part in
vector registers if its bit in xstat_bv is zero. */
clear_bv = (~fp->xstate_bv) & x86_xcr0;
/* Check if any x87 registers are changed. */
- if ((x86_xcr0 & I386_XSTATE_X87))
+ if ((x86_xcr0 & I386_XSTATE_X87) != 0)
{
- int st0_regnum = find_regno ("st0");
+ int st0_regnum = find_regno (regcache->tdesc, "st0");
- if ((clear_bv & I386_XSTATE_X87))
- p = NULL;
+ if ((clear_bv & I386_XSTATE_X87) != 0)
+ {
+ for (i = 0; i < 8; i++)
+ supply_register_zeroed (regcache, i + st0_regnum);
+ }
else
- p = (char *) buf;
-
- for (i = 0; i < 8; i++)
{
- if (p)
- p = ((char *) &fp->st_space[0]) + i * 16;
- supply_register (regcache, i + st0_regnum, p);
+ p = (gdb_byte *) &fp->st_space[0];
+ for (i = 0; i < 8; i++)
+ supply_register (regcache, i + st0_regnum, p + i * 16);
}
}
- if ((x86_xcr0 & I386_XSTATE_SSE))
+ if ((x86_xcr0 & I386_XSTATE_SSE) != 0)
{
- int xmm0_regnum = find_regno ("xmm0");
+ int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
if ((clear_bv & I386_XSTATE_SSE))
- p = NULL;
+ {
+ for (i = 0; i < num_xmm_registers; i++)
+ supply_register_zeroed (regcache, i + xmm0_regnum);
+ }
else
- p = (char *) buf;
+ {
+ p = (gdb_byte *) &fp->xmm_space[0];
+ for (i = 0; i < num_xmm_registers; i++)
+ supply_register (regcache, i + xmm0_regnum, p + i * 16);
+ }
+ }
+
+ if ((x86_xcr0 & I386_XSTATE_AVX) != 0)
+ {
+ int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
- for (i = 0; i < num_xmm_registers; i++)
+ if ((clear_bv & I386_XSTATE_AVX) != 0)
{
- if (p)
- p = ((char *) &fp->xmm_space[0]) + i * 16;
- supply_register (regcache, i + xmm0_regnum, p);
+ for (i = 0; i < num_xmm_registers; i++)
+ supply_register_zeroed (regcache, i + ymm0h_regnum);
+ }
+ else
+ {
+ p = (gdb_byte *) &fp->ymmh_space[0];
+ for (i = 0; i < num_xmm_registers; i++)
+ supply_register (regcache, i + ymm0h_regnum, p + i * 16);
}
}
- if ((x86_xcr0 & I386_XSTATE_AVX))
+ if ((x86_xcr0 & I386_XSTATE_BNDREGS))
{
- int ymm0h_regnum = find_regno ("ymm0h");
+ int bnd0r_regnum = find_regno (regcache->tdesc, "bnd0raw");
- if ((clear_bv & I386_XSTATE_AVX))
- p = NULL;
+
+ if ((clear_bv & I386_XSTATE_BNDREGS) != 0)
+ {
+ for (i = 0; i < num_mpx_bnd_registers; i++)
+ supply_register_zeroed (regcache, i + bnd0r_regnum);
+ }
else
- p = (char *) buf;
+ {
+ p = (gdb_byte *) &fp->mpx_bnd_space[0];
+ for (i = 0; i < num_mpx_bnd_registers; i++)
+ supply_register (regcache, i + bnd0r_regnum, p + i * 16);
+ }
- for (i = 0; i < num_xmm_registers; i++)
+ }
+
+ if ((x86_xcr0 & I386_XSTATE_BNDCFG))
+ {
+ int bndcfg_regnum = find_regno (regcache->tdesc, "bndcfgu");
+
+ if ((clear_bv & I386_XSTATE_BNDCFG) != 0)
+ {
+ for (i = 0; i < num_mpx_cfg_registers; i++)
+ supply_register_zeroed (regcache, i + bndcfg_regnum);
+ }
+ else
{
- if (p)
- p = ((char *) &fp->ymmh_space[0]) + i * 16;
- supply_register (regcache, i + ymm0h_regnum, p);
+ p = (gdb_byte *) &fp->mpx_cfg_space[0];
+ for (i = 0; i < num_mpx_cfg_registers; i++)
+ supply_register (regcache, i + bndcfg_regnum, p + i * 8);
}
}