arm: Support pac_key_* register operand for MRS/MSR in Armv8.1-M Mainline
[binutils-gdb.git] / gdbserver / i387-fp.cc
blob0bf57a3aa5d83cb43e1b44609d2497e7ba46114b
1 /* i387-specific utility functions, for the remote server for GDB.
2 Copyright (C) 2000-2024 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "i387-fp.h"
20 #include "gdbsupport/x86-xstate.h"
21 #include "nat/x86-xstate.h"
23 /* Default to SSE. */
24 static uint64_t x86_xcr0 = X86_XSTATE_SSE_MASK;
26 static const int num_avx512_k_registers = 8;
27 static const int num_pkeys_registers = 1;
29 static x86_xsave_layout xsave_layout;
31 /* Note: These functions preserve the reserved bits in control registers.
32 However, gdbserver promptly throws away that information. */
34 /* These structs should have the proper sizes and alignment on both
35 i386 and x86-64 machines. */
37 struct i387_fsave
39 /* All these are only sixteen bits, plus padding, except for fop (which
40 is only eleven bits), and fooff / fioff (which are 32 bits each). */
41 unsigned short fctrl;
42 unsigned short pad1;
43 unsigned short fstat;
44 unsigned short pad2;
45 unsigned short ftag;
46 unsigned short pad3;
47 unsigned int fioff;
48 unsigned short fiseg;
49 unsigned short fop;
50 unsigned int fooff;
51 unsigned short foseg;
52 unsigned short pad4;
54 /* Space for eight 80-bit FP values. */
55 unsigned char st_space[80];
58 struct i387_fxsave
60 /* All these are only sixteen bits, plus padding, except for fop (which
61 is only eleven bits), and fooff / fioff (which are 32 bits each). */
62 unsigned short fctrl;
63 unsigned short fstat;
64 unsigned short ftag;
65 unsigned short fop;
66 unsigned int fioff;
67 unsigned short fiseg;
68 unsigned short pad1;
69 unsigned int fooff;
70 unsigned short foseg;
71 unsigned short pad12;
73 unsigned int mxcsr;
74 unsigned int pad3;
76 /* Space for eight 80-bit FP values in 128-bit spaces. */
77 unsigned char st_space[128];
79 /* Space for eight 128-bit XMM values, or 16 on x86-64. */
80 unsigned char xmm_space[256];
83 static_assert (sizeof(i387_fxsave) == 416);
85 struct i387_xsave : public i387_fxsave
87 unsigned char reserved1[48];
89 /* The extended control register 0 (the XFEATURE_ENABLED_MASK
90 register). */
91 unsigned long long xcr0;
93 unsigned char reserved2[40];
95 /* The XSTATE_BV bit vector. */
96 unsigned long long xstate_bv;
98 /* The XCOMP_BV bit vector. */
99 unsigned long long xcomp_bv;
101 unsigned char reserved3[48];
103 /* Byte 576. End of registers with fixed position in XSAVE.
104 The position of other XSAVE registers will be calculated
105 from the appropriate CPUID calls. */
107 private:
108 /* Base address of XSAVE data as an unsigned char *. Used to derive
109 pointers to XSAVE state components in the extended state
110 area. */
111 unsigned char *xsave ()
112 { return reinterpret_cast<unsigned char *> (this); }
114 public:
115 /* Memory address of eight upper 128-bit YMM values, or 16 on x86-64. */
116 unsigned char *ymmh_space ()
117 { return xsave () + xsave_layout.avx_offset; }
119 /* Memory address of 8 OpMask register values of 64 bits. */
120 unsigned char *k_space ()
121 { return xsave () + xsave_layout.k_offset; }
123 /* Memory address of 16 256-bit zmm0-15. */
124 unsigned char *zmmh_space ()
125 { return xsave () + xsave_layout.zmm_h_offset; }
127 /* Memory address of 16 512-bit zmm16-31 values. */
128 unsigned char *zmm16_space ()
129 { return xsave () + xsave_layout.zmm_offset; }
131 /* Memory address of 1 32-bit PKRU register. The HW XSTATE size for this
132 feature is actually 64 bits, but WRPKRU/RDPKRU instructions ignore upper
133 32 bits. */
134 unsigned char *pkru_space ()
135 { return xsave () + xsave_layout.pkru_offset; }
138 static_assert (sizeof(i387_xsave) == 576);
140 void
141 i387_cache_to_fsave (struct regcache *regcache, void *buf)
143 struct i387_fsave *fp = (struct i387_fsave *) buf;
144 int i;
145 int st0_regnum = find_regno (regcache->tdesc, "st0");
146 unsigned long val2;
148 for (i = 0; i < 8; i++)
149 collect_register (regcache, i + st0_regnum,
150 ((char *) &fp->st_space[0]) + i * 10);
152 fp->fioff = regcache_raw_get_unsigned_by_name (regcache, "fioff");
153 fp->fooff = regcache_raw_get_unsigned_by_name (regcache, "fooff");
155 /* This one's 11 bits... */
156 val2 = regcache_raw_get_unsigned_by_name (regcache, "fop");
157 fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
159 /* Some registers are 16-bit. */
160 fp->fctrl = regcache_raw_get_unsigned_by_name (regcache, "fctrl");
161 fp->fstat = regcache_raw_get_unsigned_by_name (regcache, "fstat");
162 fp->ftag = regcache_raw_get_unsigned_by_name (regcache, "ftag");
163 fp->fiseg = regcache_raw_get_unsigned_by_name (regcache, "fiseg");
164 fp->foseg = regcache_raw_get_unsigned_by_name (regcache, "foseg");
167 void
168 i387_fsave_to_cache (struct regcache *regcache, const void *buf)
170 struct i387_fsave *fp = (struct i387_fsave *) buf;
171 int i;
172 int st0_regnum = find_regno (regcache->tdesc, "st0");
173 unsigned long val;
175 for (i = 0; i < 8; i++)
176 supply_register (regcache, i + st0_regnum,
177 ((char *) &fp->st_space[0]) + i * 10);
179 supply_register_by_name (regcache, "fioff", &fp->fioff);
180 supply_register_by_name (regcache, "fooff", &fp->fooff);
182 /* Some registers are 16-bit. */
183 val = fp->fctrl & 0xFFFF;
184 supply_register_by_name (regcache, "fctrl", &val);
186 val = fp->fstat & 0xFFFF;
187 supply_register_by_name (regcache, "fstat", &val);
189 val = fp->ftag & 0xFFFF;
190 supply_register_by_name (regcache, "ftag", &val);
192 val = fp->fiseg & 0xFFFF;
193 supply_register_by_name (regcache, "fiseg", &val);
195 val = fp->foseg & 0xFFFF;
196 supply_register_by_name (regcache, "foseg", &val);
198 /* fop has only 11 valid bits. */
199 val = (fp->fop) & 0x7FF;
200 supply_register_by_name (regcache, "fop", &val);
203 void
204 i387_cache_to_fxsave (struct regcache *regcache, void *buf)
206 struct i387_fxsave *fp = (struct i387_fxsave *) buf;
207 int i;
208 int st0_regnum = find_regno (regcache->tdesc, "st0");
209 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
210 unsigned long val, val2;
211 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
212 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
214 for (i = 0; i < 8; i++)
215 collect_register (regcache, i + st0_regnum,
216 ((char *) &fp->st_space[0]) + i * 16);
217 for (i = 0; i < num_xmm_registers; i++)
218 collect_register (regcache, i + xmm0_regnum,
219 ((char *) &fp->xmm_space[0]) + i * 16);
221 fp->fioff = regcache_raw_get_unsigned_by_name (regcache, "fioff");
222 fp->fooff = regcache_raw_get_unsigned_by_name (regcache, "fooff");
223 fp->mxcsr = regcache_raw_get_unsigned_by_name (regcache, "mxcsr");
225 /* This one's 11 bits... */
226 val2 = regcache_raw_get_unsigned_by_name (regcache, "fop");
227 fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
229 /* Some registers are 16-bit. */
230 fp->fctrl = regcache_raw_get_unsigned_by_name (regcache, "fctrl");
231 fp->fstat = regcache_raw_get_unsigned_by_name (regcache, "fstat");
233 /* Convert to the simplifed tag form stored in fxsave data. */
234 val = regcache_raw_get_unsigned_by_name (regcache, "ftag");
235 val2 = 0;
236 for (i = 7; i >= 0; i--)
238 int tag = (val >> (i * 2)) & 3;
240 if (tag != 3)
241 val2 |= (1 << i);
243 fp->ftag = val2;
245 fp->fiseg = regcache_raw_get_unsigned_by_name (regcache, "fiseg");
246 fp->foseg = regcache_raw_get_unsigned_by_name (regcache, "foseg");
249 void
250 i387_cache_to_xsave (struct regcache *regcache, void *buf)
252 struct i387_xsave *fp = (struct i387_xsave *) buf;
253 bool amd64 = register_size (regcache->tdesc, 0) == 8;
254 int i;
255 unsigned long val, val2;
256 unsigned long long xstate_bv = 0;
257 unsigned long long clear_bv = 0;
258 char raw[64];
259 unsigned char *p;
261 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
262 int num_xmm_registers = amd64 ? 16 : 8;
263 /* AVX512 adds 16 extra ZMM regs in Amd64 mode, but none in I386 mode.*/
264 int num_zmm_high_registers = amd64 ? 16 : 0;
266 /* The supported bits in `xstat_bv' are 8 bytes. Clear part in
267 vector registers if its bit in xstat_bv is zero. */
268 clear_bv = (~fp->xstate_bv) & x86_xcr0;
270 /* Clear part in x87 and vector registers if its bit in xstat_bv is
271 zero. */
272 if (clear_bv)
274 if ((clear_bv & X86_XSTATE_X87))
276 for (i = 0; i < 8; i++)
277 memset (((char *) &fp->st_space[0]) + i * 16, 0, 10);
279 fp->fioff = 0;
280 fp->fooff = 0;
281 fp->fctrl = I387_FCTRL_INIT_VAL;
282 fp->fstat = 0;
283 fp->ftag = 0;
284 fp->fiseg = 0;
285 fp->foseg = 0;
286 fp->fop = 0;
289 if ((clear_bv & X86_XSTATE_SSE))
290 for (i = 0; i < num_xmm_registers; i++)
291 memset (((char *) &fp->xmm_space[0]) + i * 16, 0, 16);
293 if ((clear_bv & X86_XSTATE_AVX))
294 for (i = 0; i < num_xmm_registers; i++)
295 memset (fp->ymmh_space () + i * 16, 0, 16);
297 if ((clear_bv & X86_XSTATE_SSE) && (clear_bv & X86_XSTATE_AVX))
298 memset (((char *) &fp->mxcsr), 0, 4);
300 if ((clear_bv & X86_XSTATE_K))
301 for (i = 0; i < num_avx512_k_registers; i++)
302 memset (fp->k_space () + i * 8, 0, 8);
304 if ((clear_bv & X86_XSTATE_ZMM_H))
305 for (i = 0; i < num_xmm_registers; i++)
306 memset (fp->zmmh_space () + i * 32, 0, 32);
308 if ((clear_bv & X86_XSTATE_ZMM))
309 for (i = 0; i < num_zmm_high_registers; i++)
310 memset (fp->zmm16_space () + i * 64, 0, 64);
312 if ((clear_bv & X86_XSTATE_PKRU))
313 for (i = 0; i < num_pkeys_registers; i++)
314 memset (fp->pkru_space () + i * 4, 0, 4);
317 /* Check if any x87 registers are changed. */
318 if ((x86_xcr0 & X86_XSTATE_X87))
320 int st0_regnum = find_regno (regcache->tdesc, "st0");
322 for (i = 0; i < 8; i++)
324 collect_register (regcache, i + st0_regnum, raw);
325 p = fp->st_space + i * 16;
326 if (memcmp (raw, p, 10))
328 xstate_bv |= X86_XSTATE_X87;
329 memcpy (p, raw, 10);
334 /* Check if any SSE registers are changed. */
335 if ((x86_xcr0 & X86_XSTATE_SSE))
337 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
339 for (i = 0; i < num_xmm_registers; i++)
341 collect_register (regcache, i + xmm0_regnum, raw);
342 p = fp->xmm_space + i * 16;
343 if (memcmp (raw, p, 16))
345 xstate_bv |= X86_XSTATE_SSE;
346 memcpy (p, raw, 16);
351 /* Check if any AVX registers are changed. */
352 if ((x86_xcr0 & X86_XSTATE_AVX))
354 int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
356 for (i = 0; i < num_xmm_registers; i++)
358 collect_register (regcache, i + ymm0h_regnum, raw);
359 p = fp->ymmh_space () + i * 16;
360 if (memcmp (raw, p, 16))
362 xstate_bv |= X86_XSTATE_AVX;
363 memcpy (p, raw, 16);
368 /* Check if any K registers are changed. */
369 if ((x86_xcr0 & X86_XSTATE_K))
371 int k0_regnum = find_regno (regcache->tdesc, "k0");
373 for (i = 0; i < num_avx512_k_registers; i++)
375 collect_register (regcache, i + k0_regnum, raw);
376 p = fp->k_space () + i * 8;
377 if (memcmp (raw, p, 8) != 0)
379 xstate_bv |= X86_XSTATE_K;
380 memcpy (p, raw, 8);
385 /* Check if any of ZMM0H-ZMM15H registers are changed. */
386 if ((x86_xcr0 & X86_XSTATE_ZMM_H))
388 int zmm0h_regnum = find_regno (regcache->tdesc, "zmm0h");
390 for (i = 0; i < num_xmm_registers; i++)
392 collect_register (regcache, i + zmm0h_regnum, raw);
393 p = fp->zmmh_space () + i * 32;
394 if (memcmp (raw, p, 32) != 0)
396 xstate_bv |= X86_XSTATE_ZMM_H;
397 memcpy (p, raw, 32);
402 /* Check if any of ZMM16-ZMM31 registers are changed. */
403 if ((x86_xcr0 & X86_XSTATE_ZMM) && num_zmm_high_registers != 0)
405 int zmm16h_regnum = find_regno (regcache->tdesc, "zmm16h");
406 int ymm16h_regnum = find_regno (regcache->tdesc, "ymm16h");
407 int xmm16_regnum = find_regno (regcache->tdesc, "xmm16");
409 for (i = 0; i < num_zmm_high_registers; i++)
411 p = fp->zmm16_space () + i * 64;
413 /* ZMMH sub-register. */
414 collect_register (regcache, i + zmm16h_regnum, raw);
415 if (memcmp (raw, p + 32, 32) != 0)
417 xstate_bv |= X86_XSTATE_ZMM;
418 memcpy (p + 32, raw, 32);
421 /* YMMH sub-register. */
422 collect_register (regcache, i + ymm16h_regnum, raw);
423 if (memcmp (raw, p + 16, 16) != 0)
425 xstate_bv |= X86_XSTATE_ZMM;
426 memcpy (p + 16, raw, 16);
429 /* XMM sub-register. */
430 collect_register (regcache, i + xmm16_regnum, raw);
431 if (memcmp (raw, p, 16) != 0)
433 xstate_bv |= X86_XSTATE_ZMM;
434 memcpy (p, raw, 16);
439 /* Check if any PKEYS registers are changed. */
440 if ((x86_xcr0 & X86_XSTATE_PKRU))
442 int pkru_regnum = find_regno (regcache->tdesc, "pkru");
444 for (i = 0; i < num_pkeys_registers; i++)
446 collect_register (regcache, i + pkru_regnum, raw);
447 p = fp->pkru_space () + i * 4;
448 if (memcmp (raw, p, 4) != 0)
450 xstate_bv |= X86_XSTATE_PKRU;
451 memcpy (p, raw, 4);
456 if ((x86_xcr0 & X86_XSTATE_SSE) || (x86_xcr0 & X86_XSTATE_AVX))
458 collect_register_by_name (regcache, "mxcsr", raw);
459 if (memcmp (raw, &fp->mxcsr, 4) != 0)
461 if (((fp->xstate_bv | xstate_bv)
462 & (X86_XSTATE_SSE | X86_XSTATE_AVX)) == 0)
463 xstate_bv |= X86_XSTATE_SSE;
464 memcpy (&fp->mxcsr, raw, 4);
468 if (x86_xcr0 & X86_XSTATE_X87)
470 collect_register_by_name (regcache, "fioff", raw);
471 if (memcmp (raw, &fp->fioff, 4) != 0)
473 xstate_bv |= X86_XSTATE_X87;
474 memcpy (&fp->fioff, raw, 4);
477 collect_register_by_name (regcache, "fooff", raw);
478 if (memcmp (raw, &fp->fooff, 4) != 0)
480 xstate_bv |= X86_XSTATE_X87;
481 memcpy (&fp->fooff, raw, 4);
484 /* This one's 11 bits... */
485 val2 = regcache_raw_get_unsigned_by_name (regcache, "fop");
486 val2 = (val2 & 0x7FF) | (fp->fop & 0xF800);
487 if (fp->fop != val2)
489 xstate_bv |= X86_XSTATE_X87;
490 fp->fop = val2;
493 /* Some registers are 16-bit. */
494 val = regcache_raw_get_unsigned_by_name (regcache, "fctrl");
495 if (fp->fctrl != val)
497 xstate_bv |= X86_XSTATE_X87;
498 fp->fctrl = val;
501 val = regcache_raw_get_unsigned_by_name (regcache, "fstat");
502 if (fp->fstat != val)
504 xstate_bv |= X86_XSTATE_X87;
505 fp->fstat = val;
508 /* Convert to the simplifed tag form stored in fxsave data. */
509 val = regcache_raw_get_unsigned_by_name (regcache, "ftag");
510 val2 = 0;
511 for (i = 7; i >= 0; i--)
513 int tag = (val >> (i * 2)) & 3;
515 if (tag != 3)
516 val2 |= (1 << i);
518 if (fp->ftag != val2)
520 xstate_bv |= X86_XSTATE_X87;
521 fp->ftag = val2;
524 val = regcache_raw_get_unsigned_by_name (regcache, "fiseg");
525 if (fp->fiseg != val)
527 xstate_bv |= X86_XSTATE_X87;
528 fp->fiseg = val;
531 val = regcache_raw_get_unsigned_by_name (regcache, "foseg");
532 if (fp->foseg != val)
534 xstate_bv |= X86_XSTATE_X87;
535 fp->foseg = val;
539 /* Update the corresponding bits in xstate_bv if any SSE/AVX
540 registers are changed. */
541 fp->xstate_bv |= xstate_bv;
544 static int
545 i387_ftag (struct i387_fxsave *fp, int regno)
547 unsigned char *raw = &fp->st_space[regno * 16];
548 unsigned int exponent;
549 unsigned long fraction[2];
550 int integer;
552 integer = raw[7] & 0x80;
553 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
554 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
555 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
556 | (raw[5] << 8) | raw[4]);
558 if (exponent == 0x7fff)
560 /* Special. */
561 return (2);
563 else if (exponent == 0x0000)
565 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
567 /* Zero. */
568 return (1);
570 else
572 /* Special. */
573 return (2);
576 else
578 if (integer)
580 /* Valid. */
581 return (0);
583 else
585 /* Special. */
586 return (2);
591 void
592 i387_fxsave_to_cache (struct regcache *regcache, const void *buf)
594 struct i387_fxsave *fp = (struct i387_fxsave *) buf;
595 int i, top;
596 int st0_regnum = find_regno (regcache->tdesc, "st0");
597 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
598 unsigned long val;
599 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
600 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
602 for (i = 0; i < 8; i++)
603 supply_register (regcache, i + st0_regnum,
604 ((char *) &fp->st_space[0]) + i * 16);
605 for (i = 0; i < num_xmm_registers; i++)
606 supply_register (regcache, i + xmm0_regnum,
607 ((char *) &fp->xmm_space[0]) + i * 16);
609 supply_register_by_name (regcache, "fioff", &fp->fioff);
610 supply_register_by_name (regcache, "fooff", &fp->fooff);
611 supply_register_by_name (regcache, "mxcsr", &fp->mxcsr);
613 /* Some registers are 16-bit. */
614 val = fp->fctrl & 0xFFFF;
615 supply_register_by_name (regcache, "fctrl", &val);
617 val = fp->fstat & 0xFFFF;
618 supply_register_by_name (regcache, "fstat", &val);
620 /* Generate the form of ftag data that GDB expects. */
621 top = (fp->fstat >> 11) & 0x7;
622 val = 0;
623 for (i = 7; i >= 0; i--)
625 int tag;
626 if (fp->ftag & (1 << i))
627 tag = i387_ftag (fp, (i + 8 - top) % 8);
628 else
629 tag = 3;
630 val |= tag << (2 * i);
632 supply_register_by_name (regcache, "ftag", &val);
634 val = fp->fiseg & 0xFFFF;
635 supply_register_by_name (regcache, "fiseg", &val);
637 val = fp->foseg & 0xFFFF;
638 supply_register_by_name (regcache, "foseg", &val);
640 val = (fp->fop) & 0x7FF;
641 supply_register_by_name (regcache, "fop", &val);
644 void
645 i387_xsave_to_cache (struct regcache *regcache, const void *buf)
647 struct i387_xsave *fp = (struct i387_xsave *) buf;
648 bool amd64 = register_size (regcache->tdesc, 0) == 8;
649 int i, top;
650 unsigned long val;
651 unsigned long long clear_bv;
652 unsigned char *p;
654 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
655 int num_xmm_registers = amd64 ? 16 : 8;
656 /* AVX512 adds 16 extra ZMM regs in Amd64 mode, but none in I386 mode.*/
657 int num_zmm_high_registers = amd64 ? 16 : 0;
659 /* The supported bits in `xstat_bv' are 8 bytes. Clear part in
660 vector registers if its bit in xstat_bv is zero. */
661 clear_bv = (~fp->xstate_bv) & x86_xcr0;
663 /* Check if any x87 registers are changed. */
664 if ((x86_xcr0 & X86_XSTATE_X87) != 0)
666 int st0_regnum = find_regno (regcache->tdesc, "st0");
668 if ((clear_bv & X86_XSTATE_X87) != 0)
670 for (i = 0; i < 8; i++)
671 supply_register_zeroed (regcache, i + st0_regnum);
673 else
675 p = (gdb_byte *) &fp->st_space[0];
676 for (i = 0; i < 8; i++)
677 supply_register (regcache, i + st0_regnum, p + i * 16);
681 if ((x86_xcr0 & X86_XSTATE_SSE) != 0)
683 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
685 if ((clear_bv & X86_XSTATE_SSE))
687 for (i = 0; i < num_xmm_registers; i++)
688 supply_register_zeroed (regcache, i + xmm0_regnum);
690 else
692 p = (gdb_byte *) &fp->xmm_space[0];
693 for (i = 0; i < num_xmm_registers; i++)
694 supply_register (regcache, i + xmm0_regnum, p + i * 16);
698 if ((x86_xcr0 & X86_XSTATE_AVX) != 0)
700 int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
702 if ((clear_bv & X86_XSTATE_AVX) != 0)
704 for (i = 0; i < num_xmm_registers; i++)
705 supply_register_zeroed (regcache, i + ymm0h_regnum);
707 else
709 p = fp->ymmh_space ();
710 for (i = 0; i < num_xmm_registers; i++)
711 supply_register (regcache, i + ymm0h_regnum, p + i * 16);
715 if ((x86_xcr0 & X86_XSTATE_K) != 0)
717 int k0_regnum = find_regno (regcache->tdesc, "k0");
719 if ((clear_bv & X86_XSTATE_K) != 0)
721 for (i = 0; i < num_avx512_k_registers; i++)
722 supply_register_zeroed (regcache, i + k0_regnum);
724 else
726 p = fp->k_space ();
727 for (i = 0; i < num_avx512_k_registers; i++)
728 supply_register (regcache, i + k0_regnum, p + i * 8);
732 if ((x86_xcr0 & X86_XSTATE_ZMM_H) != 0)
734 int zmm0h_regnum = find_regno (regcache->tdesc, "zmm0h");
736 if ((clear_bv & X86_XSTATE_ZMM_H) != 0)
738 for (i = 0; i < num_xmm_registers; i++)
739 supply_register_zeroed (regcache, i + zmm0h_regnum);
741 else
743 p = fp->zmmh_space ();
744 for (i = 0; i < num_xmm_registers; i++)
745 supply_register (regcache, i + zmm0h_regnum, p + i * 32);
749 if ((x86_xcr0 & X86_XSTATE_ZMM) != 0 && num_zmm_high_registers != 0)
751 int zmm16h_regnum = find_regno (regcache->tdesc, "zmm16h");
752 int ymm16h_regnum = find_regno (regcache->tdesc, "ymm16h");
753 int xmm16_regnum = find_regno (regcache->tdesc, "xmm16");
755 if ((clear_bv & X86_XSTATE_ZMM) != 0)
757 for (i = 0; i < num_zmm_high_registers; i++)
759 supply_register_zeroed (regcache, i + zmm16h_regnum);
760 supply_register_zeroed (regcache, i + ymm16h_regnum);
761 supply_register_zeroed (regcache, i + xmm16_regnum);
764 else
766 p = fp->zmm16_space ();
767 for (i = 0; i < num_zmm_high_registers; i++)
769 supply_register (regcache, i + zmm16h_regnum, p + 32 + i * 64);
770 supply_register (regcache, i + ymm16h_regnum, p + 16 + i * 64);
771 supply_register (regcache, i + xmm16_regnum, p + i * 64);
776 if ((x86_xcr0 & X86_XSTATE_PKRU) != 0)
778 int pkru_regnum = find_regno (regcache->tdesc, "pkru");
780 if ((clear_bv & X86_XSTATE_PKRU) != 0)
782 for (i = 0; i < num_pkeys_registers; i++)
783 supply_register_zeroed (regcache, i + pkru_regnum);
785 else
787 p = fp->pkru_space ();
788 for (i = 0; i < num_pkeys_registers; i++)
789 supply_register (regcache, i + pkru_regnum, p + i * 4);
793 if ((clear_bv & (X86_XSTATE_SSE | X86_XSTATE_AVX))
794 == (X86_XSTATE_SSE | X86_XSTATE_AVX))
796 unsigned int default_mxcsr = I387_MXCSR_INIT_VAL;
797 supply_register_by_name (regcache, "mxcsr", &default_mxcsr);
799 else
800 supply_register_by_name (regcache, "mxcsr", &fp->mxcsr);
802 if ((clear_bv & X86_XSTATE_X87) != 0)
804 supply_register_by_name_zeroed (regcache, "fioff");
805 supply_register_by_name_zeroed (regcache, "fooff");
807 val = I387_FCTRL_INIT_VAL;
808 supply_register_by_name (regcache, "fctrl", &val);
810 supply_register_by_name_zeroed (regcache, "fstat");
812 val = 0xFFFF;
813 supply_register_by_name (regcache, "ftag", &val);
815 supply_register_by_name_zeroed (regcache, "fiseg");
816 supply_register_by_name_zeroed (regcache, "foseg");
817 supply_register_by_name_zeroed (regcache, "fop");
819 else
821 supply_register_by_name (regcache, "fioff", &fp->fioff);
822 supply_register_by_name (regcache, "fooff", &fp->fooff);
824 /* Some registers are 16-bit. */
825 val = fp->fctrl & 0xFFFF;
826 supply_register_by_name (regcache, "fctrl", &val);
828 val = fp->fstat & 0xFFFF;
829 supply_register_by_name (regcache, "fstat", &val);
831 /* Generate the form of ftag data that GDB expects. */
832 top = (fp->fstat >> 11) & 0x7;
833 val = 0;
834 for (i = 7; i >= 0; i--)
836 int tag;
837 if (fp->ftag & (1 << i))
838 tag = i387_ftag (fp, (i + 8 - top) % 8);
839 else
840 tag = 3;
841 val |= tag << (2 * i);
843 supply_register_by_name (regcache, "ftag", &val);
845 val = fp->fiseg & 0xFFFF;
846 supply_register_by_name (regcache, "fiseg", &val);
848 val = fp->foseg & 0xFFFF;
849 supply_register_by_name (regcache, "foseg", &val);
851 val = (fp->fop) & 0x7FF;
852 supply_register_by_name (regcache, "fop", &val);
856 /* See i387-fp.h. */
858 std::pair<uint64_t *, x86_xsave_layout *>
859 i387_get_xsave_storage ()
861 return { &x86_xcr0, &xsave_layout };