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