]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/i387-tdep.c
PR23141, SIGSEGV in bfd_elf_set_group_contents
[thirdparty/binutils-gdb.git] / gdb / i387-tdep.c
CommitLineData
c906108c 1/* Intel 387 floating point stuff.
38edeab8 2
e2882c85 3 Copyright (C) 1988-2018 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
c5aa993b 10 (at your option) any later version.
c906108c 11
c5aa993b
JM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
c906108c 16
c5aa993b 17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
19
20#include "defs.h"
21#include "frame.h"
786a90bb 22#include "gdbcore.h"
c906108c
SS
23#include "inferior.h"
24#include "language.h"
4e052eda 25#include "regcache.h"
f69fdf9b 26#include "target-float.h"
786a90bb
MK
27#include "value.h"
28
9a82579f 29#include "i386-tdep.h"
42c466d7 30#include "i387-tdep.h"
df7e5265 31#include "x86-xstate.h"
c906108c 32
de57eccd 33/* Print the floating point number specified by RAW. */
786a90bb 34
de57eccd 35static void
27067745
UW
36print_i387_value (struct gdbarch *gdbarch,
37 const gdb_byte *raw, struct ui_file *file)
de57eccd 38{
de57eccd
JM
39 /* We try to print 19 digits. The last digit may or may not contain
40 garbage, but we'd better print one too many. We need enough room
41 to print the value, 1 position for the sign, 1 for the decimal
42 point, 19 for the digits and 6 for the exponent adds up to 27. */
f69fdf9b
UW
43 const struct type *type = i387_ext_type (gdbarch);
44 std::string str = target_float_to_string (raw, type, " %-+27.19g");
8ba0dd51 45 fprintf_filtered (file, "%s", str.c_str ());
de57eccd
JM
46}
47
48/* Print the classification for the register contents RAW. */
786a90bb 49
de57eccd 50static void
27067745
UW
51print_i387_ext (struct gdbarch *gdbarch,
52 const gdb_byte *raw, struct ui_file *file)
de57eccd
JM
53{
54 int sign;
55 int integer;
56 unsigned int exponent;
57 unsigned long fraction[2];
58
59 sign = raw[9] & 0x80;
60 integer = raw[7] & 0x80;
61 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
62 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
63 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
64 | (raw[5] << 8) | raw[4]);
65
66 if (exponent == 0x7fff && integer)
67 {
68 if (fraction[0] == 0x00000000 && fraction[1] == 0x00000000)
69 /* Infinity. */
61113f8b 70 fprintf_filtered (file, " %cInf", (sign ? '-' : '+'));
de57eccd
JM
71 else if (sign && fraction[0] == 0x00000000 && fraction[1] == 0x40000000)
72 /* Real Indefinite (QNaN). */
61113f8b 73 fputs_unfiltered (" Real Indefinite (QNaN)", file);
de57eccd
JM
74 else if (fraction[1] & 0x40000000)
75 /* QNaN. */
61113f8b 76 fputs_filtered (" QNaN", file);
de57eccd
JM
77 else
78 /* SNaN. */
61113f8b 79 fputs_filtered (" SNaN", file);
de57eccd
JM
80 }
81 else if (exponent < 0x7fff && exponent > 0x0000 && integer)
82 /* Normal. */
27067745 83 print_i387_value (gdbarch, raw, file);
de57eccd
JM
84 else if (exponent == 0x0000)
85 {
86 /* Denormal or zero. */
27067745 87 print_i387_value (gdbarch, raw, file);
de57eccd
JM
88
89 if (integer)
90 /* Pseudo-denormal. */
61113f8b 91 fputs_filtered (" Pseudo-denormal", file);
de57eccd
JM
92 else if (fraction[0] || fraction[1])
93 /* Denormal. */
61113f8b 94 fputs_filtered (" Denormal", file);
de57eccd
JM
95 }
96 else
97 /* Unsupported. */
61113f8b 98 fputs_filtered (" Unsupported", file);
de57eccd
JM
99}
100
ad5f7d6e
PA
101/* Print the status word STATUS. If STATUS_P is false, then STATUS
102 was unavailable. */
786a90bb 103
de57eccd 104static void
ad5f7d6e
PA
105print_i387_status_word (int status_p,
106 unsigned int status, struct ui_file *file)
de57eccd 107{
ad5f7d6e
PA
108 fprintf_filtered (file, "Status Word: ");
109 if (!status_p)
110 {
111 fprintf_filtered (file, "%s\n", _("<unavailable>"));
112 return;
113 }
114
115 fprintf_filtered (file, "%s", hex_string_custom (status, 4));
61113f8b
MK
116 fputs_filtered (" ", file);
117 fprintf_filtered (file, " %s", (status & 0x0001) ? "IE" : " ");
118 fprintf_filtered (file, " %s", (status & 0x0002) ? "DE" : " ");
119 fprintf_filtered (file, " %s", (status & 0x0004) ? "ZE" : " ");
120 fprintf_filtered (file, " %s", (status & 0x0008) ? "OE" : " ");
121 fprintf_filtered (file, " %s", (status & 0x0010) ? "UE" : " ");
122 fprintf_filtered (file, " %s", (status & 0x0020) ? "PE" : " ");
123 fputs_filtered (" ", file);
124 fprintf_filtered (file, " %s", (status & 0x0080) ? "ES" : " ");
125 fputs_filtered (" ", file);
126 fprintf_filtered (file, " %s", (status & 0x0040) ? "SF" : " ");
127 fputs_filtered (" ", file);
128 fprintf_filtered (file, " %s", (status & 0x0100) ? "C0" : " ");
129 fprintf_filtered (file, " %s", (status & 0x0200) ? "C1" : " ");
130 fprintf_filtered (file, " %s", (status & 0x0400) ? "C2" : " ");
131 fprintf_filtered (file, " %s", (status & 0x4000) ? "C3" : " ");
132
133 fputs_filtered ("\n", file);
134
135 fprintf_filtered (file,
136 " TOP: %d\n", ((status >> 11) & 7));
de57eccd
JM
137}
138
ad5f7d6e
PA
139/* Print the control word CONTROL. If CONTROL_P is false, then
140 CONTROL was unavailable. */
786a90bb 141
de57eccd 142static void
ad5f7d6e
PA
143print_i387_control_word (int control_p,
144 unsigned int control, struct ui_file *file)
de57eccd 145{
ad5f7d6e
PA
146 fprintf_filtered (file, "Control Word: ");
147 if (!control_p)
148 {
149 fprintf_filtered (file, "%s\n", _("<unavailable>"));
150 return;
151 }
152
153 fprintf_filtered (file, "%s", hex_string_custom (control, 4));
61113f8b
MK
154 fputs_filtered (" ", file);
155 fprintf_filtered (file, " %s", (control & 0x0001) ? "IM" : " ");
156 fprintf_filtered (file, " %s", (control & 0x0002) ? "DM" : " ");
157 fprintf_filtered (file, " %s", (control & 0x0004) ? "ZM" : " ");
158 fprintf_filtered (file, " %s", (control & 0x0008) ? "OM" : " ");
159 fprintf_filtered (file, " %s", (control & 0x0010) ? "UM" : " ");
160 fprintf_filtered (file, " %s", (control & 0x0020) ? "PM" : " ");
de57eccd 161
61113f8b 162 fputs_filtered ("\n", file);
de57eccd 163
61113f8b 164 fputs_filtered (" PC: ", file);
de57eccd
JM
165 switch ((control >> 8) & 3)
166 {
167 case 0:
61113f8b 168 fputs_filtered ("Single Precision (24-bits)\n", file);
de57eccd
JM
169 break;
170 case 1:
61113f8b 171 fputs_filtered ("Reserved\n", file);
de57eccd
JM
172 break;
173 case 2:
61113f8b 174 fputs_filtered ("Double Precision (53-bits)\n", file);
de57eccd
JM
175 break;
176 case 3:
61113f8b 177 fputs_filtered ("Extended Precision (64-bits)\n", file);
de57eccd
JM
178 break;
179 }
180
61113f8b 181 fputs_filtered (" RC: ", file);
de57eccd
JM
182 switch ((control >> 10) & 3)
183 {
184 case 0:
61113f8b 185 fputs_filtered ("Round to nearest\n", file);
de57eccd
JM
186 break;
187 case 1:
61113f8b 188 fputs_filtered ("Round down\n", file);
de57eccd
JM
189 break;
190 case 2:
61113f8b 191 fputs_filtered ("Round up\n", file);
de57eccd
JM
192 break;
193 case 3:
61113f8b 194 fputs_filtered ("Round toward zero\n", file);
de57eccd
JM
195 break;
196 }
197}
198
9b949a49 199/* Print out the i387 floating point state. Note that we ignore FRAME
7d8d2918
MK
200 in the code below. That's OK since floating-point registers are
201 never saved on the stack. */
202
de57eccd 203void
61113f8b 204i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
8e186fd6 205 struct frame_info *frame, const char *args)
de57eccd 206{
5716833c 207 struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
1d70089a 208 ULONGEST fctrl;
ad5f7d6e 209 int fctrl_p;
1d70089a 210 ULONGEST fstat;
ad5f7d6e 211 int fstat_p;
1d70089a 212 ULONGEST ftag;
ad5f7d6e 213 int ftag_p;
1d70089a 214 ULONGEST fiseg;
ad5f7d6e 215 int fiseg_p;
1d70089a 216 ULONGEST fioff;
ad5f7d6e 217 int fioff_p;
1d70089a 218 ULONGEST foseg;
ad5f7d6e 219 int foseg_p;
1d70089a 220 ULONGEST fooff;
ad5f7d6e 221 int fooff_p;
1d70089a 222 ULONGEST fop;
ad5f7d6e 223 int fop_p;
de57eccd
JM
224 int fpreg;
225 int top;
226
5716833c
MK
227 gdb_assert (gdbarch == get_frame_arch (frame));
228
ad5f7d6e
PA
229 fctrl_p = read_frame_register_unsigned (frame,
230 I387_FCTRL_REGNUM (tdep), &fctrl);
231 fstat_p = read_frame_register_unsigned (frame,
232 I387_FSTAT_REGNUM (tdep), &fstat);
233 ftag_p = read_frame_register_unsigned (frame,
234 I387_FTAG_REGNUM (tdep), &ftag);
235 fiseg_p = read_frame_register_unsigned (frame,
236 I387_FISEG_REGNUM (tdep), &fiseg);
237 fioff_p = read_frame_register_unsigned (frame,
238 I387_FIOFF_REGNUM (tdep), &fioff);
239 foseg_p = read_frame_register_unsigned (frame,
240 I387_FOSEG_REGNUM (tdep), &foseg);
241 fooff_p = read_frame_register_unsigned (frame,
242 I387_FOOFF_REGNUM (tdep), &fooff);
243 fop_p = read_frame_register_unsigned (frame,
244 I387_FOP_REGNUM (tdep), &fop);
245
246 if (fstat_p)
de57eccd 247 {
ad5f7d6e 248 top = ((fstat >> 11) & 7);
de57eccd 249
ad5f7d6e 250 for (fpreg = 7; fpreg >= 0; fpreg--)
de57eccd 251 {
ad5f7d6e
PA
252 struct value *regval;
253 int regnum;
254 int i;
255 int tag = -1;
256
257 fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg);
258
259 if (ftag_p)
260 {
261 tag = (ftag >> (fpreg * 2)) & 3;
262
263 switch (tag)
264 {
265 case 0:
266 fputs_filtered ("Valid ", file);
267 break;
268 case 1:
269 fputs_filtered ("Zero ", file);
270 break;
271 case 2:
272 fputs_filtered ("Special ", file);
273 break;
274 case 3:
275 fputs_filtered ("Empty ", file);
276 break;
277 }
278 }
279 else
280 fputs_filtered ("Unknown ", file);
281
282 regnum = (fpreg + 8 - top) % 8 + I387_ST0_REGNUM (tdep);
283 regval = get_frame_register_value (frame, regnum);
284
285 if (value_entirely_available (regval))
286 {
433730c9 287 const gdb_byte *raw = value_contents (regval);
ad5f7d6e
PA
288
289 fputs_filtered ("0x", file);
290 for (i = 9; i >= 0; i--)
291 fprintf_filtered (file, "%02x", raw[i]);
292
293 if (tag != -1 && tag != 3)
294 print_i387_ext (gdbarch, raw, file);
295 }
296 else
297 fprintf_filtered (file, "%s", _("<unavailable>"));
298
299 fputs_filtered ("\n", file);
de57eccd 300 }
de57eccd
JM
301 }
302
f16a25ae 303 fputs_filtered ("\n", file);
ad5f7d6e
PA
304 print_i387_status_word (fstat_p, fstat, file);
305 print_i387_control_word (fctrl_p, fctrl, file);
61113f8b 306 fprintf_filtered (file, "Tag Word: %s\n",
ad5f7d6e 307 ftag_p ? hex_string_custom (ftag, 4) : _("<unavailable>"));
61113f8b 308 fprintf_filtered (file, "Instruction Pointer: %s:",
ad5f7d6e
PA
309 fiseg_p ? hex_string_custom (fiseg, 2) : _("<unavailable>"));
310 fprintf_filtered (file, "%s\n",
311 fioff_p ? hex_string_custom (fioff, 8) : _("<unavailable>"));
61113f8b 312 fprintf_filtered (file, "Operand Pointer: %s:",
ad5f7d6e
PA
313 foseg_p ? hex_string_custom (foseg, 2) : _("<unavailable>"));
314 fprintf_filtered (file, "%s\n",
315 fooff_p ? hex_string_custom (fooff, 8) : _("<unavailable>"));
61113f8b 316 fprintf_filtered (file, "Opcode: %s\n",
ad5f7d6e
PA
317 fop_p
318 ? (hex_string_custom (fop ? (fop | 0xd800) : 0, 4))
319 : _("<unavailable>"));
de57eccd 320}
d532c08f
MK
321\f
322
83acabca
DJ
323/* Return nonzero if a value of type TYPE stored in register REGNUM
324 needs any special handling. */
325
326int
1777feb0
MS
327i387_convert_register_p (struct gdbarch *gdbarch, int regnum,
328 struct type *type)
83acabca 329{
20a6ec49 330 if (i386_fp_regnum_p (gdbarch, regnum))
83acabca
DJ
331 {
332 /* Floating point registers must be converted unless we are
8c8f9122
YQ
333 accessing them in their hardware type or TYPE is not float. */
334 if (type == i387_ext_type (gdbarch)
335 || TYPE_CODE (type) != TYPE_CODE_FLT)
83acabca
DJ
336 return 0;
337 else
338 return 1;
339 }
340
341 return 0;
342}
343
d532c08f
MK
344/* Read a value of type TYPE from register REGNUM in frame FRAME, and
345 return its contents in TO. */
346
8dccd430 347int
d532c08f 348i387_register_to_value (struct frame_info *frame, int regnum,
8dccd430
PA
349 struct type *type, gdb_byte *to,
350 int *optimizedp, int *unavailablep)
d532c08f 351{
27067745 352 struct gdbarch *gdbarch = get_frame_arch (frame);
b4ad899f 353 gdb_byte from[I386_MAX_REGISTER_SIZE];
d532c08f 354
27067745 355 gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
d532c08f
MK
356
357 /* We only support floating-point values. */
358 if (TYPE_CODE (type) != TYPE_CODE_FLT)
359 {
8a3fe4f8
AC
360 warning (_("Cannot convert floating-point register value "
361 "to non-floating-point type."));
8dccd430
PA
362 *optimizedp = *unavailablep = 0;
363 return 0;
d532c08f
MK
364 }
365
83acabca 366 /* Convert to TYPE. */
d8e07dda
YQ
367 if (!get_frame_register_bytes (frame, regnum, 0,
368 register_size (gdbarch, regnum),
8dccd430
PA
369 from, optimizedp, unavailablep))
370 return 0;
371
3b2ca824 372 target_float_convert (from, i387_ext_type (gdbarch), to, type);
8dccd430
PA
373 *optimizedp = *unavailablep = 0;
374 return 1;
d532c08f
MK
375}
376
377/* Write the contents FROM of a value of type TYPE into register
378 REGNUM in frame FRAME. */
379
380void
381i387_value_to_register (struct frame_info *frame, int regnum,
42835c2b 382 struct type *type, const gdb_byte *from)
d532c08f 383{
27067745 384 struct gdbarch *gdbarch = get_frame_arch (frame);
b4ad899f 385 gdb_byte to[I386_MAX_REGISTER_SIZE];
d532c08f 386
27067745 387 gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
d532c08f
MK
388
389 /* We only support floating-point values. */
390 if (TYPE_CODE (type) != TYPE_CODE_FLT)
391 {
8a3fe4f8
AC
392 warning (_("Cannot convert non-floating-point type "
393 "to floating-point register value."));
d532c08f
MK
394 return;
395 }
396
83acabca 397 /* Convert from TYPE. */
3b2ca824 398 target_float_convert (from, type, to, i387_ext_type (gdbarch));
d532c08f
MK
399 put_frame_register (frame, regnum, to);
400}
401\f
e750d25e 402
786a90bb 403/* Handle FSAVE and FXSAVE formats. */
e750d25e
JT
404
405/* At fsave_offset[REGNUM] you'll find the offset to the location in
406 the data structure used by the "fsave" instruction where GDB
407 register REGNUM is stored. */
408
409static int fsave_offset[] =
410{
5716833c
MK
411 28 + 0 * 10, /* %st(0) ... */
412 28 + 1 * 10,
413 28 + 2 * 10,
414 28 + 3 * 10,
415 28 + 4 * 10,
416 28 + 5 * 10,
417 28 + 6 * 10,
418 28 + 7 * 10, /* ... %st(7). */
419 0, /* `fctrl' (16 bits). */
420 4, /* `fstat' (16 bits). */
421 8, /* `ftag' (16 bits). */
422 16, /* `fiseg' (16 bits). */
423 12, /* `fioff'. */
424 24, /* `foseg' (16 bits). */
425 20, /* `fooff'. */
426 18 /* `fop' (bottom 11 bits). */
e750d25e
JT
427};
428
20a6ec49
MD
429#define FSAVE_ADDR(tdep, fsave, regnum) \
430 (fsave + fsave_offset[regnum - I387_ST0_REGNUM (tdep)])
e750d25e
JT
431\f
432
41d041d6
MK
433/* Fill register REGNUM in REGCACHE with the appropriate value from
434 *FSAVE. This function masks off any of the reserved bits in
435 *FSAVE. */
e750d25e
JT
436
437void
41d041d6 438i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave)
e750d25e 439{
ac7936df 440 struct gdbarch *gdbarch = regcache->arch ();
e17a4113
UW
441 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
442 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
9a3c8263 443 const gdb_byte *regs = (const gdb_byte *) fsave;
e750d25e
JT
444 int i;
445
5716833c
MK
446 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
447
20a6ec49 448 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
ed504bdf
MK
449 if (regnum == -1 || regnum == i)
450 {
451 if (fsave == NULL)
452 {
5716833c
MK
453 regcache_raw_supply (regcache, i, NULL);
454 continue;
ed504bdf
MK
455 }
456
457 /* Most of the FPU control registers occupy only 16 bits in the
458 fsave area. Give those a special treatment. */
20a6ec49
MD
459 if (i >= I387_FCTRL_REGNUM (tdep)
460 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
ed504bdf 461 {
b4ad899f 462 gdb_byte val[4];
ed504bdf 463
20a6ec49 464 memcpy (val, FSAVE_ADDR (tdep, regs, i), 2);
ed504bdf 465 val[2] = val[3] = 0;
20a6ec49 466 if (i == I387_FOP_REGNUM (tdep))
ed504bdf 467 val[1] &= ((1 << 3) - 1);
5716833c 468 regcache_raw_supply (regcache, i, val);
ed504bdf
MK
469 }
470 else
20a6ec49 471 regcache_raw_supply (regcache, i, FSAVE_ADDR (tdep, regs, i));
ed504bdf 472 }
b87bc0d8
MK
473
474 /* Provide dummy values for the SSE registers. */
20a6ec49 475 for (i = I387_XMM0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
b87bc0d8
MK
476 if (regnum == -1 || regnum == i)
477 regcache_raw_supply (regcache, i, NULL);
20a6ec49 478 if (regnum == -1 || regnum == I387_MXCSR_REGNUM (tdep))
b87bc0d8 479 {
b4ad899f 480 gdb_byte buf[4];
b87bc0d8 481
e17a4113 482 store_unsigned_integer (buf, 4, byte_order, 0x1f80);
20a6ec49 483 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), buf);
b87bc0d8 484 }
e750d25e
JT
485}
486
487/* Fill register REGNUM (if it is a floating-point register) in *FSAVE
63b6c53f
MK
488 with the value from REGCACHE. If REGNUM is -1, do this for all
489 registers. This function doesn't touch any of the reserved bits in
490 *FSAVE. */
e750d25e
JT
491
492void
63b6c53f 493i387_collect_fsave (const struct regcache *regcache, int regnum, void *fsave)
e750d25e 494{
ac7936df 495 struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
9a3c8263 496 gdb_byte *regs = (gdb_byte *) fsave;
e750d25e
JT
497 int i;
498
5716833c
MK
499 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
500
20a6ec49 501 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
e750d25e
JT
502 if (regnum == -1 || regnum == i)
503 {
504 /* Most of the FPU control registers occupy only 16 bits in
505 the fsave area. Give those a special treatment. */
20a6ec49
MD
506 if (i >= I387_FCTRL_REGNUM (tdep)
507 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
e750d25e 508 {
b4ad899f 509 gdb_byte buf[4];
e750d25e 510
5716833c 511 regcache_raw_collect (regcache, i, buf);
e750d25e 512
20a6ec49 513 if (i == I387_FOP_REGNUM (tdep))
e750d25e
JT
514 {
515 /* The opcode occupies only 11 bits. Make sure we
516 don't touch the other bits. */
517 buf[1] &= ((1 << 3) - 1);
20a6ec49 518 buf[1] |= ((FSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
e750d25e 519 }
20a6ec49 520 memcpy (FSAVE_ADDR (tdep, regs, i), buf, 2);
e750d25e
JT
521 }
522 else
20a6ec49 523 regcache_raw_collect (regcache, i, FSAVE_ADDR (tdep, regs, i));
e750d25e
JT
524 }
525}
526\f
527
528/* At fxsave_offset[REGNUM] you'll find the offset to the location in
529 the data structure used by the "fxsave" instruction where GDB
530 register REGNUM is stored. */
531
532static int fxsave_offset[] =
533{
5716833c 534 32, /* %st(0) through ... */
e750d25e
JT
535 48,
536 64,
537 80,
538 96,
539 112,
540 128,
5716833c
MK
541 144, /* ... %st(7) (80 bits each). */
542 0, /* `fctrl' (16 bits). */
543 2, /* `fstat' (16 bits). */
544 4, /* `ftag' (16 bits). */
545 12, /* `fiseg' (16 bits). */
546 8, /* `fioff'. */
547 20, /* `foseg' (16 bits). */
548 16, /* `fooff'. */
549 6, /* `fop' (bottom 11 bits). */
550 160 + 0 * 16, /* %xmm0 through ... */
04c8243f
MK
551 160 + 1 * 16,
552 160 + 2 * 16,
553 160 + 3 * 16,
554 160 + 4 * 16,
555 160 + 5 * 16,
556 160 + 6 * 16,
557 160 + 7 * 16,
558 160 + 8 * 16,
559 160 + 9 * 16,
560 160 + 10 * 16,
561 160 + 11 * 16,
562 160 + 12 * 16,
563 160 + 13 * 16,
564 160 + 14 * 16,
5716833c 565 160 + 15 * 16, /* ... %xmm15 (128 bits each). */
e750d25e
JT
566};
567
20a6ec49
MD
568#define FXSAVE_ADDR(tdep, fxsave, regnum) \
569 (fxsave + fxsave_offset[regnum - I387_ST0_REGNUM (tdep)])
5716833c
MK
570
571/* We made an unfortunate choice in putting %mxcsr after the SSE
572 registers %xmm0-%xmm7 instead of before, since it makes supporting
573 the registers %xmm8-%xmm15 on AMD64 a bit involved. Therefore we
574 don't include the offset for %mxcsr here above. */
575
576#define FXSAVE_MXCSR_ADDR(fxsave) (fxsave + 24)
e750d25e 577
b4ad899f 578static int i387_tag (const gdb_byte *raw);
e750d25e
JT
579\f
580
41d041d6 581/* Fill register REGNUM in REGCACHE with the appropriate
ed504bdf
MK
582 floating-point or SSE register value from *FXSAVE. This function
583 masks off any of the reserved bits in *FXSAVE. */
e750d25e
JT
584
585void
41d041d6 586i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
e750d25e 587{
ac7936df 588 struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
9a3c8263 589 const gdb_byte *regs = (const gdb_byte *) fxsave;
5716833c
MK
590 int i;
591
592 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
593 gdb_assert (tdep->num_xmm_regs > 0);
dff95cc7 594
20a6ec49 595 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
ed504bdf
MK
596 if (regnum == -1 || regnum == i)
597 {
5716833c 598 if (regs == NULL)
ed504bdf 599 {
5716833c 600 regcache_raw_supply (regcache, i, NULL);
ed504bdf
MK
601 continue;
602 }
932bb524 603
ed504bdf
MK
604 /* Most of the FPU control registers occupy only 16 bits in
605 the fxsave area. Give those a special treatment. */
20a6ec49
MD
606 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
607 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
ed504bdf 608 {
b4ad899f 609 gdb_byte val[4];
ed504bdf 610
20a6ec49 611 memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
ed504bdf 612 val[2] = val[3] = 0;
20a6ec49 613 if (i == I387_FOP_REGNUM (tdep))
ed504bdf 614 val[1] &= ((1 << 3) - 1);
20a6ec49 615 else if (i== I387_FTAG_REGNUM (tdep))
ed504bdf
MK
616 {
617 /* The fxsave area contains a simplified version of
618 the tag word. We have to look at the actual 80-bit
619 FP data to recreate the traditional i387 tag word. */
620
621 unsigned long ftag = 0;
622 int fpreg;
623 int top;
624
20a6ec49
MD
625 top = ((FXSAVE_ADDR (tdep, regs,
626 I387_FSTAT_REGNUM (tdep)))[1] >> 3);
5716833c 627 top &= 0x7;
ed504bdf
MK
628
629 for (fpreg = 7; fpreg >= 0; fpreg--)
630 {
631 int tag;
632
633 if (val[0] & (1 << fpreg))
634 {
6d5e094a
MS
635 int thisreg = (fpreg + 8 - top) % 8
636 + I387_ST0_REGNUM (tdep);
637 tag = i387_tag (FXSAVE_ADDR (tdep, regs, thisreg));
ed504bdf
MK
638 }
639 else
640 tag = 3; /* Empty */
641
642 ftag |= tag << (2 * fpreg);
643 }
644 val[0] = ftag & 0xff;
645 val[1] = (ftag >> 8) & 0xff;
646 }
5716833c 647 regcache_raw_supply (regcache, i, val);
ed504bdf
MK
648 }
649 else
20a6ec49 650 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
ed504bdf 651 }
5716833c 652
20a6ec49 653 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
5716833c
MK
654 {
655 if (regs == NULL)
20a6ec49 656 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), NULL);
5716833c 657 else
20a6ec49 658 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep),
5716833c
MK
659 FXSAVE_MXCSR_ADDR (regs));
660 }
e750d25e
JT
661}
662
663/* Fill register REGNUM (if it is a floating-point or SSE register) in
80571bff
MK
664 *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for
665 all registers. This function doesn't touch any of the reserved
666 bits in *FXSAVE. */
e750d25e
JT
667
668void
80571bff 669i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave)
e750d25e 670{
ac7936df 671 struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
9a3c8263 672 gdb_byte *regs = (gdb_byte *) fxsave;
5716833c
MK
673 int i;
674
675 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
676 gdb_assert (tdep->num_xmm_regs > 0);
dff95cc7 677
20a6ec49 678 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
e750d25e
JT
679 if (regnum == -1 || regnum == i)
680 {
681 /* Most of the FPU control registers occupy only 16 bits in
682 the fxsave area. Give those a special treatment. */
20a6ec49
MD
683 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
684 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
e750d25e 685 {
b4ad899f 686 gdb_byte buf[4];
e750d25e 687
5716833c 688 regcache_raw_collect (regcache, i, buf);
e750d25e 689
31aeac78
L
690 if (i == I387_FOP_REGNUM (tdep))
691 {
692 /* The opcode occupies only 11 bits. Make sure we
693 don't touch the other bits. */
694 buf[1] &= ((1 << 3) - 1);
695 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
696 }
697 else if (i == I387_FTAG_REGNUM (tdep))
698 {
699 /* Converting back is much easier. */
700
701 unsigned short ftag;
702 int fpreg;
703
704 ftag = (buf[1] << 8) | buf[0];
705 buf[0] = 0;
706 buf[1] = 0;
707
708 for (fpreg = 7; fpreg >= 0; fpreg--)
709 {
710 int tag = (ftag >> (fpreg * 2)) & 3;
711
712 if (tag != 3)
713 buf[0] |= (1 << fpreg);
714 }
715 }
716 memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
717 }
718 else
719 regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
720 }
721
722 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
723 regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
724 FXSAVE_MXCSR_ADDR (regs));
725}
726
727/* `xstate_bv' is at byte offset 512. */
728#define XSAVE_XSTATE_BV_ADDR(xsave) (xsave + 512)
729
730/* At xsave_avxh_offset[REGNUM] you'll find the offset to the location in
731 the upper 128bit of AVX register data structure used by the "xsave"
732 instruction where GDB register REGNUM is stored. */
733
734static int xsave_avxh_offset[] =
735{
736 576 + 0 * 16, /* Upper 128bit of %ymm0 through ... */
737 576 + 1 * 16,
738 576 + 2 * 16,
739 576 + 3 * 16,
740 576 + 4 * 16,
741 576 + 5 * 16,
742 576 + 6 * 16,
743 576 + 7 * 16,
744 576 + 8 * 16,
745 576 + 9 * 16,
746 576 + 10 * 16,
747 576 + 11 * 16,
748 576 + 12 * 16,
749 576 + 13 * 16,
750 576 + 14 * 16,
751 576 + 15 * 16 /* Upper 128bit of ... %ymm15 (128 bits each). */
752};
753
01f9f808
MS
754#define XSAVE_AVXH_ADDR(tdep, xsave, regnum) \
755 (xsave + xsave_avxh_offset[regnum - I387_YMM0H_REGNUM (tdep)])
756
757/* At xsave_ymm_avx512_offset[REGNUM] you'll find the offset to the location in
758 the upper 128bit of ZMM register data structure used by the "xsave"
759 instruction where GDB register REGNUM is stored. */
760
761static int xsave_ymm_avx512_offset[] =
762{
763 /* HI16_ZMM_area + 16 bytes + regnum* 64 bytes. */
764 1664 + 16 + 0 * 64, /* %ymm16 through... */
765 1664 + 16 + 1 * 64,
766 1664 + 16 + 2 * 64,
767 1664 + 16 + 3 * 64,
768 1664 + 16 + 4 * 64,
769 1664 + 16 + 5 * 64,
770 1664 + 16 + 6 * 64,
771 1664 + 16 + 7 * 64,
772 1664 + 16 + 8 * 64,
773 1664 + 16 + 9 * 64,
774 1664 + 16 + 10 * 64,
775 1664 + 16 + 11 * 64,
776 1664 + 16 + 12 * 64,
777 1664 + 16 + 13 * 64,
778 1664 + 16 + 14 * 64,
779 1664 + 16 + 15 * 64 /* ... %ymm31 (128 bits each). */
780};
781
782#define XSAVE_YMM_AVX512_ADDR(tdep, xsave, regnum) \
783 (xsave + xsave_ymm_avx512_offset[regnum - I387_YMM16H_REGNUM (tdep)])
784
785static int xsave_xmm_avx512_offset[] =
1dbcd68c 786{
01f9f808
MS
787 1664 + 0 * 64, /* %ymm16 through... */
788 1664 + 1 * 64,
789 1664 + 2 * 64,
790 1664 + 3 * 64,
791 1664 + 4 * 64,
792 1664 + 5 * 64,
793 1664 + 6 * 64,
794 1664 + 7 * 64,
795 1664 + 8 * 64,
796 1664 + 9 * 64,
797 1664 + 10 * 64,
798 1664 + 11 * 64,
799 1664 + 12 * 64,
800 1664 + 13 * 64,
801 1664 + 14 * 64,
802 1664 + 15 * 64 /* ... %ymm31 (128 bits each). */
803};
804
805#define XSAVE_XMM_AVX512_ADDR(tdep, xsave, regnum) \
806 (xsave + xsave_xmm_avx512_offset[regnum - I387_XMM16_REGNUM (tdep)])
807
808static int xsave_mpx_offset[] = {
1dbcd68c
WT
809 960 + 0 * 16, /* bnd0r...bnd3r registers. */
810 960 + 1 * 16,
811 960 + 2 * 16,
812 960 + 3 * 16,
813 1024 + 0 * 8, /* bndcfg ... bndstatus. */
814 1024 + 1 * 8,
815};
816
1dbcd68c
WT
817#define XSAVE_MPX_ADDR(tdep, xsave, regnum) \
818 (xsave + xsave_mpx_offset[regnum - I387_BND0R_REGNUM (tdep)])
819
01f9f808
MS
820 /* At xsave_avx512__h_offset[REGNUM] you find the offset to the location
821 of the AVX512 opmask register data structure used by the "xsave"
822 instruction where GDB register REGNUM is stored. */
823
824static int xsave_avx512_k_offset[] =
825{
826 1088 + 0 * 8, /* %k0 through... */
827 1088 + 1 * 8,
828 1088 + 2 * 8,
829 1088 + 3 * 8,
830 1088 + 4 * 8,
831 1088 + 5 * 8,
832 1088 + 6 * 8,
833 1088 + 7 * 8 /* %k7 (64 bits each). */
834};
835
836#define XSAVE_AVX512_K_ADDR(tdep, xsave, regnum) \
837 (xsave + xsave_avx512_k_offset[regnum - I387_K0_REGNUM (tdep)])
838
839/* At xsave_avx512_zmm_h_offset[REGNUM] you find the offset to the location in
840 the upper 256bit of AVX512 ZMMH register data structure used by the "xsave"
841 instruction where GDB register REGNUM is stored. */
842
843static int xsave_avx512_zmm_h_offset[] =
844{
845 1152 + 0 * 32,
846 1152 + 1 * 32, /* Upper 256bit of %zmmh0 through... */
847 1152 + 2 * 32,
848 1152 + 3 * 32,
849 1152 + 4 * 32,
850 1152 + 5 * 32,
851 1152 + 6 * 32,
852 1152 + 7 * 32,
853 1152 + 8 * 32,
854 1152 + 9 * 32,
855 1152 + 10 * 32,
856 1152 + 11 * 32,
857 1152 + 12 * 32,
858 1152 + 13 * 32,
859 1152 + 14 * 32,
860 1152 + 15 * 32, /* Upper 256bit of... %zmmh15 (256 bits each). */
861 1664 + 32 + 0 * 64, /* Upper 256bit of... %zmmh16 (256 bits each). */
862 1664 + 32 + 1 * 64,
863 1664 + 32 + 2 * 64,
864 1664 + 32 + 3 * 64,
865 1664 + 32 + 4 * 64,
866 1664 + 32 + 5 * 64,
867 1664 + 32 + 6 * 64,
868 1664 + 32 + 7 * 64,
869 1664 + 32 + 8 * 64,
870 1664 + 32 + 9 * 64,
871 1664 + 32 + 10 * 64,
872 1664 + 32 + 11 * 64,
873 1664 + 32 + 12 * 64,
874 1664 + 32 + 13 * 64,
875 1664 + 32 + 14 * 64,
876 1664 + 32 + 15 * 64 /* Upper 256bit of... %zmmh31 (256 bits each). */
877};
878
879#define XSAVE_AVX512_ZMM_H_ADDR(tdep, xsave, regnum) \
880 (xsave + xsave_avx512_zmm_h_offset[regnum - I387_ZMM0H_REGNUM (tdep)])
881
51547df6
MS
882/* At xsave_pkeys_offset[REGNUM] you find the offset to the location
883 of the PKRU register data structure used by the "xsave"
884 instruction where GDB register REGNUM is stored. */
885
886static int xsave_pkeys_offset[] =
887{
8882688 + 0 * 8 /* %pkru (64 bits in XSTATE, 32-bit actually used by
889 instructions and applications). */
890};
891
892#define XSAVE_PKEYS_ADDR(tdep, xsave, regnum) \
893 (xsave + xsave_pkeys_offset[regnum - I387_PKRU_REGNUM (tdep)])
894
31aeac78
L
895/* Similar to i387_supply_fxsave, but use XSAVE extended state. */
896
897void
898i387_supply_xsave (struct regcache *regcache, int regnum,
899 const void *xsave)
900{
ac7936df 901 struct gdbarch *gdbarch = regcache->arch ();
01f9f808 902 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
9a3c8263 903 const gdb_byte *regs = (const gdb_byte *) xsave;
31aeac78 904 int i;
ff6527bb 905 ULONGEST clear_bv;
975c21ab 906 static const gdb_byte zero[I386_MAX_REGISTER_SIZE] = { 0 };
31aeac78
L
907 enum
908 {
909 none = 0x0,
910 x87 = 0x1,
911 sse = 0x2,
912 avxh = 0x4,
1dbcd68c 913 mpx = 0x8,
01f9f808
MS
914 avx512_k = 0x10,
915 avx512_zmm_h = 0x20,
916 avx512_ymmh_avx512 = 0x40,
917 avx512_xmm_avx512 = 0x80,
51547df6 918 pkeys = 0x100,
01f9f808 919 all = x87 | sse | avxh | mpx | avx512_k | avx512_zmm_h
51547df6 920 | avx512_ymmh_avx512 | avx512_xmm_avx512 | pkeys
31aeac78
L
921 } regclass;
922
275418ae 923 gdb_assert (regs != NULL);
31aeac78
L
924 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
925 gdb_assert (tdep->num_xmm_regs > 0);
926
927 if (regnum == -1)
928 regclass = all;
51547df6
MS
929 else if (regnum >= I387_PKRU_REGNUM (tdep)
930 && regnum < I387_PKEYSEND_REGNUM (tdep))
931 regclass = pkeys;
01f9f808
MS
932 else if (regnum >= I387_ZMM0H_REGNUM (tdep)
933 && regnum < I387_ZMMENDH_REGNUM (tdep))
934 regclass = avx512_zmm_h;
935 else if (regnum >= I387_K0_REGNUM (tdep)
936 && regnum < I387_KEND_REGNUM (tdep))
937 regclass = avx512_k;
938 else if (regnum >= I387_YMM16H_REGNUM (tdep)
939 && regnum < I387_YMMH_AVX512_END_REGNUM (tdep))
940 regclass = avx512_ymmh_avx512;
941 else if (regnum >= I387_XMM16_REGNUM (tdep)
942 && regnum < I387_XMM_AVX512_END_REGNUM (tdep))
943 regclass = avx512_xmm_avx512;
31aeac78
L
944 else if (regnum >= I387_YMM0H_REGNUM (tdep)
945 && regnum < I387_YMMENDH_REGNUM (tdep))
946 regclass = avxh;
1dbcd68c
WT
947 else if (regnum >= I387_BND0R_REGNUM (tdep)
948 && regnum < I387_MPXEND_REGNUM (tdep))
949 regclass = mpx;
01f9f808 950 else if (regnum >= I387_XMM0_REGNUM (tdep)
31aeac78
L
951 && regnum < I387_MXCSR_REGNUM (tdep))
952 regclass = sse;
953 else if (regnum >= I387_ST0_REGNUM (tdep)
954 && regnum < I387_FCTRL_REGNUM (tdep))
955 regclass = x87;
956 else
957 regclass = none;
958
275418ae 959 if (regclass != none)
31aeac78 960 {
ff6527bb
MS
961 /* Get `xstat_bv'. The supported bits in `xstat_bv' are 8 bytes. */
962 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
963 ULONGEST xstate_bv = 0;
31aeac78 964
ff6527bb
MS
965 xstate_bv = extract_unsigned_integer (XSAVE_XSTATE_BV_ADDR (regs),
966 8, byte_order);
967
968 /* Clear part in vector registers if its bit in xstat_bv is zero. */
969 clear_bv = (~(xstate_bv)) & tdep->xcr0;
31aeac78
L
970 }
971 else
df7e5265 972 clear_bv = X86_XSTATE_ALL_MASK;
31aeac78 973
b4d36fb8
PA
974 /* With the delayed xsave mechanism, in between the program
975 starting, and the program accessing the vector registers for the
976 first time, the register's values are invalid. The kernel
977 initializes register states to zero when they are set the first
978 time in a program. This means that from the user-space programs'
979 perspective, it's the same as if the registers have always been
980 zero from the start of the program. Therefore, the debugger
275418ae 981 should provide the same illusion to the user. */
b4d36fb8 982
31aeac78
L
983 switch (regclass)
984 {
985 case none:
986 break;
987
51547df6
MS
988 case pkeys:
989 if ((clear_bv & X86_XSTATE_PKRU))
990 regcache_raw_supply (regcache, regnum, zero);
991 else
992 regcache_raw_supply (regcache, regnum,
993 XSAVE_PKEYS_ADDR (tdep, regs, regnum));
994 return;
995
01f9f808 996 case avx512_zmm_h:
df7e5265 997 if ((clear_bv & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
01f9f808
MS
998 regcache_raw_supply (regcache, regnum, zero);
999 else
1000 regcache_raw_supply (regcache, regnum,
1001 XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, regnum));
1002 return;
1003
1004 case avx512_k:
df7e5265 1005 if ((clear_bv & X86_XSTATE_K))
01f9f808
MS
1006 regcache_raw_supply (regcache, regnum, zero);
1007 else
1008 regcache_raw_supply (regcache, regnum,
1009 XSAVE_AVX512_K_ADDR (tdep, regs, regnum));
1010 return;
1011
1012 case avx512_ymmh_avx512:
df7e5265 1013 if ((clear_bv & X86_XSTATE_ZMM))
01f9f808
MS
1014 regcache_raw_supply (regcache, regnum, zero);
1015 else
1016 regcache_raw_supply (regcache, regnum,
1017 XSAVE_YMM_AVX512_ADDR (tdep, regs, regnum));
1018 return;
1019
1020 case avx512_xmm_avx512:
df7e5265 1021 if ((clear_bv & X86_XSTATE_ZMM))
01f9f808
MS
1022 regcache_raw_supply (regcache, regnum, zero);
1023 else
1024 regcache_raw_supply (regcache, regnum,
1025 XSAVE_XMM_AVX512_ADDR (tdep, regs, regnum));
1026 return;
1027
31aeac78 1028 case avxh:
df7e5265 1029 if ((clear_bv & X86_XSTATE_AVX))
275418ae 1030 regcache_raw_supply (regcache, regnum, zero);
31aeac78 1031 else
b4d36fb8
PA
1032 regcache_raw_supply (regcache, regnum,
1033 XSAVE_AVXH_ADDR (tdep, regs, regnum));
31aeac78
L
1034 return;
1035
1dbcd68c 1036 case mpx:
df7e5265 1037 if ((clear_bv & X86_XSTATE_BNDREGS))
1dbcd68c
WT
1038 regcache_raw_supply (regcache, regnum, zero);
1039 else
1040 regcache_raw_supply (regcache, regnum,
1041 XSAVE_MPX_ADDR (tdep, regs, regnum));
1042 return;
1043
31aeac78 1044 case sse:
df7e5265 1045 if ((clear_bv & X86_XSTATE_SSE))
275418ae 1046 regcache_raw_supply (regcache, regnum, zero);
31aeac78 1047 else
b4d36fb8
PA
1048 regcache_raw_supply (regcache, regnum,
1049 FXSAVE_ADDR (tdep, regs, regnum));
31aeac78
L
1050 return;
1051
1052 case x87:
df7e5265 1053 if ((clear_bv & X86_XSTATE_X87))
275418ae 1054 regcache_raw_supply (regcache, regnum, zero);
31aeac78 1055 else
b4d36fb8
PA
1056 regcache_raw_supply (regcache, regnum,
1057 FXSAVE_ADDR (tdep, regs, regnum));
31aeac78
L
1058 return;
1059
1060 case all:
51547df6
MS
1061 /* Handle PKEYS registers. */
1062 if ((tdep->xcr0 & X86_XSTATE_PKRU))
1063 {
1064 if ((clear_bv & X86_XSTATE_PKRU))
1065 {
1066 for (i = I387_PKRU_REGNUM (tdep);
1067 i < I387_PKEYSEND_REGNUM (tdep);
1068 i++)
1069 regcache_raw_supply (regcache, i, zero);
1070 }
1071 else
1072 {
1073 for (i = I387_PKRU_REGNUM (tdep);
1074 i < I387_PKEYSEND_REGNUM (tdep);
1075 i++)
1076 regcache_raw_supply (regcache, i,
1077 XSAVE_PKEYS_ADDR (tdep, regs, i));
1078 }
1079 }
1080
01f9f808 1081 /* Handle the upper ZMM registers. */
df7e5265 1082 if ((tdep->xcr0 & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
01f9f808 1083 {
df7e5265 1084 if ((clear_bv & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
01f9f808
MS
1085 {
1086 for (i = I387_ZMM0H_REGNUM (tdep);
1087 i < I387_ZMMENDH_REGNUM (tdep);
1088 i++)
1089 regcache_raw_supply (regcache, i, zero);
1090 }
1091 else
1092 {
1093 for (i = I387_ZMM0H_REGNUM (tdep);
1094 i < I387_ZMMENDH_REGNUM (tdep);
1095 i++)
1096 regcache_raw_supply (regcache, i,
1097 XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i));
1098 }
1099 }
1100
1101 /* Handle AVX512 OpMask registers. */
df7e5265 1102 if ((tdep->xcr0 & X86_XSTATE_K))
01f9f808 1103 {
df7e5265 1104 if ((clear_bv & X86_XSTATE_K))
01f9f808
MS
1105 {
1106 for (i = I387_K0_REGNUM (tdep);
1107 i < I387_KEND_REGNUM (tdep);
1108 i++)
1109 regcache_raw_supply (regcache, i, zero);
1110 }
1111 else
1112 {
1113 for (i = I387_K0_REGNUM (tdep);
1114 i < I387_KEND_REGNUM (tdep);
1115 i++)
1116 regcache_raw_supply (regcache, i,
1117 XSAVE_AVX512_K_ADDR (tdep, regs, i));
1118 }
1119 }
1120
1121 /* Handle the YMM_AVX512 registers. */
df7e5265 1122 if ((tdep->xcr0 & X86_XSTATE_ZMM))
01f9f808 1123 {
df7e5265 1124 if ((clear_bv & X86_XSTATE_ZMM))
01f9f808
MS
1125 {
1126 for (i = I387_YMM16H_REGNUM (tdep);
1127 i < I387_YMMH_AVX512_END_REGNUM (tdep);
1128 i++)
1129 regcache_raw_supply (regcache, i, zero);
1130 for (i = I387_XMM16_REGNUM (tdep);
1131 i < I387_XMM_AVX512_END_REGNUM (tdep);
1132 i++)
1133 regcache_raw_supply (regcache, i, zero);
1134 }
1135 else
1136 {
1137 for (i = I387_YMM16H_REGNUM (tdep);
1138 i < I387_YMMH_AVX512_END_REGNUM (tdep);
1139 i++)
1140 regcache_raw_supply (regcache, i,
1141 XSAVE_YMM_AVX512_ADDR (tdep, regs, i));
1142 for (i = I387_XMM16_REGNUM (tdep);
1143 i < I387_XMM_AVX512_END_REGNUM (tdep);
1144 i++)
1145 regcache_raw_supply (regcache, i,
1146 XSAVE_XMM_AVX512_ADDR (tdep, regs, i));
1147 }
1148 }
86d31898 1149 /* Handle the upper YMM registers. */
df7e5265 1150 if ((tdep->xcr0 & X86_XSTATE_AVX))
31aeac78 1151 {
df7e5265 1152 if ((clear_bv & X86_XSTATE_AVX))
b4d36fb8
PA
1153 {
1154 for (i = I387_YMM0H_REGNUM (tdep);
1155 i < I387_YMMENDH_REGNUM (tdep);
1156 i++)
275418ae 1157 regcache_raw_supply (regcache, i, zero);
b4d36fb8 1158 }
31aeac78 1159 else
31aeac78 1160 {
b4d36fb8
PA
1161 for (i = I387_YMM0H_REGNUM (tdep);
1162 i < I387_YMMENDH_REGNUM (tdep);
1163 i++)
1164 regcache_raw_supply (regcache, i,
1165 XSAVE_AVXH_ADDR (tdep, regs, i));
31aeac78
L
1166 }
1167 }
1168
1dbcd68c 1169 /* Handle the MPX registers. */
df7e5265 1170 if ((tdep->xcr0 & X86_XSTATE_BNDREGS))
1dbcd68c 1171 {
df7e5265 1172 if (clear_bv & X86_XSTATE_BNDREGS)
1dbcd68c
WT
1173 {
1174 for (i = I387_BND0R_REGNUM (tdep);
1175 i < I387_BNDCFGU_REGNUM (tdep); i++)
1176 regcache_raw_supply (regcache, i, zero);
1177 }
1178 else
1179 {
1180 for (i = I387_BND0R_REGNUM (tdep);
1181 i < I387_BNDCFGU_REGNUM (tdep); i++)
1182 regcache_raw_supply (regcache, i,
1183 XSAVE_MPX_ADDR (tdep, regs, i));
1184 }
1185 }
1186
1187 /* Handle the MPX registers. */
df7e5265 1188 if ((tdep->xcr0 & X86_XSTATE_BNDCFG))
1dbcd68c 1189 {
df7e5265 1190 if (clear_bv & X86_XSTATE_BNDCFG)
1dbcd68c
WT
1191 {
1192 for (i = I387_BNDCFGU_REGNUM (tdep);
1193 i < I387_MPXEND_REGNUM (tdep); i++)
1194 regcache_raw_supply (regcache, i, zero);
1195 }
1196 else
1197 {
1198 for (i = I387_BNDCFGU_REGNUM (tdep);
1199 i < I387_MPXEND_REGNUM (tdep); i++)
1200 regcache_raw_supply (regcache, i,
1201 XSAVE_MPX_ADDR (tdep, regs, i));
1202 }
1203 }
1204
31aeac78 1205 /* Handle the XMM registers. */
df7e5265 1206 if ((tdep->xcr0 & X86_XSTATE_SSE))
31aeac78 1207 {
df7e5265 1208 if ((clear_bv & X86_XSTATE_SSE))
b4d36fb8
PA
1209 {
1210 for (i = I387_XMM0_REGNUM (tdep);
1211 i < I387_MXCSR_REGNUM (tdep);
1212 i++)
275418ae 1213 regcache_raw_supply (regcache, i, zero);
b4d36fb8 1214 }
31aeac78 1215 else
31aeac78 1216 {
b4d36fb8
PA
1217 for (i = I387_XMM0_REGNUM (tdep);
1218 i < I387_MXCSR_REGNUM (tdep); i++)
1219 regcache_raw_supply (regcache, i,
1220 FXSAVE_ADDR (tdep, regs, i));
31aeac78
L
1221 }
1222 }
1223
1224 /* Handle the x87 registers. */
df7e5265 1225 if ((tdep->xcr0 & X86_XSTATE_X87))
31aeac78 1226 {
df7e5265 1227 if ((clear_bv & X86_XSTATE_X87))
b4d36fb8
PA
1228 {
1229 for (i = I387_ST0_REGNUM (tdep);
1230 i < I387_FCTRL_REGNUM (tdep);
1231 i++)
275418ae 1232 regcache_raw_supply (regcache, i, zero);
b4d36fb8 1233 }
31aeac78 1234 else
31aeac78 1235 {
b4d36fb8
PA
1236 for (i = I387_ST0_REGNUM (tdep);
1237 i < I387_FCTRL_REGNUM (tdep);
1238 i++)
1239 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
31aeac78
L
1240 }
1241 }
1242 break;
1243 }
1244
1245 /* Only handle x87 control registers. */
1246 for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
1247 if (regnum == -1 || regnum == i)
1248 {
31aeac78
L
1249 /* Most of the FPU control registers occupy only 16 bits in
1250 the xsave extended state. Give those a special treatment. */
1251 if (i != I387_FIOFF_REGNUM (tdep)
1252 && i != I387_FOOFF_REGNUM (tdep))
1253 {
1254 gdb_byte val[4];
1255
1256 memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
1257 val[2] = val[3] = 0;
1258 if (i == I387_FOP_REGNUM (tdep))
1259 val[1] &= ((1 << 3) - 1);
1260 else if (i== I387_FTAG_REGNUM (tdep))
1261 {
1262 /* The fxsave area contains a simplified version of
1263 the tag word. We have to look at the actual 80-bit
1264 FP data to recreate the traditional i387 tag word. */
1265
1266 unsigned long ftag = 0;
1267 int fpreg;
1268 int top;
1269
1270 top = ((FXSAVE_ADDR (tdep, regs,
1271 I387_FSTAT_REGNUM (tdep)))[1] >> 3);
1272 top &= 0x7;
1273
1274 for (fpreg = 7; fpreg >= 0; fpreg--)
1275 {
1276 int tag;
1277
1278 if (val[0] & (1 << fpreg))
1279 {
e5b3d7d6 1280 int thisreg = (fpreg + 8 - top) % 8
31aeac78 1281 + I387_ST0_REGNUM (tdep);
e5b3d7d6 1282 tag = i387_tag (FXSAVE_ADDR (tdep, regs, thisreg));
31aeac78
L
1283 }
1284 else
1285 tag = 3; /* Empty */
1286
1287 ftag |= tag << (2 * fpreg);
1288 }
1289 val[0] = ftag & 0xff;
1290 val[1] = (ftag >> 8) & 0xff;
1291 }
1292 regcache_raw_supply (regcache, i, val);
1293 }
1294 else
1295 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
1296 }
1297
1298 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
275418ae
PA
1299 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep),
1300 FXSAVE_MXCSR_ADDR (regs));
31aeac78
L
1301}
1302
1303/* Similar to i387_collect_fxsave, but use XSAVE extended state. */
1304
1305void
1306i387_collect_xsave (const struct regcache *regcache, int regnum,
1307 void *xsave, int gcore)
1308{
ac7936df 1309 struct gdbarch *gdbarch = regcache->arch ();
01f9f808 1310 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
9a3c8263 1311 gdb_byte *regs = (gdb_byte *) xsave;
31aeac78
L
1312 int i;
1313 enum
1314 {
1315 none = 0x0,
1316 check = 0x1,
1317 x87 = 0x2 | check,
1318 sse = 0x4 | check,
1319 avxh = 0x8 | check,
1dbcd68c 1320 mpx = 0x10 | check,
01f9f808
MS
1321 avx512_k = 0x20 | check,
1322 avx512_zmm_h = 0x40 | check,
1323 avx512_ymmh_avx512 = 0x80 | check,
1324 avx512_xmm_avx512 = 0x100 | check,
51547df6 1325 pkeys = 0x200 | check,
01f9f808 1326 all = x87 | sse | avxh | mpx | avx512_k | avx512_zmm_h
51547df6 1327 | avx512_ymmh_avx512 | avx512_xmm_avx512 | pkeys
31aeac78
L
1328 } regclass;
1329
1330 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
1331 gdb_assert (tdep->num_xmm_regs > 0);
1332
1333 if (regnum == -1)
1334 regclass = all;
51547df6
MS
1335 else if (regnum >= I387_PKRU_REGNUM (tdep)
1336 && regnum < I387_PKEYSEND_REGNUM (tdep))
1337 regclass = pkeys;
01f9f808
MS
1338 else if (regnum >= I387_ZMM0H_REGNUM (tdep)
1339 && regnum < I387_ZMMENDH_REGNUM (tdep))
1340 regclass = avx512_zmm_h;
1341 else if (regnum >= I387_K0_REGNUM (tdep)
1342 && regnum < I387_KEND_REGNUM (tdep))
1343 regclass = avx512_k;
1344 else if (regnum >= I387_YMM16H_REGNUM (tdep)
1345 && regnum < I387_YMMH_AVX512_END_REGNUM (tdep))
1346 regclass = avx512_ymmh_avx512;
1347 else if (regnum >= I387_XMM16_REGNUM (tdep)
1348 && regnum < I387_XMM_AVX512_END_REGNUM (tdep))
1349 regclass = avx512_xmm_avx512;
31aeac78
L
1350 else if (regnum >= I387_YMM0H_REGNUM (tdep)
1351 && regnum < I387_YMMENDH_REGNUM (tdep))
1352 regclass = avxh;
1dbcd68c
WT
1353 else if (regnum >= I387_BND0R_REGNUM (tdep)
1354 && regnum < I387_MPXEND_REGNUM (tdep))
1355 regclass = mpx;
1356 else if (regnum >= I387_XMM0_REGNUM (tdep)
31aeac78
L
1357 && regnum < I387_MXCSR_REGNUM (tdep))
1358 regclass = sse;
1359 else if (regnum >= I387_ST0_REGNUM (tdep)
1360 && regnum < I387_FCTRL_REGNUM (tdep))
1361 regclass = x87;
1362 else
1363 regclass = none;
1364
1365 if (gcore)
1366 {
1367 /* Clear XSAVE extended state. */
df7e5265 1368 memset (regs, 0, X86_XSTATE_SIZE (tdep->xcr0));
31aeac78
L
1369
1370 /* Update XCR0 and `xstate_bv' with XCR0 for gcore. */
1371 if (tdep->xsave_xcr0_offset != -1)
1372 memcpy (regs + tdep->xsave_xcr0_offset, &tdep->xcr0, 8);
1373 memcpy (XSAVE_XSTATE_BV_ADDR (regs), &tdep->xcr0, 8);
1374 }
1375
1376 if ((regclass & check))
1377 {
1378 gdb_byte raw[I386_MAX_REGISTER_SIZE];
ff6527bb 1379 ULONGEST initial_xstate_bv, clear_bv, xstate_bv = 0;
31aeac78 1380 gdb_byte *p;
ff6527bb
MS
1381 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1382
1383 /* The supported bits in `xstat_bv' are 8 bytes. */
1384 initial_xstate_bv = extract_unsigned_integer (XSAVE_XSTATE_BV_ADDR (regs),
1385 8, byte_order);
1386 clear_bv = (~(initial_xstate_bv)) & tdep->xcr0;
31aeac78
L
1387
1388 /* Clear register set if its bit in xstat_bv is zero. */
1389 if (clear_bv)
1390 {
51547df6
MS
1391 if ((clear_bv & X86_XSTATE_PKRU))
1392 for (i = I387_PKRU_REGNUM (tdep);
1393 i < I387_PKEYSEND_REGNUM (tdep); i++)
1394 memset (XSAVE_PKEYS_ADDR (tdep, regs, i), 0, 4);
1395
df7e5265 1396 if ((clear_bv & X86_XSTATE_BNDREGS))
1dbcd68c
WT
1397 for (i = I387_BND0R_REGNUM (tdep);
1398 i < I387_BNDCFGU_REGNUM (tdep); i++)
1399 memset (XSAVE_MPX_ADDR (tdep, regs, i), 0, 16);
1400
df7e5265 1401 if ((clear_bv & X86_XSTATE_BNDCFG))
1dbcd68c
WT
1402 for (i = I387_BNDCFGU_REGNUM (tdep);
1403 i < I387_MPXEND_REGNUM (tdep); i++)
1404 memset (XSAVE_MPX_ADDR (tdep, regs, i), 0, 8);
1405
df7e5265 1406 if ((clear_bv & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
01f9f808
MS
1407 for (i = I387_ZMM0H_REGNUM (tdep);
1408 i < I387_ZMMENDH_REGNUM (tdep); i++)
1409 memset (XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i), 0, 32);
1410
df7e5265 1411 if ((clear_bv & X86_XSTATE_K))
01f9f808
MS
1412 for (i = I387_K0_REGNUM (tdep);
1413 i < I387_KEND_REGNUM (tdep); i++)
1414 memset (XSAVE_AVX512_K_ADDR (tdep, regs, i), 0, 8);
1415
df7e5265 1416 if ((clear_bv & X86_XSTATE_ZMM))
01f9f808
MS
1417 {
1418 for (i = I387_YMM16H_REGNUM (tdep);
1419 i < I387_YMMH_AVX512_END_REGNUM (tdep); i++)
1420 memset (XSAVE_YMM_AVX512_ADDR (tdep, regs, i), 0, 16);
1421 for (i = I387_XMM16_REGNUM (tdep);
1422 i < I387_XMM_AVX512_END_REGNUM (tdep); i++)
1423 memset (XSAVE_XMM_AVX512_ADDR (tdep, regs, i), 0, 16);
1424 }
1425
df7e5265 1426 if ((clear_bv & X86_XSTATE_AVX))
31aeac78
L
1427 for (i = I387_YMM0H_REGNUM (tdep);
1428 i < I387_YMMENDH_REGNUM (tdep); i++)
1429 memset (XSAVE_AVXH_ADDR (tdep, regs, i), 0, 16);
1430
df7e5265 1431 if ((clear_bv & X86_XSTATE_SSE))
31aeac78
L
1432 for (i = I387_XMM0_REGNUM (tdep);
1433 i < I387_MXCSR_REGNUM (tdep); i++)
1434 memset (FXSAVE_ADDR (tdep, regs, i), 0, 16);
1435
df7e5265 1436 if ((clear_bv & X86_XSTATE_X87))
31aeac78
L
1437 for (i = I387_ST0_REGNUM (tdep);
1438 i < I387_FCTRL_REGNUM (tdep); i++)
1439 memset (FXSAVE_ADDR (tdep, regs, i), 0, 10);
1440 }
1441
1442 if (regclass == all)
1443 {
51547df6
MS
1444 /* Check if any PKEYS registers are changed. */
1445 if ((tdep->xcr0 & X86_XSTATE_PKRU))
1446 for (i = I387_PKRU_REGNUM (tdep);
1447 i < I387_PKEYSEND_REGNUM (tdep); i++)
1448 {
1449 regcache_raw_collect (regcache, i, raw);
1450 p = XSAVE_PKEYS_ADDR (tdep, regs, i);
1451 if (memcmp (raw, p, 4) != 0)
1452 {
1453 xstate_bv |= X86_XSTATE_PKRU;
1454 memcpy (p, raw, 4);
1455 }
1456 }
1457
01f9f808 1458 /* Check if any ZMMH registers are changed. */
df7e5265 1459 if ((tdep->xcr0 & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
01f9f808
MS
1460 for (i = I387_ZMM0H_REGNUM (tdep);
1461 i < I387_ZMMENDH_REGNUM (tdep); i++)
1462 {
1463 regcache_raw_collect (regcache, i, raw);
1464 p = XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i);
1465 if (memcmp (raw, p, 32) != 0)
1466 {
df7e5265 1467 xstate_bv |= (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM);
01f9f808
MS
1468 memcpy (p, raw, 32);
1469 }
1470 }
1471
1472 /* Check if any K registers are changed. */
df7e5265 1473 if ((tdep->xcr0 & X86_XSTATE_K))
01f9f808
MS
1474 for (i = I387_K0_REGNUM (tdep);
1475 i < I387_KEND_REGNUM (tdep); i++)
1476 {
1477 regcache_raw_collect (regcache, i, raw);
1478 p = XSAVE_AVX512_K_ADDR (tdep, regs, i);
1479 if (memcmp (raw, p, 8) != 0)
1480 {
df7e5265 1481 xstate_bv |= X86_XSTATE_K;
01f9f808
MS
1482 memcpy (p, raw, 8);
1483 }
1484 }
1485
1486 /* Check if any XMM or upper YMM registers are changed. */
df7e5265 1487 if ((tdep->xcr0 & X86_XSTATE_ZMM))
01f9f808
MS
1488 {
1489 for (i = I387_YMM16H_REGNUM (tdep);
1490 i < I387_YMMH_AVX512_END_REGNUM (tdep); i++)
1491 {
1492 regcache_raw_collect (regcache, i, raw);
1493 p = XSAVE_YMM_AVX512_ADDR (tdep, regs, i);
1494 if (memcmp (raw, p, 16) != 0)
1495 {
df7e5265 1496 xstate_bv |= X86_XSTATE_ZMM;
01f9f808
MS
1497 memcpy (p, raw, 16);
1498 }
1499 }
1500 for (i = I387_XMM16_REGNUM (tdep);
1501 i < I387_XMM_AVX512_END_REGNUM (tdep); i++)
1502 {
1503 regcache_raw_collect (regcache, i, raw);
1504 p = XSAVE_XMM_AVX512_ADDR (tdep, regs, i);
1505 if (memcmp (raw, p, 16) != 0)
1506 {
df7e5265 1507 xstate_bv |= X86_XSTATE_ZMM;
01f9f808
MS
1508 memcpy (p, raw, 16);
1509 }
1510 }
1511 }
1512
31aeac78 1513 /* Check if any upper YMM registers are changed. */
df7e5265 1514 if ((tdep->xcr0 & X86_XSTATE_AVX))
31aeac78
L
1515 for (i = I387_YMM0H_REGNUM (tdep);
1516 i < I387_YMMENDH_REGNUM (tdep); i++)
1517 {
1518 regcache_raw_collect (regcache, i, raw);
1519 p = XSAVE_AVXH_ADDR (tdep, regs, i);
1520 if (memcmp (raw, p, 16))
1521 {
df7e5265 1522 xstate_bv |= X86_XSTATE_AVX;
31aeac78
L
1523 memcpy (p, raw, 16);
1524 }
1525 }
1dbcd68c 1526 /* Check if any upper MPX registers are changed. */
df7e5265 1527 if ((tdep->xcr0 & X86_XSTATE_BNDREGS))
1dbcd68c
WT
1528 for (i = I387_BND0R_REGNUM (tdep);
1529 i < I387_BNDCFGU_REGNUM (tdep); i++)
1530 {
1531 regcache_raw_collect (regcache, i, raw);
1532 p = XSAVE_MPX_ADDR (tdep, regs, i);
1533 if (memcmp (raw, p, 16))
1534 {
df7e5265 1535 xstate_bv |= X86_XSTATE_BNDREGS;
1dbcd68c
WT
1536 memcpy (p, raw, 16);
1537 }
1538 }
1539
1540 /* Check if any upper MPX registers are changed. */
df7e5265 1541 if ((tdep->xcr0 & X86_XSTATE_BNDCFG))
1dbcd68c
WT
1542 for (i = I387_BNDCFGU_REGNUM (tdep);
1543 i < I387_MPXEND_REGNUM (tdep); i++)
1544 {
1545 regcache_raw_collect (regcache, i, raw);
1546 p = XSAVE_MPX_ADDR (tdep, regs, i);
1547 if (memcmp (raw, p, 8))
1548 {
df7e5265 1549 xstate_bv |= X86_XSTATE_BNDCFG;
1dbcd68c
WT
1550 memcpy (p, raw, 8);
1551 }
1552 }
31aeac78
L
1553
1554 /* Check if any SSE registers are changed. */
df7e5265 1555 if ((tdep->xcr0 & X86_XSTATE_SSE))
31aeac78
L
1556 for (i = I387_XMM0_REGNUM (tdep);
1557 i < I387_MXCSR_REGNUM (tdep); i++)
1558 {
1559 regcache_raw_collect (regcache, i, raw);
1560 p = FXSAVE_ADDR (tdep, regs, i);
1561 if (memcmp (raw, p, 16))
1562 {
df7e5265 1563 xstate_bv |= X86_XSTATE_SSE;
31aeac78
L
1564 memcpy (p, raw, 16);
1565 }
1566 }
1567
1568 /* Check if any X87 registers are changed. */
df7e5265 1569 if ((tdep->xcr0 & X86_XSTATE_X87))
31aeac78
L
1570 for (i = I387_ST0_REGNUM (tdep);
1571 i < I387_FCTRL_REGNUM (tdep); i++)
1572 {
1573 regcache_raw_collect (regcache, i, raw);
1574 p = FXSAVE_ADDR (tdep, regs, i);
1575 if (memcmp (raw, p, 10))
1576 {
df7e5265 1577 xstate_bv |= X86_XSTATE_X87;
31aeac78
L
1578 memcpy (p, raw, 10);
1579 }
1580 }
1581 }
1582 else
1583 {
1584 /* Check if REGNUM is changed. */
1585 regcache_raw_collect (regcache, regnum, raw);
1586
1587 switch (regclass)
1588 {
1589 default:
4e4d8374
L
1590 internal_error (__FILE__, __LINE__,
1591 _("invalid i387 regclass"));
31aeac78 1592
51547df6
MS
1593 case pkeys:
1594 /* This is a PKEYS register. */
1595 p = XSAVE_PKEYS_ADDR (tdep, regs, regnum);
1596 if (memcmp (raw, p, 4) != 0)
1597 {
1598 xstate_bv |= X86_XSTATE_PKRU;
1599 memcpy (p, raw, 4);
1600 }
1601 break;
1602
01f9f808
MS
1603 case avx512_zmm_h:
1604 /* This is a ZMM register. */
1605 p = XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, regnum);
1606 if (memcmp (raw, p, 32) != 0)
1607 {
df7e5265 1608 xstate_bv |= (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM);
01f9f808
MS
1609 memcpy (p, raw, 32);
1610 }
1611 break;
1612 case avx512_k:
1613 /* This is a AVX512 mask register. */
1614 p = XSAVE_AVX512_K_ADDR (tdep, regs, regnum);
1615 if (memcmp (raw, p, 8) != 0)
1616 {
df7e5265 1617 xstate_bv |= X86_XSTATE_K;
01f9f808
MS
1618 memcpy (p, raw, 8);
1619 }
1620 break;
1621
1622 case avx512_ymmh_avx512:
1623 /* This is an upper YMM16-31 register. */
1624 p = XSAVE_YMM_AVX512_ADDR (tdep, regs, regnum);
1625 if (memcmp (raw, p, 16) != 0)
1626 {
df7e5265 1627 xstate_bv |= X86_XSTATE_ZMM;
01f9f808
MS
1628 memcpy (p, raw, 16);
1629 }
1630 break;
1631
1632 case avx512_xmm_avx512:
1633 /* This is an upper XMM16-31 register. */
1634 p = XSAVE_XMM_AVX512_ADDR (tdep, regs, regnum);
1635 if (memcmp (raw, p, 16) != 0)
1636 {
df7e5265 1637 xstate_bv |= X86_XSTATE_ZMM;
01f9f808
MS
1638 memcpy (p, raw, 16);
1639 }
1640 break;
1641
40936b0d
L
1642 case avxh:
1643 /* This is an upper YMM register. */
1644 p = XSAVE_AVXH_ADDR (tdep, regs, regnum);
1645 if (memcmp (raw, p, 16))
31aeac78 1646 {
df7e5265 1647 xstate_bv |= X86_XSTATE_AVX;
40936b0d
L
1648 memcpy (p, raw, 16);
1649 }
1650 break;
31aeac78 1651
1dbcd68c
WT
1652 case mpx:
1653 if (regnum < I387_BNDCFGU_REGNUM (tdep))
1654 {
1655 regcache_raw_collect (regcache, regnum, raw);
1656 p = XSAVE_MPX_ADDR (tdep, regs, regnum);
1657 if (memcmp (raw, p, 16))
1658 {
df7e5265 1659 xstate_bv |= X86_XSTATE_BNDREGS;
1dbcd68c
WT
1660 memcpy (p, raw, 16);
1661 }
1662 }
1663 else
1664 {
1665 p = XSAVE_MPX_ADDR (tdep, regs, regnum);
df7e5265 1666 xstate_bv |= X86_XSTATE_BNDCFG;
1dbcd68c
WT
1667 memcpy (p, raw, 8);
1668 }
1669 break;
1670
40936b0d
L
1671 case sse:
1672 /* This is an SSE register. */
1673 p = FXSAVE_ADDR (tdep, regs, regnum);
1674 if (memcmp (raw, p, 16))
1675 {
df7e5265 1676 xstate_bv |= X86_XSTATE_SSE;
40936b0d
L
1677 memcpy (p, raw, 16);
1678 }
1679 break;
31aeac78 1680
40936b0d
L
1681 case x87:
1682 /* This is an x87 register. */
1683 p = FXSAVE_ADDR (tdep, regs, regnum);
1684 if (memcmp (raw, p, 10))
1685 {
df7e5265 1686 xstate_bv |= X86_XSTATE_X87;
40936b0d 1687 memcpy (p, raw, 10);
31aeac78 1688 }
40936b0d 1689 break;
31aeac78 1690 }
40936b0d
L
1691 }
1692
1693 /* Update the corresponding bits in `xstate_bv' if any SSE/AVX
1694 registers are changed. */
1695 if (xstate_bv)
1696 {
ff6527bb
MS
1697 /* The supported bits in `xstat_bv' are 8 bytes. */
1698 initial_xstate_bv |= xstate_bv;
1699 store_unsigned_integer (XSAVE_XSTATE_BV_ADDR (regs),
1700 8, byte_order,
1701 initial_xstate_bv);
40936b0d
L
1702
1703 switch (regclass)
31aeac78 1704 {
40936b0d 1705 default:
4e4d8374
L
1706 internal_error (__FILE__, __LINE__,
1707 _("invalid i387 regclass"));
40936b0d
L
1708
1709 case all:
1710 break;
1711
1712 case x87:
1713 case sse:
1714 case avxh:
1dbcd68c 1715 case mpx:
01f9f808
MS
1716 case avx512_k:
1717 case avx512_zmm_h:
1718 case avx512_ymmh_avx512:
1719 case avx512_xmm_avx512:
51547df6 1720 case pkeys:
40936b0d
L
1721 /* Register REGNUM has been updated. Return. */
1722 return;
31aeac78 1723 }
40936b0d
L
1724 }
1725 else
1726 {
1727 /* Return if REGNUM isn't changed. */
1728 if (regclass != all)
1729 return;
1730 }
31aeac78
L
1731 }
1732
1733 /* Only handle x87 control registers. */
1734 for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
1735 if (regnum == -1 || regnum == i)
1736 {
1737 /* Most of the FPU control registers occupy only 16 bits in
1738 the xsave extended state. Give those a special treatment. */
1739 if (i != I387_FIOFF_REGNUM (tdep)
1740 && i != I387_FOOFF_REGNUM (tdep))
1741 {
1742 gdb_byte buf[4];
1743
1744 regcache_raw_collect (regcache, i, buf);
1745
20a6ec49 1746 if (i == I387_FOP_REGNUM (tdep))
e750d25e
JT
1747 {
1748 /* The opcode occupies only 11 bits. Make sure we
40936b0d 1749 don't touch the other bits. */
e750d25e 1750 buf[1] &= ((1 << 3) - 1);
20a6ec49 1751 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
e750d25e 1752 }
20a6ec49 1753 else if (i == I387_FTAG_REGNUM (tdep))
e750d25e
JT
1754 {
1755 /* Converting back is much easier. */
1756
1757 unsigned short ftag;
1758 int fpreg;
1759
1760 ftag = (buf[1] << 8) | buf[0];
1761 buf[0] = 0;
1762 buf[1] = 0;
1763
1764 for (fpreg = 7; fpreg >= 0; fpreg--)
1765 {
1766 int tag = (ftag >> (fpreg * 2)) & 3;
1767
1768 if (tag != 3)
1769 buf[0] |= (1 << fpreg);
1770 }
1771 }
20a6ec49 1772 memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
e750d25e
JT
1773 }
1774 else
20a6ec49 1775 regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
e750d25e 1776 }
5716833c 1777
20a6ec49
MD
1778 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
1779 regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
5716833c 1780 FXSAVE_MXCSR_ADDR (regs));
e750d25e
JT
1781}
1782
1783/* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
1784 *RAW. */
1785
1786static int
b4ad899f 1787i387_tag (const gdb_byte *raw)
e750d25e
JT
1788{
1789 int integer;
1790 unsigned int exponent;
1791 unsigned long fraction[2];
1792
1793 integer = raw[7] & 0x80;
1794 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
1795 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
1796 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
1797 | (raw[5] << 8) | raw[4]);
1798
1799 if (exponent == 0x7fff)
1800 {
1801 /* Special. */
1802 return (2);
1803 }
1804 else if (exponent == 0x0000)
1805 {
1806 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
1807 {
1808 /* Zero. */
1809 return (1);
1810 }
1811 else
1812 {
1813 /* Special. */
1814 return (2);
1815 }
1816 }
1817 else
1818 {
1819 if (integer)
1820 {
1821 /* Valid. */
1822 return (0);
1823 }
1824 else
1825 {
1826 /* Special. */
1827 return (2);
1828 }
1829 }
1830}
efb1c01c
MK
1831
1832/* Prepare the FPU stack in REGCACHE for a function return. */
1833
1834void
1835i387_return_value (struct gdbarch *gdbarch, struct regcache *regcache)
1836{
1837 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1838 ULONGEST fstat;
1839
efb1c01c
MK
1840 /* Set the top of the floating-point register stack to 7. The
1841 actual value doesn't really matter, but 7 is what a normal
1842 function return would end up with if the program started out with
1843 a freshly initialized FPU. */
20a6ec49 1844 regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM (tdep), &fstat);
efb1c01c 1845 fstat |= (7 << 11);
20a6ec49 1846 regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM (tdep), fstat);
efb1c01c
MK
1847
1848 /* Mark %st(1) through %st(7) as empty. Since we set the top of the
1849 floating-point register stack to 7, the appropriate value for the
1850 tag word is 0x3fff. */
20a6ec49 1851 regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM (tdep), 0x3fff);
efb1c01c 1852
efb1c01c 1853}
4a612d6f
WT
1854
1855/* See i387-tdep.h. */
1856
1857void
1858i387_reset_bnd_regs (struct gdbarch *gdbarch, struct regcache *regcache)
1859{
1860 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1861
1862 if (I387_BND0R_REGNUM (tdep) > 0)
1863 {
1864 gdb_byte bnd_buf[16];
1865
1866 memset (bnd_buf, 0, 16);
1867 for (int i = 0; i < I387_NUM_BND_REGS; i++)
1868 regcache_raw_write (regcache, I387_BND0R_REGNUM (tdep) + i, bnd_buf);
1869 }
1870}