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