Add support for Intel PKRU register to GDB and GDBserver.
[deliverable/binutils-gdb.git] / gdb / gdbserver / i387-fp.c
1 /* i387-specific utility functions, for the remote server for GDB.
2 Copyright (C) 2000-2017 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
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.
10
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.
15
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/>. */
18
19 #include "server.h"
20 #include "i387-fp.h"
21 #include "x86-xstate.h"
22
23 static const int num_mpx_bnd_registers = 4;
24 static const int num_mpx_cfg_registers = 2;
25 static const int num_avx512_k_registers = 8;
26 static const int num_avx512_zmmh_low_registers = 16;
27 static const int num_avx512_zmmh_high_registers = 16;
28 static const int num_avx512_ymmh_registers = 16;
29 static const int num_avx512_xmm_registers = 16;
30 static const int num_pkeys_registers = 1;
31
32 /* Note: These functions preserve the reserved bits in control registers.
33 However, gdbserver promptly throws away that information. */
34
35 /* These structs should have the proper sizes and alignment on both
36 i386 and x86-64 machines. */
37
38 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;
53
54 /* Space for eight 80-bit FP values. */
55 unsigned char st_space[80];
56 };
57
58 struct i387_fxsave {
59 /* All these are only sixteen bits, plus padding, except for fop (which
60 is only eleven bits), and fooff / fioff (which are 32 bits each). */
61 unsigned short fctrl;
62 unsigned short fstat;
63 unsigned short ftag;
64 unsigned short fop;
65 unsigned int fioff;
66 unsigned short fiseg;
67 unsigned short pad1;
68 unsigned int fooff;
69 unsigned short foseg;
70 unsigned short pad12;
71
72 unsigned int mxcsr;
73 unsigned int pad3;
74
75 /* Space for eight 80-bit FP values in 128-bit spaces. */
76 unsigned char st_space[128];
77
78 /* Space for eight 128-bit XMM values, or 16 on x86-64. */
79 unsigned char xmm_space[256];
80 };
81
82 struct i387_xsave {
83 /* All these are only sixteen bits, plus padding, except for fop (which
84 is only eleven bits), and fooff / fioff (which are 32 bits each). */
85 unsigned short fctrl;
86 unsigned short fstat;
87 unsigned short ftag;
88 unsigned short fop;
89 unsigned int fioff;
90 unsigned short fiseg;
91 unsigned short pad1;
92 unsigned int fooff;
93 unsigned short foseg;
94 unsigned short pad12;
95
96 unsigned int mxcsr;
97 unsigned int mxcsr_mask;
98
99 /* Space for eight 80-bit FP values in 128-bit spaces. */
100 unsigned char st_space[128];
101
102 /* Space for eight 128-bit XMM values, or 16 on x86-64. */
103 unsigned char xmm_space[256];
104
105 unsigned char reserved1[48];
106
107 /* The extended control register 0 (the XFEATURE_ENABLED_MASK
108 register). */
109 unsigned long long xcr0;
110
111 unsigned char reserved2[40];
112
113 /* The XSTATE_BV bit vector. */
114 unsigned long long xstate_bv;
115
116 unsigned char reserved3[56];
117
118 /* Space for eight upper 128-bit YMM values, or 16 on x86-64. */
119 unsigned char ymmh_space[256];
120
121 unsigned char reserved4[128];
122
123 /* Space for 4 bound registers values of 128 bits. */
124 unsigned char mpx_bnd_space[64];
125
126 /* Space for 2 MPX configuration registers of 64 bits
127 plus reserved space. */
128 unsigned char mpx_cfg_space[16];
129
130 unsigned char reserved5[48];
131
132 /* Space for 8 OpMask register values of 64 bits. */
133 unsigned char k_space[64];
134
135 /* Space for 16 256-bit zmm0-15. */
136 unsigned char zmmh_low_space[512];
137
138 /* Space for 16 512-bit zmm16-31 values. */
139 unsigned char zmmh_high_space[1024];
140
141 /* Space for 1 32-bit PKRU register. The HW XSTATE size for this feature is
142 actually 64 bits, but WRPKRU/RDPKRU instructions ignore upper 32 bits. */
143 unsigned char pkru_space[8];
144 };
145
146 void
147 i387_cache_to_fsave (struct regcache *regcache, void *buf)
148 {
149 struct i387_fsave *fp = (struct i387_fsave *) buf;
150 int i;
151 int st0_regnum = find_regno (regcache->tdesc, "st0");
152 unsigned long val, val2;
153
154 for (i = 0; i < 8; i++)
155 collect_register (regcache, i + st0_regnum,
156 ((char *) &fp->st_space[0]) + i * 10);
157
158 collect_register_by_name (regcache, "fioff", &fp->fioff);
159 collect_register_by_name (regcache, "fooff", &fp->fooff);
160
161 /* This one's 11 bits... */
162 collect_register_by_name (regcache, "fop", &val2);
163 fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
164
165 /* Some registers are 16-bit. */
166 collect_register_by_name (regcache, "fctrl", &val);
167 fp->fctrl = val;
168
169 collect_register_by_name (regcache, "fstat", &val);
170 val &= 0xFFFF;
171 fp->fstat = val;
172
173 collect_register_by_name (regcache, "ftag", &val);
174 val &= 0xFFFF;
175 fp->ftag = val;
176
177 collect_register_by_name (regcache, "fiseg", &val);
178 val &= 0xFFFF;
179 fp->fiseg = val;
180
181 collect_register_by_name (regcache, "foseg", &val);
182 val &= 0xFFFF;
183 fp->foseg = val;
184 }
185
186 void
187 i387_fsave_to_cache (struct regcache *regcache, const void *buf)
188 {
189 struct i387_fsave *fp = (struct i387_fsave *) buf;
190 int i;
191 int st0_regnum = find_regno (regcache->tdesc, "st0");
192 unsigned long val;
193
194 for (i = 0; i < 8; i++)
195 supply_register (regcache, i + st0_regnum,
196 ((char *) &fp->st_space[0]) + i * 10);
197
198 supply_register_by_name (regcache, "fioff", &fp->fioff);
199 supply_register_by_name (regcache, "fooff", &fp->fooff);
200
201 /* Some registers are 16-bit. */
202 val = fp->fctrl & 0xFFFF;
203 supply_register_by_name (regcache, "fctrl", &val);
204
205 val = fp->fstat & 0xFFFF;
206 supply_register_by_name (regcache, "fstat", &val);
207
208 val = fp->ftag & 0xFFFF;
209 supply_register_by_name (regcache, "ftag", &val);
210
211 val = fp->fiseg & 0xFFFF;
212 supply_register_by_name (regcache, "fiseg", &val);
213
214 val = fp->foseg & 0xFFFF;
215 supply_register_by_name (regcache, "foseg", &val);
216
217 /* fop has only 11 valid bits. */
218 val = (fp->fop) & 0x7FF;
219 supply_register_by_name (regcache, "fop", &val);
220 }
221
222 void
223 i387_cache_to_fxsave (struct regcache *regcache, void *buf)
224 {
225 struct i387_fxsave *fp = (struct i387_fxsave *) buf;
226 int i;
227 int st0_regnum = find_regno (regcache->tdesc, "st0");
228 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
229 unsigned long val, val2;
230 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
231 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
232
233 for (i = 0; i < 8; i++)
234 collect_register (regcache, i + st0_regnum,
235 ((char *) &fp->st_space[0]) + i * 16);
236 for (i = 0; i < num_xmm_registers; i++)
237 collect_register (regcache, i + xmm0_regnum,
238 ((char *) &fp->xmm_space[0]) + i * 16);
239
240 collect_register_by_name (regcache, "fioff", &fp->fioff);
241 collect_register_by_name (regcache, "fooff", &fp->fooff);
242 collect_register_by_name (regcache, "mxcsr", &fp->mxcsr);
243
244 /* This one's 11 bits... */
245 collect_register_by_name (regcache, "fop", &val2);
246 fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
247
248 /* Some registers are 16-bit. */
249 collect_register_by_name (regcache, "fctrl", &val);
250 fp->fctrl = val;
251
252 collect_register_by_name (regcache, "fstat", &val);
253 fp->fstat = val;
254
255 /* Convert to the simplifed tag form stored in fxsave data. */
256 collect_register_by_name (regcache, "ftag", &val);
257 val &= 0xFFFF;
258 val2 = 0;
259 for (i = 7; i >= 0; i--)
260 {
261 int tag = (val >> (i * 2)) & 3;
262
263 if (tag != 3)
264 val2 |= (1 << i);
265 }
266 fp->ftag = val2;
267
268 collect_register_by_name (regcache, "fiseg", &val);
269 fp->fiseg = val;
270
271 collect_register_by_name (regcache, "foseg", &val);
272 fp->foseg = val;
273 }
274
275 void
276 i387_cache_to_xsave (struct regcache *regcache, void *buf)
277 {
278 struct i387_xsave *fp = (struct i387_xsave *) buf;
279 int i;
280 unsigned long val, val2;
281 unsigned long long xstate_bv = 0;
282 unsigned long long clear_bv = 0;
283 char raw[64];
284 char *p;
285 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
286 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
287
288 /* The supported bits in `xstat_bv' are 8 bytes. Clear part in
289 vector registers if its bit in xstat_bv is zero. */
290 clear_bv = (~fp->xstate_bv) & x86_xcr0;
291
292 /* Clear part in x87 and vector registers if its bit in xstat_bv is
293 zero. */
294 if (clear_bv)
295 {
296 if ((clear_bv & X86_XSTATE_X87))
297 for (i = 0; i < 8; i++)
298 memset (((char *) &fp->st_space[0]) + i * 16, 0, 10);
299
300 if ((clear_bv & X86_XSTATE_SSE))
301 for (i = 0; i < num_xmm_registers; i++)
302 memset (((char *) &fp->xmm_space[0]) + i * 16, 0, 16);
303
304 if ((clear_bv & X86_XSTATE_AVX))
305 for (i = 0; i < num_xmm_registers; i++)
306 memset (((char *) &fp->ymmh_space[0]) + i * 16, 0, 16);
307
308 if ((clear_bv & X86_XSTATE_BNDREGS))
309 for (i = 0; i < num_mpx_bnd_registers; i++)
310 memset (((char *) &fp->mpx_bnd_space[0]) + i * 16, 0, 16);
311
312 if ((clear_bv & X86_XSTATE_BNDCFG))
313 for (i = 0; i < num_mpx_cfg_registers; i++)
314 memset (((char *) &fp->mpx_cfg_space[0]) + i * 8, 0, 8);
315
316 if ((clear_bv & X86_XSTATE_K))
317 for (i = 0; i < num_avx512_k_registers; i++)
318 memset (((char *) &fp->k_space[0]) + i * 8, 0, 8);
319
320 if ((clear_bv & X86_XSTATE_ZMM_H))
321 for (i = 0; i < num_avx512_zmmh_low_registers; i++)
322 memset (((char *) &fp->zmmh_low_space[0]) + i * 32, 0, 32);
323
324 if ((clear_bv & X86_XSTATE_ZMM))
325 {
326 for (i = 0; i < num_avx512_zmmh_high_registers; i++)
327 memset (((char *) &fp->zmmh_low_space[0]) + 32 + i * 64, 0, 32);
328 for (i = 0; i < num_avx512_xmm_registers; i++)
329 memset (((char *) &fp->zmmh_high_space[0]) + i * 64, 0, 16);
330 for (i = 0; i < num_avx512_ymmh_registers; i++)
331 memset (((char *) &fp->zmmh_high_space[0]) + 16 + i * 64, 0, 16);
332 }
333
334 if ((clear_bv & X86_XSTATE_PKRU))
335 for (i = 0; i < num_pkeys_registers; i++)
336 memset (((char *) &fp->pkru_space[0]) + i * 4, 0, 4);
337 }
338
339 /* Check if any x87 registers are changed. */
340 if ((x86_xcr0 & X86_XSTATE_X87))
341 {
342 int st0_regnum = find_regno (regcache->tdesc, "st0");
343
344 for (i = 0; i < 8; i++)
345 {
346 collect_register (regcache, i + st0_regnum, raw);
347 p = ((char *) &fp->st_space[0]) + i * 16;
348 if (memcmp (raw, p, 10))
349 {
350 xstate_bv |= X86_XSTATE_X87;
351 memcpy (p, raw, 10);
352 }
353 }
354 }
355
356 /* Check if any SSE registers are changed. */
357 if ((x86_xcr0 & X86_XSTATE_SSE))
358 {
359 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
360
361 for (i = 0; i < num_xmm_registers; i++)
362 {
363 collect_register (regcache, i + xmm0_regnum, raw);
364 p = ((char *) &fp->xmm_space[0]) + i * 16;
365 if (memcmp (raw, p, 16))
366 {
367 xstate_bv |= X86_XSTATE_SSE;
368 memcpy (p, raw, 16);
369 }
370 }
371 }
372
373 /* Check if any AVX registers are changed. */
374 if ((x86_xcr0 & X86_XSTATE_AVX))
375 {
376 int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
377
378 for (i = 0; i < num_xmm_registers; i++)
379 {
380 collect_register (regcache, i + ymm0h_regnum, raw);
381 p = ((char *) &fp->ymmh_space[0]) + i * 16;
382 if (memcmp (raw, p, 16))
383 {
384 xstate_bv |= X86_XSTATE_AVX;
385 memcpy (p, raw, 16);
386 }
387 }
388 }
389
390 /* Check if any bound register has changed. */
391 if ((x86_xcr0 & X86_XSTATE_BNDREGS))
392 {
393 int bnd0r_regnum = find_regno (regcache->tdesc, "bnd0raw");
394
395 for (i = 0; i < num_mpx_bnd_registers; i++)
396 {
397 collect_register (regcache, i + bnd0r_regnum, raw);
398 p = ((char *) &fp->mpx_bnd_space[0]) + i * 16;
399 if (memcmp (raw, p, 16))
400 {
401 xstate_bv |= X86_XSTATE_BNDREGS;
402 memcpy (p, raw, 16);
403 }
404 }
405 }
406
407 /* Check if any status register has changed. */
408 if ((x86_xcr0 & X86_XSTATE_BNDCFG))
409 {
410 int bndcfg_regnum = find_regno (regcache->tdesc, "bndcfgu");
411
412 for (i = 0; i < num_mpx_cfg_registers; i++)
413 {
414 collect_register (regcache, i + bndcfg_regnum, raw);
415 p = ((char *) &fp->mpx_cfg_space[0]) + i * 8;
416 if (memcmp (raw, p, 8))
417 {
418 xstate_bv |= X86_XSTATE_BNDCFG;
419 memcpy (p, raw, 8);
420 }
421 }
422 }
423
424 /* Check if any K registers are changed. */
425 if ((x86_xcr0 & X86_XSTATE_K))
426 {
427 int k0_regnum = find_regno (regcache->tdesc, "k0");
428
429 for (i = 0; i < num_avx512_k_registers; i++)
430 {
431 collect_register (regcache, i + k0_regnum, raw);
432 p = ((char *) &fp->k_space[0]) + i * 8;
433 if (memcmp (raw, p, 8) != 0)
434 {
435 xstate_bv |= X86_XSTATE_K;
436 memcpy (p, raw, 8);
437 }
438 }
439 }
440
441 /* Check if any of ZMM0H-ZMM15H registers are changed. */
442 if ((x86_xcr0 & X86_XSTATE_ZMM_H))
443 {
444 int zmm0h_regnum = find_regno (regcache->tdesc, "zmm0h");
445
446 for (i = 0; i < num_avx512_zmmh_low_registers; i++)
447 {
448 collect_register (regcache, i + zmm0h_regnum, raw);
449 p = ((char *) &fp->zmmh_low_space[0]) + i * 32;
450 if (memcmp (raw, p, 32) != 0)
451 {
452 xstate_bv |= X86_XSTATE_ZMM_H;
453 memcpy (p, raw, 32);
454 }
455 }
456 }
457
458 /* Check if any of ZMM16H-ZMM31H registers are changed. */
459 if ((x86_xcr0 & X86_XSTATE_ZMM))
460 {
461 int zmm16h_regnum = find_regno (regcache->tdesc, "zmm16h");
462
463 for (i = 0; i < num_avx512_zmmh_high_registers; i++)
464 {
465 collect_register (regcache, i + zmm16h_regnum, raw);
466 p = ((char *) &fp->zmmh_high_space[0]) + 32 + i * 64;
467 if (memcmp (raw, p, 32) != 0)
468 {
469 xstate_bv |= X86_XSTATE_ZMM;
470 memcpy (p, raw, 32);
471 }
472 }
473 }
474
475 /* Check if any XMM_AVX512 registers are changed. */
476 if ((x86_xcr0 & X86_XSTATE_ZMM))
477 {
478 int xmm_avx512_regnum = find_regno (regcache->tdesc, "xmm16");
479
480 for (i = 0; i < num_avx512_xmm_registers; i++)
481 {
482 collect_register (regcache, i + xmm_avx512_regnum, raw);
483 p = ((char *) &fp->zmmh_high_space[0]) + i * 64;
484 if (memcmp (raw, p, 16) != 0)
485 {
486 xstate_bv |= X86_XSTATE_ZMM;
487 memcpy (p, raw, 16);
488 }
489 }
490 }
491
492 /* Check if any YMMH_AVX512 registers are changed. */
493 if ((x86_xcr0 & X86_XSTATE_ZMM))
494 {
495 int ymmh_avx512_regnum = find_regno (regcache->tdesc, "ymm16h");
496
497 for (i = 0; i < num_avx512_ymmh_registers; i++)
498 {
499 collect_register (regcache, i + ymmh_avx512_regnum, raw);
500 p = ((char *) &fp->zmmh_high_space[0]) + 16 + i * 64;
501 if (memcmp (raw, p, 16) != 0)
502 {
503 xstate_bv |= X86_XSTATE_ZMM;
504 memcpy (p, raw, 16);
505 }
506 }
507 }
508
509 /* Check if any PKEYS registers are changed. */
510 if ((x86_xcr0 & X86_XSTATE_PKRU))
511 {
512 int pkru_regnum = find_regno (regcache->tdesc, "pkru");
513
514 for (i = 0; i < num_pkeys_registers; i++)
515 {
516 collect_register (regcache, i + pkru_regnum, raw);
517 p = ((char *) &fp->pkru_space[0]) + i * 4;
518 if (memcmp (raw, p, 4) != 0)
519 {
520 xstate_bv |= X86_XSTATE_PKRU;
521 memcpy (p, raw, 4);
522 }
523 }
524 }
525
526 /* Update the corresponding bits in xstate_bv if any SSE/AVX
527 registers are changed. */
528 fp->xstate_bv |= xstate_bv;
529
530 collect_register_by_name (regcache, "fioff", &fp->fioff);
531 collect_register_by_name (regcache, "fooff", &fp->fooff);
532 collect_register_by_name (regcache, "mxcsr", &fp->mxcsr);
533
534 /* This one's 11 bits... */
535 collect_register_by_name (regcache, "fop", &val2);
536 fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
537
538 /* Some registers are 16-bit. */
539 collect_register_by_name (regcache, "fctrl", &val);
540 fp->fctrl = val;
541
542 collect_register_by_name (regcache, "fstat", &val);
543 fp->fstat = val;
544
545 /* Convert to the simplifed tag form stored in fxsave data. */
546 collect_register_by_name (regcache, "ftag", &val);
547 val &= 0xFFFF;
548 val2 = 0;
549 for (i = 7; i >= 0; i--)
550 {
551 int tag = (val >> (i * 2)) & 3;
552
553 if (tag != 3)
554 val2 |= (1 << i);
555 }
556 fp->ftag = val2;
557
558 collect_register_by_name (regcache, "fiseg", &val);
559 fp->fiseg = val;
560
561 collect_register_by_name (regcache, "foseg", &val);
562 fp->foseg = val;
563 }
564
565 static int
566 i387_ftag (struct i387_fxsave *fp, int regno)
567 {
568 unsigned char *raw = &fp->st_space[regno * 16];
569 unsigned int exponent;
570 unsigned long fraction[2];
571 int integer;
572
573 integer = raw[7] & 0x80;
574 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
575 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
576 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
577 | (raw[5] << 8) | raw[4]);
578
579 if (exponent == 0x7fff)
580 {
581 /* Special. */
582 return (2);
583 }
584 else if (exponent == 0x0000)
585 {
586 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
587 {
588 /* Zero. */
589 return (1);
590 }
591 else
592 {
593 /* Special. */
594 return (2);
595 }
596 }
597 else
598 {
599 if (integer)
600 {
601 /* Valid. */
602 return (0);
603 }
604 else
605 {
606 /* Special. */
607 return (2);
608 }
609 }
610 }
611
612 void
613 i387_fxsave_to_cache (struct regcache *regcache, const void *buf)
614 {
615 struct i387_fxsave *fp = (struct i387_fxsave *) buf;
616 int i, top;
617 int st0_regnum = find_regno (regcache->tdesc, "st0");
618 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
619 unsigned long val;
620 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
621 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
622
623 for (i = 0; i < 8; i++)
624 supply_register (regcache, i + st0_regnum,
625 ((char *) &fp->st_space[0]) + i * 16);
626 for (i = 0; i < num_xmm_registers; i++)
627 supply_register (regcache, i + xmm0_regnum,
628 ((char *) &fp->xmm_space[0]) + i * 16);
629
630 supply_register_by_name (regcache, "fioff", &fp->fioff);
631 supply_register_by_name (regcache, "fooff", &fp->fooff);
632 supply_register_by_name (regcache, "mxcsr", &fp->mxcsr);
633
634 /* Some registers are 16-bit. */
635 val = fp->fctrl & 0xFFFF;
636 supply_register_by_name (regcache, "fctrl", &val);
637
638 val = fp->fstat & 0xFFFF;
639 supply_register_by_name (regcache, "fstat", &val);
640
641 /* Generate the form of ftag data that GDB expects. */
642 top = (fp->fstat >> 11) & 0x7;
643 val = 0;
644 for (i = 7; i >= 0; i--)
645 {
646 int tag;
647 if (fp->ftag & (1 << i))
648 tag = i387_ftag (fp, (i + 8 - top) % 8);
649 else
650 tag = 3;
651 val |= tag << (2 * i);
652 }
653 supply_register_by_name (regcache, "ftag", &val);
654
655 val = fp->fiseg & 0xFFFF;
656 supply_register_by_name (regcache, "fiseg", &val);
657
658 val = fp->foseg & 0xFFFF;
659 supply_register_by_name (regcache, "foseg", &val);
660
661 val = (fp->fop) & 0x7FF;
662 supply_register_by_name (regcache, "fop", &val);
663 }
664
665 void
666 i387_xsave_to_cache (struct regcache *regcache, const void *buf)
667 {
668 struct i387_xsave *fp = (struct i387_xsave *) buf;
669 struct i387_fxsave *fxp = (struct i387_fxsave *) buf;
670 int i, top;
671 unsigned long val;
672 unsigned long long clear_bv;
673 gdb_byte *p;
674 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
675 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
676
677 /* The supported bits in `xstat_bv' are 8 bytes. Clear part in
678 vector registers if its bit in xstat_bv is zero. */
679 clear_bv = (~fp->xstate_bv) & x86_xcr0;
680
681 /* Check if any x87 registers are changed. */
682 if ((x86_xcr0 & X86_XSTATE_X87) != 0)
683 {
684 int st0_regnum = find_regno (regcache->tdesc, "st0");
685
686 if ((clear_bv & X86_XSTATE_X87) != 0)
687 {
688 for (i = 0; i < 8; i++)
689 supply_register_zeroed (regcache, i + st0_regnum);
690 }
691 else
692 {
693 p = (gdb_byte *) &fp->st_space[0];
694 for (i = 0; i < 8; i++)
695 supply_register (regcache, i + st0_regnum, p + i * 16);
696 }
697 }
698
699 if ((x86_xcr0 & X86_XSTATE_SSE) != 0)
700 {
701 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
702
703 if ((clear_bv & X86_XSTATE_SSE))
704 {
705 for (i = 0; i < num_xmm_registers; i++)
706 supply_register_zeroed (regcache, i + xmm0_regnum);
707 }
708 else
709 {
710 p = (gdb_byte *) &fp->xmm_space[0];
711 for (i = 0; i < num_xmm_registers; i++)
712 supply_register (regcache, i + xmm0_regnum, p + i * 16);
713 }
714 }
715
716 if ((x86_xcr0 & X86_XSTATE_AVX) != 0)
717 {
718 int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
719
720 if ((clear_bv & X86_XSTATE_AVX) != 0)
721 {
722 for (i = 0; i < num_xmm_registers; i++)
723 supply_register_zeroed (regcache, i + ymm0h_regnum);
724 }
725 else
726 {
727 p = (gdb_byte *) &fp->ymmh_space[0];
728 for (i = 0; i < num_xmm_registers; i++)
729 supply_register (regcache, i + ymm0h_regnum, p + i * 16);
730 }
731 }
732
733 if ((x86_xcr0 & X86_XSTATE_BNDREGS))
734 {
735 int bnd0r_regnum = find_regno (regcache->tdesc, "bnd0raw");
736
737
738 if ((clear_bv & X86_XSTATE_BNDREGS) != 0)
739 {
740 for (i = 0; i < num_mpx_bnd_registers; i++)
741 supply_register_zeroed (regcache, i + bnd0r_regnum);
742 }
743 else
744 {
745 p = (gdb_byte *) &fp->mpx_bnd_space[0];
746 for (i = 0; i < num_mpx_bnd_registers; i++)
747 supply_register (regcache, i + bnd0r_regnum, p + i * 16);
748 }
749
750 }
751
752 if ((x86_xcr0 & X86_XSTATE_BNDCFG))
753 {
754 int bndcfg_regnum = find_regno (regcache->tdesc, "bndcfgu");
755
756 if ((clear_bv & X86_XSTATE_BNDCFG) != 0)
757 {
758 for (i = 0; i < num_mpx_cfg_registers; i++)
759 supply_register_zeroed (regcache, i + bndcfg_regnum);
760 }
761 else
762 {
763 p = (gdb_byte *) &fp->mpx_cfg_space[0];
764 for (i = 0; i < num_mpx_cfg_registers; i++)
765 supply_register (regcache, i + bndcfg_regnum, p + i * 8);
766 }
767 }
768
769 if ((x86_xcr0 & X86_XSTATE_K) != 0)
770 {
771 int k0_regnum = find_regno (regcache->tdesc, "k0");
772
773 if ((clear_bv & X86_XSTATE_K) != 0)
774 {
775 for (i = 0; i < num_avx512_k_registers; i++)
776 supply_register_zeroed (regcache, i + k0_regnum);
777 }
778 else
779 {
780 p = (gdb_byte *) &fp->k_space[0];
781 for (i = 0; i < num_avx512_k_registers; i++)
782 supply_register (regcache, i + k0_regnum, p + i * 8);
783 }
784 }
785
786 if ((x86_xcr0 & X86_XSTATE_ZMM_H) != 0)
787 {
788 int zmm0h_regnum = find_regno (regcache->tdesc, "zmm0h");
789
790 if ((clear_bv & X86_XSTATE_ZMM_H) != 0)
791 {
792 for (i = 0; i < num_avx512_zmmh_low_registers; i++)
793 supply_register_zeroed (regcache, i + zmm0h_regnum);
794 }
795 else
796 {
797 p = (gdb_byte *) &fp->zmmh_low_space[0];
798 for (i = 0; i < num_avx512_zmmh_low_registers; i++)
799 supply_register (regcache, i + zmm0h_regnum, p + i * 32);
800 }
801 }
802
803 if ((x86_xcr0 & X86_XSTATE_ZMM) != 0)
804 {
805 int zmm16h_regnum = find_regno (regcache->tdesc, "zmm16h");
806 int ymm16h_regnum = find_regno (regcache->tdesc, "ymm16h");
807 int xmm16_regnum = find_regno (regcache->tdesc, "xmm16");
808
809 if ((clear_bv & X86_XSTATE_ZMM) != 0)
810 {
811 for (i = 0; i < num_avx512_zmmh_high_registers; i++)
812 supply_register_zeroed (regcache, i + zmm16h_regnum);
813 for (i = 0; i < num_avx512_ymmh_registers; i++)
814 supply_register_zeroed (regcache, i + ymm16h_regnum);
815 for (i = 0; i < num_avx512_xmm_registers; i++)
816 supply_register_zeroed (regcache, i + xmm16_regnum);
817 }
818 else
819 {
820 p = (gdb_byte *) &fp->zmmh_high_space[0];
821 for (i = 0; i < num_avx512_zmmh_high_registers; i++)
822 supply_register (regcache, i + zmm16h_regnum, p + 32 + i * 64);
823 for (i = 0; i < num_avx512_ymmh_registers; i++)
824 supply_register (regcache, i + ymm16h_regnum, p + 16 + i * 64);
825 for (i = 0; i < num_avx512_xmm_registers; i++)
826 supply_register (regcache, i + xmm16_regnum, p + i * 64);
827 }
828 }
829
830 if ((x86_xcr0 & X86_XSTATE_PKRU) != 0)
831 {
832 int pkru_regnum = find_regno (regcache->tdesc, "pkru");
833
834 if ((clear_bv & X86_XSTATE_PKRU) != 0)
835 {
836 for (i = 0; i < num_pkeys_registers; i++)
837 supply_register_zeroed (regcache, i + pkru_regnum);
838 }
839 else
840 {
841 p = (gdb_byte *) &fp->pkru_space[0];
842 for (i = 0; i < num_pkeys_registers; i++)
843 supply_register (regcache, i + pkru_regnum, p + i * 4);
844 }
845 }
846
847 supply_register_by_name (regcache, "fioff", &fp->fioff);
848 supply_register_by_name (regcache, "fooff", &fp->fooff);
849 supply_register_by_name (regcache, "mxcsr", &fp->mxcsr);
850
851 /* Some registers are 16-bit. */
852 val = fp->fctrl & 0xFFFF;
853 supply_register_by_name (regcache, "fctrl", &val);
854
855 val = fp->fstat & 0xFFFF;
856 supply_register_by_name (regcache, "fstat", &val);
857
858 /* Generate the form of ftag data that GDB expects. */
859 top = (fp->fstat >> 11) & 0x7;
860 val = 0;
861 for (i = 7; i >= 0; i--)
862 {
863 int tag;
864 if (fp->ftag & (1 << i))
865 tag = i387_ftag (fxp, (i + 8 - top) % 8);
866 else
867 tag = 3;
868 val |= tag << (2 * i);
869 }
870 supply_register_by_name (regcache, "ftag", &val);
871
872 val = fp->fiseg & 0xFFFF;
873 supply_register_by_name (regcache, "fiseg", &val);
874
875 val = fp->foseg & 0xFFFF;
876 supply_register_by_name (regcache, "foseg", &val);
877
878 val = (fp->fop) & 0x7FF;
879 supply_register_by_name (regcache, "fop", &val);
880 }
881
882 /* Default to SSE. */
883 unsigned long long x86_xcr0 = X86_XSTATE_SSE_MASK;
This page took 0.072572 seconds and 4 git commands to generate.