1/* Intel 387 floating point stuff. 2 3 Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000, 2001, 4 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. 5 6 This file is part of GDB. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21#include "defs.h" 22#include "doublest.h" 23#include "floatformat.h" 24#include "frame.h" 25#include "gdbcore.h" 26#include "inferior.h" 27#include "language.h" 28#include "regcache.h" 29#include "value.h" 30 31#include "gdb_assert.h" 32#include "gdb_string.h" 33 34#include "i386-tdep.h" 35#include "i387-tdep.h" 36 37/* Print the floating point number specified by RAW. */ 38 39static void 40print_i387_value (const gdb_byte *raw, struct ui_file *file) 41{ 42 DOUBLEST value; 43 44 /* Using extract_typed_floating here might affect the representation 45 of certain numbers such as NaNs, even if GDB is running natively. 46 This is fine since our caller already detects such special 47 numbers and we print the hexadecimal representation anyway. */ 48 value = extract_typed_floating (raw, builtin_type_i387_ext); 49 50 /* We try to print 19 digits. The last digit may or may not contain 51 garbage, but we'd better print one too many. We need enough room 52 to print the value, 1 position for the sign, 1 for the decimal 53 point, 19 for the digits and 6 for the exponent adds up to 27. */ 54#ifdef PRINTF_HAS_LONG_DOUBLE 55 fprintf_filtered (file, " %-+27.19Lg", (long double) value); 56#else 57 fprintf_filtered (file, " %-+27.19g", (double) value); 58#endif 59} 60 61/* Print the classification for the register contents RAW. */ 62 63static void 64print_i387_ext (const gdb_byte *raw, struct ui_file *file) 65{ 66 int sign; 67 int integer; 68 unsigned int exponent; 69 unsigned long fraction[2]; 70 71 sign = raw[9] & 0x80; 72 integer = raw[7] & 0x80; 73 exponent = (((raw[9] & 0x7f) << 8) | raw[8]); 74 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]); 75 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16) 76 | (raw[5] << 8) | raw[4]); 77 78 if (exponent == 0x7fff && integer) 79 { 80 if (fraction[0] == 0x00000000 && fraction[1] == 0x00000000) 81 /* Infinity. */ 82 fprintf_filtered (file, " %cInf", (sign ? '-' : '+')); 83 else if (sign && fraction[0] == 0x00000000 && fraction[1] == 0x40000000) 84 /* Real Indefinite (QNaN). */ 85 fputs_unfiltered (" Real Indefinite (QNaN)", file); 86 else if (fraction[1] & 0x40000000) 87 /* QNaN. */ 88 fputs_filtered (" QNaN", file); 89 else 90 /* SNaN. */ 91 fputs_filtered (" SNaN", file); 92 } 93 else if (exponent < 0x7fff && exponent > 0x0000 && integer) 94 /* Normal. */ 95 print_i387_value (raw, file); 96 else if (exponent == 0x0000) 97 { 98 /* Denormal or zero. */ 99 print_i387_value (raw, file); 100 101 if (integer) 102 /* Pseudo-denormal. */ 103 fputs_filtered (" Pseudo-denormal", file); 104 else if (fraction[0] || fraction[1]) 105 /* Denormal. */ 106 fputs_filtered (" Denormal", file); 107 } 108 else 109 /* Unsupported. */ 110 fputs_filtered (" Unsupported", file); 111} 112 113/* Print the status word STATUS. */ 114 115static void 116print_i387_status_word (unsigned int status, struct ui_file *file) 117{ 118 fprintf_filtered (file, "Status Word: %s", 119 hex_string_custom (status, 4)); 120 fputs_filtered (" ", file); 121 fprintf_filtered (file, " %s", (status & 0x0001) ? "IE" : " "); 122 fprintf_filtered (file, " %s", (status & 0x0002) ? "DE" : " "); 123 fprintf_filtered (file, " %s", (status & 0x0004) ? "ZE" : " "); 124 fprintf_filtered (file, " %s", (status & 0x0008) ? "OE" : " "); 125 fprintf_filtered (file, " %s", (status & 0x0010) ? "UE" : " "); 126 fprintf_filtered (file, " %s", (status & 0x0020) ? "PE" : " "); 127 fputs_filtered (" ", file); 128 fprintf_filtered (file, " %s", (status & 0x0080) ? "ES" : " "); 129 fputs_filtered (" ", file); 130 fprintf_filtered (file, " %s", (status & 0x0040) ? "SF" : " "); 131 fputs_filtered (" ", file); 132 fprintf_filtered (file, " %s", (status & 0x0100) ? "C0" : " "); 133 fprintf_filtered (file, " %s", (status & 0x0200) ? "C1" : " "); 134 fprintf_filtered (file, " %s", (status & 0x0400) ? "C2" : " "); 135 fprintf_filtered (file, " %s", (status & 0x4000) ? "C3" : " "); 136 137 fputs_filtered ("\n", file); 138 139 fprintf_filtered (file, 140 " TOP: %d\n", ((status >> 11) & 7)); 141} 142 143/* Print the control word CONTROL. */ 144 145static void 146print_i387_control_word (unsigned int control, struct ui_file *file) 147{ 148 fprintf_filtered (file, "Control Word: %s", 149 hex_string_custom (control, 4)); 150 fputs_filtered (" ", file); 151 fprintf_filtered (file, " %s", (control & 0x0001) ? "IM" : " "); 152 fprintf_filtered (file, " %s", (control & 0x0002) ? "DM" : " "); 153 fprintf_filtered (file, " %s", (control & 0x0004) ? "ZM" : " "); 154 fprintf_filtered (file, " %s", (control & 0x0008) ? "OM" : " "); 155 fprintf_filtered (file, " %s", (control & 0x0010) ? "UM" : " "); 156 fprintf_filtered (file, " %s", (control & 0x0020) ? "PM" : " "); 157 158 fputs_filtered ("\n", file); 159 160 fputs_filtered (" PC: ", file); 161 switch ((control >> 8) & 3) 162 { 163 case 0: 164 fputs_filtered ("Single Precision (24-bits)\n", file); 165 break; 166 case 1: 167 fputs_filtered ("Reserved\n", file); 168 break; 169 case 2: 170 fputs_filtered ("Double Precision (53-bits)\n", file); 171 break; 172 case 3: 173 fputs_filtered ("Extended Precision (64-bits)\n", file); 174 break; 175 } 176 177 fputs_filtered (" RC: ", file); 178 switch ((control >> 10) & 3) 179 { 180 case 0: 181 fputs_filtered ("Round to nearest\n", file); 182 break; 183 case 1: 184 fputs_filtered ("Round down\n", file); 185 break; 186 case 2: 187 fputs_filtered ("Round up\n", file); 188 break; 189 case 3: 190 fputs_filtered ("Round toward zero\n", file); 191 break; 192 } 193} 194 195/* Print out the i387 floating point state. Note that we ignore FRAME 196 in the code below. That's OK since floating-point registers are 197 never saved on the stack. */ 198 199void 200i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file, 201 struct frame_info *frame, const char *args) 202{ 203 struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame)); 204 gdb_byte buf[4]; 205 ULONGEST fctrl; 206 ULONGEST fstat; 207 ULONGEST ftag; 208 ULONGEST fiseg; 209 ULONGEST fioff; 210 ULONGEST foseg; 211 ULONGEST fooff; 212 ULONGEST fop; 213 int fpreg; 214 int top; 215 216 gdb_assert (gdbarch == get_frame_arch (frame)); 217 218 /* Define I387_ST0_REGNUM such that we use the proper definitions 219 for FRAME's architecture. */ 220#define I387_ST0_REGNUM tdep->st0_regnum 221 222 fctrl = get_frame_register_unsigned (frame, I387_FCTRL_REGNUM); 223 fstat = get_frame_register_unsigned (frame, I387_FSTAT_REGNUM); 224 ftag = get_frame_register_unsigned (frame, I387_FTAG_REGNUM); 225 fiseg = get_frame_register_unsigned (frame, I387_FISEG_REGNUM); 226 fioff = get_frame_register_unsigned (frame, I387_FIOFF_REGNUM); 227 foseg = get_frame_register_unsigned (frame, I387_FOSEG_REGNUM); 228 fooff = get_frame_register_unsigned (frame, I387_FOOFF_REGNUM); 229 fop = get_frame_register_unsigned (frame, I387_FOP_REGNUM); 230 231 top = ((fstat >> 11) & 7); 232 233 for (fpreg = 7; fpreg >= 0; fpreg--) 234 { 235 gdb_byte raw[I386_MAX_REGISTER_SIZE]; 236 int tag = (ftag >> (fpreg * 2)) & 3; 237 int i; 238 239 fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg); 240 241 switch (tag) 242 { 243 case 0: 244 fputs_filtered ("Valid ", file); 245 break; 246 case 1: 247 fputs_filtered ("Zero ", file); 248 break; 249 case 2: 250 fputs_filtered ("Special ", file); 251 break; 252 case 3: 253 fputs_filtered ("Empty ", file); 254 break; 255 } 256 257 get_frame_register (frame, (fpreg + 8 - top) % 8 + I387_ST0_REGNUM, raw); 258 259 fputs_filtered ("0x", file); 260 for (i = 9; i >= 0; i--) 261 fprintf_filtered (file, "%02x", raw[i]); 262 263 if (tag != 3) 264 print_i387_ext (raw, file); 265 266 fputs_filtered ("\n", file); 267 } 268 269 fputs_filtered ("\n", file); 270 271 print_i387_status_word (fstat, file); 272 print_i387_control_word (fctrl, file); 273 fprintf_filtered (file, "Tag Word: %s\n", 274 hex_string_custom (ftag, 4)); 275 fprintf_filtered (file, "Instruction Pointer: %s:", 276 hex_string_custom (fiseg, 2)); 277 fprintf_filtered (file, "%s\n", hex_string_custom (fioff, 8)); 278 fprintf_filtered (file, "Operand Pointer: %s:", 279 hex_string_custom (foseg, 2)); 280 fprintf_filtered (file, "%s\n", hex_string_custom (fooff, 8)); 281 fprintf_filtered (file, "Opcode: %s\n", 282 hex_string_custom (fop ? (fop | 0xd800) : 0, 4)); 283 284#undef I387_ST0_REGNUM 285} 286 287 288/* Read a value of type TYPE from register REGNUM in frame FRAME, and 289 return its contents in TO. */ 290 291void 292i387_register_to_value (struct frame_info *frame, int regnum, 293 struct type *type, gdb_byte *to) 294{ 295 gdb_byte from[I386_MAX_REGISTER_SIZE]; 296 297 gdb_assert (i386_fp_regnum_p (regnum)); 298 299 /* We only support floating-point values. */ 300 if (TYPE_CODE (type) != TYPE_CODE_FLT) 301 { 302 warning (_("Cannot convert floating-point register value " 303 "to non-floating-point type.")); 304 return; 305 } 306 307 /* Convert to TYPE. This should be a no-op if TYPE is equivalent to 308 the extended floating-point format used by the FPU. */ 309 get_frame_register (frame, regnum, from); 310 convert_typed_floating (from, builtin_type_i387_ext, to, type); 311} 312 313/* Write the contents FROM of a value of type TYPE into register 314 REGNUM in frame FRAME. */ 315 316void 317i387_value_to_register (struct frame_info *frame, int regnum, 318 struct type *type, const gdb_byte *from) 319{ 320 gdb_byte to[I386_MAX_REGISTER_SIZE]; 321 322 gdb_assert (i386_fp_regnum_p (regnum)); 323 324 /* We only support floating-point values. */ 325 if (TYPE_CODE (type) != TYPE_CODE_FLT) 326 { 327 warning (_("Cannot convert non-floating-point type " 328 "to floating-point register value.")); 329 return; 330 } 331 332 /* Convert from TYPE. This should be a no-op if TYPE is equivalent 333 to the extended floating-point format used by the FPU. */ 334 convert_typed_floating (from, type, to, builtin_type_i387_ext); 335 put_frame_register (frame, regnum, to); 336} 337 338 339/* Handle FSAVE and FXSAVE formats. */ 340 341/* At fsave_offset[REGNUM] you'll find the offset to the location in 342 the data structure used by the "fsave" instruction where GDB 343 register REGNUM is stored. */ 344 345static int fsave_offset[] = 346{ 347 28 + 0 * 10, /* %st(0) ... */ 348 28 + 1 * 10, 349 28 + 2 * 10, 350 28 + 3 * 10, 351 28 + 4 * 10, 352 28 + 5 * 10, 353 28 + 6 * 10, 354 28 + 7 * 10, /* ... %st(7). */ 355 0, /* `fctrl' (16 bits). */ 356 4, /* `fstat' (16 bits). */ 357 8, /* `ftag' (16 bits). */ 358 16, /* `fiseg' (16 bits). */ 359 12, /* `fioff'. */ 360 24, /* `foseg' (16 bits). */ 361 20, /* `fooff'. */ 362 18 /* `fop' (bottom 11 bits). */ 363}; 364 365#define FSAVE_ADDR(fsave, regnum) \ 366 (fsave + fsave_offset[regnum - I387_ST0_REGNUM]) 367 368 369/* Fill register REGNUM in REGCACHE with the appropriate value from 370 *FSAVE. This function masks off any of the reserved bits in 371 *FSAVE. */ 372 373void 374i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave) 375{ 376 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache)); 377 const gdb_byte *regs = fsave; 378 int i; 379 380 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); 381 382 /* Define I387_ST0_REGNUM and I387_NUM_XMM_REGS such that we use the 383 proper definitions for REGCACHE's architecture. */ 384 385#define I387_ST0_REGNUM tdep->st0_regnum 386#define I387_NUM_XMM_REGS tdep->num_xmm_regs 387 388 for (i = I387_ST0_REGNUM; i < I387_XMM0_REGNUM; i++) 389 if (regnum == -1 || regnum == i) 390 { 391 if (fsave == NULL) 392 { 393 regcache_raw_supply (regcache, i, NULL); 394 continue; 395 } 396 397 /* Most of the FPU control registers occupy only 16 bits in the 398 fsave area. Give those a special treatment. */ 399 if (i >= I387_FCTRL_REGNUM 400 && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM) 401 { 402 gdb_byte val[4]; 403 404 memcpy (val, FSAVE_ADDR (regs, i), 2); 405 val[2] = val[3] = 0; 406 if (i == I387_FOP_REGNUM) 407 val[1] &= ((1 << 3) - 1); 408 regcache_raw_supply (regcache, i, val); 409 } 410 else 411 regcache_raw_supply (regcache, i, FSAVE_ADDR (regs, i)); 412 } 413 414 /* Provide dummy values for the SSE registers. */ 415 for (i = I387_XMM0_REGNUM; i < I387_MXCSR_REGNUM; i++) 416 if (regnum == -1 || regnum == i) 417 regcache_raw_supply (regcache, i, NULL); 418 if (regnum == -1 || regnum == I387_MXCSR_REGNUM) 419 { 420 gdb_byte buf[4]; 421 422 store_unsigned_integer (buf, 4, 0x1f80); 423 regcache_raw_supply (regcache, I387_MXCSR_REGNUM, buf); 424 } 425 426#undef I387_ST0_REGNUM 427#undef I387_NUM_XMM_REGS 428} 429 430/* Fill register REGNUM (if it is a floating-point register) in *FSAVE 431 with the value from REGCACHE. If REGNUM is -1, do this for all 432 registers. This function doesn't touch any of the reserved bits in 433 *FSAVE. */ 434 435void 436i387_collect_fsave (const struct regcache *regcache, int regnum, void *fsave) 437{ 438 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); 439 gdb_byte *regs = fsave; 440 int i; 441 442 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); 443 444 /* Define I387_ST0_REGNUM such that we use the proper definitions 445 for REGCACHE's architecture. */ 446#define I387_ST0_REGNUM tdep->st0_regnum 447 448 for (i = I387_ST0_REGNUM; i < I387_XMM0_REGNUM; i++) 449 if (regnum == -1 || regnum == i) 450 { 451 /* Most of the FPU control registers occupy only 16 bits in 452 the fsave area. Give those a special treatment. */ 453 if (i >= I387_FCTRL_REGNUM 454 && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM) 455 { 456 gdb_byte buf[4]; 457 458 regcache_raw_collect (regcache, i, buf); 459 460 if (i == I387_FOP_REGNUM) 461 { 462 /* The opcode occupies only 11 bits. Make sure we 463 don't touch the other bits. */ 464 buf[1] &= ((1 << 3) - 1); 465 buf[1] |= ((FSAVE_ADDR (regs, i))[1] & ~((1 << 3) - 1)); 466 } 467 memcpy (FSAVE_ADDR (regs, i), buf, 2); 468 } 469 else 470 regcache_raw_collect (regcache, i, FSAVE_ADDR (regs, i)); 471 } 472#undef I387_ST0_REGNUM 473} 474 475 476/* At fxsave_offset[REGNUM] you'll find the offset to the location in 477 the data structure used by the "fxsave" instruction where GDB 478 register REGNUM is stored. */ 479 480static int fxsave_offset[] = 481{ 482 32, /* %st(0) through ... */ 483 48, 484 64, 485 80, 486 96, 487 112, 488 128, 489 144, /* ... %st(7) (80 bits each). */ 490 0, /* `fctrl' (16 bits). */ 491 2, /* `fstat' (16 bits). */ 492 4, /* `ftag' (16 bits). */ 493 12, /* `fiseg' (16 bits). */ 494 8, /* `fioff'. */ 495 20, /* `foseg' (16 bits). */ 496 16, /* `fooff'. */ 497 6, /* `fop' (bottom 11 bits). */ 498 160 + 0 * 16, /* %xmm0 through ... */ 499 160 + 1 * 16, 500 160 + 2 * 16, 501 160 + 3 * 16, 502 160 + 4 * 16, 503 160 + 5 * 16, 504 160 + 6 * 16, 505 160 + 7 * 16, 506 160 + 8 * 16, 507 160 + 9 * 16, 508 160 + 10 * 16, 509 160 + 11 * 16, 510 160 + 12 * 16, 511 160 + 13 * 16, 512 160 + 14 * 16, 513 160 + 15 * 16, /* ... %xmm15 (128 bits each). */ 514}; 515 516#define FXSAVE_ADDR(fxsave, regnum) \ 517 (fxsave + fxsave_offset[regnum - I387_ST0_REGNUM]) 518 519/* We made an unfortunate choice in putting %mxcsr after the SSE 520 registers %xmm0-%xmm7 instead of before, since it makes supporting 521 the registers %xmm8-%xmm15 on AMD64 a bit involved. Therefore we 522 don't include the offset for %mxcsr here above. */ 523 524#define FXSAVE_MXCSR_ADDR(fxsave) (fxsave + 24) 525 526static int i387_tag (const gdb_byte *raw); 527 528 529/* Fill register REGNUM in REGCACHE with the appropriate 530 floating-point or SSE register value from *FXSAVE. This function 531 masks off any of the reserved bits in *FXSAVE. */ 532 533void 534i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave) 535{ 536 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache)); 537 const gdb_byte *regs = fxsave; 538 int i; 539 540 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); 541 gdb_assert (tdep->num_xmm_regs > 0); 542 543 /* Define I387_ST0_REGNUM and I387_NUM_XMM_REGS such that we use the 544 proper definitions for REGCACHE's architecture. */ 545 546#define I387_ST0_REGNUM tdep->st0_regnum 547#define I387_NUM_XMM_REGS tdep->num_xmm_regs 548 549 for (i = I387_ST0_REGNUM; i < I387_MXCSR_REGNUM; i++) 550 if (regnum == -1 || regnum == i) 551 { 552 if (regs == NULL) 553 { 554 regcache_raw_supply (regcache, i, NULL); 555 continue; 556 } 557 558 /* Most of the FPU control registers occupy only 16 bits in 559 the fxsave area. Give those a special treatment. */ 560 if (i >= I387_FCTRL_REGNUM && i < I387_XMM0_REGNUM 561 && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM) 562 { 563 gdb_byte val[4]; 564 565 memcpy (val, FXSAVE_ADDR (regs, i), 2); 566 val[2] = val[3] = 0; 567 if (i == I387_FOP_REGNUM) 568 val[1] &= ((1 << 3) - 1); 569 else if (i== I387_FTAG_REGNUM) 570 { 571 /* The fxsave area contains a simplified version of 572 the tag word. We have to look at the actual 80-bit 573 FP data to recreate the traditional i387 tag word. */ 574 575 unsigned long ftag = 0; 576 int fpreg; 577 int top; 578 579 top = ((FXSAVE_ADDR (regs, I387_FSTAT_REGNUM))[1] >> 3); 580 top &= 0x7; 581 582 for (fpreg = 7; fpreg >= 0; fpreg--) 583 { 584 int tag; 585 586 if (val[0] & (1 << fpreg)) 587 { 588 int regnum = (fpreg + 8 - top) % 8 + I387_ST0_REGNUM; 589 tag = i387_tag (FXSAVE_ADDR (regs, regnum)); 590 } 591 else 592 tag = 3; /* Empty */ 593 594 ftag |= tag << (2 * fpreg); 595 } 596 val[0] = ftag & 0xff; 597 val[1] = (ftag >> 8) & 0xff; 598 } 599 regcache_raw_supply (regcache, i, val); 600 } 601 else 602 regcache_raw_supply (regcache, i, FXSAVE_ADDR (regs, i)); 603 } 604 605 if (regnum == I387_MXCSR_REGNUM || regnum == -1) 606 { 607 if (regs == NULL) 608 regcache_raw_supply (regcache, I387_MXCSR_REGNUM, NULL); 609 else 610 regcache_raw_supply (regcache, I387_MXCSR_REGNUM, 611 FXSAVE_MXCSR_ADDR (regs)); 612 } 613 614#undef I387_ST0_REGNUM 615#undef I387_NUM_XMM_REGS 616} 617 618/* Fill register REGNUM (if it is a floating-point or SSE register) in 619 *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for 620 all registers. This function doesn't touch any of the reserved 621 bits in *FXSAVE. */ 622 623void 624i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave) 625{ 626 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); 627 gdb_byte *regs = fxsave; 628 int i; 629 630 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); 631 gdb_assert (tdep->num_xmm_regs > 0); 632 633 /* Define I387_ST0_REGNUM and I387_NUM_XMM_REGS such that we use the 634 proper definitions for REGCACHE's architecture. */ 635 636#define I387_ST0_REGNUM tdep->st0_regnum 637#define I387_NUM_XMM_REGS tdep->num_xmm_regs 638 639 for (i = I387_ST0_REGNUM; i < I387_MXCSR_REGNUM; i++) 640 if (regnum == -1 || regnum == i) 641 { 642 /* Most of the FPU control registers occupy only 16 bits in 643 the fxsave area. Give those a special treatment. */ 644 if (i >= I387_FCTRL_REGNUM && i < I387_XMM0_REGNUM 645 && i != I387_FIOFF_REGNUM && i != I387_FOOFF_REGNUM) 646 { 647 gdb_byte buf[4]; 648 649 regcache_raw_collect (regcache, i, buf); 650 651 if (i == I387_FOP_REGNUM) 652 { 653 /* The opcode occupies only 11 bits. Make sure we 654 don't touch the other bits. */ 655 buf[1] &= ((1 << 3) - 1); 656 buf[1] |= ((FXSAVE_ADDR (regs, i))[1] & ~((1 << 3) - 1)); 657 } 658 else if (i == I387_FTAG_REGNUM) 659 { 660 /* Converting back is much easier. */ 661 662 unsigned short ftag; 663 int fpreg; 664 665 ftag = (buf[1] << 8) | buf[0]; 666 buf[0] = 0; 667 buf[1] = 0; 668 669 for (fpreg = 7; fpreg >= 0; fpreg--) 670 { 671 int tag = (ftag >> (fpreg * 2)) & 3; 672 673 if (tag != 3) 674 buf[0] |= (1 << fpreg); 675 } 676 } 677 memcpy (FXSAVE_ADDR (regs, i), buf, 2); 678 } 679 else 680 regcache_raw_collect (regcache, i, FXSAVE_ADDR (regs, i)); 681 } 682 683 if (regnum == I387_MXCSR_REGNUM || regnum == -1) 684 regcache_raw_collect (regcache, I387_MXCSR_REGNUM, 685 FXSAVE_MXCSR_ADDR (regs)); 686 687#undef I387_ST0_REGNUM 688#undef I387_NUM_XMM_REGS 689} 690 691/* Recreate the FTW (tag word) valid bits from the 80-bit FP data in 692 *RAW. */ 693 694static int 695i387_tag (const gdb_byte *raw) 696{ 697 int integer; 698 unsigned int exponent; 699 unsigned long fraction[2]; 700 701 integer = raw[7] & 0x80; 702 exponent = (((raw[9] & 0x7f) << 8) | raw[8]); 703 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]); 704 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16) 705 | (raw[5] << 8) | raw[4]); 706 707 if (exponent == 0x7fff) 708 { 709 /* Special. */ 710 return (2); 711 } 712 else if (exponent == 0x0000) 713 { 714 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer) 715 { 716 /* Zero. */ 717 return (1); 718 } 719 else 720 { 721 /* Special. */ 722 return (2); 723 } 724 } 725 else 726 { 727 if (integer) 728 { 729 /* Valid. */ 730 return (0); 731 } 732 else 733 { 734 /* Special. */ 735 return (2); 736 } 737 } 738} 739 740/* Prepare the FPU stack in REGCACHE for a function return. */ 741 742void 743i387_return_value (struct gdbarch *gdbarch, struct regcache *regcache) 744{ 745 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 746 ULONGEST fstat; 747 748 /* Define I387_ST0_REGNUM such that we use the proper 749 definitions for the architecture. */ 750#define I387_ST0_REGNUM tdep->st0_regnum 751 752 /* Set the top of the floating-point register stack to 7. The 753 actual value doesn't really matter, but 7 is what a normal 754 function return would end up with if the program started out with 755 a freshly initialized FPU. */ 756 regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM, &fstat); 757 fstat |= (7 << 11); 758 regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM, fstat); 759 760 /* Mark %st(1) through %st(7) as empty. Since we set the top of the 761 floating-point register stack to 7, the appropriate value for the 762 tag word is 0x3fff. */ 763 regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM, 0x3fff); 764 765#undef I387_ST0_REGNUM 766} 767