GDB (API)
|
00001 /* Intel 387 floating point stuff. 00002 00003 Copyright (C) 1988-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "doublest.h" 00022 #include "floatformat.h" 00023 #include "frame.h" 00024 #include "gdbcore.h" 00025 #include "inferior.h" 00026 #include "language.h" 00027 #include "regcache.h" 00028 #include "value.h" 00029 00030 #include "gdb_assert.h" 00031 #include "gdb_string.h" 00032 00033 #include "i386-tdep.h" 00034 #include "i387-tdep.h" 00035 #include "i386-xstate.h" 00036 00037 /* Print the floating point number specified by RAW. */ 00038 00039 static void 00040 print_i387_value (struct gdbarch *gdbarch, 00041 const gdb_byte *raw, struct ui_file *file) 00042 { 00043 DOUBLEST value; 00044 00045 /* Using extract_typed_floating here might affect the representation 00046 of certain numbers such as NaNs, even if GDB is running natively. 00047 This is fine since our caller already detects such special 00048 numbers and we print the hexadecimal representation anyway. */ 00049 value = extract_typed_floating (raw, i387_ext_type (gdbarch)); 00050 00051 /* We try to print 19 digits. The last digit may or may not contain 00052 garbage, but we'd better print one too many. We need enough room 00053 to print the value, 1 position for the sign, 1 for the decimal 00054 point, 19 for the digits and 6 for the exponent adds up to 27. */ 00055 #ifdef PRINTF_HAS_LONG_DOUBLE 00056 fprintf_filtered (file, " %-+27.19Lg", (long double) value); 00057 #else 00058 fprintf_filtered (file, " %-+27.19g", (double) value); 00059 #endif 00060 } 00061 00062 /* Print the classification for the register contents RAW. */ 00063 00064 static void 00065 print_i387_ext (struct gdbarch *gdbarch, 00066 const gdb_byte *raw, struct ui_file *file) 00067 { 00068 int sign; 00069 int integer; 00070 unsigned int exponent; 00071 unsigned long fraction[2]; 00072 00073 sign = raw[9] & 0x80; 00074 integer = raw[7] & 0x80; 00075 exponent = (((raw[9] & 0x7f) << 8) | raw[8]); 00076 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]); 00077 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16) 00078 | (raw[5] << 8) | raw[4]); 00079 00080 if (exponent == 0x7fff && integer) 00081 { 00082 if (fraction[0] == 0x00000000 && fraction[1] == 0x00000000) 00083 /* Infinity. */ 00084 fprintf_filtered (file, " %cInf", (sign ? '-' : '+')); 00085 else if (sign && fraction[0] == 0x00000000 && fraction[1] == 0x40000000) 00086 /* Real Indefinite (QNaN). */ 00087 fputs_unfiltered (" Real Indefinite (QNaN)", file); 00088 else if (fraction[1] & 0x40000000) 00089 /* QNaN. */ 00090 fputs_filtered (" QNaN", file); 00091 else 00092 /* SNaN. */ 00093 fputs_filtered (" SNaN", file); 00094 } 00095 else if (exponent < 0x7fff && exponent > 0x0000 && integer) 00096 /* Normal. */ 00097 print_i387_value (gdbarch, raw, file); 00098 else if (exponent == 0x0000) 00099 { 00100 /* Denormal or zero. */ 00101 print_i387_value (gdbarch, raw, file); 00102 00103 if (integer) 00104 /* Pseudo-denormal. */ 00105 fputs_filtered (" Pseudo-denormal", file); 00106 else if (fraction[0] || fraction[1]) 00107 /* Denormal. */ 00108 fputs_filtered (" Denormal", file); 00109 } 00110 else 00111 /* Unsupported. */ 00112 fputs_filtered (" Unsupported", file); 00113 } 00114 00115 /* Print the status word STATUS. If STATUS_P is false, then STATUS 00116 was unavailable. */ 00117 00118 static void 00119 print_i387_status_word (int status_p, 00120 unsigned int status, struct ui_file *file) 00121 { 00122 fprintf_filtered (file, "Status Word: "); 00123 if (!status_p) 00124 { 00125 fprintf_filtered (file, "%s\n", _("<unavailable>")); 00126 return; 00127 } 00128 00129 fprintf_filtered (file, "%s", hex_string_custom (status, 4)); 00130 fputs_filtered (" ", file); 00131 fprintf_filtered (file, " %s", (status & 0x0001) ? "IE" : " "); 00132 fprintf_filtered (file, " %s", (status & 0x0002) ? "DE" : " "); 00133 fprintf_filtered (file, " %s", (status & 0x0004) ? "ZE" : " "); 00134 fprintf_filtered (file, " %s", (status & 0x0008) ? "OE" : " "); 00135 fprintf_filtered (file, " %s", (status & 0x0010) ? "UE" : " "); 00136 fprintf_filtered (file, " %s", (status & 0x0020) ? "PE" : " "); 00137 fputs_filtered (" ", file); 00138 fprintf_filtered (file, " %s", (status & 0x0080) ? "ES" : " "); 00139 fputs_filtered (" ", file); 00140 fprintf_filtered (file, " %s", (status & 0x0040) ? "SF" : " "); 00141 fputs_filtered (" ", file); 00142 fprintf_filtered (file, " %s", (status & 0x0100) ? "C0" : " "); 00143 fprintf_filtered (file, " %s", (status & 0x0200) ? "C1" : " "); 00144 fprintf_filtered (file, " %s", (status & 0x0400) ? "C2" : " "); 00145 fprintf_filtered (file, " %s", (status & 0x4000) ? "C3" : " "); 00146 00147 fputs_filtered ("\n", file); 00148 00149 fprintf_filtered (file, 00150 " TOP: %d\n", ((status >> 11) & 7)); 00151 } 00152 00153 /* Print the control word CONTROL. If CONTROL_P is false, then 00154 CONTROL was unavailable. */ 00155 00156 static void 00157 print_i387_control_word (int control_p, 00158 unsigned int control, struct ui_file *file) 00159 { 00160 fprintf_filtered (file, "Control Word: "); 00161 if (!control_p) 00162 { 00163 fprintf_filtered (file, "%s\n", _("<unavailable>")); 00164 return; 00165 } 00166 00167 fprintf_filtered (file, "%s", hex_string_custom (control, 4)); 00168 fputs_filtered (" ", file); 00169 fprintf_filtered (file, " %s", (control & 0x0001) ? "IM" : " "); 00170 fprintf_filtered (file, " %s", (control & 0x0002) ? "DM" : " "); 00171 fprintf_filtered (file, " %s", (control & 0x0004) ? "ZM" : " "); 00172 fprintf_filtered (file, " %s", (control & 0x0008) ? "OM" : " "); 00173 fprintf_filtered (file, " %s", (control & 0x0010) ? "UM" : " "); 00174 fprintf_filtered (file, " %s", (control & 0x0020) ? "PM" : " "); 00175 00176 fputs_filtered ("\n", file); 00177 00178 fputs_filtered (" PC: ", file); 00179 switch ((control >> 8) & 3) 00180 { 00181 case 0: 00182 fputs_filtered ("Single Precision (24-bits)\n", file); 00183 break; 00184 case 1: 00185 fputs_filtered ("Reserved\n", file); 00186 break; 00187 case 2: 00188 fputs_filtered ("Double Precision (53-bits)\n", file); 00189 break; 00190 case 3: 00191 fputs_filtered ("Extended Precision (64-bits)\n", file); 00192 break; 00193 } 00194 00195 fputs_filtered (" RC: ", file); 00196 switch ((control >> 10) & 3) 00197 { 00198 case 0: 00199 fputs_filtered ("Round to nearest\n", file); 00200 break; 00201 case 1: 00202 fputs_filtered ("Round down\n", file); 00203 break; 00204 case 2: 00205 fputs_filtered ("Round up\n", file); 00206 break; 00207 case 3: 00208 fputs_filtered ("Round toward zero\n", file); 00209 break; 00210 } 00211 } 00212 00213 /* Print out the i387 floating point state. Note that we ignore FRAME 00214 in the code below. That's OK since floating-point registers are 00215 never saved on the stack. */ 00216 00217 void 00218 i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file, 00219 struct frame_info *frame, const char *args) 00220 { 00221 struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame)); 00222 ULONGEST fctrl; 00223 int fctrl_p; 00224 ULONGEST fstat; 00225 int fstat_p; 00226 ULONGEST ftag; 00227 int ftag_p; 00228 ULONGEST fiseg; 00229 int fiseg_p; 00230 ULONGEST fioff; 00231 int fioff_p; 00232 ULONGEST foseg; 00233 int foseg_p; 00234 ULONGEST fooff; 00235 int fooff_p; 00236 ULONGEST fop; 00237 int fop_p; 00238 int fpreg; 00239 int top; 00240 00241 gdb_assert (gdbarch == get_frame_arch (frame)); 00242 00243 fctrl_p = read_frame_register_unsigned (frame, 00244 I387_FCTRL_REGNUM (tdep), &fctrl); 00245 fstat_p = read_frame_register_unsigned (frame, 00246 I387_FSTAT_REGNUM (tdep), &fstat); 00247 ftag_p = read_frame_register_unsigned (frame, 00248 I387_FTAG_REGNUM (tdep), &ftag); 00249 fiseg_p = read_frame_register_unsigned (frame, 00250 I387_FISEG_REGNUM (tdep), &fiseg); 00251 fioff_p = read_frame_register_unsigned (frame, 00252 I387_FIOFF_REGNUM (tdep), &fioff); 00253 foseg_p = read_frame_register_unsigned (frame, 00254 I387_FOSEG_REGNUM (tdep), &foseg); 00255 fooff_p = read_frame_register_unsigned (frame, 00256 I387_FOOFF_REGNUM (tdep), &fooff); 00257 fop_p = read_frame_register_unsigned (frame, 00258 I387_FOP_REGNUM (tdep), &fop); 00259 00260 if (fstat_p) 00261 { 00262 top = ((fstat >> 11) & 7); 00263 00264 for (fpreg = 7; fpreg >= 0; fpreg--) 00265 { 00266 struct value *regval; 00267 int regnum; 00268 int i; 00269 int tag = -1; 00270 00271 fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg); 00272 00273 if (ftag_p) 00274 { 00275 tag = (ftag >> (fpreg * 2)) & 3; 00276 00277 switch (tag) 00278 { 00279 case 0: 00280 fputs_filtered ("Valid ", file); 00281 break; 00282 case 1: 00283 fputs_filtered ("Zero ", file); 00284 break; 00285 case 2: 00286 fputs_filtered ("Special ", file); 00287 break; 00288 case 3: 00289 fputs_filtered ("Empty ", file); 00290 break; 00291 } 00292 } 00293 else 00294 fputs_filtered ("Unknown ", file); 00295 00296 regnum = (fpreg + 8 - top) % 8 + I387_ST0_REGNUM (tdep); 00297 regval = get_frame_register_value (frame, regnum); 00298 00299 if (value_entirely_available (regval)) 00300 { 00301 const gdb_byte *raw = value_contents (regval); 00302 00303 fputs_filtered ("0x", file); 00304 for (i = 9; i >= 0; i--) 00305 fprintf_filtered (file, "%02x", raw[i]); 00306 00307 if (tag != -1 && tag != 3) 00308 print_i387_ext (gdbarch, raw, file); 00309 } 00310 else 00311 fprintf_filtered (file, "%s", _("<unavailable>")); 00312 00313 fputs_filtered ("\n", file); 00314 } 00315 } 00316 00317 fputs_filtered ("\n", file); 00318 print_i387_status_word (fstat_p, fstat, file); 00319 print_i387_control_word (fctrl_p, fctrl, file); 00320 fprintf_filtered (file, "Tag Word: %s\n", 00321 ftag_p ? hex_string_custom (ftag, 4) : _("<unavailable>")); 00322 fprintf_filtered (file, "Instruction Pointer: %s:", 00323 fiseg_p ? hex_string_custom (fiseg, 2) : _("<unavailable>")); 00324 fprintf_filtered (file, "%s\n", 00325 fioff_p ? hex_string_custom (fioff, 8) : _("<unavailable>")); 00326 fprintf_filtered (file, "Operand Pointer: %s:", 00327 foseg_p ? hex_string_custom (foseg, 2) : _("<unavailable>")); 00328 fprintf_filtered (file, "%s\n", 00329 fooff_p ? hex_string_custom (fooff, 8) : _("<unavailable>")); 00330 fprintf_filtered (file, "Opcode: %s\n", 00331 fop_p 00332 ? (hex_string_custom (fop ? (fop | 0xd800) : 0, 4)) 00333 : _("<unavailable>")); 00334 } 00335 00336 00337 /* Return nonzero if a value of type TYPE stored in register REGNUM 00338 needs any special handling. */ 00339 00340 int 00341 i387_convert_register_p (struct gdbarch *gdbarch, int regnum, 00342 struct type *type) 00343 { 00344 if (i386_fp_regnum_p (gdbarch, regnum)) 00345 { 00346 /* Floating point registers must be converted unless we are 00347 accessing them in their hardware type. */ 00348 if (type == i387_ext_type (gdbarch)) 00349 return 0; 00350 else 00351 return 1; 00352 } 00353 00354 return 0; 00355 } 00356 00357 /* Read a value of type TYPE from register REGNUM in frame FRAME, and 00358 return its contents in TO. */ 00359 00360 int 00361 i387_register_to_value (struct frame_info *frame, int regnum, 00362 struct type *type, gdb_byte *to, 00363 int *optimizedp, int *unavailablep) 00364 { 00365 struct gdbarch *gdbarch = get_frame_arch (frame); 00366 gdb_byte from[I386_MAX_REGISTER_SIZE]; 00367 00368 gdb_assert (i386_fp_regnum_p (gdbarch, regnum)); 00369 00370 /* We only support floating-point values. */ 00371 if (TYPE_CODE (type) != TYPE_CODE_FLT) 00372 { 00373 warning (_("Cannot convert floating-point register value " 00374 "to non-floating-point type.")); 00375 *optimizedp = *unavailablep = 0; 00376 return 0; 00377 } 00378 00379 /* Convert to TYPE. */ 00380 if (!get_frame_register_bytes (frame, regnum, 0, TYPE_LENGTH (type), 00381 from, optimizedp, unavailablep)) 00382 return 0; 00383 00384 convert_typed_floating (from, i387_ext_type (gdbarch), to, type); 00385 *optimizedp = *unavailablep = 0; 00386 return 1; 00387 } 00388 00389 /* Write the contents FROM of a value of type TYPE into register 00390 REGNUM in frame FRAME. */ 00391 00392 void 00393 i387_value_to_register (struct frame_info *frame, int regnum, 00394 struct type *type, const gdb_byte *from) 00395 { 00396 struct gdbarch *gdbarch = get_frame_arch (frame); 00397 gdb_byte to[I386_MAX_REGISTER_SIZE]; 00398 00399 gdb_assert (i386_fp_regnum_p (gdbarch, regnum)); 00400 00401 /* We only support floating-point values. */ 00402 if (TYPE_CODE (type) != TYPE_CODE_FLT) 00403 { 00404 warning (_("Cannot convert non-floating-point type " 00405 "to floating-point register value.")); 00406 return; 00407 } 00408 00409 /* Convert from TYPE. */ 00410 convert_typed_floating (from, type, to, i387_ext_type (gdbarch)); 00411 put_frame_register (frame, regnum, to); 00412 } 00413 00414 00415 /* Handle FSAVE and FXSAVE formats. */ 00416 00417 /* At fsave_offset[REGNUM] you'll find the offset to the location in 00418 the data structure used by the "fsave" instruction where GDB 00419 register REGNUM is stored. */ 00420 00421 static int fsave_offset[] = 00422 { 00423 28 + 0 * 10, /* %st(0) ... */ 00424 28 + 1 * 10, 00425 28 + 2 * 10, 00426 28 + 3 * 10, 00427 28 + 4 * 10, 00428 28 + 5 * 10, 00429 28 + 6 * 10, 00430 28 + 7 * 10, /* ... %st(7). */ 00431 0, /* `fctrl' (16 bits). */ 00432 4, /* `fstat' (16 bits). */ 00433 8, /* `ftag' (16 bits). */ 00434 16, /* `fiseg' (16 bits). */ 00435 12, /* `fioff'. */ 00436 24, /* `foseg' (16 bits). */ 00437 20, /* `fooff'. */ 00438 18 /* `fop' (bottom 11 bits). */ 00439 }; 00440 00441 #define FSAVE_ADDR(tdep, fsave, regnum) \ 00442 (fsave + fsave_offset[regnum - I387_ST0_REGNUM (tdep)]) 00443 00444 00445 /* Fill register REGNUM in REGCACHE with the appropriate value from 00446 *FSAVE. This function masks off any of the reserved bits in 00447 *FSAVE. */ 00448 00449 void 00450 i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave) 00451 { 00452 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00453 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 00454 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00455 const gdb_byte *regs = fsave; 00456 int i; 00457 00458 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); 00459 00460 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++) 00461 if (regnum == -1 || regnum == i) 00462 { 00463 if (fsave == NULL) 00464 { 00465 regcache_raw_supply (regcache, i, NULL); 00466 continue; 00467 } 00468 00469 /* Most of the FPU control registers occupy only 16 bits in the 00470 fsave area. Give those a special treatment. */ 00471 if (i >= I387_FCTRL_REGNUM (tdep) 00472 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep)) 00473 { 00474 gdb_byte val[4]; 00475 00476 memcpy (val, FSAVE_ADDR (tdep, regs, i), 2); 00477 val[2] = val[3] = 0; 00478 if (i == I387_FOP_REGNUM (tdep)) 00479 val[1] &= ((1 << 3) - 1); 00480 regcache_raw_supply (regcache, i, val); 00481 } 00482 else 00483 regcache_raw_supply (regcache, i, FSAVE_ADDR (tdep, regs, i)); 00484 } 00485 00486 /* Provide dummy values for the SSE registers. */ 00487 for (i = I387_XMM0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++) 00488 if (regnum == -1 || regnum == i) 00489 regcache_raw_supply (regcache, i, NULL); 00490 if (regnum == -1 || regnum == I387_MXCSR_REGNUM (tdep)) 00491 { 00492 gdb_byte buf[4]; 00493 00494 store_unsigned_integer (buf, 4, byte_order, 0x1f80); 00495 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), buf); 00496 } 00497 } 00498 00499 /* Fill register REGNUM (if it is a floating-point register) in *FSAVE 00500 with the value from REGCACHE. If REGNUM is -1, do this for all 00501 registers. This function doesn't touch any of the reserved bits in 00502 *FSAVE. */ 00503 00504 void 00505 i387_collect_fsave (const struct regcache *regcache, int regnum, void *fsave) 00506 { 00507 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache)); 00508 gdb_byte *regs = fsave; 00509 int i; 00510 00511 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); 00512 00513 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++) 00514 if (regnum == -1 || regnum == i) 00515 { 00516 /* Most of the FPU control registers occupy only 16 bits in 00517 the fsave area. Give those a special treatment. */ 00518 if (i >= I387_FCTRL_REGNUM (tdep) 00519 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep)) 00520 { 00521 gdb_byte buf[4]; 00522 00523 regcache_raw_collect (regcache, i, buf); 00524 00525 if (i == I387_FOP_REGNUM (tdep)) 00526 { 00527 /* The opcode occupies only 11 bits. Make sure we 00528 don't touch the other bits. */ 00529 buf[1] &= ((1 << 3) - 1); 00530 buf[1] |= ((FSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1)); 00531 } 00532 memcpy (FSAVE_ADDR (tdep, regs, i), buf, 2); 00533 } 00534 else 00535 regcache_raw_collect (regcache, i, FSAVE_ADDR (tdep, regs, i)); 00536 } 00537 } 00538 00539 00540 /* At fxsave_offset[REGNUM] you'll find the offset to the location in 00541 the data structure used by the "fxsave" instruction where GDB 00542 register REGNUM is stored. */ 00543 00544 static int fxsave_offset[] = 00545 { 00546 32, /* %st(0) through ... */ 00547 48, 00548 64, 00549 80, 00550 96, 00551 112, 00552 128, 00553 144, /* ... %st(7) (80 bits each). */ 00554 0, /* `fctrl' (16 bits). */ 00555 2, /* `fstat' (16 bits). */ 00556 4, /* `ftag' (16 bits). */ 00557 12, /* `fiseg' (16 bits). */ 00558 8, /* `fioff'. */ 00559 20, /* `foseg' (16 bits). */ 00560 16, /* `fooff'. */ 00561 6, /* `fop' (bottom 11 bits). */ 00562 160 + 0 * 16, /* %xmm0 through ... */ 00563 160 + 1 * 16, 00564 160 + 2 * 16, 00565 160 + 3 * 16, 00566 160 + 4 * 16, 00567 160 + 5 * 16, 00568 160 + 6 * 16, 00569 160 + 7 * 16, 00570 160 + 8 * 16, 00571 160 + 9 * 16, 00572 160 + 10 * 16, 00573 160 + 11 * 16, 00574 160 + 12 * 16, 00575 160 + 13 * 16, 00576 160 + 14 * 16, 00577 160 + 15 * 16, /* ... %xmm15 (128 bits each). */ 00578 }; 00579 00580 #define FXSAVE_ADDR(tdep, fxsave, regnum) \ 00581 (fxsave + fxsave_offset[regnum - I387_ST0_REGNUM (tdep)]) 00582 00583 /* We made an unfortunate choice in putting %mxcsr after the SSE 00584 registers %xmm0-%xmm7 instead of before, since it makes supporting 00585 the registers %xmm8-%xmm15 on AMD64 a bit involved. Therefore we 00586 don't include the offset for %mxcsr here above. */ 00587 00588 #define FXSAVE_MXCSR_ADDR(fxsave) (fxsave + 24) 00589 00590 static int i387_tag (const gdb_byte *raw); 00591 00592 00593 /* Fill register REGNUM in REGCACHE with the appropriate 00594 floating-point or SSE register value from *FXSAVE. This function 00595 masks off any of the reserved bits in *FXSAVE. */ 00596 00597 void 00598 i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave) 00599 { 00600 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache)); 00601 const gdb_byte *regs = fxsave; 00602 int i; 00603 00604 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); 00605 gdb_assert (tdep->num_xmm_regs > 0); 00606 00607 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++) 00608 if (regnum == -1 || regnum == i) 00609 { 00610 if (regs == NULL) 00611 { 00612 regcache_raw_supply (regcache, i, NULL); 00613 continue; 00614 } 00615 00616 /* Most of the FPU control registers occupy only 16 bits in 00617 the fxsave area. Give those a special treatment. */ 00618 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep) 00619 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep)) 00620 { 00621 gdb_byte val[4]; 00622 00623 memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2); 00624 val[2] = val[3] = 0; 00625 if (i == I387_FOP_REGNUM (tdep)) 00626 val[1] &= ((1 << 3) - 1); 00627 else if (i== I387_FTAG_REGNUM (tdep)) 00628 { 00629 /* The fxsave area contains a simplified version of 00630 the tag word. We have to look at the actual 80-bit 00631 FP data to recreate the traditional i387 tag word. */ 00632 00633 unsigned long ftag = 0; 00634 int fpreg; 00635 int top; 00636 00637 top = ((FXSAVE_ADDR (tdep, regs, 00638 I387_FSTAT_REGNUM (tdep)))[1] >> 3); 00639 top &= 0x7; 00640 00641 for (fpreg = 7; fpreg >= 0; fpreg--) 00642 { 00643 int tag; 00644 00645 if (val[0] & (1 << fpreg)) 00646 { 00647 int thisreg = (fpreg + 8 - top) % 8 00648 + I387_ST0_REGNUM (tdep); 00649 tag = i387_tag (FXSAVE_ADDR (tdep, regs, thisreg)); 00650 } 00651 else 00652 tag = 3; /* Empty */ 00653 00654 ftag |= tag << (2 * fpreg); 00655 } 00656 val[0] = ftag & 0xff; 00657 val[1] = (ftag >> 8) & 0xff; 00658 } 00659 regcache_raw_supply (regcache, i, val); 00660 } 00661 else 00662 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i)); 00663 } 00664 00665 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1) 00666 { 00667 if (regs == NULL) 00668 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), NULL); 00669 else 00670 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), 00671 FXSAVE_MXCSR_ADDR (regs)); 00672 } 00673 } 00674 00675 /* Fill register REGNUM (if it is a floating-point or SSE register) in 00676 *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for 00677 all registers. This function doesn't touch any of the reserved 00678 bits in *FXSAVE. */ 00679 00680 void 00681 i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave) 00682 { 00683 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache)); 00684 gdb_byte *regs = fxsave; 00685 int i; 00686 00687 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); 00688 gdb_assert (tdep->num_xmm_regs > 0); 00689 00690 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++) 00691 if (regnum == -1 || regnum == i) 00692 { 00693 /* Most of the FPU control registers occupy only 16 bits in 00694 the fxsave area. Give those a special treatment. */ 00695 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep) 00696 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep)) 00697 { 00698 gdb_byte buf[4]; 00699 00700 regcache_raw_collect (regcache, i, buf); 00701 00702 if (i == I387_FOP_REGNUM (tdep)) 00703 { 00704 /* The opcode occupies only 11 bits. Make sure we 00705 don't touch the other bits. */ 00706 buf[1] &= ((1 << 3) - 1); 00707 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1)); 00708 } 00709 else if (i == I387_FTAG_REGNUM (tdep)) 00710 { 00711 /* Converting back is much easier. */ 00712 00713 unsigned short ftag; 00714 int fpreg; 00715 00716 ftag = (buf[1] << 8) | buf[0]; 00717 buf[0] = 0; 00718 buf[1] = 0; 00719 00720 for (fpreg = 7; fpreg >= 0; fpreg--) 00721 { 00722 int tag = (ftag >> (fpreg * 2)) & 3; 00723 00724 if (tag != 3) 00725 buf[0] |= (1 << fpreg); 00726 } 00727 } 00728 memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2); 00729 } 00730 else 00731 regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i)); 00732 } 00733 00734 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1) 00735 regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep), 00736 FXSAVE_MXCSR_ADDR (regs)); 00737 } 00738 00739 /* `xstate_bv' is at byte offset 512. */ 00740 #define XSAVE_XSTATE_BV_ADDR(xsave) (xsave + 512) 00741 00742 /* At xsave_avxh_offset[REGNUM] you'll find the offset to the location in 00743 the upper 128bit of AVX register data structure used by the "xsave" 00744 instruction where GDB register REGNUM is stored. */ 00745 00746 static int xsave_avxh_offset[] = 00747 { 00748 576 + 0 * 16, /* Upper 128bit of %ymm0 through ... */ 00749 576 + 1 * 16, 00750 576 + 2 * 16, 00751 576 + 3 * 16, 00752 576 + 4 * 16, 00753 576 + 5 * 16, 00754 576 + 6 * 16, 00755 576 + 7 * 16, 00756 576 + 8 * 16, 00757 576 + 9 * 16, 00758 576 + 10 * 16, 00759 576 + 11 * 16, 00760 576 + 12 * 16, 00761 576 + 13 * 16, 00762 576 + 14 * 16, 00763 576 + 15 * 16 /* Upper 128bit of ... %ymm15 (128 bits each). */ 00764 }; 00765 00766 #define XSAVE_AVXH_ADDR(tdep, xsave, regnum) \ 00767 (xsave + xsave_avxh_offset[regnum - I387_YMM0H_REGNUM (tdep)]) 00768 00769 /* Similar to i387_supply_fxsave, but use XSAVE extended state. */ 00770 00771 void 00772 i387_supply_xsave (struct regcache *regcache, int regnum, 00773 const void *xsave) 00774 { 00775 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache)); 00776 const gdb_byte *regs = xsave; 00777 int i; 00778 unsigned int clear_bv; 00779 static const gdb_byte zero[MAX_REGISTER_SIZE] = { 0 }; 00780 enum 00781 { 00782 none = 0x0, 00783 x87 = 0x1, 00784 sse = 0x2, 00785 avxh = 0x4, 00786 all = x87 | sse | avxh 00787 } regclass; 00788 00789 gdb_assert (regs != NULL); 00790 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); 00791 gdb_assert (tdep->num_xmm_regs > 0); 00792 00793 if (regnum == -1) 00794 regclass = all; 00795 else if (regnum >= I387_YMM0H_REGNUM (tdep) 00796 && regnum < I387_YMMENDH_REGNUM (tdep)) 00797 regclass = avxh; 00798 else if (regnum >= I387_XMM0_REGNUM(tdep) 00799 && regnum < I387_MXCSR_REGNUM (tdep)) 00800 regclass = sse; 00801 else if (regnum >= I387_ST0_REGNUM (tdep) 00802 && regnum < I387_FCTRL_REGNUM (tdep)) 00803 regclass = x87; 00804 else 00805 regclass = none; 00806 00807 if (regclass != none) 00808 { 00809 /* Get `xstat_bv'. */ 00810 const gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs); 00811 00812 /* The supported bits in `xstat_bv' are 1 byte. Clear part in 00813 vector registers if its bit in xstat_bv is zero. */ 00814 clear_bv = (~(*xstate_bv_p)) & tdep->xcr0; 00815 } 00816 else 00817 clear_bv = I386_XSTATE_AVX_MASK; 00818 00819 /* With the delayed xsave mechanism, in between the program 00820 starting, and the program accessing the vector registers for the 00821 first time, the register's values are invalid. The kernel 00822 initializes register states to zero when they are set the first 00823 time in a program. This means that from the user-space programs' 00824 perspective, it's the same as if the registers have always been 00825 zero from the start of the program. Therefore, the debugger 00826 should provide the same illusion to the user. */ 00827 00828 switch (regclass) 00829 { 00830 case none: 00831 break; 00832 00833 case avxh: 00834 if ((clear_bv & I386_XSTATE_AVX)) 00835 regcache_raw_supply (regcache, regnum, zero); 00836 else 00837 regcache_raw_supply (regcache, regnum, 00838 XSAVE_AVXH_ADDR (tdep, regs, regnum)); 00839 return; 00840 00841 case sse: 00842 if ((clear_bv & I386_XSTATE_SSE)) 00843 regcache_raw_supply (regcache, regnum, zero); 00844 else 00845 regcache_raw_supply (regcache, regnum, 00846 FXSAVE_ADDR (tdep, regs, regnum)); 00847 return; 00848 00849 case x87: 00850 if ((clear_bv & I386_XSTATE_X87)) 00851 regcache_raw_supply (regcache, regnum, zero); 00852 else 00853 regcache_raw_supply (regcache, regnum, 00854 FXSAVE_ADDR (tdep, regs, regnum)); 00855 return; 00856 00857 case all: 00858 /* Handle the upper YMM registers. */ 00859 if ((tdep->xcr0 & I386_XSTATE_AVX)) 00860 { 00861 if ((clear_bv & I386_XSTATE_AVX)) 00862 { 00863 for (i = I387_YMM0H_REGNUM (tdep); 00864 i < I387_YMMENDH_REGNUM (tdep); 00865 i++) 00866 regcache_raw_supply (regcache, i, zero); 00867 } 00868 else 00869 { 00870 for (i = I387_YMM0H_REGNUM (tdep); 00871 i < I387_YMMENDH_REGNUM (tdep); 00872 i++) 00873 regcache_raw_supply (regcache, i, 00874 XSAVE_AVXH_ADDR (tdep, regs, i)); 00875 } 00876 } 00877 00878 /* Handle the XMM registers. */ 00879 if ((tdep->xcr0 & I386_XSTATE_SSE)) 00880 { 00881 if ((clear_bv & I386_XSTATE_SSE)) 00882 { 00883 for (i = I387_XMM0_REGNUM (tdep); 00884 i < I387_MXCSR_REGNUM (tdep); 00885 i++) 00886 regcache_raw_supply (regcache, i, zero); 00887 } 00888 else 00889 { 00890 for (i = I387_XMM0_REGNUM (tdep); 00891 i < I387_MXCSR_REGNUM (tdep); i++) 00892 regcache_raw_supply (regcache, i, 00893 FXSAVE_ADDR (tdep, regs, i)); 00894 } 00895 } 00896 00897 /* Handle the x87 registers. */ 00898 if ((tdep->xcr0 & I386_XSTATE_X87)) 00899 { 00900 if ((clear_bv & I386_XSTATE_X87)) 00901 { 00902 for (i = I387_ST0_REGNUM (tdep); 00903 i < I387_FCTRL_REGNUM (tdep); 00904 i++) 00905 regcache_raw_supply (regcache, i, zero); 00906 } 00907 else 00908 { 00909 for (i = I387_ST0_REGNUM (tdep); 00910 i < I387_FCTRL_REGNUM (tdep); 00911 i++) 00912 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i)); 00913 } 00914 } 00915 break; 00916 } 00917 00918 /* Only handle x87 control registers. */ 00919 for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++) 00920 if (regnum == -1 || regnum == i) 00921 { 00922 /* Most of the FPU control registers occupy only 16 bits in 00923 the xsave extended state. Give those a special treatment. */ 00924 if (i != I387_FIOFF_REGNUM (tdep) 00925 && i != I387_FOOFF_REGNUM (tdep)) 00926 { 00927 gdb_byte val[4]; 00928 00929 memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2); 00930 val[2] = val[3] = 0; 00931 if (i == I387_FOP_REGNUM (tdep)) 00932 val[1] &= ((1 << 3) - 1); 00933 else if (i== I387_FTAG_REGNUM (tdep)) 00934 { 00935 /* The fxsave area contains a simplified version of 00936 the tag word. We have to look at the actual 80-bit 00937 FP data to recreate the traditional i387 tag word. */ 00938 00939 unsigned long ftag = 0; 00940 int fpreg; 00941 int top; 00942 00943 top = ((FXSAVE_ADDR (tdep, regs, 00944 I387_FSTAT_REGNUM (tdep)))[1] >> 3); 00945 top &= 0x7; 00946 00947 for (fpreg = 7; fpreg >= 0; fpreg--) 00948 { 00949 int tag; 00950 00951 if (val[0] & (1 << fpreg)) 00952 { 00953 int thisreg = (fpreg + 8 - top) % 8 00954 + I387_ST0_REGNUM (tdep); 00955 tag = i387_tag (FXSAVE_ADDR (tdep, regs, thisreg)); 00956 } 00957 else 00958 tag = 3; /* Empty */ 00959 00960 ftag |= tag << (2 * fpreg); 00961 } 00962 val[0] = ftag & 0xff; 00963 val[1] = (ftag >> 8) & 0xff; 00964 } 00965 regcache_raw_supply (regcache, i, val); 00966 } 00967 else 00968 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i)); 00969 } 00970 00971 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1) 00972 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), 00973 FXSAVE_MXCSR_ADDR (regs)); 00974 } 00975 00976 /* Similar to i387_collect_fxsave, but use XSAVE extended state. */ 00977 00978 void 00979 i387_collect_xsave (const struct regcache *regcache, int regnum, 00980 void *xsave, int gcore) 00981 { 00982 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache)); 00983 gdb_byte *regs = xsave; 00984 int i; 00985 enum 00986 { 00987 none = 0x0, 00988 check = 0x1, 00989 x87 = 0x2 | check, 00990 sse = 0x4 | check, 00991 avxh = 0x8 | check, 00992 all = x87 | sse | avxh 00993 } regclass; 00994 00995 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); 00996 gdb_assert (tdep->num_xmm_regs > 0); 00997 00998 if (regnum == -1) 00999 regclass = all; 01000 else if (regnum >= I387_YMM0H_REGNUM (tdep) 01001 && regnum < I387_YMMENDH_REGNUM (tdep)) 01002 regclass = avxh; 01003 else if (regnum >= I387_XMM0_REGNUM(tdep) 01004 && regnum < I387_MXCSR_REGNUM (tdep)) 01005 regclass = sse; 01006 else if (regnum >= I387_ST0_REGNUM (tdep) 01007 && regnum < I387_FCTRL_REGNUM (tdep)) 01008 regclass = x87; 01009 else 01010 regclass = none; 01011 01012 if (gcore) 01013 { 01014 /* Clear XSAVE extended state. */ 01015 memset (regs, 0, I386_XSTATE_SIZE (tdep->xcr0)); 01016 01017 /* Update XCR0 and `xstate_bv' with XCR0 for gcore. */ 01018 if (tdep->xsave_xcr0_offset != -1) 01019 memcpy (regs + tdep->xsave_xcr0_offset, &tdep->xcr0, 8); 01020 memcpy (XSAVE_XSTATE_BV_ADDR (regs), &tdep->xcr0, 8); 01021 } 01022 01023 if ((regclass & check)) 01024 { 01025 gdb_byte raw[I386_MAX_REGISTER_SIZE]; 01026 gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs); 01027 unsigned int xstate_bv = 0; 01028 /* The supported bits in `xstat_bv' are 1 byte. */ 01029 unsigned int clear_bv = (~(*xstate_bv_p)) & tdep->xcr0; 01030 gdb_byte *p; 01031 01032 /* Clear register set if its bit in xstat_bv is zero. */ 01033 if (clear_bv) 01034 { 01035 if ((clear_bv & I386_XSTATE_AVX)) 01036 for (i = I387_YMM0H_REGNUM (tdep); 01037 i < I387_YMMENDH_REGNUM (tdep); i++) 01038 memset (XSAVE_AVXH_ADDR (tdep, regs, i), 0, 16); 01039 01040 if ((clear_bv & I386_XSTATE_SSE)) 01041 for (i = I387_XMM0_REGNUM (tdep); 01042 i < I387_MXCSR_REGNUM (tdep); i++) 01043 memset (FXSAVE_ADDR (tdep, regs, i), 0, 16); 01044 01045 if ((clear_bv & I386_XSTATE_X87)) 01046 for (i = I387_ST0_REGNUM (tdep); 01047 i < I387_FCTRL_REGNUM (tdep); i++) 01048 memset (FXSAVE_ADDR (tdep, regs, i), 0, 10); 01049 } 01050 01051 if (regclass == all) 01052 { 01053 /* Check if any upper YMM registers are changed. */ 01054 if ((tdep->xcr0 & I386_XSTATE_AVX)) 01055 for (i = I387_YMM0H_REGNUM (tdep); 01056 i < I387_YMMENDH_REGNUM (tdep); i++) 01057 { 01058 regcache_raw_collect (regcache, i, raw); 01059 p = XSAVE_AVXH_ADDR (tdep, regs, i); 01060 if (memcmp (raw, p, 16)) 01061 { 01062 xstate_bv |= I386_XSTATE_AVX; 01063 memcpy (p, raw, 16); 01064 } 01065 } 01066 01067 /* Check if any SSE registers are changed. */ 01068 if ((tdep->xcr0 & I386_XSTATE_SSE)) 01069 for (i = I387_XMM0_REGNUM (tdep); 01070 i < I387_MXCSR_REGNUM (tdep); i++) 01071 { 01072 regcache_raw_collect (regcache, i, raw); 01073 p = FXSAVE_ADDR (tdep, regs, i); 01074 if (memcmp (raw, p, 16)) 01075 { 01076 xstate_bv |= I386_XSTATE_SSE; 01077 memcpy (p, raw, 16); 01078 } 01079 } 01080 01081 /* Check if any X87 registers are changed. */ 01082 if ((tdep->xcr0 & I386_XSTATE_X87)) 01083 for (i = I387_ST0_REGNUM (tdep); 01084 i < I387_FCTRL_REGNUM (tdep); i++) 01085 { 01086 regcache_raw_collect (regcache, i, raw); 01087 p = FXSAVE_ADDR (tdep, regs, i); 01088 if (memcmp (raw, p, 10)) 01089 { 01090 xstate_bv |= I386_XSTATE_X87; 01091 memcpy (p, raw, 10); 01092 } 01093 } 01094 } 01095 else 01096 { 01097 /* Check if REGNUM is changed. */ 01098 regcache_raw_collect (regcache, regnum, raw); 01099 01100 switch (regclass) 01101 { 01102 default: 01103 internal_error (__FILE__, __LINE__, 01104 _("invalid i387 regclass")); 01105 01106 case avxh: 01107 /* This is an upper YMM register. */ 01108 p = XSAVE_AVXH_ADDR (tdep, regs, regnum); 01109 if (memcmp (raw, p, 16)) 01110 { 01111 xstate_bv |= I386_XSTATE_AVX; 01112 memcpy (p, raw, 16); 01113 } 01114 break; 01115 01116 case sse: 01117 /* This is an SSE register. */ 01118 p = FXSAVE_ADDR (tdep, regs, regnum); 01119 if (memcmp (raw, p, 16)) 01120 { 01121 xstate_bv |= I386_XSTATE_SSE; 01122 memcpy (p, raw, 16); 01123 } 01124 break; 01125 01126 case x87: 01127 /* This is an x87 register. */ 01128 p = FXSAVE_ADDR (tdep, regs, regnum); 01129 if (memcmp (raw, p, 10)) 01130 { 01131 xstate_bv |= I386_XSTATE_X87; 01132 memcpy (p, raw, 10); 01133 } 01134 break; 01135 } 01136 } 01137 01138 /* Update the corresponding bits in `xstate_bv' if any SSE/AVX 01139 registers are changed. */ 01140 if (xstate_bv) 01141 { 01142 /* The supported bits in `xstat_bv' are 1 byte. */ 01143 *xstate_bv_p |= (gdb_byte) xstate_bv; 01144 01145 switch (regclass) 01146 { 01147 default: 01148 internal_error (__FILE__, __LINE__, 01149 _("invalid i387 regclass")); 01150 01151 case all: 01152 break; 01153 01154 case x87: 01155 case sse: 01156 case avxh: 01157 /* Register REGNUM has been updated. Return. */ 01158 return; 01159 } 01160 } 01161 else 01162 { 01163 /* Return if REGNUM isn't changed. */ 01164 if (regclass != all) 01165 return; 01166 } 01167 } 01168 01169 /* Only handle x87 control registers. */ 01170 for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++) 01171 if (regnum == -1 || regnum == i) 01172 { 01173 /* Most of the FPU control registers occupy only 16 bits in 01174 the xsave extended state. Give those a special treatment. */ 01175 if (i != I387_FIOFF_REGNUM (tdep) 01176 && i != I387_FOOFF_REGNUM (tdep)) 01177 { 01178 gdb_byte buf[4]; 01179 01180 regcache_raw_collect (regcache, i, buf); 01181 01182 if (i == I387_FOP_REGNUM (tdep)) 01183 { 01184 /* The opcode occupies only 11 bits. Make sure we 01185 don't touch the other bits. */ 01186 buf[1] &= ((1 << 3) - 1); 01187 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1)); 01188 } 01189 else if (i == I387_FTAG_REGNUM (tdep)) 01190 { 01191 /* Converting back is much easier. */ 01192 01193 unsigned short ftag; 01194 int fpreg; 01195 01196 ftag = (buf[1] << 8) | buf[0]; 01197 buf[0] = 0; 01198 buf[1] = 0; 01199 01200 for (fpreg = 7; fpreg >= 0; fpreg--) 01201 { 01202 int tag = (ftag >> (fpreg * 2)) & 3; 01203 01204 if (tag != 3) 01205 buf[0] |= (1 << fpreg); 01206 } 01207 } 01208 memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2); 01209 } 01210 else 01211 regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i)); 01212 } 01213 01214 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1) 01215 regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep), 01216 FXSAVE_MXCSR_ADDR (regs)); 01217 } 01218 01219 /* Recreate the FTW (tag word) valid bits from the 80-bit FP data in 01220 *RAW. */ 01221 01222 static int 01223 i387_tag (const gdb_byte *raw) 01224 { 01225 int integer; 01226 unsigned int exponent; 01227 unsigned long fraction[2]; 01228 01229 integer = raw[7] & 0x80; 01230 exponent = (((raw[9] & 0x7f) << 8) | raw[8]); 01231 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]); 01232 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16) 01233 | (raw[5] << 8) | raw[4]); 01234 01235 if (exponent == 0x7fff) 01236 { 01237 /* Special. */ 01238 return (2); 01239 } 01240 else if (exponent == 0x0000) 01241 { 01242 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer) 01243 { 01244 /* Zero. */ 01245 return (1); 01246 } 01247 else 01248 { 01249 /* Special. */ 01250 return (2); 01251 } 01252 } 01253 else 01254 { 01255 if (integer) 01256 { 01257 /* Valid. */ 01258 return (0); 01259 } 01260 else 01261 { 01262 /* Special. */ 01263 return (2); 01264 } 01265 } 01266 } 01267 01268 /* Prepare the FPU stack in REGCACHE for a function return. */ 01269 01270 void 01271 i387_return_value (struct gdbarch *gdbarch, struct regcache *regcache) 01272 { 01273 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 01274 ULONGEST fstat; 01275 01276 /* Set the top of the floating-point register stack to 7. The 01277 actual value doesn't really matter, but 7 is what a normal 01278 function return would end up with if the program started out with 01279 a freshly initialized FPU. */ 01280 regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM (tdep), &fstat); 01281 fstat |= (7 << 11); 01282 regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM (tdep), fstat); 01283 01284 /* Mark %st(1) through %st(7) as empty. Since we set the top of the 01285 floating-point register stack to 7, the appropriate value for the 01286 tag word is 0x3fff. */ 01287 regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM (tdep), 0x3fff); 01288 01289 }