X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fgdbserver%2Fi387-fp.c;h=e655f742ab16bd6c0057fdb239f5a33c9a5f059a;hb=87ce2a04c53fa7bb4fff50a41e45c0b29af06dae;hp=75531d07427d1a360002c8fffa984f9f7f41aded;hpb=7b6bb8daaceb9ecf3f42dea57ae82733d6a3b2f6;p=binutils-gdb.git diff --git a/gdb/gdbserver/i387-fp.c b/gdb/gdbserver/i387-fp.c index 75531d07427..e655f742ab1 100644 --- a/gdb/gdbserver/i387-fp.c +++ b/gdb/gdbserver/i387-fp.c @@ -1,6 +1,5 @@ /* 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. @@ -21,7 +20,8 @@ #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. */ @@ -111,6 +111,15 @@ struct i387_xsave { /* 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 @@ -118,7 +127,7 @@ i387_cache_to_fsave (struct regcache *regcache, void *buf) { 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++) @@ -158,7 +167,7 @@ i387_fsave_to_cache (struct regcache *regcache, const void *buf) { 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++) @@ -194,9 +203,11 @@ i387_cache_to_fxsave (struct regcache *regcache, void *buf) { 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, @@ -250,6 +261,8 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf) 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. */ @@ -270,12 +283,20 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf) 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++) { @@ -292,7 +313,7 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf) /* 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++) { @@ -309,7 +330,7 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf) /* 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++) { @@ -323,6 +344,40 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf) } } + /* 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; @@ -414,9 +469,11 @@ i387_fxsave_to_cache (struct regcache *regcache, const void *buf) { 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, @@ -468,61 +525,99 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf) 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); } }