Tidy up readelf's use of boolean values.
[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
344 accessing them in their hardware type. */
27067745 345 if (type == i387_ext_type (gdbarch))
83acabca
DJ
346 return 0;
347 else
348 return 1;
349 }
350
351 return 0;
352}
353
d532c08f
MK
354/* Read a value of type TYPE from register REGNUM in frame FRAME, and
355 return its contents in TO. */
356
8dccd430 357int
d532c08f 358i387_register_to_value (struct frame_info *frame, int regnum,
8dccd430
PA
359 struct type *type, gdb_byte *to,
360 int *optimizedp, int *unavailablep)
d532c08f 361{
27067745 362 struct gdbarch *gdbarch = get_frame_arch (frame);
b4ad899f 363 gdb_byte from[I386_MAX_REGISTER_SIZE];
d532c08f 364
27067745 365 gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
d532c08f
MK
366
367 /* We only support floating-point values. */
368 if (TYPE_CODE (type) != TYPE_CODE_FLT)
369 {
8a3fe4f8
AC
370 warning (_("Cannot convert floating-point register value "
371 "to non-floating-point type."));
8dccd430
PA
372 *optimizedp = *unavailablep = 0;
373 return 0;
d532c08f
MK
374 }
375
83acabca 376 /* Convert to TYPE. */
8dccd430
PA
377 if (!get_frame_register_bytes (frame, regnum, 0, TYPE_LENGTH (type),
378 from, optimizedp, unavailablep))
379 return 0;
380
27067745 381 convert_typed_floating (from, i387_ext_type (gdbarch), to, type);
8dccd430
PA
382 *optimizedp = *unavailablep = 0;
383 return 1;
d532c08f
MK
384}
385
386/* Write the contents FROM of a value of type TYPE into register
387 REGNUM in frame FRAME. */
388
389void
390i387_value_to_register (struct frame_info *frame, int regnum,
42835c2b 391 struct type *type, const gdb_byte *from)
d532c08f 392{
27067745 393 struct gdbarch *gdbarch = get_frame_arch (frame);
b4ad899f 394 gdb_byte to[I386_MAX_REGISTER_SIZE];
d532c08f 395
27067745 396 gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
d532c08f
MK
397
398 /* We only support floating-point values. */
399 if (TYPE_CODE (type) != TYPE_CODE_FLT)
400 {
8a3fe4f8
AC
401 warning (_("Cannot convert non-floating-point type "
402 "to floating-point register value."));
d532c08f
MK
403 return;
404 }
405
83acabca 406 /* Convert from TYPE. */
27067745 407 convert_typed_floating (from, type, to, i387_ext_type (gdbarch));
d532c08f
MK
408 put_frame_register (frame, regnum, to);
409}
410\f
e750d25e 411
786a90bb 412/* Handle FSAVE and FXSAVE formats. */
e750d25e
JT
413
414/* At fsave_offset[REGNUM] you'll find the offset to the location in
415 the data structure used by the "fsave" instruction where GDB
416 register REGNUM is stored. */
417
418static int fsave_offset[] =
419{
5716833c
MK
420 28 + 0 * 10, /* %st(0) ... */
421 28 + 1 * 10,
422 28 + 2 * 10,
423 28 + 3 * 10,
424 28 + 4 * 10,
425 28 + 5 * 10,
426 28 + 6 * 10,
427 28 + 7 * 10, /* ... %st(7). */
428 0, /* `fctrl' (16 bits). */
429 4, /* `fstat' (16 bits). */
430 8, /* `ftag' (16 bits). */
431 16, /* `fiseg' (16 bits). */
432 12, /* `fioff'. */
433 24, /* `foseg' (16 bits). */
434 20, /* `fooff'. */
435 18 /* `fop' (bottom 11 bits). */
e750d25e
JT
436};
437
20a6ec49
MD
438#define FSAVE_ADDR(tdep, fsave, regnum) \
439 (fsave + fsave_offset[regnum - I387_ST0_REGNUM (tdep)])
e750d25e
JT
440\f
441
41d041d6
MK
442/* Fill register REGNUM in REGCACHE with the appropriate value from
443 *FSAVE. This function masks off any of the reserved bits in
444 *FSAVE. */
e750d25e
JT
445
446void
41d041d6 447i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave)
e750d25e 448{
e17a4113
UW
449 struct gdbarch *gdbarch = get_regcache_arch (regcache);
450 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
451 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
9a3c8263 452 const gdb_byte *regs = (const gdb_byte *) fsave;
e750d25e
JT
453 int i;
454
5716833c
MK
455 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
456
20a6ec49 457 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
ed504bdf
MK
458 if (regnum == -1 || regnum == i)
459 {
460 if (fsave == NULL)
461 {
5716833c
MK
462 regcache_raw_supply (regcache, i, NULL);
463 continue;
ed504bdf
MK
464 }
465
466 /* Most of the FPU control registers occupy only 16 bits in the
467 fsave area. Give those a special treatment. */
20a6ec49
MD
468 if (i >= I387_FCTRL_REGNUM (tdep)
469 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
ed504bdf 470 {
b4ad899f 471 gdb_byte val[4];
ed504bdf 472
20a6ec49 473 memcpy (val, FSAVE_ADDR (tdep, regs, i), 2);
ed504bdf 474 val[2] = val[3] = 0;
20a6ec49 475 if (i == I387_FOP_REGNUM (tdep))
ed504bdf 476 val[1] &= ((1 << 3) - 1);
5716833c 477 regcache_raw_supply (regcache, i, val);
ed504bdf
MK
478 }
479 else
20a6ec49 480 regcache_raw_supply (regcache, i, FSAVE_ADDR (tdep, regs, i));
ed504bdf 481 }
b87bc0d8
MK
482
483 /* Provide dummy values for the SSE registers. */
20a6ec49 484 for (i = I387_XMM0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
b87bc0d8
MK
485 if (regnum == -1 || regnum == i)
486 regcache_raw_supply (regcache, i, NULL);
20a6ec49 487 if (regnum == -1 || regnum == I387_MXCSR_REGNUM (tdep))
b87bc0d8 488 {
b4ad899f 489 gdb_byte buf[4];
b87bc0d8 490
e17a4113 491 store_unsigned_integer (buf, 4, byte_order, 0x1f80);
20a6ec49 492 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), buf);
b87bc0d8 493 }
e750d25e
JT
494}
495
496/* Fill register REGNUM (if it is a floating-point register) in *FSAVE
63b6c53f
MK
497 with the value from REGCACHE. If REGNUM is -1, do this for all
498 registers. This function doesn't touch any of the reserved bits in
499 *FSAVE. */
e750d25e
JT
500
501void
63b6c53f 502i387_collect_fsave (const struct regcache *regcache, int regnum, void *fsave)
e750d25e 503{
e071d1f6 504 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
9a3c8263 505 gdb_byte *regs = (gdb_byte *) fsave;
e750d25e
JT
506 int i;
507
5716833c
MK
508 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
509
20a6ec49 510 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
e750d25e
JT
511 if (regnum == -1 || regnum == i)
512 {
513 /* Most of the FPU control registers occupy only 16 bits in
514 the fsave area. Give those a special treatment. */
20a6ec49
MD
515 if (i >= I387_FCTRL_REGNUM (tdep)
516 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
e750d25e 517 {
b4ad899f 518 gdb_byte buf[4];
e750d25e 519
5716833c 520 regcache_raw_collect (regcache, i, buf);
e750d25e 521
20a6ec49 522 if (i == I387_FOP_REGNUM (tdep))
e750d25e
JT
523 {
524 /* The opcode occupies only 11 bits. Make sure we
525 don't touch the other bits. */
526 buf[1] &= ((1 << 3) - 1);
20a6ec49 527 buf[1] |= ((FSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
e750d25e 528 }
20a6ec49 529 memcpy (FSAVE_ADDR (tdep, regs, i), buf, 2);
e750d25e
JT
530 }
531 else
20a6ec49 532 regcache_raw_collect (regcache, i, FSAVE_ADDR (tdep, regs, i));
e750d25e
JT
533 }
534}
535\f
536
537/* At fxsave_offset[REGNUM] you'll find the offset to the location in
538 the data structure used by the "fxsave" instruction where GDB
539 register REGNUM is stored. */
540
541static int fxsave_offset[] =
542{
5716833c 543 32, /* %st(0) through ... */
e750d25e
JT
544 48,
545 64,
546 80,
547 96,
548 112,
549 128,
5716833c
MK
550 144, /* ... %st(7) (80 bits each). */
551 0, /* `fctrl' (16 bits). */
552 2, /* `fstat' (16 bits). */
553 4, /* `ftag' (16 bits). */
554 12, /* `fiseg' (16 bits). */
555 8, /* `fioff'. */
556 20, /* `foseg' (16 bits). */
557 16, /* `fooff'. */
558 6, /* `fop' (bottom 11 bits). */
559 160 + 0 * 16, /* %xmm0 through ... */
04c8243f
MK
560 160 + 1 * 16,
561 160 + 2 * 16,
562 160 + 3 * 16,
563 160 + 4 * 16,
564 160 + 5 * 16,
565 160 + 6 * 16,
566 160 + 7 * 16,
567 160 + 8 * 16,
568 160 + 9 * 16,
569 160 + 10 * 16,
570 160 + 11 * 16,
571 160 + 12 * 16,
572 160 + 13 * 16,
573 160 + 14 * 16,
5716833c 574 160 + 15 * 16, /* ... %xmm15 (128 bits each). */
e750d25e
JT
575};
576
20a6ec49
MD
577#define FXSAVE_ADDR(tdep, fxsave, regnum) \
578 (fxsave + fxsave_offset[regnum - I387_ST0_REGNUM (tdep)])
5716833c
MK
579
580/* We made an unfortunate choice in putting %mxcsr after the SSE
581 registers %xmm0-%xmm7 instead of before, since it makes supporting
582 the registers %xmm8-%xmm15 on AMD64 a bit involved. Therefore we
583 don't include the offset for %mxcsr here above. */
584
585#define FXSAVE_MXCSR_ADDR(fxsave) (fxsave + 24)
e750d25e 586
b4ad899f 587static int i387_tag (const gdb_byte *raw);
e750d25e
JT
588\f
589
41d041d6 590/* Fill register REGNUM in REGCACHE with the appropriate
ed504bdf
MK
591 floating-point or SSE register value from *FXSAVE. This function
592 masks off any of the reserved bits in *FXSAVE. */
e750d25e
JT
593
594void
41d041d6 595i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
e750d25e 596{
41d041d6 597 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
9a3c8263 598 const gdb_byte *regs = (const gdb_byte *) fxsave;
5716833c
MK
599 int i;
600
601 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
602 gdb_assert (tdep->num_xmm_regs > 0);
dff95cc7 603
20a6ec49 604 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
ed504bdf
MK
605 if (regnum == -1 || regnum == i)
606 {
5716833c 607 if (regs == NULL)
ed504bdf 608 {
5716833c 609 regcache_raw_supply (regcache, i, NULL);
ed504bdf
MK
610 continue;
611 }
932bb524 612
ed504bdf
MK
613 /* Most of the FPU control registers occupy only 16 bits in
614 the fxsave area. Give those a special treatment. */
20a6ec49
MD
615 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
616 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
ed504bdf 617 {
b4ad899f 618 gdb_byte val[4];
ed504bdf 619
20a6ec49 620 memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
ed504bdf 621 val[2] = val[3] = 0;
20a6ec49 622 if (i == I387_FOP_REGNUM (tdep))
ed504bdf 623 val[1] &= ((1 << 3) - 1);
20a6ec49 624 else if (i== I387_FTAG_REGNUM (tdep))
ed504bdf
MK
625 {
626 /* The fxsave area contains a simplified version of
627 the tag word. We have to look at the actual 80-bit
628 FP data to recreate the traditional i387 tag word. */
629
630 unsigned long ftag = 0;
631 int fpreg;
632 int top;
633
20a6ec49
MD
634 top = ((FXSAVE_ADDR (tdep, regs,
635 I387_FSTAT_REGNUM (tdep)))[1] >> 3);
5716833c 636 top &= 0x7;
ed504bdf
MK
637
638 for (fpreg = 7; fpreg >= 0; fpreg--)
639 {
640 int tag;
641
642 if (val[0] & (1 << fpreg))
643 {
6d5e094a
MS
644 int thisreg = (fpreg + 8 - top) % 8
645 + I387_ST0_REGNUM (tdep);
646 tag = i387_tag (FXSAVE_ADDR (tdep, regs, thisreg));
ed504bdf
MK
647 }
648 else
649 tag = 3; /* Empty */
650
651 ftag |= tag << (2 * fpreg);
652 }
653 val[0] = ftag & 0xff;
654 val[1] = (ftag >> 8) & 0xff;
655 }
5716833c 656 regcache_raw_supply (regcache, i, val);
ed504bdf
MK
657 }
658 else
20a6ec49 659 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
ed504bdf 660 }
5716833c 661
20a6ec49 662 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
5716833c
MK
663 {
664 if (regs == NULL)
20a6ec49 665 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), NULL);
5716833c 666 else
20a6ec49 667 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep),
5716833c
MK
668 FXSAVE_MXCSR_ADDR (regs));
669 }
e750d25e
JT
670}
671
672/* Fill register REGNUM (if it is a floating-point or SSE register) in
80571bff
MK
673 *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for
674 all registers. This function doesn't touch any of the reserved
675 bits in *FXSAVE. */
e750d25e
JT
676
677void
80571bff 678i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave)
e750d25e 679{
e071d1f6 680 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
9a3c8263 681 gdb_byte *regs = (gdb_byte *) fxsave;
5716833c
MK
682 int i;
683
684 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
685 gdb_assert (tdep->num_xmm_regs > 0);
dff95cc7 686
20a6ec49 687 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
e750d25e
JT
688 if (regnum == -1 || regnum == i)
689 {
690 /* Most of the FPU control registers occupy only 16 bits in
691 the fxsave area. Give those a special treatment. */
20a6ec49
MD
692 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
693 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
e750d25e 694 {
b4ad899f 695 gdb_byte buf[4];
e750d25e 696
5716833c 697 regcache_raw_collect (regcache, i, buf);
e750d25e 698
31aeac78
L
699 if (i == I387_FOP_REGNUM (tdep))
700 {
701 /* The opcode occupies only 11 bits. Make sure we
702 don't touch the other bits. */
703 buf[1] &= ((1 << 3) - 1);
704 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
705 }
706 else if (i == I387_FTAG_REGNUM (tdep))
707 {
708 /* Converting back is much easier. */
709
710 unsigned short ftag;
711 int fpreg;
712
713 ftag = (buf[1] << 8) | buf[0];
714 buf[0] = 0;
715 buf[1] = 0;
716
717 for (fpreg = 7; fpreg >= 0; fpreg--)
718 {
719 int tag = (ftag >> (fpreg * 2)) & 3;
720
721 if (tag != 3)
722 buf[0] |= (1 << fpreg);
723 }
724 }
725 memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
726 }
727 else
728 regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
729 }
730
731 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
732 regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
733 FXSAVE_MXCSR_ADDR (regs));
734}
735
736/* `xstate_bv' is at byte offset 512. */
737#define XSAVE_XSTATE_BV_ADDR(xsave) (xsave + 512)
738
739/* At xsave_avxh_offset[REGNUM] you'll find the offset to the location in
740 the upper 128bit of AVX register data structure used by the "xsave"
741 instruction where GDB register REGNUM is stored. */
742
743static int xsave_avxh_offset[] =
744{
745 576 + 0 * 16, /* Upper 128bit of %ymm0 through ... */
746 576 + 1 * 16,
747 576 + 2 * 16,
748 576 + 3 * 16,
749 576 + 4 * 16,
750 576 + 5 * 16,
751 576 + 6 * 16,
752 576 + 7 * 16,
753 576 + 8 * 16,
754 576 + 9 * 16,
755 576 + 10 * 16,
756 576 + 11 * 16,
757 576 + 12 * 16,
758 576 + 13 * 16,
759 576 + 14 * 16,
760 576 + 15 * 16 /* Upper 128bit of ... %ymm15 (128 bits each). */
761};
762
01f9f808
MS
763#define XSAVE_AVXH_ADDR(tdep, xsave, regnum) \
764 (xsave + xsave_avxh_offset[regnum - I387_YMM0H_REGNUM (tdep)])
765
766/* At xsave_ymm_avx512_offset[REGNUM] you'll find the offset to the location in
767 the upper 128bit of ZMM register data structure used by the "xsave"
768 instruction where GDB register REGNUM is stored. */
769
770static int xsave_ymm_avx512_offset[] =
771{
772 /* HI16_ZMM_area + 16 bytes + regnum* 64 bytes. */
773 1664 + 16 + 0 * 64, /* %ymm16 through... */
774 1664 + 16 + 1 * 64,
775 1664 + 16 + 2 * 64,
776 1664 + 16 + 3 * 64,
777 1664 + 16 + 4 * 64,
778 1664 + 16 + 5 * 64,
779 1664 + 16 + 6 * 64,
780 1664 + 16 + 7 * 64,
781 1664 + 16 + 8 * 64,
782 1664 + 16 + 9 * 64,
783 1664 + 16 + 10 * 64,
784 1664 + 16 + 11 * 64,
785 1664 + 16 + 12 * 64,
786 1664 + 16 + 13 * 64,
787 1664 + 16 + 14 * 64,
788 1664 + 16 + 15 * 64 /* ... %ymm31 (128 bits each). */
789};
790
791#define XSAVE_YMM_AVX512_ADDR(tdep, xsave, regnum) \
792 (xsave + xsave_ymm_avx512_offset[regnum - I387_YMM16H_REGNUM (tdep)])
793
794static int xsave_xmm_avx512_offset[] =
1dbcd68c 795{
01f9f808
MS
796 1664 + 0 * 64, /* %ymm16 through... */
797 1664 + 1 * 64,
798 1664 + 2 * 64,
799 1664 + 3 * 64,
800 1664 + 4 * 64,
801 1664 + 5 * 64,
802 1664 + 6 * 64,
803 1664 + 7 * 64,
804 1664 + 8 * 64,
805 1664 + 9 * 64,
806 1664 + 10 * 64,
807 1664 + 11 * 64,
808 1664 + 12 * 64,
809 1664 + 13 * 64,
810 1664 + 14 * 64,
811 1664 + 15 * 64 /* ... %ymm31 (128 bits each). */
812};
813
814#define XSAVE_XMM_AVX512_ADDR(tdep, xsave, regnum) \
815 (xsave + xsave_xmm_avx512_offset[regnum - I387_XMM16_REGNUM (tdep)])
816
817static int xsave_mpx_offset[] = {
1dbcd68c
WT
818 960 + 0 * 16, /* bnd0r...bnd3r registers. */
819 960 + 1 * 16,
820 960 + 2 * 16,
821 960 + 3 * 16,
822 1024 + 0 * 8, /* bndcfg ... bndstatus. */
823 1024 + 1 * 8,
824};
825
1dbcd68c
WT
826#define XSAVE_MPX_ADDR(tdep, xsave, regnum) \
827 (xsave + xsave_mpx_offset[regnum - I387_BND0R_REGNUM (tdep)])
828
01f9f808
MS
829 /* At xsave_avx512__h_offset[REGNUM] you find the offset to the location
830 of the AVX512 opmask register data structure used by the "xsave"
831 instruction where GDB register REGNUM is stored. */
832
833static int xsave_avx512_k_offset[] =
834{
835 1088 + 0 * 8, /* %k0 through... */
836 1088 + 1 * 8,
837 1088 + 2 * 8,
838 1088 + 3 * 8,
839 1088 + 4 * 8,
840 1088 + 5 * 8,
841 1088 + 6 * 8,
842 1088 + 7 * 8 /* %k7 (64 bits each). */
843};
844
845#define XSAVE_AVX512_K_ADDR(tdep, xsave, regnum) \
846 (xsave + xsave_avx512_k_offset[regnum - I387_K0_REGNUM (tdep)])
847
848/* At xsave_avx512_zmm_h_offset[REGNUM] you find the offset to the location in
849 the upper 256bit of AVX512 ZMMH register data structure used by the "xsave"
850 instruction where GDB register REGNUM is stored. */
851
852static int xsave_avx512_zmm_h_offset[] =
853{
854 1152 + 0 * 32,
855 1152 + 1 * 32, /* Upper 256bit of %zmmh0 through... */
856 1152 + 2 * 32,
857 1152 + 3 * 32,
858 1152 + 4 * 32,
859 1152 + 5 * 32,
860 1152 + 6 * 32,
861 1152 + 7 * 32,
862 1152 + 8 * 32,
863 1152 + 9 * 32,
864 1152 + 10 * 32,
865 1152 + 11 * 32,
866 1152 + 12 * 32,
867 1152 + 13 * 32,
868 1152 + 14 * 32,
869 1152 + 15 * 32, /* Upper 256bit of... %zmmh15 (256 bits each). */
870 1664 + 32 + 0 * 64, /* Upper 256bit of... %zmmh16 (256 bits each). */
871 1664 + 32 + 1 * 64,
872 1664 + 32 + 2 * 64,
873 1664 + 32 + 3 * 64,
874 1664 + 32 + 4 * 64,
875 1664 + 32 + 5 * 64,
876 1664 + 32 + 6 * 64,
877 1664 + 32 + 7 * 64,
878 1664 + 32 + 8 * 64,
879 1664 + 32 + 9 * 64,
880 1664 + 32 + 10 * 64,
881 1664 + 32 + 11 * 64,
882 1664 + 32 + 12 * 64,
883 1664 + 32 + 13 * 64,
884 1664 + 32 + 14 * 64,
885 1664 + 32 + 15 * 64 /* Upper 256bit of... %zmmh31 (256 bits each). */
886};
887
888#define XSAVE_AVX512_ZMM_H_ADDR(tdep, xsave, regnum) \
889 (xsave + xsave_avx512_zmm_h_offset[regnum - I387_ZMM0H_REGNUM (tdep)])
890
51547df6
MS
891/* At xsave_pkeys_offset[REGNUM] you find the offset to the location
892 of the PKRU register data structure used by the "xsave"
893 instruction where GDB register REGNUM is stored. */
894
895static int xsave_pkeys_offset[] =
896{
8972688 + 0 * 8 /* %pkru (64 bits in XSTATE, 32-bit actually used by
898 instructions and applications). */
899};
900
901#define XSAVE_PKEYS_ADDR(tdep, xsave, regnum) \
902 (xsave + xsave_pkeys_offset[regnum - I387_PKRU_REGNUM (tdep)])
903
31aeac78
L
904/* Similar to i387_supply_fxsave, but use XSAVE extended state. */
905
906void
907i387_supply_xsave (struct regcache *regcache, int regnum,
908 const void *xsave)
909{
01f9f808
MS
910 struct gdbarch *gdbarch = get_regcache_arch (regcache);
911 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
9a3c8263 912 const gdb_byte *regs = (const gdb_byte *) xsave;
31aeac78 913 int i;
ff6527bb 914 ULONGEST clear_bv;
b4d36fb8 915 static const gdb_byte zero[MAX_REGISTER_SIZE] = { 0 };
31aeac78
L
916 enum
917 {
918 none = 0x0,
919 x87 = 0x1,
920 sse = 0x2,
921 avxh = 0x4,
1dbcd68c 922 mpx = 0x8,
01f9f808
MS
923 avx512_k = 0x10,
924 avx512_zmm_h = 0x20,
925 avx512_ymmh_avx512 = 0x40,
926 avx512_xmm_avx512 = 0x80,
51547df6 927 pkeys = 0x100,
01f9f808 928 all = x87 | sse | avxh | mpx | avx512_k | avx512_zmm_h
51547df6 929 | avx512_ymmh_avx512 | avx512_xmm_avx512 | pkeys
31aeac78
L
930 } regclass;
931
275418ae 932 gdb_assert (regs != NULL);
31aeac78
L
933 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
934 gdb_assert (tdep->num_xmm_regs > 0);
935
936 if (regnum == -1)
937 regclass = all;
51547df6
MS
938 else if (regnum >= I387_PKRU_REGNUM (tdep)
939 && regnum < I387_PKEYSEND_REGNUM (tdep))
940 regclass = pkeys;
01f9f808
MS
941 else if (regnum >= I387_ZMM0H_REGNUM (tdep)
942 && regnum < I387_ZMMENDH_REGNUM (tdep))
943 regclass = avx512_zmm_h;
944 else if (regnum >= I387_K0_REGNUM (tdep)
945 && regnum < I387_KEND_REGNUM (tdep))
946 regclass = avx512_k;
947 else if (regnum >= I387_YMM16H_REGNUM (tdep)
948 && regnum < I387_YMMH_AVX512_END_REGNUM (tdep))
949 regclass = avx512_ymmh_avx512;
950 else if (regnum >= I387_XMM16_REGNUM (tdep)
951 && regnum < I387_XMM_AVX512_END_REGNUM (tdep))
952 regclass = avx512_xmm_avx512;
31aeac78
L
953 else if (regnum >= I387_YMM0H_REGNUM (tdep)
954 && regnum < I387_YMMENDH_REGNUM (tdep))
955 regclass = avxh;
1dbcd68c
WT
956 else if (regnum >= I387_BND0R_REGNUM (tdep)
957 && regnum < I387_MPXEND_REGNUM (tdep))
958 regclass = mpx;
01f9f808 959 else if (regnum >= I387_XMM0_REGNUM (tdep)
31aeac78
L
960 && regnum < I387_MXCSR_REGNUM (tdep))
961 regclass = sse;
962 else if (regnum >= I387_ST0_REGNUM (tdep)
963 && regnum < I387_FCTRL_REGNUM (tdep))
964 regclass = x87;
965 else
966 regclass = none;
967
275418ae 968 if (regclass != none)
31aeac78 969 {
ff6527bb
MS
970 /* Get `xstat_bv'. The supported bits in `xstat_bv' are 8 bytes. */
971 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
972 ULONGEST xstate_bv = 0;
31aeac78 973
ff6527bb
MS
974 xstate_bv = extract_unsigned_integer (XSAVE_XSTATE_BV_ADDR (regs),
975 8, byte_order);
976
977 /* Clear part in vector registers if its bit in xstat_bv is zero. */
978 clear_bv = (~(xstate_bv)) & tdep->xcr0;
31aeac78
L
979 }
980 else
df7e5265 981 clear_bv = X86_XSTATE_ALL_MASK;
31aeac78 982
b4d36fb8
PA
983 /* With the delayed xsave mechanism, in between the program
984 starting, and the program accessing the vector registers for the
985 first time, the register's values are invalid. The kernel
986 initializes register states to zero when they are set the first
987 time in a program. This means that from the user-space programs'
988 perspective, it's the same as if the registers have always been
989 zero from the start of the program. Therefore, the debugger
275418ae 990 should provide the same illusion to the user. */
b4d36fb8 991
31aeac78
L
992 switch (regclass)
993 {
994 case none:
995 break;
996
51547df6
MS
997 case pkeys:
998 if ((clear_bv & X86_XSTATE_PKRU))
999 regcache_raw_supply (regcache, regnum, zero);
1000 else
1001 regcache_raw_supply (regcache, regnum,
1002 XSAVE_PKEYS_ADDR (tdep, regs, regnum));
1003 return;
1004
01f9f808 1005 case avx512_zmm_h:
df7e5265 1006 if ((clear_bv & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
01f9f808
MS
1007 regcache_raw_supply (regcache, regnum, zero);
1008 else
1009 regcache_raw_supply (regcache, regnum,
1010 XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, regnum));
1011 return;
1012
1013 case avx512_k:
df7e5265 1014 if ((clear_bv & X86_XSTATE_K))
01f9f808
MS
1015 regcache_raw_supply (regcache, regnum, zero);
1016 else
1017 regcache_raw_supply (regcache, regnum,
1018 XSAVE_AVX512_K_ADDR (tdep, regs, regnum));
1019 return;
1020
1021 case avx512_ymmh_avx512:
df7e5265 1022 if ((clear_bv & X86_XSTATE_ZMM))
01f9f808
MS
1023 regcache_raw_supply (regcache, regnum, zero);
1024 else
1025 regcache_raw_supply (regcache, regnum,
1026 XSAVE_YMM_AVX512_ADDR (tdep, regs, regnum));
1027 return;
1028
1029 case avx512_xmm_avx512:
df7e5265 1030 if ((clear_bv & X86_XSTATE_ZMM))
01f9f808
MS
1031 regcache_raw_supply (regcache, regnum, zero);
1032 else
1033 regcache_raw_supply (regcache, regnum,
1034 XSAVE_XMM_AVX512_ADDR (tdep, regs, regnum));
1035 return;
1036
31aeac78 1037 case avxh:
df7e5265 1038 if ((clear_bv & X86_XSTATE_AVX))
275418ae 1039 regcache_raw_supply (regcache, regnum, zero);
31aeac78 1040 else
b4d36fb8
PA
1041 regcache_raw_supply (regcache, regnum,
1042 XSAVE_AVXH_ADDR (tdep, regs, regnum));
31aeac78
L
1043 return;
1044
1dbcd68c 1045 case mpx:
df7e5265 1046 if ((clear_bv & X86_XSTATE_BNDREGS))
1dbcd68c
WT
1047 regcache_raw_supply (regcache, regnum, zero);
1048 else
1049 regcache_raw_supply (regcache, regnum,
1050 XSAVE_MPX_ADDR (tdep, regs, regnum));
1051 return;
1052
31aeac78 1053 case sse:
df7e5265 1054 if ((clear_bv & X86_XSTATE_SSE))
275418ae 1055 regcache_raw_supply (regcache, regnum, zero);
31aeac78 1056 else
b4d36fb8
PA
1057 regcache_raw_supply (regcache, regnum,
1058 FXSAVE_ADDR (tdep, regs, regnum));
31aeac78
L
1059 return;
1060
1061 case x87:
df7e5265 1062 if ((clear_bv & X86_XSTATE_X87))
275418ae 1063 regcache_raw_supply (regcache, regnum, zero);
31aeac78 1064 else
b4d36fb8
PA
1065 regcache_raw_supply (regcache, regnum,
1066 FXSAVE_ADDR (tdep, regs, regnum));
31aeac78
L
1067 return;
1068
1069 case all:
51547df6
MS
1070 /* Handle PKEYS registers. */
1071 if ((tdep->xcr0 & X86_XSTATE_PKRU))
1072 {
1073 if ((clear_bv & X86_XSTATE_PKRU))
1074 {
1075 for (i = I387_PKRU_REGNUM (tdep);
1076 i < I387_PKEYSEND_REGNUM (tdep);
1077 i++)
1078 regcache_raw_supply (regcache, i, zero);
1079 }
1080 else
1081 {
1082 for (i = I387_PKRU_REGNUM (tdep);
1083 i < I387_PKEYSEND_REGNUM (tdep);
1084 i++)
1085 regcache_raw_supply (regcache, i,
1086 XSAVE_PKEYS_ADDR (tdep, regs, i));
1087 }
1088 }
1089
01f9f808 1090 /* Handle the upper ZMM registers. */
df7e5265 1091 if ((tdep->xcr0 & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
01f9f808 1092 {
df7e5265 1093 if ((clear_bv & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
01f9f808
MS
1094 {
1095 for (i = I387_ZMM0H_REGNUM (tdep);
1096 i < I387_ZMMENDH_REGNUM (tdep);
1097 i++)
1098 regcache_raw_supply (regcache, i, zero);
1099 }
1100 else
1101 {
1102 for (i = I387_ZMM0H_REGNUM (tdep);
1103 i < I387_ZMMENDH_REGNUM (tdep);
1104 i++)
1105 regcache_raw_supply (regcache, i,
1106 XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i));
1107 }
1108 }
1109
1110 /* Handle AVX512 OpMask registers. */
df7e5265 1111 if ((tdep->xcr0 & X86_XSTATE_K))
01f9f808 1112 {
df7e5265 1113 if ((clear_bv & X86_XSTATE_K))
01f9f808
MS
1114 {
1115 for (i = I387_K0_REGNUM (tdep);
1116 i < I387_KEND_REGNUM (tdep);
1117 i++)
1118 regcache_raw_supply (regcache, i, zero);
1119 }
1120 else
1121 {
1122 for (i = I387_K0_REGNUM (tdep);
1123 i < I387_KEND_REGNUM (tdep);
1124 i++)
1125 regcache_raw_supply (regcache, i,
1126 XSAVE_AVX512_K_ADDR (tdep, regs, i));
1127 }
1128 }
1129
1130 /* Handle the YMM_AVX512 registers. */
df7e5265 1131 if ((tdep->xcr0 & X86_XSTATE_ZMM))
01f9f808 1132 {
df7e5265 1133 if ((clear_bv & X86_XSTATE_ZMM))
01f9f808
MS
1134 {
1135 for (i = I387_YMM16H_REGNUM (tdep);
1136 i < I387_YMMH_AVX512_END_REGNUM (tdep);
1137 i++)
1138 regcache_raw_supply (regcache, i, zero);
1139 for (i = I387_XMM16_REGNUM (tdep);
1140 i < I387_XMM_AVX512_END_REGNUM (tdep);
1141 i++)
1142 regcache_raw_supply (regcache, i, zero);
1143 }
1144 else
1145 {
1146 for (i = I387_YMM16H_REGNUM (tdep);
1147 i < I387_YMMH_AVX512_END_REGNUM (tdep);
1148 i++)
1149 regcache_raw_supply (regcache, i,
1150 XSAVE_YMM_AVX512_ADDR (tdep, regs, i));
1151 for (i = I387_XMM16_REGNUM (tdep);
1152 i < I387_XMM_AVX512_END_REGNUM (tdep);
1153 i++)
1154 regcache_raw_supply (regcache, i,
1155 XSAVE_XMM_AVX512_ADDR (tdep, regs, i));
1156 }
1157 }
86d31898 1158 /* Handle the upper YMM registers. */
df7e5265 1159 if ((tdep->xcr0 & X86_XSTATE_AVX))
31aeac78 1160 {
df7e5265 1161 if ((clear_bv & X86_XSTATE_AVX))
b4d36fb8
PA
1162 {
1163 for (i = I387_YMM0H_REGNUM (tdep);
1164 i < I387_YMMENDH_REGNUM (tdep);
1165 i++)
275418ae 1166 regcache_raw_supply (regcache, i, zero);
b4d36fb8 1167 }
31aeac78 1168 else
31aeac78 1169 {
b4d36fb8
PA
1170 for (i = I387_YMM0H_REGNUM (tdep);
1171 i < I387_YMMENDH_REGNUM (tdep);
1172 i++)
1173 regcache_raw_supply (regcache, i,
1174 XSAVE_AVXH_ADDR (tdep, regs, i));
31aeac78
L
1175 }
1176 }
1177
1dbcd68c 1178 /* Handle the MPX registers. */
df7e5265 1179 if ((tdep->xcr0 & X86_XSTATE_BNDREGS))
1dbcd68c 1180 {
df7e5265 1181 if (clear_bv & X86_XSTATE_BNDREGS)
1dbcd68c
WT
1182 {
1183 for (i = I387_BND0R_REGNUM (tdep);
1184 i < I387_BNDCFGU_REGNUM (tdep); i++)
1185 regcache_raw_supply (regcache, i, zero);
1186 }
1187 else
1188 {
1189 for (i = I387_BND0R_REGNUM (tdep);
1190 i < I387_BNDCFGU_REGNUM (tdep); i++)
1191 regcache_raw_supply (regcache, i,
1192 XSAVE_MPX_ADDR (tdep, regs, i));
1193 }
1194 }
1195
1196 /* Handle the MPX registers. */
df7e5265 1197 if ((tdep->xcr0 & X86_XSTATE_BNDCFG))
1dbcd68c 1198 {
df7e5265 1199 if (clear_bv & X86_XSTATE_BNDCFG)
1dbcd68c
WT
1200 {
1201 for (i = I387_BNDCFGU_REGNUM (tdep);
1202 i < I387_MPXEND_REGNUM (tdep); i++)
1203 regcache_raw_supply (regcache, i, zero);
1204 }
1205 else
1206 {
1207 for (i = I387_BNDCFGU_REGNUM (tdep);
1208 i < I387_MPXEND_REGNUM (tdep); i++)
1209 regcache_raw_supply (regcache, i,
1210 XSAVE_MPX_ADDR (tdep, regs, i));
1211 }
1212 }
1213
31aeac78 1214 /* Handle the XMM registers. */
df7e5265 1215 if ((tdep->xcr0 & X86_XSTATE_SSE))
31aeac78 1216 {
df7e5265 1217 if ((clear_bv & X86_XSTATE_SSE))
b4d36fb8
PA
1218 {
1219 for (i = I387_XMM0_REGNUM (tdep);
1220 i < I387_MXCSR_REGNUM (tdep);
1221 i++)
275418ae 1222 regcache_raw_supply (regcache, i, zero);
b4d36fb8 1223 }
31aeac78 1224 else
31aeac78 1225 {
b4d36fb8
PA
1226 for (i = I387_XMM0_REGNUM (tdep);
1227 i < I387_MXCSR_REGNUM (tdep); i++)
1228 regcache_raw_supply (regcache, i,
1229 FXSAVE_ADDR (tdep, regs, i));
31aeac78
L
1230 }
1231 }
1232
1233 /* Handle the x87 registers. */
df7e5265 1234 if ((tdep->xcr0 & X86_XSTATE_X87))
31aeac78 1235 {
df7e5265 1236 if ((clear_bv & X86_XSTATE_X87))
b4d36fb8
PA
1237 {
1238 for (i = I387_ST0_REGNUM (tdep);
1239 i < I387_FCTRL_REGNUM (tdep);
1240 i++)
275418ae 1241 regcache_raw_supply (regcache, i, zero);
b4d36fb8 1242 }
31aeac78 1243 else
31aeac78 1244 {
b4d36fb8
PA
1245 for (i = I387_ST0_REGNUM (tdep);
1246 i < I387_FCTRL_REGNUM (tdep);
1247 i++)
1248 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
31aeac78
L
1249 }
1250 }
1251 break;
1252 }
1253
1254 /* Only handle x87 control registers. */
1255 for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
1256 if (regnum == -1 || regnum == i)
1257 {
31aeac78
L
1258 /* Most of the FPU control registers occupy only 16 bits in
1259 the xsave extended state. Give those a special treatment. */
1260 if (i != I387_FIOFF_REGNUM (tdep)
1261 && i != I387_FOOFF_REGNUM (tdep))
1262 {
1263 gdb_byte val[4];
1264
1265 memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
1266 val[2] = val[3] = 0;
1267 if (i == I387_FOP_REGNUM (tdep))
1268 val[1] &= ((1 << 3) - 1);
1269 else if (i== I387_FTAG_REGNUM (tdep))
1270 {
1271 /* The fxsave area contains a simplified version of
1272 the tag word. We have to look at the actual 80-bit
1273 FP data to recreate the traditional i387 tag word. */
1274
1275 unsigned long ftag = 0;
1276 int fpreg;
1277 int top;
1278
1279 top = ((FXSAVE_ADDR (tdep, regs,
1280 I387_FSTAT_REGNUM (tdep)))[1] >> 3);
1281 top &= 0x7;
1282
1283 for (fpreg = 7; fpreg >= 0; fpreg--)
1284 {
1285 int tag;
1286
1287 if (val[0] & (1 << fpreg))
1288 {
e5b3d7d6 1289 int thisreg = (fpreg + 8 - top) % 8
31aeac78 1290 + I387_ST0_REGNUM (tdep);
e5b3d7d6 1291 tag = i387_tag (FXSAVE_ADDR (tdep, regs, thisreg));
31aeac78
L
1292 }
1293 else
1294 tag = 3; /* Empty */
1295
1296 ftag |= tag << (2 * fpreg);
1297 }
1298 val[0] = ftag & 0xff;
1299 val[1] = (ftag >> 8) & 0xff;
1300 }
1301 regcache_raw_supply (regcache, i, val);
1302 }
1303 else
1304 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
1305 }
1306
1307 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
275418ae
PA
1308 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep),
1309 FXSAVE_MXCSR_ADDR (regs));
31aeac78
L
1310}
1311
1312/* Similar to i387_collect_fxsave, but use XSAVE extended state. */
1313
1314void
1315i387_collect_xsave (const struct regcache *regcache, int regnum,
1316 void *xsave, int gcore)
1317{
01f9f808
MS
1318 struct gdbarch *gdbarch = get_regcache_arch (regcache);
1319 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
9a3c8263 1320 gdb_byte *regs = (gdb_byte *) xsave;
31aeac78
L
1321 int i;
1322 enum
1323 {
1324 none = 0x0,
1325 check = 0x1,
1326 x87 = 0x2 | check,
1327 sse = 0x4 | check,
1328 avxh = 0x8 | check,
1dbcd68c 1329 mpx = 0x10 | check,
01f9f808
MS
1330 avx512_k = 0x20 | check,
1331 avx512_zmm_h = 0x40 | check,
1332 avx512_ymmh_avx512 = 0x80 | check,
1333 avx512_xmm_avx512 = 0x100 | check,
51547df6 1334 pkeys = 0x200 | check,
01f9f808 1335 all = x87 | sse | avxh | mpx | avx512_k | avx512_zmm_h
51547df6 1336 | avx512_ymmh_avx512 | avx512_xmm_avx512 | pkeys
31aeac78
L
1337 } regclass;
1338
1339 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
1340 gdb_assert (tdep->num_xmm_regs > 0);
1341
1342 if (regnum == -1)
1343 regclass = all;
51547df6
MS
1344 else if (regnum >= I387_PKRU_REGNUM (tdep)
1345 && regnum < I387_PKEYSEND_REGNUM (tdep))
1346 regclass = pkeys;
01f9f808
MS
1347 else if (regnum >= I387_ZMM0H_REGNUM (tdep)
1348 && regnum < I387_ZMMENDH_REGNUM (tdep))
1349 regclass = avx512_zmm_h;
1350 else if (regnum >= I387_K0_REGNUM (tdep)
1351 && regnum < I387_KEND_REGNUM (tdep))
1352 regclass = avx512_k;
1353 else if (regnum >= I387_YMM16H_REGNUM (tdep)
1354 && regnum < I387_YMMH_AVX512_END_REGNUM (tdep))
1355 regclass = avx512_ymmh_avx512;
1356 else if (regnum >= I387_XMM16_REGNUM (tdep)
1357 && regnum < I387_XMM_AVX512_END_REGNUM (tdep))
1358 regclass = avx512_xmm_avx512;
31aeac78
L
1359 else if (regnum >= I387_YMM0H_REGNUM (tdep)
1360 && regnum < I387_YMMENDH_REGNUM (tdep))
1361 regclass = avxh;
1dbcd68c
WT
1362 else if (regnum >= I387_BND0R_REGNUM (tdep)
1363 && regnum < I387_MPXEND_REGNUM (tdep))
1364 regclass = mpx;
1365 else if (regnum >= I387_XMM0_REGNUM (tdep)
31aeac78
L
1366 && regnum < I387_MXCSR_REGNUM (tdep))
1367 regclass = sse;
1368 else if (regnum >= I387_ST0_REGNUM (tdep)
1369 && regnum < I387_FCTRL_REGNUM (tdep))
1370 regclass = x87;
1371 else
1372 regclass = none;
1373
1374 if (gcore)
1375 {
1376 /* Clear XSAVE extended state. */
df7e5265 1377 memset (regs, 0, X86_XSTATE_SIZE (tdep->xcr0));
31aeac78
L
1378
1379 /* Update XCR0 and `xstate_bv' with XCR0 for gcore. */
1380 if (tdep->xsave_xcr0_offset != -1)
1381 memcpy (regs + tdep->xsave_xcr0_offset, &tdep->xcr0, 8);
1382 memcpy (XSAVE_XSTATE_BV_ADDR (regs), &tdep->xcr0, 8);
1383 }
1384
1385 if ((regclass & check))
1386 {
1387 gdb_byte raw[I386_MAX_REGISTER_SIZE];
ff6527bb 1388 ULONGEST initial_xstate_bv, clear_bv, xstate_bv = 0;
31aeac78 1389 gdb_byte *p;
ff6527bb
MS
1390 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1391
1392 /* The supported bits in `xstat_bv' are 8 bytes. */
1393 initial_xstate_bv = extract_unsigned_integer (XSAVE_XSTATE_BV_ADDR (regs),
1394 8, byte_order);
1395 clear_bv = (~(initial_xstate_bv)) & tdep->xcr0;
31aeac78
L
1396
1397 /* Clear register set if its bit in xstat_bv is zero. */
1398 if (clear_bv)
1399 {
51547df6
MS
1400 if ((clear_bv & X86_XSTATE_PKRU))
1401 for (i = I387_PKRU_REGNUM (tdep);
1402 i < I387_PKEYSEND_REGNUM (tdep); i++)
1403 memset (XSAVE_PKEYS_ADDR (tdep, regs, i), 0, 4);
1404
df7e5265 1405 if ((clear_bv & X86_XSTATE_BNDREGS))
1dbcd68c
WT
1406 for (i = I387_BND0R_REGNUM (tdep);
1407 i < I387_BNDCFGU_REGNUM (tdep); i++)
1408 memset (XSAVE_MPX_ADDR (tdep, regs, i), 0, 16);
1409
df7e5265 1410 if ((clear_bv & X86_XSTATE_BNDCFG))
1dbcd68c
WT
1411 for (i = I387_BNDCFGU_REGNUM (tdep);
1412 i < I387_MPXEND_REGNUM (tdep); i++)
1413 memset (XSAVE_MPX_ADDR (tdep, regs, i), 0, 8);
1414
df7e5265 1415 if ((clear_bv & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
01f9f808
MS
1416 for (i = I387_ZMM0H_REGNUM (tdep);
1417 i < I387_ZMMENDH_REGNUM (tdep); i++)
1418 memset (XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i), 0, 32);
1419
df7e5265 1420 if ((clear_bv & X86_XSTATE_K))
01f9f808
MS
1421 for (i = I387_K0_REGNUM (tdep);
1422 i < I387_KEND_REGNUM (tdep); i++)
1423 memset (XSAVE_AVX512_K_ADDR (tdep, regs, i), 0, 8);
1424
df7e5265 1425 if ((clear_bv & X86_XSTATE_ZMM))
01f9f808
MS
1426 {
1427 for (i = I387_YMM16H_REGNUM (tdep);
1428 i < I387_YMMH_AVX512_END_REGNUM (tdep); i++)
1429 memset (XSAVE_YMM_AVX512_ADDR (tdep, regs, i), 0, 16);
1430 for (i = I387_XMM16_REGNUM (tdep);
1431 i < I387_XMM_AVX512_END_REGNUM (tdep); i++)
1432 memset (XSAVE_XMM_AVX512_ADDR (tdep, regs, i), 0, 16);
1433 }
1434
df7e5265 1435 if ((clear_bv & X86_XSTATE_AVX))
31aeac78
L
1436 for (i = I387_YMM0H_REGNUM (tdep);
1437 i < I387_YMMENDH_REGNUM (tdep); i++)
1438 memset (XSAVE_AVXH_ADDR (tdep, regs, i), 0, 16);
1439
df7e5265 1440 if ((clear_bv & X86_XSTATE_SSE))
31aeac78
L
1441 for (i = I387_XMM0_REGNUM (tdep);
1442 i < I387_MXCSR_REGNUM (tdep); i++)
1443 memset (FXSAVE_ADDR (tdep, regs, i), 0, 16);
1444
df7e5265 1445 if ((clear_bv & X86_XSTATE_X87))
31aeac78
L
1446 for (i = I387_ST0_REGNUM (tdep);
1447 i < I387_FCTRL_REGNUM (tdep); i++)
1448 memset (FXSAVE_ADDR (tdep, regs, i), 0, 10);
1449 }
1450
1451 if (regclass == all)
1452 {
51547df6
MS
1453 /* Check if any PKEYS registers are changed. */
1454 if ((tdep->xcr0 & X86_XSTATE_PKRU))
1455 for (i = I387_PKRU_REGNUM (tdep);
1456 i < I387_PKEYSEND_REGNUM (tdep); i++)
1457 {
1458 regcache_raw_collect (regcache, i, raw);
1459 p = XSAVE_PKEYS_ADDR (tdep, regs, i);
1460 if (memcmp (raw, p, 4) != 0)
1461 {
1462 xstate_bv |= X86_XSTATE_PKRU;
1463 memcpy (p, raw, 4);
1464 }
1465 }
1466
01f9f808 1467 /* Check if any ZMMH registers are changed. */
df7e5265 1468 if ((tdep->xcr0 & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM)))
01f9f808
MS
1469 for (i = I387_ZMM0H_REGNUM (tdep);
1470 i < I387_ZMMENDH_REGNUM (tdep); i++)
1471 {
1472 regcache_raw_collect (regcache, i, raw);
1473 p = XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, i);
1474 if (memcmp (raw, p, 32) != 0)
1475 {
df7e5265 1476 xstate_bv |= (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM);
01f9f808
MS
1477 memcpy (p, raw, 32);
1478 }
1479 }
1480
1481 /* Check if any K registers are changed. */
df7e5265 1482 if ((tdep->xcr0 & X86_XSTATE_K))
01f9f808
MS
1483 for (i = I387_K0_REGNUM (tdep);
1484 i < I387_KEND_REGNUM (tdep); i++)
1485 {
1486 regcache_raw_collect (regcache, i, raw);
1487 p = XSAVE_AVX512_K_ADDR (tdep, regs, i);
1488 if (memcmp (raw, p, 8) != 0)
1489 {
df7e5265 1490 xstate_bv |= X86_XSTATE_K;
01f9f808
MS
1491 memcpy (p, raw, 8);
1492 }
1493 }
1494
1495 /* Check if any XMM or upper YMM registers are changed. */
df7e5265 1496 if ((tdep->xcr0 & X86_XSTATE_ZMM))
01f9f808
MS
1497 {
1498 for (i = I387_YMM16H_REGNUM (tdep);
1499 i < I387_YMMH_AVX512_END_REGNUM (tdep); i++)
1500 {
1501 regcache_raw_collect (regcache, i, raw);
1502 p = XSAVE_YMM_AVX512_ADDR (tdep, regs, i);
1503 if (memcmp (raw, p, 16) != 0)
1504 {
df7e5265 1505 xstate_bv |= X86_XSTATE_ZMM;
01f9f808
MS
1506 memcpy (p, raw, 16);
1507 }
1508 }
1509 for (i = I387_XMM16_REGNUM (tdep);
1510 i < I387_XMM_AVX512_END_REGNUM (tdep); i++)
1511 {
1512 regcache_raw_collect (regcache, i, raw);
1513 p = XSAVE_XMM_AVX512_ADDR (tdep, regs, i);
1514 if (memcmp (raw, p, 16) != 0)
1515 {
df7e5265 1516 xstate_bv |= X86_XSTATE_ZMM;
01f9f808
MS
1517 memcpy (p, raw, 16);
1518 }
1519 }
1520 }
1521
31aeac78 1522 /* Check if any upper YMM registers are changed. */
df7e5265 1523 if ((tdep->xcr0 & X86_XSTATE_AVX))
31aeac78
L
1524 for (i = I387_YMM0H_REGNUM (tdep);
1525 i < I387_YMMENDH_REGNUM (tdep); i++)
1526 {
1527 regcache_raw_collect (regcache, i, raw);
1528 p = XSAVE_AVXH_ADDR (tdep, regs, i);
1529 if (memcmp (raw, p, 16))
1530 {
df7e5265 1531 xstate_bv |= X86_XSTATE_AVX;
31aeac78
L
1532 memcpy (p, raw, 16);
1533 }
1534 }
1dbcd68c 1535 /* Check if any upper MPX registers are changed. */
df7e5265 1536 if ((tdep->xcr0 & X86_XSTATE_BNDREGS))
1dbcd68c
WT
1537 for (i = I387_BND0R_REGNUM (tdep);
1538 i < I387_BNDCFGU_REGNUM (tdep); i++)
1539 {
1540 regcache_raw_collect (regcache, i, raw);
1541 p = XSAVE_MPX_ADDR (tdep, regs, i);
1542 if (memcmp (raw, p, 16))
1543 {
df7e5265 1544 xstate_bv |= X86_XSTATE_BNDREGS;
1dbcd68c
WT
1545 memcpy (p, raw, 16);
1546 }
1547 }
1548
1549 /* Check if any upper MPX registers are changed. */
df7e5265 1550 if ((tdep->xcr0 & X86_XSTATE_BNDCFG))
1dbcd68c
WT
1551 for (i = I387_BNDCFGU_REGNUM (tdep);
1552 i < I387_MPXEND_REGNUM (tdep); i++)
1553 {
1554 regcache_raw_collect (regcache, i, raw);
1555 p = XSAVE_MPX_ADDR (tdep, regs, i);
1556 if (memcmp (raw, p, 8))
1557 {
df7e5265 1558 xstate_bv |= X86_XSTATE_BNDCFG;
1dbcd68c
WT
1559 memcpy (p, raw, 8);
1560 }
1561 }
31aeac78
L
1562
1563 /* Check if any SSE registers are changed. */
df7e5265 1564 if ((tdep->xcr0 & X86_XSTATE_SSE))
31aeac78
L
1565 for (i = I387_XMM0_REGNUM (tdep);
1566 i < I387_MXCSR_REGNUM (tdep); i++)
1567 {
1568 regcache_raw_collect (regcache, i, raw);
1569 p = FXSAVE_ADDR (tdep, regs, i);
1570 if (memcmp (raw, p, 16))
1571 {
df7e5265 1572 xstate_bv |= X86_XSTATE_SSE;
31aeac78
L
1573 memcpy (p, raw, 16);
1574 }
1575 }
1576
1577 /* Check if any X87 registers are changed. */
df7e5265 1578 if ((tdep->xcr0 & X86_XSTATE_X87))
31aeac78
L
1579 for (i = I387_ST0_REGNUM (tdep);
1580 i < I387_FCTRL_REGNUM (tdep); i++)
1581 {
1582 regcache_raw_collect (regcache, i, raw);
1583 p = FXSAVE_ADDR (tdep, regs, i);
1584 if (memcmp (raw, p, 10))
1585 {
df7e5265 1586 xstate_bv |= X86_XSTATE_X87;
31aeac78
L
1587 memcpy (p, raw, 10);
1588 }
1589 }
1590 }
1591 else
1592 {
1593 /* Check if REGNUM is changed. */
1594 regcache_raw_collect (regcache, regnum, raw);
1595
1596 switch (regclass)
1597 {
1598 default:
4e4d8374
L
1599 internal_error (__FILE__, __LINE__,
1600 _("invalid i387 regclass"));
31aeac78 1601
51547df6
MS
1602 case pkeys:
1603 /* This is a PKEYS register. */
1604 p = XSAVE_PKEYS_ADDR (tdep, regs, regnum);
1605 if (memcmp (raw, p, 4) != 0)
1606 {
1607 xstate_bv |= X86_XSTATE_PKRU;
1608 memcpy (p, raw, 4);
1609 }
1610 break;
1611
01f9f808
MS
1612 case avx512_zmm_h:
1613 /* This is a ZMM register. */
1614 p = XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, regnum);
1615 if (memcmp (raw, p, 32) != 0)
1616 {
df7e5265 1617 xstate_bv |= (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM);
01f9f808
MS
1618 memcpy (p, raw, 32);
1619 }
1620 break;
1621 case avx512_k:
1622 /* This is a AVX512 mask register. */
1623 p = XSAVE_AVX512_K_ADDR (tdep, regs, regnum);
1624 if (memcmp (raw, p, 8) != 0)
1625 {
df7e5265 1626 xstate_bv |= X86_XSTATE_K;
01f9f808
MS
1627 memcpy (p, raw, 8);
1628 }
1629 break;
1630
1631 case avx512_ymmh_avx512:
1632 /* This is an upper YMM16-31 register. */
1633 p = XSAVE_YMM_AVX512_ADDR (tdep, regs, regnum);
1634 if (memcmp (raw, p, 16) != 0)
1635 {
df7e5265 1636 xstate_bv |= X86_XSTATE_ZMM;
01f9f808
MS
1637 memcpy (p, raw, 16);
1638 }
1639 break;
1640
1641 case avx512_xmm_avx512:
1642 /* This is an upper XMM16-31 register. */
1643 p = XSAVE_XMM_AVX512_ADDR (tdep, regs, regnum);
1644 if (memcmp (raw, p, 16) != 0)
1645 {
df7e5265 1646 xstate_bv |= X86_XSTATE_ZMM;
01f9f808
MS
1647 memcpy (p, raw, 16);
1648 }
1649 break;
1650
40936b0d
L
1651 case avxh:
1652 /* This is an upper YMM register. */
1653 p = XSAVE_AVXH_ADDR (tdep, regs, regnum);
1654 if (memcmp (raw, p, 16))
31aeac78 1655 {
df7e5265 1656 xstate_bv |= X86_XSTATE_AVX;
40936b0d
L
1657 memcpy (p, raw, 16);
1658 }
1659 break;
31aeac78 1660
1dbcd68c
WT
1661 case mpx:
1662 if (regnum < I387_BNDCFGU_REGNUM (tdep))
1663 {
1664 regcache_raw_collect (regcache, regnum, raw);
1665 p = XSAVE_MPX_ADDR (tdep, regs, regnum);
1666 if (memcmp (raw, p, 16))
1667 {
df7e5265 1668 xstate_bv |= X86_XSTATE_BNDREGS;
1dbcd68c
WT
1669 memcpy (p, raw, 16);
1670 }
1671 }
1672 else
1673 {
1674 p = XSAVE_MPX_ADDR (tdep, regs, regnum);
df7e5265 1675 xstate_bv |= X86_XSTATE_BNDCFG;
1dbcd68c
WT
1676 memcpy (p, raw, 8);
1677 }
1678 break;
1679
40936b0d
L
1680 case sse:
1681 /* This is an SSE register. */
1682 p = FXSAVE_ADDR (tdep, regs, regnum);
1683 if (memcmp (raw, p, 16))
1684 {
df7e5265 1685 xstate_bv |= X86_XSTATE_SSE;
40936b0d
L
1686 memcpy (p, raw, 16);
1687 }
1688 break;
31aeac78 1689
40936b0d
L
1690 case x87:
1691 /* This is an x87 register. */
1692 p = FXSAVE_ADDR (tdep, regs, regnum);
1693 if (memcmp (raw, p, 10))
1694 {
df7e5265 1695 xstate_bv |= X86_XSTATE_X87;
40936b0d 1696 memcpy (p, raw, 10);
31aeac78 1697 }
40936b0d 1698 break;
31aeac78 1699 }
40936b0d
L
1700 }
1701
1702 /* Update the corresponding bits in `xstate_bv' if any SSE/AVX
1703 registers are changed. */
1704 if (xstate_bv)
1705 {
ff6527bb
MS
1706 /* The supported bits in `xstat_bv' are 8 bytes. */
1707 initial_xstate_bv |= xstate_bv;
1708 store_unsigned_integer (XSAVE_XSTATE_BV_ADDR (regs),
1709 8, byte_order,
1710 initial_xstate_bv);
40936b0d
L
1711
1712 switch (regclass)
31aeac78 1713 {
40936b0d 1714 default:
4e4d8374
L
1715 internal_error (__FILE__, __LINE__,
1716 _("invalid i387 regclass"));
40936b0d
L
1717
1718 case all:
1719 break;
1720
1721 case x87:
1722 case sse:
1723 case avxh:
1dbcd68c 1724 case mpx:
01f9f808
MS
1725 case avx512_k:
1726 case avx512_zmm_h:
1727 case avx512_ymmh_avx512:
1728 case avx512_xmm_avx512:
51547df6 1729 case pkeys:
40936b0d
L
1730 /* Register REGNUM has been updated. Return. */
1731 return;
31aeac78 1732 }
40936b0d
L
1733 }
1734 else
1735 {
1736 /* Return if REGNUM isn't changed. */
1737 if (regclass != all)
1738 return;
1739 }
31aeac78
L
1740 }
1741
1742 /* Only handle x87 control registers. */
1743 for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
1744 if (regnum == -1 || regnum == i)
1745 {
1746 /* Most of the FPU control registers occupy only 16 bits in
1747 the xsave extended state. Give those a special treatment. */
1748 if (i != I387_FIOFF_REGNUM (tdep)
1749 && i != I387_FOOFF_REGNUM (tdep))
1750 {
1751 gdb_byte buf[4];
1752
1753 regcache_raw_collect (regcache, i, buf);
1754
20a6ec49 1755 if (i == I387_FOP_REGNUM (tdep))
e750d25e
JT
1756 {
1757 /* The opcode occupies only 11 bits. Make sure we
40936b0d 1758 don't touch the other bits. */
e750d25e 1759 buf[1] &= ((1 << 3) - 1);
20a6ec49 1760 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
e750d25e 1761 }
20a6ec49 1762 else if (i == I387_FTAG_REGNUM (tdep))
e750d25e
JT
1763 {
1764 /* Converting back is much easier. */
1765
1766 unsigned short ftag;
1767 int fpreg;
1768
1769 ftag = (buf[1] << 8) | buf[0];
1770 buf[0] = 0;
1771 buf[1] = 0;
1772
1773 for (fpreg = 7; fpreg >= 0; fpreg--)
1774 {
1775 int tag = (ftag >> (fpreg * 2)) & 3;
1776
1777 if (tag != 3)
1778 buf[0] |= (1 << fpreg);
1779 }
1780 }
20a6ec49 1781 memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
e750d25e
JT
1782 }
1783 else
20a6ec49 1784 regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
e750d25e 1785 }
5716833c 1786
20a6ec49
MD
1787 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
1788 regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
5716833c 1789 FXSAVE_MXCSR_ADDR (regs));
e750d25e
JT
1790}
1791
1792/* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
1793 *RAW. */
1794
1795static int
b4ad899f 1796i387_tag (const gdb_byte *raw)
e750d25e
JT
1797{
1798 int integer;
1799 unsigned int exponent;
1800 unsigned long fraction[2];
1801
1802 integer = raw[7] & 0x80;
1803 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
1804 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
1805 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
1806 | (raw[5] << 8) | raw[4]);
1807
1808 if (exponent == 0x7fff)
1809 {
1810 /* Special. */
1811 return (2);
1812 }
1813 else if (exponent == 0x0000)
1814 {
1815 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
1816 {
1817 /* Zero. */
1818 return (1);
1819 }
1820 else
1821 {
1822 /* Special. */
1823 return (2);
1824 }
1825 }
1826 else
1827 {
1828 if (integer)
1829 {
1830 /* Valid. */
1831 return (0);
1832 }
1833 else
1834 {
1835 /* Special. */
1836 return (2);
1837 }
1838 }
1839}
efb1c01c
MK
1840
1841/* Prepare the FPU stack in REGCACHE for a function return. */
1842
1843void
1844i387_return_value (struct gdbarch *gdbarch, struct regcache *regcache)
1845{
1846 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1847 ULONGEST fstat;
1848
efb1c01c
MK
1849 /* Set the top of the floating-point register stack to 7. The
1850 actual value doesn't really matter, but 7 is what a normal
1851 function return would end up with if the program started out with
1852 a freshly initialized FPU. */
20a6ec49 1853 regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM (tdep), &fstat);
efb1c01c 1854 fstat |= (7 << 11);
20a6ec49 1855 regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM (tdep), fstat);
efb1c01c
MK
1856
1857 /* Mark %st(1) through %st(7) as empty. Since we set the top of the
1858 floating-point register stack to 7, the appropriate value for the
1859 tag word is 0x3fff. */
20a6ec49 1860 regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM (tdep), 0x3fff);
efb1c01c 1861
efb1c01c 1862}
This page took 1.508933 seconds and 4 git commands to generate.