Adds the speculation barrier instructions to the ARM assembler and disassembler.
[deliverable/binutils-gdb.git] / gdb / gdbserver / i387-fp.c
CommitLineData
58caa3dc 1/* i387-specific utility functions, for the remote server for GDB.
e2882c85 2 Copyright (C) 2000-2018 Free Software Foundation, Inc.
58caa3dc
DJ
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
a9762ec7 8 the Free Software Foundation; either version 3 of the License, or
58caa3dc
DJ
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
a9762ec7 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
58caa3dc
DJ
18
19#include "server.h"
0d62e5e8 20#include "i387-fp.h"
df7e5265 21#include "x86-xstate.h"
58caa3dc 22
a196ebeb
WT
23static const int num_mpx_bnd_registers = 4;
24static const int num_mpx_cfg_registers = 2;
01f9f808
MS
25static const int num_avx512_k_registers = 8;
26static const int num_avx512_zmmh_low_registers = 16;
27static const int num_avx512_zmmh_high_registers = 16;
28static const int num_avx512_ymmh_registers = 16;
29static const int num_avx512_xmm_registers = 16;
51547df6 30static const int num_pkeys_registers = 1;
a196ebeb 31
58caa3dc
DJ
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
38struct 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). */
0c2ead7e
DJ
41 unsigned short fctrl;
42 unsigned short pad1;
43 unsigned short fstat;
44 unsigned short pad2;
45 unsigned short ftag;
46 unsigned short pad3;
58caa3dc
DJ
47 unsigned int fioff;
48 unsigned short fiseg;
49 unsigned short fop;
50 unsigned int fooff;
0c2ead7e
DJ
51 unsigned short foseg;
52 unsigned short pad4;
58caa3dc
DJ
53
54 /* Space for eight 80-bit FP values. */
f450004a 55 unsigned char st_space[80];
58caa3dc
DJ
56};
57
58struct 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;
0c2ead7e
DJ
66 unsigned short fiseg;
67 unsigned short pad1;
58caa3dc 68 unsigned int fooff;
0c2ead7e
DJ
69 unsigned short foseg;
70 unsigned short pad12;
58caa3dc
DJ
71
72 unsigned int mxcsr;
0c2ead7e 73 unsigned int pad3;
58caa3dc
DJ
74
75 /* Space for eight 80-bit FP values in 128-bit spaces. */
f450004a 76 unsigned char st_space[128];
58caa3dc
DJ
77
78 /* Space for eight 128-bit XMM values, or 16 on x86-64. */
f450004a 79 unsigned char xmm_space[256];
58caa3dc
DJ
80};
81
1570b33e
L
82struct 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];
a196ebeb
WT
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];
01f9f808
MS
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];
51547df6
MS
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];
1570b33e
L
144};
145
58caa3dc 146void
442ea881 147i387_cache_to_fsave (struct regcache *regcache, void *buf)
58caa3dc
DJ
148{
149 struct i387_fsave *fp = (struct i387_fsave *) buf;
150 int i;
3aee8918 151 int st0_regnum = find_regno (regcache->tdesc, "st0");
58caa3dc
DJ
152 unsigned long val, val2;
153
154 for (i = 0; i < 8; i++)
442ea881
PA
155 collect_register (regcache, i + st0_regnum,
156 ((char *) &fp->st_space[0]) + i * 10);
58caa3dc 157
442ea881
PA
158 collect_register_by_name (regcache, "fioff", &fp->fioff);
159 collect_register_by_name (regcache, "fooff", &fp->fooff);
58caa3dc
DJ
160
161 /* This one's 11 bits... */
442ea881 162 collect_register_by_name (regcache, "fop", &val2);
58caa3dc
DJ
163 fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
164
165 /* Some registers are 16-bit. */
442ea881 166 collect_register_by_name (regcache, "fctrl", &val);
0c2ead7e 167 fp->fctrl = val;
58caa3dc 168
442ea881 169 collect_register_by_name (regcache, "fstat", &val);
58caa3dc 170 val &= 0xFFFF;
0c2ead7e 171 fp->fstat = val;
58caa3dc 172
442ea881 173 collect_register_by_name (regcache, "ftag", &val);
58caa3dc 174 val &= 0xFFFF;
0c2ead7e 175 fp->ftag = val;
58caa3dc 176
442ea881 177 collect_register_by_name (regcache, "fiseg", &val);
58caa3dc 178 val &= 0xFFFF;
0c2ead7e 179 fp->fiseg = val;
58caa3dc 180
442ea881 181 collect_register_by_name (regcache, "foseg", &val);
58caa3dc 182 val &= 0xFFFF;
0c2ead7e 183 fp->foseg = val;
58caa3dc
DJ
184}
185
186void
442ea881 187i387_fsave_to_cache (struct regcache *regcache, const void *buf)
58caa3dc
DJ
188{
189 struct i387_fsave *fp = (struct i387_fsave *) buf;
190 int i;
3aee8918 191 int st0_regnum = find_regno (regcache->tdesc, "st0");
58caa3dc
DJ
192 unsigned long val;
193
194 for (i = 0; i < 8; i++)
442ea881
PA
195 supply_register (regcache, i + st0_regnum,
196 ((char *) &fp->st_space[0]) + i * 10);
58caa3dc 197
442ea881
PA
198 supply_register_by_name (regcache, "fioff", &fp->fioff);
199 supply_register_by_name (regcache, "fooff", &fp->fooff);
1b3f6016 200
58caa3dc
DJ
201 /* Some registers are 16-bit. */
202 val = fp->fctrl & 0xFFFF;
442ea881 203 supply_register_by_name (regcache, "fctrl", &val);
58caa3dc
DJ
204
205 val = fp->fstat & 0xFFFF;
442ea881 206 supply_register_by_name (regcache, "fstat", &val);
58caa3dc
DJ
207
208 val = fp->ftag & 0xFFFF;
442ea881 209 supply_register_by_name (regcache, "ftag", &val);
58caa3dc
DJ
210
211 val = fp->fiseg & 0xFFFF;
442ea881 212 supply_register_by_name (regcache, "fiseg", &val);
58caa3dc
DJ
213
214 val = fp->foseg & 0xFFFF;
442ea881 215 supply_register_by_name (regcache, "foseg", &val);
58caa3dc 216
0c2ead7e 217 /* fop has only 11 valid bits. */
58caa3dc 218 val = (fp->fop) & 0x7FF;
442ea881 219 supply_register_by_name (regcache, "fop", &val);
58caa3dc
DJ
220}
221
222void
442ea881 223i387_cache_to_fxsave (struct regcache *regcache, void *buf)
58caa3dc
DJ
224{
225 struct i387_fxsave *fp = (struct i387_fxsave *) buf;
226 int i;
3aee8918
PA
227 int st0_regnum = find_regno (regcache->tdesc, "st0");
228 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
58caa3dc 229 unsigned long val, val2;
3aee8918
PA
230 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
231 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
58caa3dc
DJ
232
233 for (i = 0; i < 8; i++)
442ea881
PA
234 collect_register (regcache, i + st0_regnum,
235 ((char *) &fp->st_space[0]) + i * 16);
58caa3dc 236 for (i = 0; i < num_xmm_registers; i++)
442ea881
PA
237 collect_register (regcache, i + xmm0_regnum,
238 ((char *) &fp->xmm_space[0]) + i * 16);
58caa3dc 239
442ea881
PA
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);
1b3f6016 243
58caa3dc 244 /* This one's 11 bits... */
442ea881 245 collect_register_by_name (regcache, "fop", &val2);
58caa3dc
DJ
246 fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
247
248 /* Some registers are 16-bit. */
442ea881 249 collect_register_by_name (regcache, "fctrl", &val);
0c2ead7e 250 fp->fctrl = val;
58caa3dc 251
442ea881 252 collect_register_by_name (regcache, "fstat", &val);
0c2ead7e 253 fp->fstat = val;
58caa3dc
DJ
254
255 /* Convert to the simplifed tag form stored in fxsave data. */
442ea881 256 collect_register_by_name (regcache, "ftag", &val);
58caa3dc 257 val &= 0xFFFF;
73725ff3 258 val2 = 0;
58caa3dc
DJ
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 }
0c2ead7e 266 fp->ftag = val2;
58caa3dc 267
442ea881 268 collect_register_by_name (regcache, "fiseg", &val);
0c2ead7e 269 fp->fiseg = val;
58caa3dc 270
442ea881 271 collect_register_by_name (regcache, "foseg", &val);
0c2ead7e 272 fp->foseg = val;
58caa3dc
DJ
273}
274
1570b33e
L
275void
276i387_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;
1570b33e 281 unsigned long long xstate_bv = 0;
ff6527bb 282 unsigned long long clear_bv = 0;
01f9f808 283 char raw[64];
1570b33e 284 char *p;
3aee8918
PA
285 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
286 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
1570b33e 287
ff6527bb 288 /* The supported bits in `xstat_bv' are 8 bytes. Clear part in
1570b33e
L
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 {
df7e5265 296 if ((clear_bv & X86_XSTATE_X87))
8ee22052
AB
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 }
1570b33e 310
df7e5265 311 if ((clear_bv & X86_XSTATE_SSE))
8ee22052 312 for (i = 0; i < num_xmm_registers; i++)
1570b33e
L
313 memset (((char *) &fp->xmm_space[0]) + i * 16, 0, 16);
314
df7e5265 315 if ((clear_bv & X86_XSTATE_AVX))
8ee22052 316 for (i = 0; i < num_xmm_registers; i++)
1570b33e 317 memset (((char *) &fp->ymmh_space[0]) + i * 16, 0, 16);
a196ebeb 318
8ee22052
AB
319 if ((clear_bv & X86_XSTATE_SSE) && (clear_bv & X86_XSTATE_AVX))
320 memset (((char *) &fp->mxcsr), 0, 4);
321
df7e5265 322 if ((clear_bv & X86_XSTATE_BNDREGS))
a196ebeb
WT
323 for (i = 0; i < num_mpx_bnd_registers; i++)
324 memset (((char *) &fp->mpx_bnd_space[0]) + i * 16, 0, 16);
325
df7e5265 326 if ((clear_bv & X86_XSTATE_BNDCFG))
a196ebeb
WT
327 for (i = 0; i < num_mpx_cfg_registers; i++)
328 memset (((char *) &fp->mpx_cfg_space[0]) + i * 8, 0, 8);
01f9f808 329
df7e5265 330 if ((clear_bv & X86_XSTATE_K))
01f9f808
MS
331 for (i = 0; i < num_avx512_k_registers; i++)
332 memset (((char *) &fp->k_space[0]) + i * 8, 0, 8);
333
df7e5265 334 if ((clear_bv & X86_XSTATE_ZMM_H))
01f9f808
MS
335 for (i = 0; i < num_avx512_zmmh_low_registers; i++)
336 memset (((char *) &fp->zmmh_low_space[0]) + i * 32, 0, 32);
337
df7e5265 338 if ((clear_bv & X86_XSTATE_ZMM))
01f9f808
MS
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 }
51547df6
MS
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);
1570b33e
L
351 }
352
353 /* Check if any x87 registers are changed. */
df7e5265 354 if ((x86_xcr0 & X86_XSTATE_X87))
1570b33e 355 {
3aee8918 356 int st0_regnum = find_regno (regcache->tdesc, "st0");
1570b33e
L
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 {
df7e5265 364 xstate_bv |= X86_XSTATE_X87;
1570b33e
L
365 memcpy (p, raw, 10);
366 }
367 }
368 }
369
370 /* Check if any SSE registers are changed. */
df7e5265 371 if ((x86_xcr0 & X86_XSTATE_SSE))
1570b33e 372 {
3aee8918 373 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
1570b33e
L
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 {
df7e5265 381 xstate_bv |= X86_XSTATE_SSE;
1570b33e
L
382 memcpy (p, raw, 16);
383 }
384 }
385 }
386
387 /* Check if any AVX registers are changed. */
df7e5265 388 if ((x86_xcr0 & X86_XSTATE_AVX))
1570b33e 389 {
3aee8918 390 int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
1570b33e
L
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 {
df7e5265 398 xstate_bv |= X86_XSTATE_AVX;
1570b33e
L
399 memcpy (p, raw, 16);
400 }
401 }
402 }
403
a196ebeb 404 /* Check if any bound register has changed. */
df7e5265 405 if ((x86_xcr0 & X86_XSTATE_BNDREGS))
a196ebeb
WT
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 {
df7e5265 415 xstate_bv |= X86_XSTATE_BNDREGS;
a196ebeb
WT
416 memcpy (p, raw, 16);
417 }
418 }
419 }
420
421 /* Check if any status register has changed. */
df7e5265 422 if ((x86_xcr0 & X86_XSTATE_BNDCFG))
a196ebeb
WT
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 {
df7e5265 432 xstate_bv |= X86_XSTATE_BNDCFG;
a196ebeb
WT
433 memcpy (p, raw, 8);
434 }
435 }
436 }
437
01f9f808 438 /* Check if any K registers are changed. */
df7e5265 439 if ((x86_xcr0 & X86_XSTATE_K))
01f9f808
MS
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 {
df7e5265 449 xstate_bv |= X86_XSTATE_K;
01f9f808
MS
450 memcpy (p, raw, 8);
451 }
452 }
453 }
454
455 /* Check if any of ZMM0H-ZMM15H registers are changed. */
df7e5265 456 if ((x86_xcr0 & X86_XSTATE_ZMM_H))
01f9f808
MS
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 {
df7e5265 466 xstate_bv |= X86_XSTATE_ZMM_H;
01f9f808
MS
467 memcpy (p, raw, 32);
468 }
469 }
470 }
471
472 /* Check if any of ZMM16H-ZMM31H registers are changed. */
df7e5265 473 if ((x86_xcr0 & X86_XSTATE_ZMM))
01f9f808
MS
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);
3368c1e5 480 p = ((char *) &fp->zmmh_high_space[0]) + 32 + i * 64;
01f9f808
MS
481 if (memcmp (raw, p, 32) != 0)
482 {
df7e5265 483 xstate_bv |= X86_XSTATE_ZMM;
01f9f808
MS
484 memcpy (p, raw, 32);
485 }
486 }
487 }
488
489 /* Check if any XMM_AVX512 registers are changed. */
df7e5265 490 if ((x86_xcr0 & X86_XSTATE_ZMM))
01f9f808
MS
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 {
df7e5265 500 xstate_bv |= X86_XSTATE_ZMM;
01f9f808
MS
501 memcpy (p, raw, 16);
502 }
503 }
504 }
505
506 /* Check if any YMMH_AVX512 registers are changed. */
df7e5265 507 if ((x86_xcr0 & X86_XSTATE_ZMM))
01f9f808
MS
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 {
df7e5265 517 xstate_bv |= X86_XSTATE_ZMM;
01f9f808
MS
518 memcpy (p, raw, 16);
519 }
520 }
521 }
522
51547df6
MS
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
8ee22052
AB
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 }
1570b33e 551
8ee22052
AB
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 }
1570b33e 560
8ee22052
AB
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 }
1570b33e 567
8ee22052
AB
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 }
1570b33e 576
8ee22052
AB
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 }
1570b33e 584
8ee22052
AB
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 }
1570b33e 591
8ee22052
AB
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;
1570b33e 599
8ee22052
AB
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 }
1570b33e 608
8ee22052
AB
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;
1570b33e
L
627}
628
58caa3dc
DJ
629static int
630i387_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)
1b3f6016 641 | (raw[5] << 8) | raw[4]);
58caa3dc
DJ
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)
1b3f6016
PA
651 {
652 /* Zero. */
653 return (1);
654 }
58caa3dc 655 else
1b3f6016
PA
656 {
657 /* Special. */
658 return (2);
659 }
58caa3dc
DJ
660 }
661 else
662 {
663 if (integer)
1b3f6016
PA
664 {
665 /* Valid. */
666 return (0);
667 }
58caa3dc 668 else
1b3f6016
PA
669 {
670 /* Special. */
671 return (2);
672 }
58caa3dc
DJ
673 }
674}
675
676void
442ea881 677i387_fxsave_to_cache (struct regcache *regcache, const void *buf)
58caa3dc
DJ
678{
679 struct i387_fxsave *fp = (struct i387_fxsave *) buf;
680 int i, top;
3aee8918
PA
681 int st0_regnum = find_regno (regcache->tdesc, "st0");
682 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
58caa3dc 683 unsigned long val;
3aee8918
PA
684 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
685 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
58caa3dc
DJ
686
687 for (i = 0; i < 8; i++)
442ea881
PA
688 supply_register (regcache, i + st0_regnum,
689 ((char *) &fp->st_space[0]) + i * 16);
58caa3dc 690 for (i = 0; i < num_xmm_registers; i++)
442ea881
PA
691 supply_register (regcache, i + xmm0_regnum,
692 ((char *) &fp->xmm_space[0]) + i * 16);
58caa3dc 693
442ea881
PA
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);
1b3f6016 697
58caa3dc
DJ
698 /* Some registers are 16-bit. */
699 val = fp->fctrl & 0xFFFF;
442ea881 700 supply_register_by_name (regcache, "fctrl", &val);
58caa3dc
DJ
701
702 val = fp->fstat & 0xFFFF;
442ea881 703 supply_register_by_name (regcache, "fstat", &val);
58caa3dc
DJ
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;
73725ff3 711 if (fp->ftag & (1 << i))
58caa3dc
DJ
712 tag = i387_ftag (fp, (i + 8 - top) % 8);
713 else
714 tag = 3;
715 val |= tag << (2 * i);
716 }
442ea881 717 supply_register_by_name (regcache, "ftag", &val);
58caa3dc
DJ
718
719 val = fp->fiseg & 0xFFFF;
442ea881 720 supply_register_by_name (regcache, "fiseg", &val);
58caa3dc
DJ
721
722 val = fp->foseg & 0xFFFF;
442ea881 723 supply_register_by_name (regcache, "foseg", &val);
58caa3dc
DJ
724
725 val = (fp->fop) & 0x7FF;
442ea881 726 supply_register_by_name (regcache, "fop", &val);
58caa3dc 727}
1570b33e
L
728
729void
730i387_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;
ff6527bb 736 unsigned long long clear_bv;
85724a0e 737 gdb_byte *p;
3aee8918
PA
738 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
739 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
1570b33e 740
ff6527bb 741 /* The supported bits in `xstat_bv' are 8 bytes. Clear part in
1570b33e
L
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. */
df7e5265 746 if ((x86_xcr0 & X86_XSTATE_X87) != 0)
1570b33e 747 {
3aee8918 748 int st0_regnum = find_regno (regcache->tdesc, "st0");
1570b33e 749
df7e5265 750 if ((clear_bv & X86_XSTATE_X87) != 0)
85724a0e
PA
751 {
752 for (i = 0; i < 8; i++)
1c79eb8a 753 supply_register_zeroed (regcache, i + st0_regnum);
85724a0e 754 }
1570b33e 755 else
1570b33e 756 {
85724a0e
PA
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);
1570b33e
L
760 }
761 }
762
df7e5265 763 if ((x86_xcr0 & X86_XSTATE_SSE) != 0)
1570b33e 764 {
3aee8918 765 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
1570b33e 766
df7e5265 767 if ((clear_bv & X86_XSTATE_SSE))
85724a0e
PA
768 {
769 for (i = 0; i < num_xmm_registers; i++)
1c79eb8a 770 supply_register_zeroed (regcache, i + xmm0_regnum);
85724a0e 771 }
1570b33e 772 else
1570b33e 773 {
85724a0e
PA
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);
1570b33e
L
777 }
778 }
779
df7e5265 780 if ((x86_xcr0 & X86_XSTATE_AVX) != 0)
1570b33e 781 {
3aee8918 782 int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
1570b33e 783
df7e5265 784 if ((clear_bv & X86_XSTATE_AVX) != 0)
85724a0e
PA
785 {
786 for (i = 0; i < num_xmm_registers; i++)
1c79eb8a 787 supply_register_zeroed (regcache, i + ymm0h_regnum);
85724a0e 788 }
1570b33e 789 else
1570b33e 790 {
85724a0e
PA
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);
1570b33e
L
794 }
795 }
796
df7e5265 797 if ((x86_xcr0 & X86_XSTATE_BNDREGS))
a196ebeb
WT
798 {
799 int bnd0r_regnum = find_regno (regcache->tdesc, "bnd0raw");
800
801
df7e5265 802 if ((clear_bv & X86_XSTATE_BNDREGS) != 0)
a196ebeb
WT
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
df7e5265 816 if ((x86_xcr0 & X86_XSTATE_BNDCFG))
a196ebeb
WT
817 {
818 int bndcfg_regnum = find_regno (regcache->tdesc, "bndcfgu");
819
df7e5265 820 if ((clear_bv & X86_XSTATE_BNDCFG) != 0)
a196ebeb
WT
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
df7e5265 833 if ((x86_xcr0 & X86_XSTATE_K) != 0)
01f9f808
MS
834 {
835 int k0_regnum = find_regno (regcache->tdesc, "k0");
836
df7e5265 837 if ((clear_bv & X86_XSTATE_K) != 0)
01f9f808
MS
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
df7e5265 850 if ((x86_xcr0 & X86_XSTATE_ZMM_H) != 0)
01f9f808
MS
851 {
852 int zmm0h_regnum = find_regno (regcache->tdesc, "zmm0h");
853
df7e5265 854 if ((clear_bv & X86_XSTATE_ZMM_H) != 0)
01f9f808
MS
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
df7e5265 867 if ((x86_xcr0 & X86_XSTATE_ZMM) != 0)
01f9f808
MS
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
df7e5265 873 if ((clear_bv & X86_XSTATE_ZMM) != 0)
01f9f808
MS
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
51547df6
MS
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
8ee22052
AB
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);
1570b33e 919
8ee22052
AB
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");
1570b33e 924
8ee22052
AB
925 val = I387_FCTRL_INIT_VAL;
926 supply_register_by_name (regcache, "fctrl", &val);
1570b33e 927
8ee22052
AB
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");
1570b33e 936 }
8ee22052
AB
937 else
938 {
939 supply_register_by_name (regcache, "fioff", &fp->fioff);
940 supply_register_by_name (regcache, "fooff", &fp->fooff);
1570b33e 941
8ee22052
AB
942 /* Some registers are 16-bit. */
943 val = fp->fctrl & 0xFFFF;
944 supply_register_by_name (regcache, "fctrl", &val);
1570b33e 945
8ee22052
AB
946 val = fp->fstat & 0xFFFF;
947 supply_register_by_name (regcache, "fstat", &val);
1570b33e 948
8ee22052
AB
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 }
1570b33e
L
972}
973
974/* Default to SSE. */
df7e5265 975unsigned long long x86_xcr0 = X86_XSTATE_SSE_MASK;
This page took 1.262368 seconds and 4 git commands to generate.