1/* i387-specific utility functions, for the remote server for GDB. 2 Copyright (C) 2000-2023 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 23static const int num_mpx_bnd_registers = 4; 24static const int num_mpx_cfg_registers = 2; 25static const int num_avx512_k_registers = 8; 26static const int num_pkeys_registers = 1; 27 28/* Note: These functions preserve the reserved bits in control registers. 29 However, gdbserver promptly throws away that information. */ 30 31/* These structs should have the proper sizes and alignment on both 32 i386 and x86-64 machines. */ 33 34struct i387_fsave { 35 /* All these are only sixteen bits, plus padding, except for fop (which 36 is only eleven bits), and fooff / fioff (which are 32 bits each). */ 37 unsigned short fctrl; 38 unsigned short pad1; 39 unsigned short fstat; 40 unsigned short pad2; 41 unsigned short ftag; 42 unsigned short pad3; 43 unsigned int fioff; 44 unsigned short fiseg; 45 unsigned short fop; 46 unsigned int fooff; 47 unsigned short foseg; 48 unsigned short pad4; 49 50 /* Space for eight 80-bit FP values. */ 51 unsigned char st_space[80]; 52}; 53 54struct i387_fxsave { 55 /* All these are only sixteen bits, plus padding, except for fop (which 56 is only eleven bits), and fooff / fioff (which are 32 bits each). */ 57 unsigned short fctrl; 58 unsigned short fstat; 59 unsigned short ftag; 60 unsigned short fop; 61 unsigned int fioff; 62 unsigned short fiseg; 63 unsigned short pad1; 64 unsigned int fooff; 65 unsigned short foseg; 66 unsigned short pad12; 67 68 unsigned int mxcsr; 69 unsigned int pad3; 70 71 /* Space for eight 80-bit FP values in 128-bit spaces. */ 72 unsigned char st_space[128]; 73 74 /* Space for eight 128-bit XMM values, or 16 on x86-64. */ 75 unsigned char xmm_space[256]; 76}; 77 78struct i387_xsave { 79 /* All these are only sixteen bits, plus padding, except for fop (which 80 is only eleven bits), and fooff / fioff (which are 32 bits each). */ 81 unsigned short fctrl; 82 unsigned short fstat; 83 unsigned short ftag; 84 unsigned short fop; 85 unsigned int fioff; 86 unsigned short fiseg; 87 unsigned short pad1; 88 unsigned int fooff; 89 unsigned short foseg; 90 unsigned short pad12; 91 92 unsigned int mxcsr; 93 unsigned int mxcsr_mask; 94 95 /* Space for eight 80-bit FP values in 128-bit spaces. */ 96 unsigned char st_space[128]; 97 98 /* Space for eight 128-bit XMM values, or 16 on x86-64. */ 99 unsigned char xmm_space[256]; 100 101 unsigned char reserved1[48]; 102 103 /* The extended control register 0 (the XFEATURE_ENABLED_MASK 104 register). */ 105 unsigned long long xcr0; 106 107 unsigned char reserved2[40]; 108 109 /* The XSTATE_BV bit vector. */ 110 unsigned long long xstate_bv; 111 112 unsigned char reserved3[56]; 113 114 /* Space for eight upper 128-bit YMM values, or 16 on x86-64. */ 115 unsigned char ymmh_space[256]; 116 117 unsigned char reserved4[128]; 118 119 /* Space for 4 bound registers values of 128 bits. */ 120 unsigned char mpx_bnd_space[64]; 121 122 /* Space for 2 MPX configuration registers of 64 bits 123 plus reserved space. */ 124 unsigned char mpx_cfg_space[16]; 125 126 unsigned char reserved5[48]; 127 128 /* Space for 8 OpMask register values of 64 bits. */ 129 unsigned char k_space[64]; 130 131 /* Space for 16 256-bit zmm0-15. */ 132 unsigned char zmmh_low_space[512]; 133 134 /* Space for 16 512-bit zmm16-31 values. */ 135 unsigned char zmmh_high_space[1024]; 136 137 /* Space for 1 32-bit PKRU register. The HW XSTATE size for this feature is 138 actually 64 bits, but WRPKRU/RDPKRU instructions ignore upper 32 bits. */ 139 unsigned char pkru_space[8]; 140}; 141 142void 143i387_cache_to_fsave (struct regcache *regcache, void *buf) 144{ 145 struct i387_fsave *fp = (struct i387_fsave *) buf; 146 int i; 147 int st0_regnum = find_regno (regcache->tdesc, "st0"); 148 unsigned long val2; 149 150 for (i = 0; i < 8; i++) 151 collect_register (regcache, i + st0_regnum, 152 ((char *) &fp->st_space[0]) + i * 10); 153 154 fp->fioff = regcache_raw_get_unsigned_by_name (regcache, "fioff"); 155 fp->fooff = regcache_raw_get_unsigned_by_name (regcache, "fooff"); 156 157 /* This one's 11 bits... */ 158 val2 = regcache_raw_get_unsigned_by_name (regcache, "fop"); 159 fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800); 160 161 /* Some registers are 16-bit. */ 162 fp->fctrl = regcache_raw_get_unsigned_by_name (regcache, "fctrl"); 163 fp->fstat = regcache_raw_get_unsigned_by_name (regcache, "fstat"); 164 fp->ftag = regcache_raw_get_unsigned_by_name (regcache, "ftag"); 165 fp->fiseg = regcache_raw_get_unsigned_by_name (regcache, "fiseg"); 166 fp->foseg = regcache_raw_get_unsigned_by_name (regcache, "foseg"); 167} 168 169void 170i387_fsave_to_cache (struct regcache *regcache, const void *buf) 171{ 172 struct i387_fsave *fp = (struct i387_fsave *) buf; 173 int i; 174 int st0_regnum = find_regno (regcache->tdesc, "st0"); 175 unsigned long val; 176 177 for (i = 0; i < 8; i++) 178 supply_register (regcache, i + st0_regnum, 179 ((char *) &fp->st_space[0]) + i * 10); 180 181 supply_register_by_name (regcache, "fioff", &fp->fioff); 182 supply_register_by_name (regcache, "fooff", &fp->fooff); 183 184 /* Some registers are 16-bit. */ 185 val = fp->fctrl & 0xFFFF; 186 supply_register_by_name (regcache, "fctrl", &val); 187 188 val = fp->fstat & 0xFFFF; 189 supply_register_by_name (regcache, "fstat", &val); 190 191 val = fp->ftag & 0xFFFF; 192 supply_register_by_name (regcache, "ftag", &val); 193 194 val = fp->fiseg & 0xFFFF; 195 supply_register_by_name (regcache, "fiseg", &val); 196 197 val = fp->foseg & 0xFFFF; 198 supply_register_by_name (regcache, "foseg", &val); 199 200 /* fop has only 11 valid bits. */ 201 val = (fp->fop) & 0x7FF; 202 supply_register_by_name (regcache, "fop", &val); 203} 204 205void 206i387_cache_to_fxsave (struct regcache *regcache, void *buf) 207{ 208 struct i387_fxsave *fp = (struct i387_fxsave *) buf; 209 int i; 210 int st0_regnum = find_regno (regcache->tdesc, "st0"); 211 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0"); 212 unsigned long val, val2; 213 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */ 214 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8; 215 216 for (i = 0; i < 8; i++) 217 collect_register (regcache, i + st0_regnum, 218 ((char *) &fp->st_space[0]) + i * 16); 219 for (i = 0; i < num_xmm_registers; i++) 220 collect_register (regcache, i + xmm0_regnum, 221 ((char *) &fp->xmm_space[0]) + i * 16); 222 223 fp->fioff = regcache_raw_get_unsigned_by_name (regcache, "fioff"); 224 fp->fooff = regcache_raw_get_unsigned_by_name (regcache, "fooff"); 225 fp->mxcsr = regcache_raw_get_unsigned_by_name (regcache, "mxcsr"); 226 227 /* This one's 11 bits... */ 228 val2 = regcache_raw_get_unsigned_by_name (regcache, "fop"); 229 fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800); 230 231 /* Some registers are 16-bit. */ 232 fp->fctrl = regcache_raw_get_unsigned_by_name (regcache, "fctrl"); 233 fp->fstat = regcache_raw_get_unsigned_by_name (regcache, "fstat"); 234 235 /* Convert to the simplifed tag form stored in fxsave data. */ 236 val = regcache_raw_get_unsigned_by_name (regcache, "ftag"); 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 fp->fiseg = regcache_raw_get_unsigned_by_name (regcache, "fiseg"); 248 fp->foseg = regcache_raw_get_unsigned_by_name (regcache, "foseg"); 249} 250 251void 252i387_cache_to_xsave (struct regcache *regcache, void *buf) 253{ 254 struct i387_xsave *fp = (struct i387_xsave *) buf; 255 bool amd64 = register_size (regcache->tdesc, 0) == 8; 256 int i; 257 unsigned long val, val2; 258 unsigned long long xstate_bv = 0; 259 unsigned long long clear_bv = 0; 260 char raw[64]; 261 char *p; 262 263 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */ 264 int num_xmm_registers = amd64 ? 16 : 8; 265 /* AVX512 extends the existing xmm/ymm registers to a wider mode: zmm. */ 266 int num_avx512_zmmh_low_registers = num_xmm_registers; 267 /* AVX512 adds 16 extra regs in Amd64 mode, but none in I386 mode.*/ 268 int num_avx512_zmmh_high_registers = amd64 ? 16 : 0; 269 int num_avx512_ymmh_registers = amd64 ? 16 : 0; 270 int num_avx512_xmm_registers = amd64 ? 16 : 0; 271 272 /* The supported bits in `xstat_bv' are 8 bytes. Clear part in 273 vector registers if its bit in xstat_bv is zero. */ 274 clear_bv = (~fp->xstate_bv) & x86_xcr0; 275 276 /* Clear part in x87 and vector registers if its bit in xstat_bv is 277 zero. */ 278 if (clear_bv) 279 { 280 if ((clear_bv & X86_XSTATE_X87)) 281 { 282 for (i = 0; i < 8; i++) 283 memset (((char *) &fp->st_space[0]) + i * 16, 0, 10); 284 285 fp->fioff = 0; 286 fp->fooff = 0; 287 fp->fctrl = I387_FCTRL_INIT_VAL; 288 fp->fstat = 0; 289 fp->ftag = 0; 290 fp->fiseg = 0; 291 fp->foseg = 0; 292 fp->fop = 0; 293 } 294 295 if ((clear_bv & X86_XSTATE_SSE)) 296 for (i = 0; i < num_xmm_registers; i++) 297 memset (((char *) &fp->xmm_space[0]) + i * 16, 0, 16); 298 299 if ((clear_bv & X86_XSTATE_AVX)) 300 for (i = 0; i < num_xmm_registers; i++) 301 memset (((char *) &fp->ymmh_space[0]) + i * 16, 0, 16); 302 303 if ((clear_bv & X86_XSTATE_SSE) && (clear_bv & X86_XSTATE_AVX)) 304 memset (((char *) &fp->mxcsr), 0, 4); 305 306 if ((clear_bv & X86_XSTATE_BNDREGS)) 307 for (i = 0; i < num_mpx_bnd_registers; i++) 308 memset (((char *) &fp->mpx_bnd_space[0]) + i * 16, 0, 16); 309 310 if ((clear_bv & X86_XSTATE_BNDCFG)) 311 for (i = 0; i < num_mpx_cfg_registers; i++) 312 memset (((char *) &fp->mpx_cfg_space[0]) + i * 8, 0, 8); 313 314 if ((clear_bv & X86_XSTATE_K)) 315 for (i = 0; i < num_avx512_k_registers; i++) 316 memset (((char *) &fp->k_space[0]) + i * 8, 0, 8); 317 318 if ((clear_bv & X86_XSTATE_ZMM_H)) 319 for (i = 0; i < num_avx512_zmmh_low_registers; i++) 320 memset (((char *) &fp->zmmh_low_space[0]) + i * 32, 0, 32); 321 322 if ((clear_bv & X86_XSTATE_ZMM)) 323 { 324 for (i = 0; i < num_avx512_zmmh_high_registers; i++) 325 memset (((char *) &fp->zmmh_low_space[0]) + 32 + i * 64, 0, 32); 326 for (i = 0; i < num_avx512_xmm_registers; i++) 327 memset (((char *) &fp->zmmh_high_space[0]) + i * 64, 0, 16); 328 for (i = 0; i < num_avx512_ymmh_registers; i++) 329 memset (((char *) &fp->zmmh_high_space[0]) + 16 + i * 64, 0, 16); 330 } 331 332 if ((clear_bv & X86_XSTATE_PKRU)) 333 for (i = 0; i < num_pkeys_registers; i++) 334 memset (((char *) &fp->pkru_space[0]) + i * 4, 0, 4); 335 } 336 337 /* Check if any x87 registers are changed. */ 338 if ((x86_xcr0 & X86_XSTATE_X87)) 339 { 340 int st0_regnum = find_regno (regcache->tdesc, "st0"); 341 342 for (i = 0; i < 8; i++) 343 { 344 collect_register (regcache, i + st0_regnum, raw); 345 p = ((char *) &fp->st_space[0]) + i * 16; 346 if (memcmp (raw, p, 10)) 347 { 348 xstate_bv |= X86_XSTATE_X87; 349 memcpy (p, raw, 10); 350 } 351 } 352 } 353 354 /* Check if any SSE registers are changed. */ 355 if ((x86_xcr0 & X86_XSTATE_SSE)) 356 { 357 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0"); 358 359 for (i = 0; i < num_xmm_registers; i++) 360 { 361 collect_register (regcache, i + xmm0_regnum, raw); 362 p = ((char *) &fp->xmm_space[0]) + i * 16; 363 if (memcmp (raw, p, 16)) 364 { 365 xstate_bv |= X86_XSTATE_SSE; 366 memcpy (p, raw, 16); 367 } 368 } 369 } 370 371 /* Check if any AVX registers are changed. */ 372 if ((x86_xcr0 & X86_XSTATE_AVX)) 373 { 374 int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h"); 375 376 for (i = 0; i < num_xmm_registers; i++) 377 { 378 collect_register (regcache, i + ymm0h_regnum, raw); 379 p = ((char *) &fp->ymmh_space[0]) + i * 16; 380 if (memcmp (raw, p, 16)) 381 { 382 xstate_bv |= X86_XSTATE_AVX; 383 memcpy (p, raw, 16); 384 } 385 } 386 } 387 388 /* Check if any bound register has changed. */ 389 if ((x86_xcr0 & X86_XSTATE_BNDREGS)) 390 { 391 int bnd0r_regnum = find_regno (regcache->tdesc, "bnd0raw"); 392 393 for (i = 0; i < num_mpx_bnd_registers; i++) 394 { 395 collect_register (regcache, i + bnd0r_regnum, raw); 396 p = ((char *) &fp->mpx_bnd_space[0]) + i * 16; 397 if (memcmp (raw, p, 16)) 398 { 399 xstate_bv |= X86_XSTATE_BNDREGS; 400 memcpy (p, raw, 16); 401 } 402 } 403 } 404 405 /* Check if any status register has changed. */ 406 if ((x86_xcr0 & X86_XSTATE_BNDCFG)) 407 { 408 int bndcfg_regnum = find_regno (regcache->tdesc, "bndcfgu"); 409 410 for (i = 0; i < num_mpx_cfg_registers; i++) 411 { 412 collect_register (regcache, i + bndcfg_regnum, raw); 413 p = ((char *) &fp->mpx_cfg_space[0]) + i * 8; 414 if (memcmp (raw, p, 8)) 415 { 416 xstate_bv |= X86_XSTATE_BNDCFG; 417 memcpy (p, raw, 8); 418 } 419 } 420 } 421 422 /* Check if any K registers are changed. */ 423 if ((x86_xcr0 & X86_XSTATE_K)) 424 { 425 int k0_regnum = find_regno (regcache->tdesc, "k0"); 426 427 for (i = 0; i < num_avx512_k_registers; i++) 428 { 429 collect_register (regcache, i + k0_regnum, raw); 430 p = ((char *) &fp->k_space[0]) + i * 8; 431 if (memcmp (raw, p, 8) != 0) 432 { 433 xstate_bv |= X86_XSTATE_K; 434 memcpy (p, raw, 8); 435 } 436 } 437 } 438 439 /* Check if any of ZMM0H-ZMM15H registers are changed. */ 440 if ((x86_xcr0 & X86_XSTATE_ZMM_H)) 441 { 442 int zmm0h_regnum = find_regno (regcache->tdesc, "zmm0h"); 443 444 for (i = 0; i < num_avx512_zmmh_low_registers; i++) 445 { 446 collect_register (regcache, i + zmm0h_regnum, raw); 447 p = ((char *) &fp->zmmh_low_space[0]) + i * 32; 448 if (memcmp (raw, p, 32) != 0) 449 { 450 xstate_bv |= X86_XSTATE_ZMM_H; 451 memcpy (p, raw, 32); 452 } 453 } 454 } 455 456 /* Check if any of ZMM16H-ZMM31H registers are changed. */ 457 if ((x86_xcr0 & X86_XSTATE_ZMM)) 458 { 459 int zmm16h_regnum = (num_avx512_zmmh_high_registers == 0 460 ? -1 461 : find_regno (regcache->tdesc, "zmm16h")); 462 463 for (i = 0; i < num_avx512_zmmh_high_registers; i++) 464 { 465 collect_register (regcache, i + zmm16h_regnum, raw); 466 p = ((char *) &fp->zmmh_high_space[0]) + 32 + i * 64; 467 if (memcmp (raw, p, 32) != 0) 468 { 469 xstate_bv |= X86_XSTATE_ZMM; 470 memcpy (p, raw, 32); 471 } 472 } 473 } 474 475 /* Check if any XMM_AVX512 registers are changed. */ 476 if ((x86_xcr0 & X86_XSTATE_ZMM)) 477 { 478 int xmm_avx512_regnum = (num_avx512_xmm_registers == 0 479 ? -1 480 : find_regno (regcache->tdesc, "xmm16")); 481 482 for (i = 0; i < num_avx512_xmm_registers; i++) 483 { 484 collect_register (regcache, i + xmm_avx512_regnum, raw); 485 p = ((char *) &fp->zmmh_high_space[0]) + i * 64; 486 if (memcmp (raw, p, 16) != 0) 487 { 488 xstate_bv |= X86_XSTATE_ZMM; 489 memcpy (p, raw, 16); 490 } 491 } 492 } 493 494 /* Check if any YMMH_AVX512 registers are changed. */ 495 if ((x86_xcr0 & X86_XSTATE_ZMM)) 496 { 497 int ymmh_avx512_regnum = (num_avx512_ymmh_registers == 0 498 ? -1 499 : find_regno (regcache->tdesc, "ymm16h")); 500 501 for (i = 0; i < num_avx512_ymmh_registers; i++) 502 { 503 collect_register (regcache, i + ymmh_avx512_regnum, raw); 504 p = ((char *) &fp->zmmh_high_space[0]) + 16 + i * 64; 505 if (memcmp (raw, p, 16) != 0) 506 { 507 xstate_bv |= X86_XSTATE_ZMM; 508 memcpy (p, raw, 16); 509 } 510 } 511 } 512 513 /* Check if any PKEYS registers are changed. */ 514 if ((x86_xcr0 & X86_XSTATE_PKRU)) 515 { 516 int pkru_regnum = find_regno (regcache->tdesc, "pkru"); 517 518 for (i = 0; i < num_pkeys_registers; i++) 519 { 520 collect_register (regcache, i + pkru_regnum, raw); 521 p = ((char *) &fp->pkru_space[0]) + i * 4; 522 if (memcmp (raw, p, 4) != 0) 523 { 524 xstate_bv |= X86_XSTATE_PKRU; 525 memcpy (p, raw, 4); 526 } 527 } 528 } 529 530 if ((x86_xcr0 & X86_XSTATE_SSE) || (x86_xcr0 & X86_XSTATE_AVX)) 531 { 532 collect_register_by_name (regcache, "mxcsr", raw); 533 if (memcmp (raw, &fp->mxcsr, 4) != 0) 534 { 535 if (((fp->xstate_bv | xstate_bv) 536 & (X86_XSTATE_SSE | X86_XSTATE_AVX)) == 0) 537 xstate_bv |= X86_XSTATE_SSE; 538 memcpy (&fp->mxcsr, raw, 4); 539 } 540 } 541 542 if (x86_xcr0 & X86_XSTATE_X87) 543 { 544 collect_register_by_name (regcache, "fioff", raw); 545 if (memcmp (raw, &fp->fioff, 4) != 0) 546 { 547 xstate_bv |= X86_XSTATE_X87; 548 memcpy (&fp->fioff, raw, 4); 549 } 550 551 collect_register_by_name (regcache, "fooff", raw); 552 if (memcmp (raw, &fp->fooff, 4) != 0) 553 { 554 xstate_bv |= X86_XSTATE_X87; 555 memcpy (&fp->fooff, raw, 4); 556 } 557 558 /* This one's 11 bits... */ 559 val2 = regcache_raw_get_unsigned_by_name (regcache, "fop"); 560 val2 = (val2 & 0x7FF) | (fp->fop & 0xF800); 561 if (fp->fop != val2) 562 { 563 xstate_bv |= X86_XSTATE_X87; 564 fp->fop = val2; 565 } 566 567 /* Some registers are 16-bit. */ 568 val = regcache_raw_get_unsigned_by_name (regcache, "fctrl"); 569 if (fp->fctrl != val) 570 { 571 xstate_bv |= X86_XSTATE_X87; 572 fp->fctrl = val; 573 } 574 575 val = regcache_raw_get_unsigned_by_name (regcache, "fstat"); 576 if (fp->fstat != val) 577 { 578 xstate_bv |= X86_XSTATE_X87; 579 fp->fstat = val; 580 } 581 582 /* Convert to the simplifed tag form stored in fxsave data. */ 583 val = regcache_raw_get_unsigned_by_name (regcache, "ftag"); 584 val2 = 0; 585 for (i = 7; i >= 0; i--) 586 { 587 int tag = (val >> (i * 2)) & 3; 588 589 if (tag != 3) 590 val2 |= (1 << i); 591 } 592 if (fp->ftag != val2) 593 { 594 xstate_bv |= X86_XSTATE_X87; 595 fp->ftag = val2; 596 } 597 598 val = regcache_raw_get_unsigned_by_name (regcache, "fiseg"); 599 if (fp->fiseg != val) 600 { 601 xstate_bv |= X86_XSTATE_X87; 602 fp->fiseg = val; 603 } 604 605 val = regcache_raw_get_unsigned_by_name (regcache, "foseg"); 606 if (fp->foseg != val) 607 { 608 xstate_bv |= X86_XSTATE_X87; 609 fp->foseg = val; 610 } 611 } 612 613 /* Update the corresponding bits in xstate_bv if any SSE/AVX 614 registers are changed. */ 615 fp->xstate_bv |= xstate_bv; 616} 617 618static int 619i387_ftag (struct i387_fxsave *fp, int regno) 620{ 621 unsigned char *raw = &fp->st_space[regno * 16]; 622 unsigned int exponent; 623 unsigned long fraction[2]; 624 int integer; 625 626 integer = raw[7] & 0x80; 627 exponent = (((raw[9] & 0x7f) << 8) | raw[8]); 628 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]); 629 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16) 630 | (raw[5] << 8) | raw[4]); 631 632 if (exponent == 0x7fff) 633 { 634 /* Special. */ 635 return (2); 636 } 637 else if (exponent == 0x0000) 638 { 639 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer) 640 { 641 /* Zero. */ 642 return (1); 643 } 644 else 645 { 646 /* Special. */ 647 return (2); 648 } 649 } 650 else 651 { 652 if (integer) 653 { 654 /* Valid. */ 655 return (0); 656 } 657 else 658 { 659 /* Special. */ 660 return (2); 661 } 662 } 663} 664 665void 666i387_fxsave_to_cache (struct regcache *regcache, const void *buf) 667{ 668 struct i387_fxsave *fp = (struct i387_fxsave *) buf; 669 int i, top; 670 int st0_regnum = find_regno (regcache->tdesc, "st0"); 671 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0"); 672 unsigned long val; 673 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */ 674 int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8; 675 676 for (i = 0; i < 8; i++) 677 supply_register (regcache, i + st0_regnum, 678 ((char *) &fp->st_space[0]) + i * 16); 679 for (i = 0; i < num_xmm_registers; i++) 680 supply_register (regcache, i + xmm0_regnum, 681 ((char *) &fp->xmm_space[0]) + i * 16); 682 683 supply_register_by_name (regcache, "fioff", &fp->fioff); 684 supply_register_by_name (regcache, "fooff", &fp->fooff); 685 supply_register_by_name (regcache, "mxcsr", &fp->mxcsr); 686 687 /* Some registers are 16-bit. */ 688 val = fp->fctrl & 0xFFFF; 689 supply_register_by_name (regcache, "fctrl", &val); 690 691 val = fp->fstat & 0xFFFF; 692 supply_register_by_name (regcache, "fstat", &val); 693 694 /* Generate the form of ftag data that GDB expects. */ 695 top = (fp->fstat >> 11) & 0x7; 696 val = 0; 697 for (i = 7; i >= 0; i--) 698 { 699 int tag; 700 if (fp->ftag & (1 << i)) 701 tag = i387_ftag (fp, (i + 8 - top) % 8); 702 else 703 tag = 3; 704 val |= tag << (2 * i); 705 } 706 supply_register_by_name (regcache, "ftag", &val); 707 708 val = fp->fiseg & 0xFFFF; 709 supply_register_by_name (regcache, "fiseg", &val); 710 711 val = fp->foseg & 0xFFFF; 712 supply_register_by_name (regcache, "foseg", &val); 713 714 val = (fp->fop) & 0x7FF; 715 supply_register_by_name (regcache, "fop", &val); 716} 717 718void 719i387_xsave_to_cache (struct regcache *regcache, const void *buf) 720{ 721 struct i387_xsave *fp = (struct i387_xsave *) buf; 722 struct i387_fxsave *fxp = (struct i387_fxsave *) buf; 723 bool amd64 = register_size (regcache->tdesc, 0) == 8; 724 int i, top; 725 unsigned long val; 726 unsigned long long clear_bv; 727 gdb_byte *p; 728 729 /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */ 730 int num_xmm_registers = amd64 ? 16 : 8; 731 /* AVX512 extends the existing xmm/ymm registers to a wider mode: zmm. */ 732 int num_avx512_zmmh_low_registers = num_xmm_registers; 733 /* AVX512 adds 16 extra regs in Amd64 mode, but none in I386 mode.*/ 734 int num_avx512_zmmh_high_registers = amd64 ? 16 : 0; 735 int num_avx512_ymmh_registers = amd64 ? 16 : 0; 736 int num_avx512_xmm_registers = amd64 ? 16 : 0; 737 738 /* The supported bits in `xstat_bv' are 8 bytes. Clear part in 739 vector registers if its bit in xstat_bv is zero. */ 740 clear_bv = (~fp->xstate_bv) & x86_xcr0; 741 742 /* Check if any x87 registers are changed. */ 743 if ((x86_xcr0 & X86_XSTATE_X87) != 0) 744 { 745 int st0_regnum = find_regno (regcache->tdesc, "st0"); 746 747 if ((clear_bv & X86_XSTATE_X87) != 0) 748 { 749 for (i = 0; i < 8; i++) 750 supply_register_zeroed (regcache, i + st0_regnum); 751 } 752 else 753 { 754 p = (gdb_byte *) &fp->st_space[0]; 755 for (i = 0; i < 8; i++) 756 supply_register (regcache, i + st0_regnum, p + i * 16); 757 } 758 } 759 760 if ((x86_xcr0 & X86_XSTATE_SSE) != 0) 761 { 762 int xmm0_regnum = find_regno (regcache->tdesc, "xmm0"); 763 764 if ((clear_bv & X86_XSTATE_SSE)) 765 { 766 for (i = 0; i < num_xmm_registers; i++) 767 supply_register_zeroed (regcache, i + xmm0_regnum); 768 } 769 else 770 { 771 p = (gdb_byte *) &fp->xmm_space[0]; 772 for (i = 0; i < num_xmm_registers; i++) 773 supply_register (regcache, i + xmm0_regnum, p + i * 16); 774 } 775 } 776 777 if ((x86_xcr0 & X86_XSTATE_AVX) != 0) 778 { 779 int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h"); 780 781 if ((clear_bv & X86_XSTATE_AVX) != 0) 782 { 783 for (i = 0; i < num_xmm_registers; i++) 784 supply_register_zeroed (regcache, i + ymm0h_regnum); 785 } 786 else 787 { 788 p = (gdb_byte *) &fp->ymmh_space[0]; 789 for (i = 0; i < num_xmm_registers; i++) 790 supply_register (regcache, i + ymm0h_regnum, p + i * 16); 791 } 792 } 793 794 if ((x86_xcr0 & X86_XSTATE_BNDREGS)) 795 { 796 int bnd0r_regnum = find_regno (regcache->tdesc, "bnd0raw"); 797 798 799 if ((clear_bv & X86_XSTATE_BNDREGS) != 0) 800 { 801 for (i = 0; i < num_mpx_bnd_registers; i++) 802 supply_register_zeroed (regcache, i + bnd0r_regnum); 803 } 804 else 805 { 806 p = (gdb_byte *) &fp->mpx_bnd_space[0]; 807 for (i = 0; i < num_mpx_bnd_registers; i++) 808 supply_register (regcache, i + bnd0r_regnum, p + i * 16); 809 } 810 811 } 812 813 if ((x86_xcr0 & X86_XSTATE_BNDCFG)) 814 { 815 int bndcfg_regnum = find_regno (regcache->tdesc, "bndcfgu"); 816 817 if ((clear_bv & X86_XSTATE_BNDCFG) != 0) 818 { 819 for (i = 0; i < num_mpx_cfg_registers; i++) 820 supply_register_zeroed (regcache, i + bndcfg_regnum); 821 } 822 else 823 { 824 p = (gdb_byte *) &fp->mpx_cfg_space[0]; 825 for (i = 0; i < num_mpx_cfg_registers; i++) 826 supply_register (regcache, i + bndcfg_regnum, p + i * 8); 827 } 828 } 829 830 if ((x86_xcr0 & X86_XSTATE_K) != 0) 831 { 832 int k0_regnum = find_regno (regcache->tdesc, "k0"); 833 834 if ((clear_bv & X86_XSTATE_K) != 0) 835 { 836 for (i = 0; i < num_avx512_k_registers; i++) 837 supply_register_zeroed (regcache, i + k0_regnum); 838 } 839 else 840 { 841 p = (gdb_byte *) &fp->k_space[0]; 842 for (i = 0; i < num_avx512_k_registers; i++) 843 supply_register (regcache, i + k0_regnum, p + i * 8); 844 } 845 } 846 847 if ((x86_xcr0 & X86_XSTATE_ZMM_H) != 0) 848 { 849 int zmm0h_regnum = find_regno (regcache->tdesc, "zmm0h"); 850 851 if ((clear_bv & X86_XSTATE_ZMM_H) != 0) 852 { 853 for (i = 0; i < num_avx512_zmmh_low_registers; i++) 854 supply_register_zeroed (regcache, i + zmm0h_regnum); 855 } 856 else 857 { 858 p = (gdb_byte *) &fp->zmmh_low_space[0]; 859 for (i = 0; i < num_avx512_zmmh_low_registers; i++) 860 supply_register (regcache, i + zmm0h_regnum, p + i * 32); 861 } 862 } 863 864 if ((x86_xcr0 & X86_XSTATE_ZMM) != 0) 865 { 866 int zmm16h_regnum = (num_avx512_zmmh_high_registers == 0 867 ? -1 868 : find_regno (regcache->tdesc, "zmm16h")); 869 int ymm16h_regnum = (num_avx512_ymmh_registers == 0 870 ? -1 871 : find_regno (regcache->tdesc, "ymm16h")); 872 int xmm16_regnum = (num_avx512_xmm_registers == 0 873 ? -1 874 : find_regno (regcache->tdesc, "xmm16")); 875 876 if ((clear_bv & X86_XSTATE_ZMM) != 0) 877 { 878 for (i = 0; i < num_avx512_zmmh_high_registers; i++) 879 supply_register_zeroed (regcache, i + zmm16h_regnum); 880 for (i = 0; i < num_avx512_ymmh_registers; i++) 881 supply_register_zeroed (regcache, i + ymm16h_regnum); 882 for (i = 0; i < num_avx512_xmm_registers; i++) 883 supply_register_zeroed (regcache, i + xmm16_regnum); 884 } 885 else 886 { 887 p = (gdb_byte *) &fp->zmmh_high_space[0]; 888 for (i = 0; i < num_avx512_zmmh_high_registers; i++) 889 supply_register (regcache, i + zmm16h_regnum, p + 32 + i * 64); 890 for (i = 0; i < num_avx512_ymmh_registers; i++) 891 supply_register (regcache, i + ymm16h_regnum, p + 16 + i * 64); 892 for (i = 0; i < num_avx512_xmm_registers; i++) 893 supply_register (regcache, i + xmm16_regnum, p + i * 64); 894 } 895 } 896 897 if ((x86_xcr0 & X86_XSTATE_PKRU) != 0) 898 { 899 int pkru_regnum = find_regno (regcache->tdesc, "pkru"); 900 901 if ((clear_bv & X86_XSTATE_PKRU) != 0) 902 { 903 for (i = 0; i < num_pkeys_registers; i++) 904 supply_register_zeroed (regcache, i + pkru_regnum); 905 } 906 else 907 { 908 p = (gdb_byte *) &fp->pkru_space[0]; 909 for (i = 0; i < num_pkeys_registers; i++) 910 supply_register (regcache, i + pkru_regnum, p + i * 4); 911 } 912 } 913 914 if ((clear_bv & (X86_XSTATE_SSE | X86_XSTATE_AVX)) 915 == (X86_XSTATE_SSE | X86_XSTATE_AVX)) 916 { 917 unsigned int default_mxcsr = I387_MXCSR_INIT_VAL; 918 supply_register_by_name (regcache, "mxcsr", &default_mxcsr); 919 } 920 else 921 supply_register_by_name (regcache, "mxcsr", &fp->mxcsr); 922 923 if ((clear_bv & X86_XSTATE_X87) != 0) 924 { 925 supply_register_by_name_zeroed (regcache, "fioff"); 926 supply_register_by_name_zeroed (regcache, "fooff"); 927 928 val = I387_FCTRL_INIT_VAL; 929 supply_register_by_name (regcache, "fctrl", &val); 930 931 supply_register_by_name_zeroed (regcache, "fstat"); 932 933 val = 0xFFFF; 934 supply_register_by_name (regcache, "ftag", &val); 935 936 supply_register_by_name_zeroed (regcache, "fiseg"); 937 supply_register_by_name_zeroed (regcache, "foseg"); 938 supply_register_by_name_zeroed (regcache, "fop"); 939 } 940 else 941 { 942 supply_register_by_name (regcache, "fioff", &fp->fioff); 943 supply_register_by_name (regcache, "fooff", &fp->fooff); 944 945 /* Some registers are 16-bit. */ 946 val = fp->fctrl & 0xFFFF; 947 supply_register_by_name (regcache, "fctrl", &val); 948 949 val = fp->fstat & 0xFFFF; 950 supply_register_by_name (regcache, "fstat", &val); 951 952 /* Generate the form of ftag data that GDB expects. */ 953 top = (fp->fstat >> 11) & 0x7; 954 val = 0; 955 for (i = 7; i >= 0; i--) 956 { 957 int tag; 958 if (fp->ftag & (1 << i)) 959 tag = i387_ftag (fxp, (i + 8 - top) % 8); 960 else 961 tag = 3; 962 val |= tag << (2 * i); 963 } 964 supply_register_by_name (regcache, "ftag", &val); 965 966 val = fp->fiseg & 0xFFFF; 967 supply_register_by_name (regcache, "fiseg", &val); 968 969 val = fp->foseg & 0xFFFF; 970 supply_register_by_name (regcache, "foseg", &val); 971 972 val = (fp->fop) & 0x7FF; 973 supply_register_by_name (regcache, "fop", &val); 974 } 975} 976 977/* Default to SSE. */ 978unsigned long long x86_xcr0 = X86_XSTATE_SSE_MASK; 979