1 /* i387-specific utility functions, for the remote server for GDB.
2 Copyright (C) 2000-2014 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "i386-xstate.h"
23 static const int num_mpx_bnd_registers
= 4;
24 static const int num_mpx_cfg_registers
= 2;
26 /* Note: These functions preserve the reserved bits in control registers.
27 However, gdbserver promptly throws away that information. */
29 /* These structs should have the proper sizes and alignment on both
30 i386 and x86-64 machines. */
33 /* All these are only sixteen bits, plus padding, except for fop (which
34 is only eleven bits), and fooff / fioff (which are 32 bits each). */
48 /* Space for eight 80-bit FP values. */
49 unsigned char st_space
[80];
53 /* All these are only sixteen bits, plus padding, except for fop (which
54 is only eleven bits), and fooff / fioff (which are 32 bits each). */
69 /* Space for eight 80-bit FP values in 128-bit spaces. */
70 unsigned char st_space
[128];
72 /* Space for eight 128-bit XMM values, or 16 on x86-64. */
73 unsigned char xmm_space
[256];
77 /* All these are only sixteen bits, plus padding, except for fop (which
78 is only eleven bits), and fooff / fioff (which are 32 bits each). */
91 unsigned int mxcsr_mask
;
93 /* Space for eight 80-bit FP values in 128-bit spaces. */
94 unsigned char st_space
[128];
96 /* Space for eight 128-bit XMM values, or 16 on x86-64. */
97 unsigned char xmm_space
[256];
99 unsigned char reserved1
[48];
101 /* The extended control register 0 (the XFEATURE_ENABLED_MASK
103 unsigned long long xcr0
;
105 unsigned char reserved2
[40];
107 /* The XSTATE_BV bit vector. */
108 unsigned long long xstate_bv
;
110 unsigned char reserved3
[56];
112 /* Space for eight upper 128-bit YMM values, or 16 on x86-64. */
113 unsigned char ymmh_space
[256];
115 unsigned char reserved4
[128];
117 /* Space for 4 bound registers values of 128 bits. */
118 unsigned char mpx_bnd_space
[64];
120 /* Space for 2 MPX configuration registers of 64 bits
121 plus reserved space. */
122 unsigned char mpx_cfg_space
[16];
126 i387_cache_to_fsave (struct regcache
*regcache
, void *buf
)
128 struct i387_fsave
*fp
= (struct i387_fsave
*) buf
;
130 int st0_regnum
= find_regno (regcache
->tdesc
, "st0");
131 unsigned long val
, val2
;
133 for (i
= 0; i
< 8; i
++)
134 collect_register (regcache
, i
+ st0_regnum
,
135 ((char *) &fp
->st_space
[0]) + i
* 10);
137 collect_register_by_name (regcache
, "fioff", &fp
->fioff
);
138 collect_register_by_name (regcache
, "fooff", &fp
->fooff
);
140 /* This one's 11 bits... */
141 collect_register_by_name (regcache
, "fop", &val2
);
142 fp
->fop
= (val2
& 0x7FF) | (fp
->fop
& 0xF800);
144 /* Some registers are 16-bit. */
145 collect_register_by_name (regcache
, "fctrl", &val
);
148 collect_register_by_name (regcache
, "fstat", &val
);
152 collect_register_by_name (regcache
, "ftag", &val
);
156 collect_register_by_name (regcache
, "fiseg", &val
);
160 collect_register_by_name (regcache
, "foseg", &val
);
166 i387_fsave_to_cache (struct regcache
*regcache
, const void *buf
)
168 struct i387_fsave
*fp
= (struct i387_fsave
*) buf
;
170 int st0_regnum
= find_regno (regcache
->tdesc
, "st0");
173 for (i
= 0; i
< 8; i
++)
174 supply_register (regcache
, i
+ st0_regnum
,
175 ((char *) &fp
->st_space
[0]) + i
* 10);
177 supply_register_by_name (regcache
, "fioff", &fp
->fioff
);
178 supply_register_by_name (regcache
, "fooff", &fp
->fooff
);
180 /* Some registers are 16-bit. */
181 val
= fp
->fctrl
& 0xFFFF;
182 supply_register_by_name (regcache
, "fctrl", &val
);
184 val
= fp
->fstat
& 0xFFFF;
185 supply_register_by_name (regcache
, "fstat", &val
);
187 val
= fp
->ftag
& 0xFFFF;
188 supply_register_by_name (regcache
, "ftag", &val
);
190 val
= fp
->fiseg
& 0xFFFF;
191 supply_register_by_name (regcache
, "fiseg", &val
);
193 val
= fp
->foseg
& 0xFFFF;
194 supply_register_by_name (regcache
, "foseg", &val
);
196 /* fop has only 11 valid bits. */
197 val
= (fp
->fop
) & 0x7FF;
198 supply_register_by_name (regcache
, "fop", &val
);
202 i387_cache_to_fxsave (struct regcache
*regcache
, void *buf
)
204 struct i387_fxsave
*fp
= (struct i387_fxsave
*) buf
;
206 int st0_regnum
= find_regno (regcache
->tdesc
, "st0");
207 int xmm0_regnum
= find_regno (regcache
->tdesc
, "xmm0");
208 unsigned long val
, val2
;
209 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
210 int num_xmm_registers
= register_size (regcache
->tdesc
, 0) == 8 ? 16 : 8;
212 for (i
= 0; i
< 8; i
++)
213 collect_register (regcache
, i
+ st0_regnum
,
214 ((char *) &fp
->st_space
[0]) + i
* 16);
215 for (i
= 0; i
< num_xmm_registers
; i
++)
216 collect_register (regcache
, i
+ xmm0_regnum
,
217 ((char *) &fp
->xmm_space
[0]) + i
* 16);
219 collect_register_by_name (regcache
, "fioff", &fp
->fioff
);
220 collect_register_by_name (regcache
, "fooff", &fp
->fooff
);
221 collect_register_by_name (regcache
, "mxcsr", &fp
->mxcsr
);
223 /* This one's 11 bits... */
224 collect_register_by_name (regcache
, "fop", &val2
);
225 fp
->fop
= (val2
& 0x7FF) | (fp
->fop
& 0xF800);
227 /* Some registers are 16-bit. */
228 collect_register_by_name (regcache
, "fctrl", &val
);
231 collect_register_by_name (regcache
, "fstat", &val
);
234 /* Convert to the simplifed tag form stored in fxsave data. */
235 collect_register_by_name (regcache
, "ftag", &val
);
238 for (i
= 7; i
>= 0; i
--)
240 int tag
= (val
>> (i
* 2)) & 3;
247 collect_register_by_name (regcache
, "fiseg", &val
);
250 collect_register_by_name (regcache
, "foseg", &val
);
255 i387_cache_to_xsave (struct regcache
*regcache
, void *buf
)
257 struct i387_xsave
*fp
= (struct i387_xsave
*) buf
;
259 unsigned long val
, val2
;
260 unsigned int clear_bv
;
261 unsigned long long xstate_bv
= 0;
264 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
265 int num_xmm_registers
= register_size (regcache
->tdesc
, 0) == 8 ? 16 : 8;
267 /* The supported bits in `xstat_bv' are 1 byte. Clear part in
268 vector registers if its bit in xstat_bv is zero. */
269 clear_bv
= (~fp
->xstate_bv
) & x86_xcr0
;
271 /* Clear part in x87 and vector registers if its bit in xstat_bv is
275 if ((clear_bv
& I386_XSTATE_X87
))
276 for (i
= 0; i
< 8; i
++)
277 memset (((char *) &fp
->st_space
[0]) + i
* 16, 0, 10);
279 if ((clear_bv
& I386_XSTATE_SSE
))
280 for (i
= 0; i
< num_xmm_registers
; i
++)
281 memset (((char *) &fp
->xmm_space
[0]) + i
* 16, 0, 16);
283 if ((clear_bv
& I386_XSTATE_AVX
))
284 for (i
= 0; i
< num_xmm_registers
; i
++)
285 memset (((char *) &fp
->ymmh_space
[0]) + i
* 16, 0, 16);
287 if ((clear_bv
& I386_XSTATE_BNDREGS
))
288 for (i
= 0; i
< num_mpx_bnd_registers
; i
++)
289 memset (((char *) &fp
->mpx_bnd_space
[0]) + i
* 16, 0, 16);
291 if ((clear_bv
& I386_XSTATE_BNDCFG
))
292 for (i
= 0; i
< num_mpx_cfg_registers
; i
++)
293 memset (((char *) &fp
->mpx_cfg_space
[0]) + i
* 8, 0, 8);
296 /* Check if any x87 registers are changed. */
297 if ((x86_xcr0
& I386_XSTATE_X87
))
299 int st0_regnum
= find_regno (regcache
->tdesc
, "st0");
301 for (i
= 0; i
< 8; i
++)
303 collect_register (regcache
, i
+ st0_regnum
, raw
);
304 p
= ((char *) &fp
->st_space
[0]) + i
* 16;
305 if (memcmp (raw
, p
, 10))
307 xstate_bv
|= I386_XSTATE_X87
;
313 /* Check if any SSE registers are changed. */
314 if ((x86_xcr0
& I386_XSTATE_SSE
))
316 int xmm0_regnum
= find_regno (regcache
->tdesc
, "xmm0");
318 for (i
= 0; i
< num_xmm_registers
; i
++)
320 collect_register (regcache
, i
+ xmm0_regnum
, raw
);
321 p
= ((char *) &fp
->xmm_space
[0]) + i
* 16;
322 if (memcmp (raw
, p
, 16))
324 xstate_bv
|= I386_XSTATE_SSE
;
330 /* Check if any AVX registers are changed. */
331 if ((x86_xcr0
& I386_XSTATE_AVX
))
333 int ymm0h_regnum
= find_regno (regcache
->tdesc
, "ymm0h");
335 for (i
= 0; i
< num_xmm_registers
; i
++)
337 collect_register (regcache
, i
+ ymm0h_regnum
, raw
);
338 p
= ((char *) &fp
->ymmh_space
[0]) + i
* 16;
339 if (memcmp (raw
, p
, 16))
341 xstate_bv
|= I386_XSTATE_AVX
;
347 /* Check if any bound register has changed. */
348 if ((x86_xcr0
& I386_XSTATE_BNDREGS
))
350 int bnd0r_regnum
= find_regno (regcache
->tdesc
, "bnd0raw");
352 for (i
= 0; i
< num_mpx_bnd_registers
; i
++)
354 collect_register (regcache
, i
+ bnd0r_regnum
, raw
);
355 p
= ((char *) &fp
->mpx_bnd_space
[0]) + i
* 16;
356 if (memcmp (raw
, p
, 16))
358 xstate_bv
|= I386_XSTATE_BNDREGS
;
364 /* Check if any status register has changed. */
365 if ((x86_xcr0
& I386_XSTATE_BNDCFG
))
367 int bndcfg_regnum
= find_regno (regcache
->tdesc
, "bndcfgu");
369 for (i
= 0; i
< num_mpx_cfg_registers
; i
++)
371 collect_register (regcache
, i
+ bndcfg_regnum
, raw
);
372 p
= ((char *) &fp
->mpx_cfg_space
[0]) + i
* 8;
373 if (memcmp (raw
, p
, 8))
375 xstate_bv
|= I386_XSTATE_BNDCFG
;
381 /* Update the corresponding bits in xstate_bv if any SSE/AVX
382 registers are changed. */
383 fp
->xstate_bv
|= xstate_bv
;
385 collect_register_by_name (regcache
, "fioff", &fp
->fioff
);
386 collect_register_by_name (regcache
, "fooff", &fp
->fooff
);
387 collect_register_by_name (regcache
, "mxcsr", &fp
->mxcsr
);
389 /* This one's 11 bits... */
390 collect_register_by_name (regcache
, "fop", &val2
);
391 fp
->fop
= (val2
& 0x7FF) | (fp
->fop
& 0xF800);
393 /* Some registers are 16-bit. */
394 collect_register_by_name (regcache
, "fctrl", &val
);
397 collect_register_by_name (regcache
, "fstat", &val
);
400 /* Convert to the simplifed tag form stored in fxsave data. */
401 collect_register_by_name (regcache
, "ftag", &val
);
404 for (i
= 7; i
>= 0; i
--)
406 int tag
= (val
>> (i
* 2)) & 3;
413 collect_register_by_name (regcache
, "fiseg", &val
);
416 collect_register_by_name (regcache
, "foseg", &val
);
421 i387_ftag (struct i387_fxsave
*fp
, int regno
)
423 unsigned char *raw
= &fp
->st_space
[regno
* 16];
424 unsigned int exponent
;
425 unsigned long fraction
[2];
428 integer
= raw
[7] & 0x80;
429 exponent
= (((raw
[9] & 0x7f) << 8) | raw
[8]);
430 fraction
[0] = ((raw
[3] << 24) | (raw
[2] << 16) | (raw
[1] << 8) | raw
[0]);
431 fraction
[1] = (((raw
[7] & 0x7f) << 24) | (raw
[6] << 16)
432 | (raw
[5] << 8) | raw
[4]);
434 if (exponent
== 0x7fff)
439 else if (exponent
== 0x0000)
441 if (fraction
[0] == 0x0000 && fraction
[1] == 0x0000 && !integer
)
468 i387_fxsave_to_cache (struct regcache
*regcache
, const void *buf
)
470 struct i387_fxsave
*fp
= (struct i387_fxsave
*) buf
;
472 int st0_regnum
= find_regno (regcache
->tdesc
, "st0");
473 int xmm0_regnum
= find_regno (regcache
->tdesc
, "xmm0");
475 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
476 int num_xmm_registers
= register_size (regcache
->tdesc
, 0) == 8 ? 16 : 8;
478 for (i
= 0; i
< 8; i
++)
479 supply_register (regcache
, i
+ st0_regnum
,
480 ((char *) &fp
->st_space
[0]) + i
* 16);
481 for (i
= 0; i
< num_xmm_registers
; i
++)
482 supply_register (regcache
, i
+ xmm0_regnum
,
483 ((char *) &fp
->xmm_space
[0]) + i
* 16);
485 supply_register_by_name (regcache
, "fioff", &fp
->fioff
);
486 supply_register_by_name (regcache
, "fooff", &fp
->fooff
);
487 supply_register_by_name (regcache
, "mxcsr", &fp
->mxcsr
);
489 /* Some registers are 16-bit. */
490 val
= fp
->fctrl
& 0xFFFF;
491 supply_register_by_name (regcache
, "fctrl", &val
);
493 val
= fp
->fstat
& 0xFFFF;
494 supply_register_by_name (regcache
, "fstat", &val
);
496 /* Generate the form of ftag data that GDB expects. */
497 top
= (fp
->fstat
>> 11) & 0x7;
499 for (i
= 7; i
>= 0; i
--)
502 if (fp
->ftag
& (1 << i
))
503 tag
= i387_ftag (fp
, (i
+ 8 - top
) % 8);
506 val
|= tag
<< (2 * i
);
508 supply_register_by_name (regcache
, "ftag", &val
);
510 val
= fp
->fiseg
& 0xFFFF;
511 supply_register_by_name (regcache
, "fiseg", &val
);
513 val
= fp
->foseg
& 0xFFFF;
514 supply_register_by_name (regcache
, "foseg", &val
);
516 val
= (fp
->fop
) & 0x7FF;
517 supply_register_by_name (regcache
, "fop", &val
);
521 i387_xsave_to_cache (struct regcache
*regcache
, const void *buf
)
523 struct i387_xsave
*fp
= (struct i387_xsave
*) buf
;
524 struct i387_fxsave
*fxp
= (struct i387_fxsave
*) buf
;
527 unsigned int clear_bv
;
529 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
530 int num_xmm_registers
= register_size (regcache
->tdesc
, 0) == 8 ? 16 : 8;
532 /* The supported bits in `xstat_bv' are 1 byte. Clear part in
533 vector registers if its bit in xstat_bv is zero. */
534 clear_bv
= (~fp
->xstate_bv
) & x86_xcr0
;
536 /* Check if any x87 registers are changed. */
537 if ((x86_xcr0
& I386_XSTATE_X87
) != 0)
539 int st0_regnum
= find_regno (regcache
->tdesc
, "st0");
541 if ((clear_bv
& I386_XSTATE_X87
) != 0)
543 for (i
= 0; i
< 8; i
++)
544 supply_register_zeroed (regcache
, i
+ st0_regnum
);
548 p
= (gdb_byte
*) &fp
->st_space
[0];
549 for (i
= 0; i
< 8; i
++)
550 supply_register (regcache
, i
+ st0_regnum
, p
+ i
* 16);
554 if ((x86_xcr0
& I386_XSTATE_SSE
) != 0)
556 int xmm0_regnum
= find_regno (regcache
->tdesc
, "xmm0");
558 if ((clear_bv
& I386_XSTATE_SSE
))
560 for (i
= 0; i
< num_xmm_registers
; i
++)
561 supply_register_zeroed (regcache
, i
+ xmm0_regnum
);
565 p
= (gdb_byte
*) &fp
->xmm_space
[0];
566 for (i
= 0; i
< num_xmm_registers
; i
++)
567 supply_register (regcache
, i
+ xmm0_regnum
, p
+ i
* 16);
571 if ((x86_xcr0
& I386_XSTATE_AVX
) != 0)
573 int ymm0h_regnum
= find_regno (regcache
->tdesc
, "ymm0h");
575 if ((clear_bv
& I386_XSTATE_AVX
) != 0)
577 for (i
= 0; i
< num_xmm_registers
; i
++)
578 supply_register_zeroed (regcache
, i
+ ymm0h_regnum
);
582 p
= (gdb_byte
*) &fp
->ymmh_space
[0];
583 for (i
= 0; i
< num_xmm_registers
; i
++)
584 supply_register (regcache
, i
+ ymm0h_regnum
, p
+ i
* 16);
588 if ((x86_xcr0
& I386_XSTATE_BNDREGS
))
590 int bnd0r_regnum
= find_regno (regcache
->tdesc
, "bnd0raw");
593 if ((clear_bv
& I386_XSTATE_BNDREGS
) != 0)
595 for (i
= 0; i
< num_mpx_bnd_registers
; i
++)
596 supply_register_zeroed (regcache
, i
+ bnd0r_regnum
);
600 p
= (gdb_byte
*) &fp
->mpx_bnd_space
[0];
601 for (i
= 0; i
< num_mpx_bnd_registers
; i
++)
602 supply_register (regcache
, i
+ bnd0r_regnum
, p
+ i
* 16);
607 if ((x86_xcr0
& I386_XSTATE_BNDCFG
))
609 int bndcfg_regnum
= find_regno (regcache
->tdesc
, "bndcfgu");
611 if ((clear_bv
& I386_XSTATE_BNDCFG
) != 0)
613 for (i
= 0; i
< num_mpx_cfg_registers
; i
++)
614 supply_register_zeroed (regcache
, i
+ bndcfg_regnum
);
618 p
= (gdb_byte
*) &fp
->mpx_cfg_space
[0];
619 for (i
= 0; i
< num_mpx_cfg_registers
; i
++)
620 supply_register (regcache
, i
+ bndcfg_regnum
, p
+ i
* 8);
624 supply_register_by_name (regcache
, "fioff", &fp
->fioff
);
625 supply_register_by_name (regcache
, "fooff", &fp
->fooff
);
626 supply_register_by_name (regcache
, "mxcsr", &fp
->mxcsr
);
628 /* Some registers are 16-bit. */
629 val
= fp
->fctrl
& 0xFFFF;
630 supply_register_by_name (regcache
, "fctrl", &val
);
632 val
= fp
->fstat
& 0xFFFF;
633 supply_register_by_name (regcache
, "fstat", &val
);
635 /* Generate the form of ftag data that GDB expects. */
636 top
= (fp
->fstat
>> 11) & 0x7;
638 for (i
= 7; i
>= 0; i
--)
641 if (fp
->ftag
& (1 << i
))
642 tag
= i387_ftag (fxp
, (i
+ 8 - top
) % 8);
645 val
|= tag
<< (2 * i
);
647 supply_register_by_name (regcache
, "ftag", &val
);
649 val
= fp
->fiseg
& 0xFFFF;
650 supply_register_by_name (regcache
, "fiseg", &val
);
652 val
= fp
->foseg
& 0xFFFF;
653 supply_register_by_name (regcache
, "foseg", &val
);
655 val
= (fp
->fop
) & 0x7FF;
656 supply_register_by_name (regcache
, "fop", &val
);
659 /* Default to SSE. */
660 unsigned long long x86_xcr0
= I386_XSTATE_SSE_MASK
;
This page took 0.058706 seconds and 5 git commands to generate.