]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/gdbserver/i387-fp.c
e655f742ab16bd6c0057fdb239f5a33c9a5f059a
[thirdparty/binutils-gdb.git] / gdb / gdbserver / i387-fp.c
1 /* i387-specific utility functions, for the remote server for GDB.
2 Copyright (C) 2000-2014 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 "i386-xstate.h"
22
23 static const int num_mpx_bnd_registers = 4;
24 static const int num_mpx_cfg_registers = 2;
25
26 /* Note: These functions preserve the reserved bits in control registers.
27 However, gdbserver promptly throws away that information. */
28
29 /* These structs should have the proper sizes and alignment on both
30 i386 and x86-64 machines. */
31
32 struct i387_fsave {
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). */
35 unsigned short fctrl;
36 unsigned short pad1;
37 unsigned short fstat;
38 unsigned short pad2;
39 unsigned short ftag;
40 unsigned short pad3;
41 unsigned int fioff;
42 unsigned short fiseg;
43 unsigned short fop;
44 unsigned int fooff;
45 unsigned short foseg;
46 unsigned short pad4;
47
48 /* Space for eight 80-bit FP values. */
49 unsigned char st_space[80];
50 };
51
52 struct i387_fxsave {
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). */
55 unsigned short fctrl;
56 unsigned short fstat;
57 unsigned short ftag;
58 unsigned short fop;
59 unsigned int fioff;
60 unsigned short fiseg;
61 unsigned short pad1;
62 unsigned int fooff;
63 unsigned short foseg;
64 unsigned short pad12;
65
66 unsigned int mxcsr;
67 unsigned int pad3;
68
69 /* Space for eight 80-bit FP values in 128-bit spaces. */
70 unsigned char st_space[128];
71
72 /* Space for eight 128-bit XMM values, or 16 on x86-64. */
73 unsigned char xmm_space[256];
74 };
75
76 struct i387_xsave {
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). */
79 unsigned short fctrl;
80 unsigned short fstat;
81 unsigned short ftag;
82 unsigned short fop;
83 unsigned int fioff;
84 unsigned short fiseg;
85 unsigned short pad1;
86 unsigned int fooff;
87 unsigned short foseg;
88 unsigned short pad12;
89
90 unsigned int mxcsr;
91 unsigned int mxcsr_mask;
92
93 /* Space for eight 80-bit FP values in 128-bit spaces. */
94 unsigned char st_space[128];
95
96 /* Space for eight 128-bit XMM values, or 16 on x86-64. */
97 unsigned char xmm_space[256];
98
99 unsigned char reserved1[48];
100
101 /* The extended control register 0 (the XFEATURE_ENABLED_MASK
102 register). */
103 unsigned long long xcr0;
104
105 unsigned char reserved2[40];
106
107 /* The XSTATE_BV bit vector. */
108 unsigned long long xstate_bv;
109
110 unsigned char reserved3[56];
111
112 /* Space for eight upper 128-bit YMM values, or 16 on x86-64. */
113 unsigned char ymmh_space[256];
114
115 unsigned char reserved4[128];
116
117 /* Space for 4 bound registers values of 128 bits. */
118 unsigned char mpx_bnd_space[64];
119
120 /* Space for 2 MPX configuration registers of 64 bits
121 plus reserved space. */
122 unsigned char mpx_cfg_space[16];
123 };
124
125 void
126 i387_cache_to_fsave (struct regcache *regcache, void *buf)
127 {
128 struct i387_fsave *fp = (struct i387_fsave *) buf;
129 int i;
130 int st0_regnum = find_regno (regcache->tdesc, "st0");
131 unsigned long val, val2;
132
133 for (i = 0; i < 8; i++)
134 collect_register (regcache, i + st0_regnum,
135 ((char *) &fp->st_space[0]) + i * 10);
136
137 collect_register_by_name (regcache, "fioff", &fp->fioff);
138 collect_register_by_name (regcache, "fooff", &fp->fooff);
139
140 /* This one's 11 bits... */
141 collect_register_by_name (regcache, "fop", &val2);
142 fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
143
144 /* Some registers are 16-bit. */
145 collect_register_by_name (regcache, "fctrl", &val);
146 fp->fctrl = val;
147
148 collect_register_by_name (regcache, "fstat", &val);
149 val &= 0xFFFF;
150 fp->fstat = val;
151
152 collect_register_by_name (regcache, "ftag", &val);
153 val &= 0xFFFF;
154 fp->ftag = val;
155
156 collect_register_by_name (regcache, "fiseg", &val);
157 val &= 0xFFFF;
158 fp->fiseg = val;
159
160 collect_register_by_name (regcache, "foseg", &val);
161 val &= 0xFFFF;
162 fp->foseg = val;
163 }
164
165 void
166 i387_fsave_to_cache (struct regcache *regcache, const void *buf)
167 {
168 struct i387_fsave *fp = (struct i387_fsave *) buf;
169 int i;
170 int st0_regnum = find_regno (regcache->tdesc, "st0");
171 unsigned long val;
172
173 for (i = 0; i < 8; i++)
174 supply_register (regcache, i + st0_regnum,
175 ((char *) &fp->st_space[0]) + i * 10);
176
177 supply_register_by_name (regcache, "fioff", &fp->fioff);
178 supply_register_by_name (regcache, "fooff", &fp->fooff);
179
180 /* Some registers are 16-bit. */
181 val = fp->fctrl & 0xFFFF;
182 supply_register_by_name (regcache, "fctrl", &val);
183
184 val = fp->fstat & 0xFFFF;
185 supply_register_by_name (regcache, "fstat", &val);
186
187 val = fp->ftag & 0xFFFF;
188 supply_register_by_name (regcache, "ftag", &val);
189
190 val = fp->fiseg & 0xFFFF;
191 supply_register_by_name (regcache, "fiseg", &val);
192
193 val = fp->foseg & 0xFFFF;
194 supply_register_by_name (regcache, "foseg", &val);
195
196 /* fop has only 11 valid bits. */
197 val = (fp->fop) & 0x7FF;
198 supply_register_by_name (regcache, "fop", &val);
199 }
200
201 void
202 i387_cache_to_fxsave (struct regcache *regcache, void *buf)
203 {
204 struct i387_fxsave *fp = (struct i387_fxsave *) buf;
205 int i;
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;
211
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);
218
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);
222
223 /* This one's 11 bits... */
224 collect_register_by_name (regcache, "fop", &val2);
225 fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
226
227 /* Some registers are 16-bit. */
228 collect_register_by_name (regcache, "fctrl", &val);
229 fp->fctrl = val;
230
231 collect_register_by_name (regcache, "fstat", &val);
232 fp->fstat = val;
233
234 /* Convert to the simplifed tag form stored in fxsave data. */
235 collect_register_by_name (regcache, "ftag", &val);
236 val &= 0xFFFF;
237 val2 = 0;
238 for (i = 7; i >= 0; i--)
239 {
240 int tag = (val >> (i * 2)) & 3;
241
242 if (tag != 3)
243 val2 |= (1 << i);
244 }
245 fp->ftag = val2;
246
247 collect_register_by_name (regcache, "fiseg", &val);
248 fp->fiseg = val;
249
250 collect_register_by_name (regcache, "foseg", &val);
251 fp->foseg = val;
252 }
253
254 void
255 i387_cache_to_xsave (struct regcache *regcache, void *buf)
256 {
257 struct i387_xsave *fp = (struct i387_xsave *) buf;
258 int i;
259 unsigned long val, val2;
260 unsigned int clear_bv;
261 unsigned long long xstate_bv = 0;
262 char raw[16];
263 char *p;
264 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
265 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
266
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;
270
271 /* Clear part in x87 and vector registers if its bit in xstat_bv is
272 zero. */
273 if (clear_bv)
274 {
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);
278
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);
282
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);
286
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);
290
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);
294 }
295
296 /* Check if any x87 registers are changed. */
297 if ((x86_xcr0 & I386_XSTATE_X87))
298 {
299 int st0_regnum = find_regno (regcache->tdesc, "st0");
300
301 for (i = 0; i < 8; i++)
302 {
303 collect_register (regcache, i + st0_regnum, raw);
304 p = ((char *) &fp->st_space[0]) + i * 16;
305 if (memcmp (raw, p, 10))
306 {
307 xstate_bv |= I386_XSTATE_X87;
308 memcpy (p, raw, 10);
309 }
310 }
311 }
312
313 /* Check if any SSE registers are changed. */
314 if ((x86_xcr0 & I386_XSTATE_SSE))
315 {
316 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
317
318 for (i = 0; i < num_xmm_registers; i++)
319 {
320 collect_register (regcache, i + xmm0_regnum, raw);
321 p = ((char *) &fp->xmm_space[0]) + i * 16;
322 if (memcmp (raw, p, 16))
323 {
324 xstate_bv |= I386_XSTATE_SSE;
325 memcpy (p, raw, 16);
326 }
327 }
328 }
329
330 /* Check if any AVX registers are changed. */
331 if ((x86_xcr0 & I386_XSTATE_AVX))
332 {
333 int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
334
335 for (i = 0; i < num_xmm_registers; i++)
336 {
337 collect_register (regcache, i + ymm0h_regnum, raw);
338 p = ((char *) &fp->ymmh_space[0]) + i * 16;
339 if (memcmp (raw, p, 16))
340 {
341 xstate_bv |= I386_XSTATE_AVX;
342 memcpy (p, raw, 16);
343 }
344 }
345 }
346
347 /* Check if any bound register has changed. */
348 if ((x86_xcr0 & I386_XSTATE_BNDREGS))
349 {
350 int bnd0r_regnum = find_regno (regcache->tdesc, "bnd0raw");
351
352 for (i = 0; i < num_mpx_bnd_registers; i++)
353 {
354 collect_register (regcache, i + bnd0r_regnum, raw);
355 p = ((char *) &fp->mpx_bnd_space[0]) + i * 16;
356 if (memcmp (raw, p, 16))
357 {
358 xstate_bv |= I386_XSTATE_BNDREGS;
359 memcpy (p, raw, 16);
360 }
361 }
362 }
363
364 /* Check if any status register has changed. */
365 if ((x86_xcr0 & I386_XSTATE_BNDCFG))
366 {
367 int bndcfg_regnum = find_regno (regcache->tdesc, "bndcfgu");
368
369 for (i = 0; i < num_mpx_cfg_registers; i++)
370 {
371 collect_register (regcache, i + bndcfg_regnum, raw);
372 p = ((char *) &fp->mpx_cfg_space[0]) + i * 8;
373 if (memcmp (raw, p, 8))
374 {
375 xstate_bv |= I386_XSTATE_BNDCFG;
376 memcpy (p, raw, 8);
377 }
378 }
379 }
380
381 /* Update the corresponding bits in xstate_bv if any SSE/AVX
382 registers are changed. */
383 fp->xstate_bv |= xstate_bv;
384
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);
388
389 /* This one's 11 bits... */
390 collect_register_by_name (regcache, "fop", &val2);
391 fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
392
393 /* Some registers are 16-bit. */
394 collect_register_by_name (regcache, "fctrl", &val);
395 fp->fctrl = val;
396
397 collect_register_by_name (regcache, "fstat", &val);
398 fp->fstat = val;
399
400 /* Convert to the simplifed tag form stored in fxsave data. */
401 collect_register_by_name (regcache, "ftag", &val);
402 val &= 0xFFFF;
403 val2 = 0;
404 for (i = 7; i >= 0; i--)
405 {
406 int tag = (val >> (i * 2)) & 3;
407
408 if (tag != 3)
409 val2 |= (1 << i);
410 }
411 fp->ftag = val2;
412
413 collect_register_by_name (regcache, "fiseg", &val);
414 fp->fiseg = val;
415
416 collect_register_by_name (regcache, "foseg", &val);
417 fp->foseg = val;
418 }
419
420 static int
421 i387_ftag (struct i387_fxsave *fp, int regno)
422 {
423 unsigned char *raw = &fp->st_space[regno * 16];
424 unsigned int exponent;
425 unsigned long fraction[2];
426 int integer;
427
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]);
433
434 if (exponent == 0x7fff)
435 {
436 /* Special. */
437 return (2);
438 }
439 else if (exponent == 0x0000)
440 {
441 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
442 {
443 /* Zero. */
444 return (1);
445 }
446 else
447 {
448 /* Special. */
449 return (2);
450 }
451 }
452 else
453 {
454 if (integer)
455 {
456 /* Valid. */
457 return (0);
458 }
459 else
460 {
461 /* Special. */
462 return (2);
463 }
464 }
465 }
466
467 void
468 i387_fxsave_to_cache (struct regcache *regcache, const void *buf)
469 {
470 struct i387_fxsave *fp = (struct i387_fxsave *) buf;
471 int i, top;
472 int st0_regnum = find_regno (regcache->tdesc, "st0");
473 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
474 unsigned long val;
475 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
476 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
477
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);
484
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);
488
489 /* Some registers are 16-bit. */
490 val = fp->fctrl & 0xFFFF;
491 supply_register_by_name (regcache, "fctrl", &val);
492
493 val = fp->fstat & 0xFFFF;
494 supply_register_by_name (regcache, "fstat", &val);
495
496 /* Generate the form of ftag data that GDB expects. */
497 top = (fp->fstat >> 11) & 0x7;
498 val = 0;
499 for (i = 7; i >= 0; i--)
500 {
501 int tag;
502 if (fp->ftag & (1 << i))
503 tag = i387_ftag (fp, (i + 8 - top) % 8);
504 else
505 tag = 3;
506 val |= tag << (2 * i);
507 }
508 supply_register_by_name (regcache, "ftag", &val);
509
510 val = fp->fiseg & 0xFFFF;
511 supply_register_by_name (regcache, "fiseg", &val);
512
513 val = fp->foseg & 0xFFFF;
514 supply_register_by_name (regcache, "foseg", &val);
515
516 val = (fp->fop) & 0x7FF;
517 supply_register_by_name (regcache, "fop", &val);
518 }
519
520 void
521 i387_xsave_to_cache (struct regcache *regcache, const void *buf)
522 {
523 struct i387_xsave *fp = (struct i387_xsave *) buf;
524 struct i387_fxsave *fxp = (struct i387_fxsave *) buf;
525 int i, top;
526 unsigned long val;
527 unsigned int clear_bv;
528 gdb_byte *p;
529 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */
530 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
531
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;
535
536 /* Check if any x87 registers are changed. */
537 if ((x86_xcr0 & I386_XSTATE_X87) != 0)
538 {
539 int st0_regnum = find_regno (regcache->tdesc, "st0");
540
541 if ((clear_bv & I386_XSTATE_X87) != 0)
542 {
543 for (i = 0; i < 8; i++)
544 supply_register_zeroed (regcache, i + st0_regnum);
545 }
546 else
547 {
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);
551 }
552 }
553
554 if ((x86_xcr0 & I386_XSTATE_SSE) != 0)
555 {
556 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
557
558 if ((clear_bv & I386_XSTATE_SSE))
559 {
560 for (i = 0; i < num_xmm_registers; i++)
561 supply_register_zeroed (regcache, i + xmm0_regnum);
562 }
563 else
564 {
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);
568 }
569 }
570
571 if ((x86_xcr0 & I386_XSTATE_AVX) != 0)
572 {
573 int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
574
575 if ((clear_bv & I386_XSTATE_AVX) != 0)
576 {
577 for (i = 0; i < num_xmm_registers; i++)
578 supply_register_zeroed (regcache, i + ymm0h_regnum);
579 }
580 else
581 {
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);
585 }
586 }
587
588 if ((x86_xcr0 & I386_XSTATE_BNDREGS))
589 {
590 int bnd0r_regnum = find_regno (regcache->tdesc, "bnd0raw");
591
592
593 if ((clear_bv & I386_XSTATE_BNDREGS) != 0)
594 {
595 for (i = 0; i < num_mpx_bnd_registers; i++)
596 supply_register_zeroed (regcache, i + bnd0r_regnum);
597 }
598 else
599 {
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);
603 }
604
605 }
606
607 if ((x86_xcr0 & I386_XSTATE_BNDCFG))
608 {
609 int bndcfg_regnum = find_regno (regcache->tdesc, "bndcfgu");
610
611 if ((clear_bv & I386_XSTATE_BNDCFG) != 0)
612 {
613 for (i = 0; i < num_mpx_cfg_registers; i++)
614 supply_register_zeroed (regcache, i + bndcfg_regnum);
615 }
616 else
617 {
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);
621 }
622 }
623
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);
627
628 /* Some registers are 16-bit. */
629 val = fp->fctrl & 0xFFFF;
630 supply_register_by_name (regcache, "fctrl", &val);
631
632 val = fp->fstat & 0xFFFF;
633 supply_register_by_name (regcache, "fstat", &val);
634
635 /* Generate the form of ftag data that GDB expects. */
636 top = (fp->fstat >> 11) & 0x7;
637 val = 0;
638 for (i = 7; i >= 0; i--)
639 {
640 int tag;
641 if (fp->ftag & (1 << i))
642 tag = i387_ftag (fxp, (i + 8 - top) % 8);
643 else
644 tag = 3;
645 val |= tag << (2 * i);
646 }
647 supply_register_by_name (regcache, "ftag", &val);
648
649 val = fp->fiseg & 0xFFFF;
650 supply_register_by_name (regcache, "fiseg", &val);
651
652 val = fp->foseg & 0xFFFF;
653 supply_register_by_name (regcache, "foseg", &val);
654
655 val = (fp->fop) & 0x7FF;
656 supply_register_by_name (regcache, "fop", &val);
657 }
658
659 /* Default to SSE. */
660 unsigned long long x86_xcr0 = I386_XSTATE_SSE_MASK;