gdb/i387-tdep.c - gdb
Global variables defined
Functions defined
Macros defined
Source code
- #include "defs.h"
- #include "doublest.h"
- #include "floatformat.h"
- #include "frame.h"
- #include "gdbcore.h"
- #include "inferior.h"
- #include "language.h"
- #include "regcache.h"
- #include "value.h"
- #include "i386-tdep.h"
- #include "i387-tdep.h"
- #include "x86-xstate.h"
- static void
- print_i387_value (struct gdbarch *gdbarch,
- const gdb_byte *raw, struct ui_file *file)
- {
- DOUBLEST value;
-
- value = extract_typed_floating (raw, i387_ext_type (gdbarch));
-
- #ifdef PRINTF_HAS_LONG_DOUBLE
- fprintf_filtered (file, " %-+27.19Lg", (long double) value);
- #else
- fprintf_filtered (file, " %-+27.19g", (double) value);
- #endif
- }
- static void
- print_i387_ext (struct gdbarch *gdbarch,
- const gdb_byte *raw, struct ui_file *file)
- {
- int sign;
- int integer;
- unsigned int exponent;
- unsigned long fraction[2];
- sign = raw[9] & 0x80;
- integer = raw[7] & 0x80;
- exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
- fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
- fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
- | (raw[5] << 8) | raw[4]);
- if (exponent == 0x7fff && integer)
- {
- if (fraction[0] == 0x00000000 && fraction[1] == 0x00000000)
-
- fprintf_filtered (file, " %cInf", (sign ? '-' : '+'));
- else if (sign && fraction[0] == 0x00000000 && fraction[1] == 0x40000000)
-
- fputs_unfiltered (" Real Indefinite (QNaN)", file);
- else if (fraction[1] & 0x40000000)
-
- fputs_filtered (" QNaN", file);
- else
-
- fputs_filtered (" SNaN", file);
- }
- else if (exponent < 0x7fff && exponent > 0x0000 && integer)
-
- print_i387_value (gdbarch, raw, file);
- else if (exponent == 0x0000)
- {
-
- print_i387_value (gdbarch, raw, file);
- if (integer)
-
- fputs_filtered (" Pseudo-denormal", file);
- else if (fraction[0] || fraction[1])
-
- fputs_filtered (" Denormal", file);
- }
- else
-
- fputs_filtered (" Unsupported", file);
- }
- static void
- print_i387_status_word (int status_p,
- unsigned int status, struct ui_file *file)
- {
- fprintf_filtered (file, "Status Word: ");
- if (!status_p)
- {
- fprintf_filtered (file, "%s\n", _("<unavailable>"));
- return;
- }
- fprintf_filtered (file, "%s", hex_string_custom (status, 4));
- fputs_filtered (" ", file);
- fprintf_filtered (file, " %s", (status & 0x0001) ? "IE" : " ");
- fprintf_filtered (file, " %s", (status & 0x0002) ? "DE" : " ");
- fprintf_filtered (file, " %s", (status & 0x0004) ? "ZE" : " ");
- fprintf_filtered (file, " %s", (status & 0x0008) ? "OE" : " ");
- fprintf_filtered (file, " %s", (status & 0x0010) ? "UE" : " ");
- fprintf_filtered (file, " %s", (status & 0x0020) ? "PE" : " ");
- fputs_filtered (" ", file);
- fprintf_filtered (file, " %s", (status & 0x0080) ? "ES" : " ");
- fputs_filtered (" ", file);
- fprintf_filtered (file, " %s", (status & 0x0040) ? "SF" : " ");
- fputs_filtered (" ", file);
- fprintf_filtered (file, " %s", (status & 0x0100) ? "C0" : " ");
- fprintf_filtered (file, " %s", (status & 0x0200) ? "C1" : " ");
- fprintf_filtered (file, " %s", (status & 0x0400) ? "C2" : " ");
- fprintf_filtered (file, " %s", (status & 0x4000) ? "C3" : " ");
- fputs_filtered ("\n", file);
- fprintf_filtered (file,
- " TOP: %d\n", ((status >> 11) & 7));
- }
- static void
- print_i387_control_word (int control_p,
- unsigned int control, struct ui_file *file)
- {
- fprintf_filtered (file, "Control Word: ");
- if (!control_p)
- {
- fprintf_filtered (file, "%s\n", _("<unavailable>"));
- return;
- }
- fprintf_filtered (file, "%s", hex_string_custom (control, 4));
- fputs_filtered (" ", file);
- fprintf_filtered (file, " %s", (control & 0x0001) ? "IM" : " ");
- fprintf_filtered (file, " %s", (control & 0x0002) ? "DM" : " ");
- fprintf_filtered (file, " %s", (control & 0x0004) ? "ZM" : " ");
- fprintf_filtered (file, " %s", (control & 0x0008) ? "OM" : " ");
- fprintf_filtered (file, " %s", (control & 0x0010) ? "UM" : " ");
- fprintf_filtered (file, " %s", (control & 0x0020) ? "PM" : " ");
- fputs_filtered ("\n", file);
- fputs_filtered (" PC: ", file);
- switch ((control >> 8) & 3)
- {
- case 0:
- fputs_filtered ("Single Precision (24-bits)\n", file);
- break;
- case 1:
- fputs_filtered ("Reserved\n", file);
- break;
- case 2:
- fputs_filtered ("Double Precision (53-bits)\n", file);
- break;
- case 3:
- fputs_filtered ("Extended Precision (64-bits)\n", file);
- break;
- }
- fputs_filtered (" RC: ", file);
- switch ((control >> 10) & 3)
- {
- case 0:
- fputs_filtered ("Round to nearest\n", file);
- break;
- case 1:
- fputs_filtered ("Round down\n", file);
- break;
- case 2:
- fputs_filtered ("Round up\n", file);
- break;
- case 3:
- fputs_filtered ("Round toward zero\n", file);
- break;
- }
- }
- void
- i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
- struct frame_info *frame, const char *args)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
- ULONGEST fctrl;
- int fctrl_p;
- ULONGEST fstat;
- int fstat_p;
- ULONGEST ftag;
- int ftag_p;
- ULONGEST fiseg;
- int fiseg_p;
- ULONGEST fioff;
- int fioff_p;
- ULONGEST foseg;
- int foseg_p;
- ULONGEST fooff;
- int fooff_p;
- ULONGEST fop;
- int fop_p;
- int fpreg;
- int top;
- gdb_assert (gdbarch == get_frame_arch (frame));
- fctrl_p = read_frame_register_unsigned (frame,
- I387_FCTRL_REGNUM (tdep), &fctrl);
- fstat_p = read_frame_register_unsigned (frame,
- I387_FSTAT_REGNUM (tdep), &fstat);
- ftag_p = read_frame_register_unsigned (frame,
- I387_FTAG_REGNUM (tdep), &ftag);
- fiseg_p = read_frame_register_unsigned (frame,
- I387_FISEG_REGNUM (tdep), &fiseg);
- fioff_p = read_frame_register_unsigned (frame,
- I387_FIOFF_REGNUM (tdep), &fioff);
- foseg_p = read_frame_register_unsigned (frame,
- I387_FOSEG_REGNUM (tdep), &foseg);
- fooff_p = read_frame_register_unsigned (frame,
- I387_FOOFF_REGNUM (tdep), &fooff);
- fop_p = read_frame_register_unsigned (frame,
- I387_FOP_REGNUM (tdep), &fop);
- if (fstat_p)
- {
- top = ((fstat >> 11) & 7);
- for (fpreg = 7; fpreg >= 0; fpreg--)
- {
- struct value *regval;
- int regnum;
- int i;
- int tag = -1;
- fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg);
- if (ftag_p)
- {
- tag = (ftag >> (fpreg * 2)) & 3;
- switch (tag)
- {
- case 0:
- fputs_filtered ("Valid ", file);
- break;
- case 1:
- fputs_filtered ("Zero ", file);
- break;
- case 2:
- fputs_filtered ("Special ", file);
- break;
- case 3:
- fputs_filtered ("Empty ", file);
- break;
- }
- }
- else
- fputs_filtered ("Unknown ", file);
- regnum = (fpreg + 8 - top) % 8 + I387_ST0_REGNUM (tdep);
- regval = get_frame_register_value (frame, regnum);
- if (value_entirely_available (regval))
- {
- const gdb_byte *raw = value_contents (regval);
- fputs_filtered ("0x", file);
- for (i = 9; i >= 0; i--)
- fprintf_filtered (file, "%02x", raw[i]);
- if (tag != -1 && tag != 3)
- print_i387_ext (gdbarch, raw, file);
- }
- else
- fprintf_filtered (file, "%s", _("<unavailable>"));
- fputs_filtered ("\n", file);
- }
- }
- fputs_filtered ("\n", file);
- print_i387_status_word (fstat_p, fstat, file);
- print_i387_control_word (fctrl_p, fctrl, file);
- fprintf_filtered (file, "Tag Word: %s\n",
- ftag_p ? hex_string_custom (ftag, 4) : _("<unavailable>"));
- fprintf_filtered (file, "Instruction Pointer: %s:",
- fiseg_p ? hex_string_custom (fiseg, 2) : _("<unavailable>"));
- fprintf_filtered (file, "%s\n",
- fioff_p ? hex_string_custom (fioff, 8) : _("<unavailable>"));
- fprintf_filtered (file, "Operand Pointer: %s:",
- foseg_p ? hex_string_custom (foseg, 2) : _("<unavailable>"));
- fprintf_filtered (file, "%s\n",
- fooff_p ? hex_string_custom (fooff, 8) : _("<unavailable>"));
- fprintf_filtered (file, "Opcode: %s\n",
- fop_p
- ? (hex_string_custom (fop ? (fop | 0xd800) : 0, 4))
- : _("<unavailable>"));
- }
- int
- i387_convert_register_p (struct gdbarch *gdbarch, int regnum,
- struct type *type)
- {
- if (i386_fp_regnum_p (gdbarch, regnum))
- {
-
- if (type == i387_ext_type (gdbarch))
- return 0;
- else
- return 1;
- }
- return 0;
- }
- int
- i387_register_to_value (struct frame_info *frame, int regnum,
- struct type *type, gdb_byte *to,
- int *optimizedp, int *unavailablep)
- {
- struct gdbarch *gdbarch = get_frame_arch (frame);
- gdb_byte from[I386_MAX_REGISTER_SIZE];
- gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
-
- if (TYPE_CODE (type) != TYPE_CODE_FLT)
- {
- warning (_("Cannot convert floating-point register value "
- "to non-floating-point type."));
- *optimizedp = *unavailablep = 0;
- return 0;
- }
-
- if (!get_frame_register_bytes (frame, regnum, 0, TYPE_LENGTH (type),
- from, optimizedp, unavailablep))
- return 0;
- convert_typed_floating (from, i387_ext_type (gdbarch), to, type);
- *optimizedp = *unavailablep = 0;
- return 1;
- }
- void
- i387_value_to_register (struct frame_info *frame, int regnum,
- struct type *type, const gdb_byte *from)
- {
- struct gdbarch *gdbarch = get_frame_arch (frame);
- gdb_byte to[I386_MAX_REGISTER_SIZE];
- gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
-
- if (TYPE_CODE (type) != TYPE_CODE_FLT)
- {
- warning (_("Cannot convert non-floating-point type "
- "to floating-point register value."));
- return;
- }
-
- convert_typed_floating (from, type, to, i387_ext_type (gdbarch));
- put_frame_register (frame, regnum, to);
- }
- static int fsave_offset[] =
- {
- 28 + 0 * 10,
- 28 + 1 * 10,
- 28 + 2 * 10,
- 28 + 3 * 10,
- 28 + 4 * 10,
- 28 + 5 * 10,
- 28 + 6 * 10,
- 28 + 7 * 10,
- 0,
- 4,
- 8,
- 16,
- 12,
- 24,
- 20,
- 18
- };
- #define FSAVE_ADDR(tdep, fsave, regnum) \
- (fsave + fsave_offset[regnum - I387_ST0_REGNUM (tdep)])
- void
- i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- const gdb_byte *regs = fsave;
- int i;
- gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
- for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
- if (regnum == -1 || regnum == i)
- {
- if (fsave == NULL)
- {
- regcache_raw_supply (regcache, i, NULL);
- continue;
- }
-
- if (i >= I387_FCTRL_REGNUM (tdep)
- && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
- {
- gdb_byte val[4];
- memcpy (val, FSAVE_ADDR (tdep, regs, i), 2);
- val[2] = val[3] = 0;
- if (i == I387_FOP_REGNUM (tdep))
- val[1] &= ((1 << 3) - 1);
- regcache_raw_supply (regcache, i, val);
- }
- else
- regcache_raw_supply (regcache, i, FSAVE_ADDR (tdep, regs, i));
- }
-
- for (i = I387_XMM0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
- if (regnum == -1 || regnum == i)
- regcache_raw_supply (regcache, i, NULL);
- if (regnum == -1 || regnum == I387_MXCSR_REGNUM (tdep))
- {
- gdb_byte buf[4];
- store_unsigned_integer (buf, 4, byte_order, 0x1f80);
- regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), buf);
- }
- }
- void
- i387_collect_fsave (const struct regcache *regcache, int regnum, void *fsave)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
- gdb_byte *regs = fsave;
- int i;
- gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
- for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
- if (regnum == -1 || regnum == i)
- {
-
- if (i >= I387_FCTRL_REGNUM (tdep)
- && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
- {
- gdb_byte buf[4];
- regcache_raw_collect (regcache, i, buf);
- if (i == I387_FOP_REGNUM (tdep))
- {
-
- buf[1] &= ((1 << 3) - 1);
- buf[1] |= ((FSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
- }
- memcpy (FSAVE_ADDR (tdep, regs, i), buf, 2);
- }
- else
- regcache_raw_collect (regcache, i, FSAVE_ADDR (tdep, regs, i));
- }
- }
- static int fxsave_offset[] =
- {
- 32,
- 48,
- 64,
- 80,
- 96,
- 112,
- 128,
- 144,
- 0,
- 2,
- 4,
- 12,
- 8,
- 20,
- 16,
- 6,
- 160 + 0 * 16,
- 160 + 1 * 16,
- 160 + 2 * 16,
- 160 + 3 * 16,
- 160 + 4 * 16,
- 160 + 5 * 16,
- 160 + 6 * 16,
- 160 + 7 * 16,
- 160 + 8 * 16,
- 160 + 9 * 16,
- 160 + 10 * 16,
- 160 + 11 * 16,
- 160 + 12 * 16,
- 160 + 13 * 16,
- 160 + 14 * 16,
- 160 + 15 * 16,
- };
- #define FXSAVE_ADDR(tdep, fxsave, regnum) \
- (fxsave + fxsave_offset[regnum - I387_ST0_REGNUM (tdep)])
- #define FXSAVE_MXCSR_ADDR(fxsave) (fxsave + 24)
- static int i387_tag (const gdb_byte *raw);
- void
- i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
- const gdb_byte *regs = fxsave;
- int i;
- gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
- gdb_assert (tdep->num_xmm_regs > 0);
- for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
- if (regnum == -1 || regnum == i)
- {
- if (regs == NULL)
- {
- regcache_raw_supply (regcache, i, NULL);
- continue;
- }
-
- if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
- && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
- {
- gdb_byte val[4];
- memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
- val[2] = val[3] = 0;
- if (i == I387_FOP_REGNUM (tdep))
- val[1] &= ((1 << 3) - 1);
- else if (i== I387_FTAG_REGNUM (tdep))
- {
-
- unsigned long ftag = 0;
- int fpreg;
- int top;
- top = ((FXSAVE_ADDR (tdep, regs,
- I387_FSTAT_REGNUM (tdep)))[1] >> 3);
- top &= 0x7;
- for (fpreg = 7; fpreg >= 0; fpreg--)
- {
- int tag;
- if (val[0] & (1 << fpreg))
- {
- int thisreg = (fpreg + 8 - top) % 8
- + I387_ST0_REGNUM (tdep);
- tag = i387_tag (FXSAVE_ADDR (tdep, regs, thisreg));
- }
- else
- tag = 3;
- ftag |= tag << (2 * fpreg);
- }
- val[0] = ftag & 0xff;
- val[1] = (ftag >> 8) & 0xff;
- }
- regcache_raw_supply (regcache, i, val);
- }
- else
- regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
- }
- if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
- {
- if (regs == NULL)
- regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), NULL);
- else
- regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep),
- FXSAVE_MXCSR_ADDR (regs));
- }
- }
- void
- i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
- gdb_byte *regs = fxsave;
- int i;
- gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
- gdb_assert (tdep->num_xmm_regs > 0);
- for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
- if (regnum == -1 || regnum == i)
- {
-
- if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
- && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
- {
- gdb_byte buf[4];
- regcache_raw_collect (regcache, i, buf);
- if (i == I387_FOP_REGNUM (tdep))
- {
-
- buf[1] &= ((1 << 3) - 1);
- buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
- }
- else if (i == I387_FTAG_REGNUM (tdep))
- {
-
- unsigned short ftag;
- int fpreg;
- ftag = (buf[1] << 8) | buf[0];
- buf[0] = 0;
- buf[1] = 0;
- for (fpreg = 7; fpreg >= 0; fpreg--)
- {
- int tag = (ftag >> (fpreg * 2)) & 3;
- if (tag != 3)
- buf[0] |= (1 << fpreg);
- }
- }
- memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
- }
- else
- regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
- }
- if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
- regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
- FXSAVE_MXCSR_ADDR (regs));
- }
- #define XSAVE_XSTATE_BV_ADDR(xsave) (xsave + 512)
- static int xsave_avxh_offset[] =
- {
- 576 + 0 * 16,
- 576 + 1 * 16,
- 576 + 2 * 16,
- 576 + 3 * 16,
- 576 + 4 * 16,
- 576 + 5 * 16,
- 576 + 6 * 16,
- 576 + 7 * 16,
- 576 + 8 * 16,
- 576 + 9 * 16,
- 576 + 10 * 16,
- 576 + 11 * 16,
- 576 + 12 * 16,
- 576 + 13 * 16,
- 576 + 14 * 16,
- 576 + 15 * 16
- };
- #define XSAVE_AVXH_ADDR(tdep, xsave, regnum) \
- (xsave + xsave_avxh_offset[regnum - I387_YMM0H_REGNUM (tdep)])
- static int xsave_ymm_avx512_offset[] =
- {
-
- 1664 + 16 + 0 * 64,
- 1664 + 16 + 1 * 64,
- 1664 + 16 + 2 * 64,
- 1664 + 16 + 3 * 64,
- 1664 + 16 + 4 * 64,
- 1664 + 16 + 5 * 64,
- 1664 + 16 + 6 * 64,
- 1664 + 16 + 7 * 64,
- 1664 + 16 + 8 * 64,
- 1664 + 16 + 9 * 64,
- 1664 + 16 + 10 * 64,
- 1664 + 16 + 11 * 64,
- 1664 + 16 + 12 * 64,
- 1664 + 16 + 13 * 64,
- 1664 + 16 + 14 * 64,
- 1664 + 16 + 15 * 64
- };
- #define XSAVE_YMM_AVX512_ADDR(tdep, xsave, regnum) \
- (xsave + xsave_ymm_avx512_offset[regnum - I387_YMM16H_REGNUM (tdep)])
- static int xsave_xmm_avx512_offset[] =
- {
- 1664 + 0 * 64,
- 1664 + 1 * 64,
- 1664 + 2 * 64,
- 1664 + 3 * 64,
- 1664 + 4 * 64,
- 1664 + 5 * 64,
- 1664 + 6 * 64,
- 1664 + 7 * 64,
- 1664 + 8 * 64,
- 1664 + 9 * 64,
- 1664 + 10 * 64,
- 1664 + 11 * 64,
- 1664 + 12 * 64,
- 1664 + 13 * 64,
- 1664 + 14 * 64,
- 1664 + 15 * 64
- };
- #define XSAVE_XMM_AVX512_ADDR(tdep, xsave, regnum) \
- (xsave + xsave_xmm_avx512_offset[regnum - I387_XMM16_REGNUM (tdep)])
- static int xsave_mpx_offset[] = {
- 960 + 0 * 16,
- 960 + 1 * 16,
- 960 + 2 * 16,
- 960 + 3 * 16,
- 1024 + 0 * 8,
- 1024 + 1 * 8,
- };
- #define XSAVE_MPX_ADDR(tdep, xsave, regnum) \
- (xsave + xsave_mpx_offset[regnum - I387_BND0R_REGNUM (tdep)])
-
- static int xsave_avx512_k_offset[] =
- {
- 1088 + 0 * 8,
- 1088 + 1 * 8,
- 1088 + 2 * 8,
- 1088 + 3 * 8,
- 1088 + 4 * 8,
- 1088 + 5 * 8,
- 1088 + 6 * 8,
- 1088 + 7 * 8
- };
- #define XSAVE_AVX512_K_ADDR(tdep, xsave, regnum) \
- (xsave + xsave_avx512_k_offset[regnum - I387_K0_REGNUM (tdep)])
- static int xsave_avx512_zmm_h_offset[] =
- {
- 1152 + 0 * 32,
- 1152 + 1 * 32,
- 1152 + 2 * 32,
- 1152 + 3 * 32,
- 1152 + 4 * 32,
- 1152 + 5 * 32,
- 1152 + 6 * 32,
- 1152 + 7 * 32,
- 1152 + 8 * 32,
- 1152 + 9 * 32,
- 1152 + 10 * 32,
- 1152 + 11 * 32,
- 1152 + 12 * 32,
- 1152 + 13 * 32,
- 1152 + 14 * 32,
- 1152 + 15 * 32,
- 1664 + 32 + 0 * 64,
- 1664 + 32 + 1 * 64,
- 1664 + 32 + 2 * 64,
- 1664 + 32 + 3 * 64,
- 1664 + 32 + 4 * 64,
- 1664 + 32 + 5 * 64,
- 1664 + 32 + 6 * 64,
- 1664 + 32 + 7 * 64,
- 1664 + 32 + 8 * 64,
- 1664 + 32 + 9 * 64,
- 1664 + 32 + 10 * 64,
- 1664 + 32 + 11 * 64,
- 1664 + 32 + 12 * 64,
- 1664 + 32 + 13 * 64,
- 1664 + 32 + 14 * 64,
- 1664 + 32 + 15 * 64
- };
- #define XSAVE_AVX512_ZMM_H_ADDR(tdep, xsave, regnum) \
- (xsave + xsave_avx512_zmm_h_offset[regnum - I387_ZMM0H_REGNUM (tdep)])
- void
- i387_supply_xsave (struct regcache *regcache, int regnum,
- const void *xsave)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- const gdb_byte *regs = xsave;
- int i;
- unsigned int clear_bv;
- static const gdb_byte zero[MAX_REGISTER_SIZE] = { 0 };
- enum
- {
- none = 0x0,
- x87 = 0x1,
- sse = 0x2,
- avxh = 0x4,
- mpx = 0x8,
- avx512_k = 0x10,
- avx512_zmm_h = 0x20,
- avx512_ymmh_avx512 = 0x40,
- avx512_xmm_avx512 = 0x80,
- all = x87 | sse | avxh | mpx | avx512_k | avx512_zmm_h
- | avx512_ymmh_avx512 | avx512_xmm_avx512
- } regclass;
- gdb_assert (regs != NULL);
- gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
- gdb_assert (tdep->num_xmm_regs > 0);
- if (regnum == -1)
- regclass = all;
- else if (regnum >= I387_ZMM0H_REGNUM (tdep)
- && regnum < I387_ZMMENDH_REGNUM (tdep))
- regclass = avx512_zmm_h;
- else if (regnum >= I387_K0_REGNUM (tdep)
- && regnum < I387_KEND_REGNUM (tdep))
- regclass = avx512_k;
- else if (regnum >= I387_YMM16H_REGNUM (tdep)
- && regnum < I387_YMMH_AVX512_END_REGNUM (tdep))
- regclass = avx512_ymmh_avx512;
- else if (regnum >= I387_XMM16_REGNUM (tdep)
- && regnum < I387_XMM_AVX512_END_REGNUM (tdep))
- regclass = avx512_xmm_avx512;
- 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;
- else if (regnum >= I387_ST0_REGNUM (tdep)
- && regnum < I387_FCTRL_REGNUM (tdep))
- regclass = x87;
- else
- regclass = none;
- if (regclass != none)
- {
-
- const gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs);
-
- clear_bv = (~(*xstate_bv_p)) & tdep->xcr0;
- }
- else
- clear_bv = X86_XSTATE_ALL_MASK;
-
- switch (regclass)
- {
- case none:
- break;
- case avx512_zmm_h:
- if ((clear_bv & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
- regcache_raw_supply (regcache, regnum, zero);
- else
- regcache_raw_supply (regcache, regnum,
- XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, regnum));
- return;
- case avx512_k:
- if ((clear_bv & X86_XSTATE_K))
- regcache_raw_supply (regcache, regnum, zero);
- else
- regcache_raw_supply (regcache, regnum,
- XSAVE_AVX512_K_ADDR (tdep, regs, regnum));
- return;
- case avx512_ymmh_avx512:
- if ((clear_bv & X86_XSTATE_ZMM))
- regcache_raw_supply (regcache, regnum, zero);
- else
- regcache_raw_supply (regcache, regnum,
- XSAVE_YMM_AVX512_ADDR (tdep, regs, regnum));
- return;
- case avx512_xmm_avx512:
- if ((clear_bv & X86_XSTATE_ZMM))
- regcache_raw_supply (regcache, regnum, zero);
- else
- regcache_raw_supply (regcache, regnum,
- XSAVE_XMM_AVX512_ADDR (tdep, regs, regnum));
- return;
- case avxh:
- if ((clear_bv & X86_XSTATE_AVX))
- regcache_raw_supply (regcache, regnum, zero);
- else
- regcache_raw_supply (regcache, regnum,
- XSAVE_AVXH_ADDR (tdep, regs, regnum));
- return;
- case mpx:
- if ((clear_bv & X86_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 & X86_XSTATE_SSE))
- regcache_raw_supply (regcache, regnum, zero);
- else
- regcache_raw_supply (regcache, regnum,
- FXSAVE_ADDR (tdep, regs, regnum));
- return;
- case x87:
- if ((clear_bv & X86_XSTATE_X87))
- regcache_raw_supply (regcache, regnum, zero);
- else
- regcache_raw_supply (regcache, regnum,
- FXSAVE_ADDR (tdep, regs, regnum));
- return;
- case all:
-
- if ((tdep->xcr0 & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
- {
- if ((clear_bv & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
- {
- for (i = I387_ZMM0H_REGNUM (tdep);
- i < I387_ZMMENDH_REGNUM (tdep);
- i++)
- regcache_raw_supply (regcache, i, zero);
- }
- else
- {
- for (i = I387_ZMM0H_REGNUM (tdep);
- i < I387_ZMMENDH_REGNUM (tdep);
- i++)
- regcache_raw_supply (regcache, i,
- XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i));
- }
- }
-
- if ((tdep->xcr0 & X86_XSTATE_K))
- {
- if ((clear_bv & X86_XSTATE_K))
- {
- for (i = I387_K0_REGNUM (tdep);
- i < I387_KEND_REGNUM (tdep);
- i++)
- regcache_raw_supply (regcache, i, zero);
- }
- else
- {
- for (i = I387_K0_REGNUM (tdep);
- i < I387_KEND_REGNUM (tdep);
- i++)
- regcache_raw_supply (regcache, i,
- XSAVE_AVX512_K_ADDR (tdep, regs, i));
- }
- }
-
- if ((tdep->xcr0 & X86_XSTATE_ZMM))
- {
- if ((clear_bv & X86_XSTATE_ZMM))
- {
- for (i = I387_YMM16H_REGNUM (tdep);
- i < I387_YMMH_AVX512_END_REGNUM (tdep);
- i++)
- regcache_raw_supply (regcache, i, zero);
- for (i = I387_XMM16_REGNUM (tdep);
- i < I387_XMM_AVX512_END_REGNUM (tdep);
- i++)
- regcache_raw_supply (regcache, i, zero);
- }
- else
- {
- for (i = I387_YMM16H_REGNUM (tdep);
- i < I387_YMMH_AVX512_END_REGNUM (tdep);
- i++)
- regcache_raw_supply (regcache, i,
- XSAVE_YMM_AVX512_ADDR (tdep, regs, i));
- for (i = I387_XMM16_REGNUM (tdep);
- i < I387_XMM_AVX512_END_REGNUM (tdep);
- i++)
- regcache_raw_supply (regcache, i,
- XSAVE_XMM_AVX512_ADDR (tdep, regs, i));
- }
- }
-
- if ((tdep->xcr0 & X86_XSTATE_AVX))
- {
- if ((clear_bv & X86_XSTATE_AVX))
- {
- for (i = I387_YMM0H_REGNUM (tdep);
- i < I387_YMMENDH_REGNUM (tdep);
- i++)
- regcache_raw_supply (regcache, i, zero);
- }
- else
- {
- for (i = I387_YMM0H_REGNUM (tdep);
- i < I387_YMMENDH_REGNUM (tdep);
- i++)
- regcache_raw_supply (regcache, i,
- XSAVE_AVXH_ADDR (tdep, regs, i));
- }
- }
-
- if ((tdep->xcr0 & X86_XSTATE_BNDREGS))
- {
- if (clear_bv & X86_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));
- }
- }
-
- if ((tdep->xcr0 & X86_XSTATE_BNDCFG))
- {
- if (clear_bv & X86_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));
- }
- }
-
- if ((tdep->xcr0 & X86_XSTATE_SSE))
- {
- if ((clear_bv & X86_XSTATE_SSE))
- {
- for (i = I387_XMM0_REGNUM (tdep);
- i < I387_MXCSR_REGNUM (tdep);
- i++)
- regcache_raw_supply (regcache, i, zero);
- }
- else
- {
- for (i = I387_XMM0_REGNUM (tdep);
- i < I387_MXCSR_REGNUM (tdep); i++)
- regcache_raw_supply (regcache, i,
- FXSAVE_ADDR (tdep, regs, i));
- }
- }
-
- if ((tdep->xcr0 & X86_XSTATE_X87))
- {
- if ((clear_bv & X86_XSTATE_X87))
- {
- for (i = I387_ST0_REGNUM (tdep);
- i < I387_FCTRL_REGNUM (tdep);
- i++)
- regcache_raw_supply (regcache, i, zero);
- }
- else
- {
- for (i = I387_ST0_REGNUM (tdep);
- i < I387_FCTRL_REGNUM (tdep);
- i++)
- regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
- }
- }
- break;
- }
-
- for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
- if (regnum == -1 || regnum == i)
- {
-
- if (i != I387_FIOFF_REGNUM (tdep)
- && i != I387_FOOFF_REGNUM (tdep))
- {
- gdb_byte val[4];
- memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
- val[2] = val[3] = 0;
- if (i == I387_FOP_REGNUM (tdep))
- val[1] &= ((1 << 3) - 1);
- else if (i== I387_FTAG_REGNUM (tdep))
- {
-
- unsigned long ftag = 0;
- int fpreg;
- int top;
- top = ((FXSAVE_ADDR (tdep, regs,
- I387_FSTAT_REGNUM (tdep)))[1] >> 3);
- top &= 0x7;
- for (fpreg = 7; fpreg >= 0; fpreg--)
- {
- int tag;
- if (val[0] & (1 << fpreg))
- {
- int thisreg = (fpreg + 8 - top) % 8
- + I387_ST0_REGNUM (tdep);
- tag = i387_tag (FXSAVE_ADDR (tdep, regs, thisreg));
- }
- else
- tag = 3;
- ftag |= tag << (2 * fpreg);
- }
- val[0] = ftag & 0xff;
- val[1] = (ftag >> 8) & 0xff;
- }
- regcache_raw_supply (regcache, i, val);
- }
- else
- regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
- }
- if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
- regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep),
- FXSAVE_MXCSR_ADDR (regs));
- }
- void
- i387_collect_xsave (const struct regcache *regcache, int regnum,
- void *xsave, int gcore)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- gdb_byte *regs = xsave;
- int i;
- enum
- {
- none = 0x0,
- check = 0x1,
- x87 = 0x2 | check,
- sse = 0x4 | check,
- avxh = 0x8 | check,
- mpx = 0x10 | check,
- avx512_k = 0x20 | check,
- avx512_zmm_h = 0x40 | check,
- avx512_ymmh_avx512 = 0x80 | check,
- avx512_xmm_avx512 = 0x100 | check,
- all = x87 | sse | avxh | mpx | avx512_k | avx512_zmm_h
- | avx512_ymmh_avx512 | avx512_xmm_avx512
- } regclass;
- gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
- gdb_assert (tdep->num_xmm_regs > 0);
- if (regnum == -1)
- regclass = all;
- else if (regnum >= I387_ZMM0H_REGNUM (tdep)
- && regnum < I387_ZMMENDH_REGNUM (tdep))
- regclass = avx512_zmm_h;
- else if (regnum >= I387_K0_REGNUM (tdep)
- && regnum < I387_KEND_REGNUM (tdep))
- regclass = avx512_k;
- else if (regnum >= I387_YMM16H_REGNUM (tdep)
- && regnum < I387_YMMH_AVX512_END_REGNUM (tdep))
- regclass = avx512_ymmh_avx512;
- else if (regnum >= I387_XMM16_REGNUM (tdep)
- && regnum < I387_XMM_AVX512_END_REGNUM (tdep))
- regclass = avx512_xmm_avx512;
- 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;
- else if (regnum >= I387_ST0_REGNUM (tdep)
- && regnum < I387_FCTRL_REGNUM (tdep))
- regclass = x87;
- else
- regclass = none;
- if (gcore)
- {
-
- memset (regs, 0, X86_XSTATE_SIZE (tdep->xcr0));
-
- if (tdep->xsave_xcr0_offset != -1)
- memcpy (regs + tdep->xsave_xcr0_offset, &tdep->xcr0, 8);
- memcpy (XSAVE_XSTATE_BV_ADDR (regs), &tdep->xcr0, 8);
- }
- if ((regclass & check))
- {
- gdb_byte raw[I386_MAX_REGISTER_SIZE];
- gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs);
- unsigned int xstate_bv = 0;
-
- unsigned int clear_bv = (~(*xstate_bv_p)) & tdep->xcr0;
- gdb_byte *p;
-
- if (clear_bv)
- {
- if ((clear_bv & X86_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 & X86_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 & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
- for (i = I387_ZMM0H_REGNUM (tdep);
- i < I387_ZMMENDH_REGNUM (tdep); i++)
- memset (XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i), 0, 32);
- if ((clear_bv & X86_XSTATE_K))
- for (i = I387_K0_REGNUM (tdep);
- i < I387_KEND_REGNUM (tdep); i++)
- memset (XSAVE_AVX512_K_ADDR (tdep, regs, i), 0, 8);
- if ((clear_bv & X86_XSTATE_ZMM))
- {
- for (i = I387_YMM16H_REGNUM (tdep);
- i < I387_YMMH_AVX512_END_REGNUM (tdep); i++)
- memset (XSAVE_YMM_AVX512_ADDR (tdep, regs, i), 0, 16);
- for (i = I387_XMM16_REGNUM (tdep);
- i < I387_XMM_AVX512_END_REGNUM (tdep); i++)
- memset (XSAVE_XMM_AVX512_ADDR (tdep, regs, i), 0, 16);
- }
- if ((clear_bv & X86_XSTATE_AVX))
- for (i = I387_YMM0H_REGNUM (tdep);
- i < I387_YMMENDH_REGNUM (tdep); i++)
- memset (XSAVE_AVXH_ADDR (tdep, regs, i), 0, 16);
- if ((clear_bv & X86_XSTATE_SSE))
- for (i = I387_XMM0_REGNUM (tdep);
- i < I387_MXCSR_REGNUM (tdep); i++)
- memset (FXSAVE_ADDR (tdep, regs, i), 0, 16);
- if ((clear_bv & X86_XSTATE_X87))
- for (i = I387_ST0_REGNUM (tdep);
- i < I387_FCTRL_REGNUM (tdep); i++)
- memset (FXSAVE_ADDR (tdep, regs, i), 0, 10);
- }
- if (regclass == all)
- {
-
- if ((tdep->xcr0 & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
- for (i = I387_ZMM0H_REGNUM (tdep);
- i < I387_ZMMENDH_REGNUM (tdep); i++)
- {
- regcache_raw_collect (regcache, i, raw);
- p = XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i);
- if (memcmp (raw, p, 32) != 0)
- {
- xstate_bv |= (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM);
- memcpy (p, raw, 32);
- }
- }
-
- if ((tdep->xcr0 & X86_XSTATE_K))
- for (i = I387_K0_REGNUM (tdep);
- i < I387_KEND_REGNUM (tdep); i++)
- {
- regcache_raw_collect (regcache, i, raw);
- p = XSAVE_AVX512_K_ADDR (tdep, regs, i);
- if (memcmp (raw, p, 8) != 0)
- {
- xstate_bv |= X86_XSTATE_K;
- memcpy (p, raw, 8);
- }
- }
-
- if ((tdep->xcr0 & X86_XSTATE_ZMM))
- {
- for (i = I387_YMM16H_REGNUM (tdep);
- i < I387_YMMH_AVX512_END_REGNUM (tdep); i++)
- {
- regcache_raw_collect (regcache, i, raw);
- p = XSAVE_YMM_AVX512_ADDR (tdep, regs, i);
- if (memcmp (raw, p, 16) != 0)
- {
- xstate_bv |= X86_XSTATE_ZMM;
- memcpy (p, raw, 16);
- }
- }
- for (i = I387_XMM16_REGNUM (tdep);
- i < I387_XMM_AVX512_END_REGNUM (tdep); i++)
- {
- regcache_raw_collect (regcache, i, raw);
- p = XSAVE_XMM_AVX512_ADDR (tdep, regs, i);
- if (memcmp (raw, p, 16) != 0)
- {
- xstate_bv |= X86_XSTATE_ZMM;
- memcpy (p, raw, 16);
- }
- }
- }
-
- if ((tdep->xcr0 & X86_XSTATE_AVX))
- for (i = I387_YMM0H_REGNUM (tdep);
- i < I387_YMMENDH_REGNUM (tdep); i++)
- {
- regcache_raw_collect (regcache, i, raw);
- p = XSAVE_AVXH_ADDR (tdep, regs, i);
- if (memcmp (raw, p, 16))
- {
- xstate_bv |= X86_XSTATE_AVX;
- memcpy (p, raw, 16);
- }
- }
-
- if ((tdep->xcr0 & X86_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 |= X86_XSTATE_BNDREGS;
- memcpy (p, raw, 16);
- }
- }
-
- if ((tdep->xcr0 & X86_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 |= X86_XSTATE_BNDCFG;
- memcpy (p, raw, 8);
- }
- }
-
- if ((tdep->xcr0 & X86_XSTATE_SSE))
- for (i = I387_XMM0_REGNUM (tdep);
- i < I387_MXCSR_REGNUM (tdep); i++)
- {
- regcache_raw_collect (regcache, i, raw);
- p = FXSAVE_ADDR (tdep, regs, i);
- if (memcmp (raw, p, 16))
- {
- xstate_bv |= X86_XSTATE_SSE;
- memcpy (p, raw, 16);
- }
- }
-
- if ((tdep->xcr0 & X86_XSTATE_X87))
- for (i = I387_ST0_REGNUM (tdep);
- i < I387_FCTRL_REGNUM (tdep); i++)
- {
- regcache_raw_collect (regcache, i, raw);
- p = FXSAVE_ADDR (tdep, regs, i);
- if (memcmp (raw, p, 10))
- {
- xstate_bv |= X86_XSTATE_X87;
- memcpy (p, raw, 10);
- }
- }
- }
- else
- {
-
- regcache_raw_collect (regcache, regnum, raw);
- switch (regclass)
- {
- default:
- internal_error (__FILE__, __LINE__,
- _("invalid i387 regclass"));
- case avx512_zmm_h:
-
- p = XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, regnum);
- if (memcmp (raw, p, 32) != 0)
- {
- xstate_bv |= (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM);
- memcpy (p, raw, 32);
- }
- break;
- case avx512_k:
-
- p = XSAVE_AVX512_K_ADDR (tdep, regs, regnum);
- if (memcmp (raw, p, 8) != 0)
- {
- xstate_bv |= X86_XSTATE_K;
- memcpy (p, raw, 8);
- }
- break;
- case avx512_ymmh_avx512:
-
- p = XSAVE_YMM_AVX512_ADDR (tdep, regs, regnum);
- if (memcmp (raw, p, 16) != 0)
- {
- xstate_bv |= X86_XSTATE_ZMM;
- memcpy (p, raw, 16);
- }
- break;
- case avx512_xmm_avx512:
-
- p = XSAVE_XMM_AVX512_ADDR (tdep, regs, regnum);
- if (memcmp (raw, p, 16) != 0)
- {
- xstate_bv |= X86_XSTATE_ZMM;
- memcpy (p, raw, 16);
- }
- break;
- case avxh:
-
- p = XSAVE_AVXH_ADDR (tdep, regs, regnum);
- if (memcmp (raw, p, 16))
- {
- xstate_bv |= X86_XSTATE_AVX;
- memcpy (p, raw, 16);
- }
- 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 |= X86_XSTATE_BNDREGS;
- memcpy (p, raw, 16);
- }
- }
- else
- {
- p = XSAVE_MPX_ADDR (tdep, regs, regnum);
- xstate_bv |= X86_XSTATE_BNDCFG;
- memcpy (p, raw, 8);
- }
- break;
- case sse:
-
- p = FXSAVE_ADDR (tdep, regs, regnum);
- if (memcmp (raw, p, 16))
- {
- xstate_bv |= X86_XSTATE_SSE;
- memcpy (p, raw, 16);
- }
- break;
- case x87:
-
- p = FXSAVE_ADDR (tdep, regs, regnum);
- if (memcmp (raw, p, 10))
- {
- xstate_bv |= X86_XSTATE_X87;
- memcpy (p, raw, 10);
- }
- break;
- }
- }
-
- if (xstate_bv)
- {
-
- *xstate_bv_p |= (gdb_byte) xstate_bv;
- switch (regclass)
- {
- default:
- internal_error (__FILE__, __LINE__,
- _("invalid i387 regclass"));
- case all:
- break;
- case x87:
- case sse:
- case avxh:
- case mpx:
- case avx512_k:
- case avx512_zmm_h:
- case avx512_ymmh_avx512:
- case avx512_xmm_avx512:
-
- return;
- }
- }
- else
- {
-
- if (regclass != all)
- return;
- }
- }
-
- for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
- if (regnum == -1 || regnum == i)
- {
-
- if (i != I387_FIOFF_REGNUM (tdep)
- && i != I387_FOOFF_REGNUM (tdep))
- {
- gdb_byte buf[4];
- regcache_raw_collect (regcache, i, buf);
- if (i == I387_FOP_REGNUM (tdep))
- {
-
- buf[1] &= ((1 << 3) - 1);
- buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
- }
- else if (i == I387_FTAG_REGNUM (tdep))
- {
-
- unsigned short ftag;
- int fpreg;
- ftag = (buf[1] << 8) | buf[0];
- buf[0] = 0;
- buf[1] = 0;
- for (fpreg = 7; fpreg >= 0; fpreg--)
- {
- int tag = (ftag >> (fpreg * 2)) & 3;
- if (tag != 3)
- buf[0] |= (1 << fpreg);
- }
- }
- memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
- }
- else
- regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
- }
- if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
- regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
- FXSAVE_MXCSR_ADDR (regs));
- }
- static int
- i387_tag (const gdb_byte *raw)
- {
- int integer;
- unsigned int exponent;
- unsigned long fraction[2];
- integer = raw[7] & 0x80;
- exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
- fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
- fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
- | (raw[5] << 8) | raw[4]);
- if (exponent == 0x7fff)
- {
-
- return (2);
- }
- else if (exponent == 0x0000)
- {
- if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
- {
-
- return (1);
- }
- else
- {
-
- return (2);
- }
- }
- else
- {
- if (integer)
- {
-
- return (0);
- }
- else
- {
-
- return (2);
- }
- }
- }
- void
- i387_return_value (struct gdbarch *gdbarch, struct regcache *regcache)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- ULONGEST fstat;
-
- regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM (tdep), &fstat);
- fstat |= (7 << 11);
- regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM (tdep), fstat);
-
- regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM (tdep), 0x3fff);
- }