gdb/x86: Handle kernels using compact xsave format
[deliverable/binutils-gdb.git] / gdb / gdbserver / i387-fp.c
1 /* i387-specific utility functions, for the remote server for GDB.
2 Copyright (C) 2000-2018 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 {
298 for (i = 0; i < 8; i++)
299 memset (((char *) &fp->st_space[0]) + i * 16, 0, 10);
300
301 fp->fioff = 0;
302 fp->fooff = 0;
303 fp->fctrl = I387_FCTRL_INIT_VAL;
304 fp->fstat = 0;
305 fp->ftag = 0;
306 fp->fiseg = 0;
307 fp->foseg = 0;
308 fp->fop = 0;
309 }
310
311 if ((clear_bv & X86_XSTATE_SSE))
312 for (i = 0; i < num_xmm_registers; i++)
313 memset (((char *) &fp->xmm_space[0]) + i * 16, 0, 16);
314
315 if ((clear_bv & X86_XSTATE_AVX))
316 for (i = 0; i < num_xmm_registers; i++)
317 memset (((char *) &fp->ymmh_space[0]) + i * 16, 0, 16);
318
319 if ((clear_bv & X86_XSTATE_SSE) && (clear_bv & X86_XSTATE_AVX))
320 memset (((char *) &fp->mxcsr), 0, 4);
321
322 if ((clear_bv & X86_XSTATE_BNDREGS))
323 for (i = 0; i < num_mpx_bnd_registers; i++)
324 memset (((char *) &fp->mpx_bnd_space[0]) + i * 16, 0, 16);
325
326 if ((clear_bv & X86_XSTATE_BNDCFG))
327 for (i = 0; i < num_mpx_cfg_registers; i++)
328 memset (((char *) &fp->mpx_cfg_space[0]) + i * 8, 0, 8);
329
330 if ((clear_bv & X86_XSTATE_K))
331 for (i = 0; i < num_avx512_k_registers; i++)
332 memset (((char *) &fp->k_space[0]) + i * 8, 0, 8);
333
334 if ((clear_bv & X86_XSTATE_ZMM_H))
335 for (i = 0; i < num_avx512_zmmh_low_registers; i++)
336 memset (((char *) &fp->zmmh_low_space[0]) + i * 32, 0, 32);
337
338 if ((clear_bv & X86_XSTATE_ZMM))
339 {
340 for (i = 0; i < num_avx512_zmmh_high_registers; i++)
341 memset (((char *) &fp->zmmh_low_space[0]) + 32 + i * 64, 0, 32);
342 for (i = 0; i < num_avx512_xmm_registers; i++)
343 memset (((char *) &fp->zmmh_high_space[0]) + i * 64, 0, 16);
344 for (i = 0; i < num_avx512_ymmh_registers; i++)
345 memset (((char *) &fp->zmmh_high_space[0]) + 16 + i * 64, 0, 16);
346 }
347
348 if ((clear_bv & X86_XSTATE_PKRU))
349 for (i = 0; i < num_pkeys_registers; i++)
350 memset (((char *) &fp->pkru_space[0]) + i * 4, 0, 4);
351 }
352
353 /* Check if any x87 registers are changed. */
354 if ((x86_xcr0 & X86_XSTATE_X87))
355 {
356 int st0_regnum = find_regno (regcache->tdesc, "st0");
357
358 for (i = 0; i < 8; i++)
359 {
360 collect_register (regcache, i + st0_regnum, raw);
361 p = ((char *) &fp->st_space[0]) + i * 16;
362 if (memcmp (raw, p, 10))
363 {
364 xstate_bv |= X86_XSTATE_X87;
365 memcpy (p, raw, 10);
366 }
367 }
368 }
369
370 /* Check if any SSE registers are changed. */
371 if ((x86_xcr0 & X86_XSTATE_SSE))
372 {
373 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
374
375 for (i = 0; i < num_xmm_registers; i++)
376 {
377 collect_register (regcache, i + xmm0_regnum, raw);
378 p = ((char *) &fp->xmm_space[0]) + i * 16;
379 if (memcmp (raw, p, 16))
380 {
381 xstate_bv |= X86_XSTATE_SSE;
382 memcpy (p, raw, 16);
383 }
384 }
385 }
386
387 /* Check if any AVX registers are changed. */
388 if ((x86_xcr0 & X86_XSTATE_AVX))
389 {
390 int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
391
392 for (i = 0; i < num_xmm_registers; i++)
393 {
394 collect_register (regcache, i + ymm0h_regnum, raw);
395 p = ((char *) &fp->ymmh_space[0]) + i * 16;
396 if (memcmp (raw, p, 16))
397 {
398 xstate_bv |= X86_XSTATE_AVX;
399 memcpy (p, raw, 16);
400 }
401 }
402 }
403
404 /* Check if any bound register has changed. */
405 if ((x86_xcr0 & X86_XSTATE_BNDREGS))
406 {
407 int bnd0r_regnum = find_regno (regcache->tdesc, "bnd0raw");
408
409 for (i = 0; i < num_mpx_bnd_registers; i++)
410 {
411 collect_register (regcache, i + bnd0r_regnum, raw);
412 p = ((char *) &fp->mpx_bnd_space[0]) + i * 16;
413 if (memcmp (raw, p, 16))
414 {
415 xstate_bv |= X86_XSTATE_BNDREGS;
416 memcpy (p, raw, 16);
417 }
418 }
419 }
420
421 /* Check if any status register has changed. */
422 if ((x86_xcr0 & X86_XSTATE_BNDCFG))
423 {
424 int bndcfg_regnum = find_regno (regcache->tdesc, "bndcfgu");
425
426 for (i = 0; i < num_mpx_cfg_registers; i++)
427 {
428 collect_register (regcache, i + bndcfg_regnum, raw);
429 p = ((char *) &fp->mpx_cfg_space[0]) + i * 8;
430 if (memcmp (raw, p, 8))
431 {
432 xstate_bv |= X86_XSTATE_BNDCFG;
433 memcpy (p, raw, 8);
434 }
435 }
436 }
437
438 /* Check if any K registers are changed. */
439 if ((x86_xcr0 & X86_XSTATE_K))
440 {
441 int k0_regnum = find_regno (regcache->tdesc, "k0");
442
443 for (i = 0; i < num_avx512_k_registers; i++)
444 {
445 collect_register (regcache, i + k0_regnum, raw);
446 p = ((char *) &fp->k_space[0]) + i * 8;
447 if (memcmp (raw, p, 8) != 0)
448 {
449 xstate_bv |= X86_XSTATE_K;
450 memcpy (p, raw, 8);
451 }
452 }
453 }
454
455 /* Check if any of ZMM0H-ZMM15H registers are changed. */
456 if ((x86_xcr0 & X86_XSTATE_ZMM_H))
457 {
458 int zmm0h_regnum = find_regno (regcache->tdesc, "zmm0h");
459
460 for (i = 0; i < num_avx512_zmmh_low_registers; i++)
461 {
462 collect_register (regcache, i + zmm0h_regnum, raw);
463 p = ((char *) &fp->zmmh_low_space[0]) + i * 32;
464 if (memcmp (raw, p, 32) != 0)
465 {
466 xstate_bv |= X86_XSTATE_ZMM_H;
467 memcpy (p, raw, 32);
468 }
469 }
470 }
471
472 /* Check if any of ZMM16H-ZMM31H registers are changed. */
473 if ((x86_xcr0 & X86_XSTATE_ZMM))
474 {
475 int zmm16h_regnum = find_regno (regcache->tdesc, "zmm16h");
476
477 for (i = 0; i < num_avx512_zmmh_high_registers; i++)
478 {
479 collect_register (regcache, i + zmm16h_regnum, raw);
480 p = ((char *) &fp->zmmh_high_space[0]) + 32 + i * 64;
481 if (memcmp (raw, p, 32) != 0)
482 {
483 xstate_bv |= X86_XSTATE_ZMM;
484 memcpy (p, raw, 32);
485 }
486 }
487 }
488
489 /* Check if any XMM_AVX512 registers are changed. */
490 if ((x86_xcr0 & X86_XSTATE_ZMM))
491 {
492 int xmm_avx512_regnum = find_regno (regcache->tdesc, "xmm16");
493
494 for (i = 0; i < num_avx512_xmm_registers; i++)
495 {
496 collect_register (regcache, i + xmm_avx512_regnum, raw);
497 p = ((char *) &fp->zmmh_high_space[0]) + i * 64;
498 if (memcmp (raw, p, 16) != 0)
499 {
500 xstate_bv |= X86_XSTATE_ZMM;
501 memcpy (p, raw, 16);
502 }
503 }
504 }
505
506 /* Check if any YMMH_AVX512 registers are changed. */
507 if ((x86_xcr0 & X86_XSTATE_ZMM))
508 {
509 int ymmh_avx512_regnum = find_regno (regcache->tdesc, "ymm16h");
510
511 for (i = 0; i < num_avx512_ymmh_registers; i++)
512 {
513 collect_register (regcache, i + ymmh_avx512_regnum, raw);
514 p = ((char *) &fp->zmmh_high_space[0]) + 16 + i * 64;
515 if (memcmp (raw, p, 16) != 0)
516 {
517 xstate_bv |= X86_XSTATE_ZMM;
518 memcpy (p, raw, 16);
519 }
520 }
521 }
522
523 /* Check if any PKEYS registers are changed. */
524 if ((x86_xcr0 & X86_XSTATE_PKRU))
525 {
526 int pkru_regnum = find_regno (regcache->tdesc, "pkru");
527
528 for (i = 0; i < num_pkeys_registers; i++)
529 {
530 collect_register (regcache, i + pkru_regnum, raw);
531 p = ((char *) &fp->pkru_space[0]) + i * 4;
532 if (memcmp (raw, p, 4) != 0)
533 {
534 xstate_bv |= X86_XSTATE_PKRU;
535 memcpy (p, raw, 4);
536 }
537 }
538 }
539
540 if ((x86_xcr0 & X86_XSTATE_SSE) || (x86_xcr0 & X86_XSTATE_AVX))
541 {
542 collect_register_by_name (regcache, "mxcsr", raw);
543 if (memcmp (raw, &fp->mxcsr, 4) != 0)
544 {
545 if (((fp->xstate_bv | xstate_bv)
546 & (X86_XSTATE_SSE | X86_XSTATE_AVX)) == 0)
547 xstate_bv |= X86_XSTATE_SSE;
548 memcpy (&fp->mxcsr, raw, 4);
549 }
550 }
551
552 if (x86_xcr0 & X86_XSTATE_X87)
553 {
554 collect_register_by_name (regcache, "fioff", raw);
555 if (memcmp (raw, &fp->fioff, 4) != 0)
556 {
557 xstate_bv |= X86_XSTATE_X87;
558 memcpy (&fp->fioff, raw, 4);
559 }
560
561 collect_register_by_name (regcache, "fooff", raw);
562 if (memcmp (raw, &fp->fooff, 4) != 0)
563 {
564 xstate_bv |= X86_XSTATE_X87;
565 memcpy (&fp->fooff, raw, 4);
566 }
567
568 /* This one's 11 bits... */
569 collect_register_by_name (regcache, "fop", &val2);
570 val2 = (val2 & 0x7FF) | (fp->fop & 0xF800);
571 if (fp->fop != val2)
572 {
573 xstate_bv |= X86_XSTATE_X87;
574 fp->fop = val2;
575 }
576
577 /* Some registers are 16-bit. */
578 collect_register_by_name (regcache, "fctrl", &val);
579 if (fp->fctrl != val)
580 {
581 xstate_bv |= X86_XSTATE_X87;
582 fp->fctrl = val;
583 }
584
585 collect_register_by_name (regcache, "fstat", &val);
586 if (fp->fstat != val)
587 {
588 xstate_bv |= X86_XSTATE_X87;
589 fp->fstat = val;
590 }
591
592 /* Convert to the simplifed tag form stored in fxsave data. */
593 collect_register_by_name (regcache, "ftag", &val);
594 val &= 0xFFFF;
595 val2 = 0;
596 for (i = 7; i >= 0; i--)
597 {
598 int tag = (val >> (i * 2)) & 3;
599
600 if (tag != 3)
601 val2 |= (1 << i);
602 }
603 if (fp->ftag != val2)
604 {
605 xstate_bv |= X86_XSTATE_X87;
606 fp->ftag = val2;
607 }
608
609 collect_register_by_name (regcache, "fiseg", &val);
610 if (fp->fiseg != val)
611 {
612 xstate_bv |= X86_XSTATE_X87;
613 fp->fiseg = val;
614 }
615
616 collect_register_by_name (regcache, "foseg", &val);
617 if (fp->foseg != val)
618 {
619 xstate_bv |= X86_XSTATE_X87;
620 fp->foseg = val;
621 }
622 }
623
624 /* Update the corresponding bits in xstate_bv if any SSE/AVX
625 registers are changed. */
626 fp->xstate_bv |= xstate_bv;
627 }
628
629 static int
630 i387_ftag (struct i387_fxsave *fp, int regno)
631 {
632 unsigned char *raw = &fp->st_space[regno * 16];
633 unsigned int exponent;
634 unsigned long fraction[2];
635 int integer;
636
637 integer = raw[7] & 0x80;
638 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
639 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
640 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
641 | (raw[5] << 8) | raw[4]);
642
643 if (exponent == 0x7fff)
644 {
645 /* Special. */
646 return (2);
647 }
648 else if (exponent == 0x0000)
649 {
650 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
651 {
652 /* Zero. */
653 return (1);
654 }
655 else
656 {
657 /* Special. */
658 return (2);
659 }
660 }
661 else
662 {
663 if (integer)
664 {
665 /* Valid. */
666 return (0);
667 }
668 else
669 {
670 /* Special. */
671 return (2);
672 }
673 }
674 }
675
676 void
677 i387_fxsave_to_cache (struct regcache *regcache, const void *buf)
678 {
679 struct i387_fxsave *fp = (struct i387_fxsave *) buf;
680 int i, top;
681 int st0_regnum = find_regno (regcache->tdesc, "st0");
682 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
683 unsigned long val;
684 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
685 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
686
687 for (i = 0; i < 8; i++)
688 supply_register (regcache, i + st0_regnum,
689 ((char *) &fp->st_space[0]) + i * 16);
690 for (i = 0; i < num_xmm_registers; i++)
691 supply_register (regcache, i + xmm0_regnum,
692 ((char *) &fp->xmm_space[0]) + i * 16);
693
694 supply_register_by_name (regcache, "fioff", &fp->fioff);
695 supply_register_by_name (regcache, "fooff", &fp->fooff);
696 supply_register_by_name (regcache, "mxcsr", &fp->mxcsr);
697
698 /* Some registers are 16-bit. */
699 val = fp->fctrl & 0xFFFF;
700 supply_register_by_name (regcache, "fctrl", &val);
701
702 val = fp->fstat & 0xFFFF;
703 supply_register_by_name (regcache, "fstat", &val);
704
705 /* Generate the form of ftag data that GDB expects. */
706 top = (fp->fstat >> 11) & 0x7;
707 val = 0;
708 for (i = 7; i >= 0; i--)
709 {
710 int tag;
711 if (fp->ftag & (1 << i))
712 tag = i387_ftag (fp, (i + 8 - top) % 8);
713 else
714 tag = 3;
715 val |= tag << (2 * i);
716 }
717 supply_register_by_name (regcache, "ftag", &val);
718
719 val = fp->fiseg & 0xFFFF;
720 supply_register_by_name (regcache, "fiseg", &val);
721
722 val = fp->foseg & 0xFFFF;
723 supply_register_by_name (regcache, "foseg", &val);
724
725 val = (fp->fop) & 0x7FF;
726 supply_register_by_name (regcache, "fop", &val);
727 }
728
729 void
730 i387_xsave_to_cache (struct regcache *regcache, const void *buf)
731 {
732 struct i387_xsave *fp = (struct i387_xsave *) buf;
733 struct i387_fxsave *fxp = (struct i387_fxsave *) buf;
734 int i, top;
735 unsigned long val;
736 unsigned long long clear_bv;
737 gdb_byte *p;
738 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
739 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
740
741 /* The supported bits in `xstat_bv' are 8 bytes. Clear part in
742 vector registers if its bit in xstat_bv is zero. */
743 clear_bv = (~fp->xstate_bv) & x86_xcr0;
744
745 /* Check if any x87 registers are changed. */
746 if ((x86_xcr0 & X86_XSTATE_X87) != 0)
747 {
748 int st0_regnum = find_regno (regcache->tdesc, "st0");
749
750 if ((clear_bv & X86_XSTATE_X87) != 0)
751 {
752 for (i = 0; i < 8; i++)
753 supply_register_zeroed (regcache, i + st0_regnum);
754 }
755 else
756 {
757 p = (gdb_byte *) &fp->st_space[0];
758 for (i = 0; i < 8; i++)
759 supply_register (regcache, i + st0_regnum, p + i * 16);
760 }
761 }
762
763 if ((x86_xcr0 & X86_XSTATE_SSE) != 0)
764 {
765 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
766
767 if ((clear_bv & X86_XSTATE_SSE))
768 {
769 for (i = 0; i < num_xmm_registers; i++)
770 supply_register_zeroed (regcache, i + xmm0_regnum);
771 }
772 else
773 {
774 p = (gdb_byte *) &fp->xmm_space[0];
775 for (i = 0; i < num_xmm_registers; i++)
776 supply_register (regcache, i + xmm0_regnum, p + i * 16);
777 }
778 }
779
780 if ((x86_xcr0 & X86_XSTATE_AVX) != 0)
781 {
782 int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
783
784 if ((clear_bv & X86_XSTATE_AVX) != 0)
785 {
786 for (i = 0; i < num_xmm_registers; i++)
787 supply_register_zeroed (regcache, i + ymm0h_regnum);
788 }
789 else
790 {
791 p = (gdb_byte *) &fp->ymmh_space[0];
792 for (i = 0; i < num_xmm_registers; i++)
793 supply_register (regcache, i + ymm0h_regnum, p + i * 16);
794 }
795 }
796
797 if ((x86_xcr0 & X86_XSTATE_BNDREGS))
798 {
799 int bnd0r_regnum = find_regno (regcache->tdesc, "bnd0raw");
800
801
802 if ((clear_bv & X86_XSTATE_BNDREGS) != 0)
803 {
804 for (i = 0; i < num_mpx_bnd_registers; i++)
805 supply_register_zeroed (regcache, i + bnd0r_regnum);
806 }
807 else
808 {
809 p = (gdb_byte *) &fp->mpx_bnd_space[0];
810 for (i = 0; i < num_mpx_bnd_registers; i++)
811 supply_register (regcache, i + bnd0r_regnum, p + i * 16);
812 }
813
814 }
815
816 if ((x86_xcr0 & X86_XSTATE_BNDCFG))
817 {
818 int bndcfg_regnum = find_regno (regcache->tdesc, "bndcfgu");
819
820 if ((clear_bv & X86_XSTATE_BNDCFG) != 0)
821 {
822 for (i = 0; i < num_mpx_cfg_registers; i++)
823 supply_register_zeroed (regcache, i + bndcfg_regnum);
824 }
825 else
826 {
827 p = (gdb_byte *) &fp->mpx_cfg_space[0];
828 for (i = 0; i < num_mpx_cfg_registers; i++)
829 supply_register (regcache, i + bndcfg_regnum, p + i * 8);
830 }
831 }
832
833 if ((x86_xcr0 & X86_XSTATE_K) != 0)
834 {
835 int k0_regnum = find_regno (regcache->tdesc, "k0");
836
837 if ((clear_bv & X86_XSTATE_K) != 0)
838 {
839 for (i = 0; i < num_avx512_k_registers; i++)
840 supply_register_zeroed (regcache, i + k0_regnum);
841 }
842 else
843 {
844 p = (gdb_byte *) &fp->k_space[0];
845 for (i = 0; i < num_avx512_k_registers; i++)
846 supply_register (regcache, i + k0_regnum, p + i * 8);
847 }
848 }
849
850 if ((x86_xcr0 & X86_XSTATE_ZMM_H) != 0)
851 {
852 int zmm0h_regnum = find_regno (regcache->tdesc, "zmm0h");
853
854 if ((clear_bv & X86_XSTATE_ZMM_H) != 0)
855 {
856 for (i = 0; i < num_avx512_zmmh_low_registers; i++)
857 supply_register_zeroed (regcache, i + zmm0h_regnum);
858 }
859 else
860 {
861 p = (gdb_byte *) &fp->zmmh_low_space[0];
862 for (i = 0; i < num_avx512_zmmh_low_registers; i++)
863 supply_register (regcache, i + zmm0h_regnum, p + i * 32);
864 }
865 }
866
867 if ((x86_xcr0 & X86_XSTATE_ZMM) != 0)
868 {
869 int zmm16h_regnum = find_regno (regcache->tdesc, "zmm16h");
870 int ymm16h_regnum = find_regno (regcache->tdesc, "ymm16h");
871 int xmm16_regnum = find_regno (regcache->tdesc, "xmm16");
872
873 if ((clear_bv & X86_XSTATE_ZMM) != 0)
874 {
875 for (i = 0; i < num_avx512_zmmh_high_registers; i++)
876 supply_register_zeroed (regcache, i + zmm16h_regnum);
877 for (i = 0; i < num_avx512_ymmh_registers; i++)
878 supply_register_zeroed (regcache, i + ymm16h_regnum);
879 for (i = 0; i < num_avx512_xmm_registers; i++)
880 supply_register_zeroed (regcache, i + xmm16_regnum);
881 }
882 else
883 {
884 p = (gdb_byte *) &fp->zmmh_high_space[0];
885 for (i = 0; i < num_avx512_zmmh_high_registers; i++)
886 supply_register (regcache, i + zmm16h_regnum, p + 32 + i * 64);
887 for (i = 0; i < num_avx512_ymmh_registers; i++)
888 supply_register (regcache, i + ymm16h_regnum, p + 16 + i * 64);
889 for (i = 0; i < num_avx512_xmm_registers; i++)
890 supply_register (regcache, i + xmm16_regnum, p + i * 64);
891 }
892 }
893
894 if ((x86_xcr0 & X86_XSTATE_PKRU) != 0)
895 {
896 int pkru_regnum = find_regno (regcache->tdesc, "pkru");
897
898 if ((clear_bv & X86_XSTATE_PKRU) != 0)
899 {
900 for (i = 0; i < num_pkeys_registers; i++)
901 supply_register_zeroed (regcache, i + pkru_regnum);
902 }
903 else
904 {
905 p = (gdb_byte *) &fp->pkru_space[0];
906 for (i = 0; i < num_pkeys_registers; i++)
907 supply_register (regcache, i + pkru_regnum, p + i * 4);
908 }
909 }
910
911 if ((clear_bv & (X86_XSTATE_SSE | X86_XSTATE_AVX))
912 == (X86_XSTATE_SSE | X86_XSTATE_AVX))
913 {
914 unsigned int default_mxcsr = I387_MXCSR_INIT_VAL;
915 supply_register_by_name (regcache, "mxcsr", &default_mxcsr);
916 }
917 else
918 supply_register_by_name (regcache, "mxcsr", &fp->mxcsr);
919
920 if ((clear_bv & X86_XSTATE_X87) != 0)
921 {
922 supply_register_by_name_zeroed (regcache, "fioff");
923 supply_register_by_name_zeroed (regcache, "fooff");
924
925 val = I387_FCTRL_INIT_VAL;
926 supply_register_by_name (regcache, "fctrl", &val);
927
928 supply_register_by_name_zeroed (regcache, "fstat");
929
930 val = 0xFFFF;
931 supply_register_by_name (regcache, "ftag", &val);
932
933 supply_register_by_name_zeroed (regcache, "fiseg");
934 supply_register_by_name_zeroed (regcache, "foseg");
935 supply_register_by_name_zeroed (regcache, "fop");
936 }
937 else
938 {
939 supply_register_by_name (regcache, "fioff", &fp->fioff);
940 supply_register_by_name (regcache, "fooff", &fp->fooff);
941
942 /* Some registers are 16-bit. */
943 val = fp->fctrl & 0xFFFF;
944 supply_register_by_name (regcache, "fctrl", &val);
945
946 val = fp->fstat & 0xFFFF;
947 supply_register_by_name (regcache, "fstat", &val);
948
949 /* Generate the form of ftag data that GDB expects. */
950 top = (fp->fstat >> 11) & 0x7;
951 val = 0;
952 for (i = 7; i >= 0; i--)
953 {
954 int tag;
955 if (fp->ftag & (1 << i))
956 tag = i387_ftag (fxp, (i + 8 - top) % 8);
957 else
958 tag = 3;
959 val |= tag << (2 * i);
960 }
961 supply_register_by_name (regcache, "ftag", &val);
962
963 val = fp->fiseg & 0xFFFF;
964 supply_register_by_name (regcache, "fiseg", &val);
965
966 val = fp->foseg & 0xFFFF;
967 supply_register_by_name (regcache, "foseg", &val);
968
969 val = (fp->fop) & 0x7FF;
970 supply_register_by_name (regcache, "fop", &val);
971 }
972 }
973
974 /* Default to SSE. */
975 unsigned long long x86_xcr0 = X86_XSTATE_SSE_MASK;
This page took 0.051324 seconds and 5 git commands to generate.