2010-05-05 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / gdb / i387-tdep.c
CommitLineData
c906108c 1/* Intel 387 floating point stuff.
38edeab8 2
6aba47ca 3 Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000, 2001,
4c38e0a4
JB
4 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
5 Free Software Foundation, Inc.
c906108c 6
c5aa993b 7 This file is part of GDB.
c906108c 8
c5aa993b
JM
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
c5aa993b 12 (at your option) any later version.
c906108c 13
c5aa993b
JM
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
c906108c 18
c5aa993b 19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
21
22#include "defs.h"
786a90bb
MK
23#include "doublest.h"
24#include "floatformat.h"
c906108c 25#include "frame.h"
786a90bb 26#include "gdbcore.h"
c906108c
SS
27#include "inferior.h"
28#include "language.h"
4e052eda 29#include "regcache.h"
786a90bb
MK
30#include "value.h"
31
d0df8472 32#include "gdb_assert.h"
309367d4 33#include "gdb_string.h"
c906108c 34
9a82579f 35#include "i386-tdep.h"
42c466d7 36#include "i387-tdep.h"
31aeac78 37#include "i386-xstate.h"
c906108c 38
de57eccd 39/* Print the floating point number specified by RAW. */
786a90bb 40
de57eccd 41static void
27067745
UW
42print_i387_value (struct gdbarch *gdbarch,
43 const gdb_byte *raw, struct ui_file *file)
de57eccd
JM
44{
45 DOUBLEST value;
4583280c
MK
46
47 /* Using extract_typed_floating here might affect the representation
48 of certain numbers such as NaNs, even if GDB is running natively.
49 This is fine since our caller already detects such special
50 numbers and we print the hexadecimal representation anyway. */
27067745 51 value = extract_typed_floating (raw, i387_ext_type (gdbarch));
de57eccd
JM
52
53 /* We try to print 19 digits. The last digit may or may not contain
54 garbage, but we'd better print one too many. We need enough room
55 to print the value, 1 position for the sign, 1 for the decimal
56 point, 19 for the digits and 6 for the exponent adds up to 27. */
57#ifdef PRINTF_HAS_LONG_DOUBLE
61113f8b 58 fprintf_filtered (file, " %-+27.19Lg", (long double) value);
de57eccd 59#else
61113f8b 60 fprintf_filtered (file, " %-+27.19g", (double) value);
de57eccd
JM
61#endif
62}
63
64/* Print the classification for the register contents RAW. */
786a90bb 65
de57eccd 66static void
27067745
UW
67print_i387_ext (struct gdbarch *gdbarch,
68 const gdb_byte *raw, struct ui_file *file)
de57eccd
JM
69{
70 int sign;
71 int integer;
72 unsigned int exponent;
73 unsigned long fraction[2];
74
75 sign = raw[9] & 0x80;
76 integer = raw[7] & 0x80;
77 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
78 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
79 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
80 | (raw[5] << 8) | raw[4]);
81
82 if (exponent == 0x7fff && integer)
83 {
84 if (fraction[0] == 0x00000000 && fraction[1] == 0x00000000)
85 /* Infinity. */
61113f8b 86 fprintf_filtered (file, " %cInf", (sign ? '-' : '+'));
de57eccd
JM
87 else if (sign && fraction[0] == 0x00000000 && fraction[1] == 0x40000000)
88 /* Real Indefinite (QNaN). */
61113f8b 89 fputs_unfiltered (" Real Indefinite (QNaN)", file);
de57eccd
JM
90 else if (fraction[1] & 0x40000000)
91 /* QNaN. */
61113f8b 92 fputs_filtered (" QNaN", file);
de57eccd
JM
93 else
94 /* SNaN. */
61113f8b 95 fputs_filtered (" SNaN", file);
de57eccd
JM
96 }
97 else if (exponent < 0x7fff && exponent > 0x0000 && integer)
98 /* Normal. */
27067745 99 print_i387_value (gdbarch, raw, file);
de57eccd
JM
100 else if (exponent == 0x0000)
101 {
102 /* Denormal or zero. */
27067745 103 print_i387_value (gdbarch, raw, file);
de57eccd
JM
104
105 if (integer)
106 /* Pseudo-denormal. */
61113f8b 107 fputs_filtered (" Pseudo-denormal", file);
de57eccd
JM
108 else if (fraction[0] || fraction[1])
109 /* Denormal. */
61113f8b 110 fputs_filtered (" Denormal", file);
de57eccd
JM
111 }
112 else
113 /* Unsupported. */
61113f8b 114 fputs_filtered (" Unsupported", file);
de57eccd
JM
115}
116
117/* Print the status word STATUS. */
786a90bb 118
de57eccd 119static void
61113f8b 120print_i387_status_word (unsigned int status, struct ui_file *file)
de57eccd 121{
61113f8b 122 fprintf_filtered (file, "Status Word: %s",
bb599908 123 hex_string_custom (status, 4));
61113f8b
MK
124 fputs_filtered (" ", file);
125 fprintf_filtered (file, " %s", (status & 0x0001) ? "IE" : " ");
126 fprintf_filtered (file, " %s", (status & 0x0002) ? "DE" : " ");
127 fprintf_filtered (file, " %s", (status & 0x0004) ? "ZE" : " ");
128 fprintf_filtered (file, " %s", (status & 0x0008) ? "OE" : " ");
129 fprintf_filtered (file, " %s", (status & 0x0010) ? "UE" : " ");
130 fprintf_filtered (file, " %s", (status & 0x0020) ? "PE" : " ");
131 fputs_filtered (" ", file);
132 fprintf_filtered (file, " %s", (status & 0x0080) ? "ES" : " ");
133 fputs_filtered (" ", file);
134 fprintf_filtered (file, " %s", (status & 0x0040) ? "SF" : " ");
135 fputs_filtered (" ", file);
136 fprintf_filtered (file, " %s", (status & 0x0100) ? "C0" : " ");
137 fprintf_filtered (file, " %s", (status & 0x0200) ? "C1" : " ");
138 fprintf_filtered (file, " %s", (status & 0x0400) ? "C2" : " ");
139 fprintf_filtered (file, " %s", (status & 0x4000) ? "C3" : " ");
140
141 fputs_filtered ("\n", file);
142
143 fprintf_filtered (file,
144 " TOP: %d\n", ((status >> 11) & 7));
de57eccd
JM
145}
146
147/* Print the control word CONTROL. */
786a90bb 148
de57eccd 149static void
61113f8b 150print_i387_control_word (unsigned int control, struct ui_file *file)
de57eccd 151{
61113f8b 152 fprintf_filtered (file, "Control Word: %s",
bb599908 153 hex_string_custom (control, 4));
61113f8b
MK
154 fputs_filtered (" ", file);
155 fprintf_filtered (file, " %s", (control & 0x0001) ? "IM" : " ");
156 fprintf_filtered (file, " %s", (control & 0x0002) ? "DM" : " ");
157 fprintf_filtered (file, " %s", (control & 0x0004) ? "ZM" : " ");
158 fprintf_filtered (file, " %s", (control & 0x0008) ? "OM" : " ");
159 fprintf_filtered (file, " %s", (control & 0x0010) ? "UM" : " ");
160 fprintf_filtered (file, " %s", (control & 0x0020) ? "PM" : " ");
de57eccd 161
61113f8b 162 fputs_filtered ("\n", file);
de57eccd 163
61113f8b 164 fputs_filtered (" PC: ", file);
de57eccd
JM
165 switch ((control >> 8) & 3)
166 {
167 case 0:
61113f8b 168 fputs_filtered ("Single Precision (24-bits)\n", file);
de57eccd
JM
169 break;
170 case 1:
61113f8b 171 fputs_filtered ("Reserved\n", file);
de57eccd
JM
172 break;
173 case 2:
61113f8b 174 fputs_filtered ("Double Precision (53-bits)\n", file);
de57eccd
JM
175 break;
176 case 3:
61113f8b 177 fputs_filtered ("Extended Precision (64-bits)\n", file);
de57eccd
JM
178 break;
179 }
180
61113f8b 181 fputs_filtered (" RC: ", file);
de57eccd
JM
182 switch ((control >> 10) & 3)
183 {
184 case 0:
61113f8b 185 fputs_filtered ("Round to nearest\n", file);
de57eccd
JM
186 break;
187 case 1:
61113f8b 188 fputs_filtered ("Round down\n", file);
de57eccd
JM
189 break;
190 case 2:
61113f8b 191 fputs_filtered ("Round up\n", file);
de57eccd
JM
192 break;
193 case 3:
61113f8b 194 fputs_filtered ("Round toward zero\n", file);
de57eccd
JM
195 break;
196 }
197}
198
9b949a49 199/* Print out the i387 floating point state. Note that we ignore FRAME
7d8d2918
MK
200 in the code below. That's OK since floating-point registers are
201 never saved on the stack. */
202
de57eccd 203void
61113f8b 204i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
8e186fd6 205 struct frame_info *frame, const char *args)
de57eccd 206{
5716833c 207 struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
1d70089a
MK
208 ULONGEST fctrl;
209 ULONGEST fstat;
210 ULONGEST ftag;
211 ULONGEST fiseg;
212 ULONGEST fioff;
213 ULONGEST foseg;
214 ULONGEST fooff;
215 ULONGEST fop;
de57eccd
JM
216 int fpreg;
217 int top;
218
5716833c
MK
219 gdb_assert (gdbarch == get_frame_arch (frame));
220
20a6ec49
MD
221 fctrl = get_frame_register_unsigned (frame, I387_FCTRL_REGNUM (tdep));
222 fstat = get_frame_register_unsigned (frame, I387_FSTAT_REGNUM (tdep));
223 ftag = get_frame_register_unsigned (frame, I387_FTAG_REGNUM (tdep));
224 fiseg = get_frame_register_unsigned (frame, I387_FISEG_REGNUM (tdep));
225 fioff = get_frame_register_unsigned (frame, I387_FIOFF_REGNUM (tdep));
226 foseg = get_frame_register_unsigned (frame, I387_FOSEG_REGNUM (tdep));
227 fooff = get_frame_register_unsigned (frame, I387_FOOFF_REGNUM (tdep));
228 fop = get_frame_register_unsigned (frame, I387_FOP_REGNUM (tdep));
1d70089a 229
de57eccd
JM
230 top = ((fstat >> 11) & 7);
231
232 for (fpreg = 7; fpreg >= 0; fpreg--)
233 {
b4ad899f 234 gdb_byte raw[I386_MAX_REGISTER_SIZE];
de57eccd
JM
235 int tag = (ftag >> (fpreg * 2)) & 3;
236 int i;
237
61113f8b 238 fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg);
de57eccd
JM
239
240 switch (tag)
241 {
242 case 0:
61113f8b 243 fputs_filtered ("Valid ", file);
de57eccd
JM
244 break;
245 case 1:
61113f8b 246 fputs_filtered ("Zero ", file);
de57eccd
JM
247 break;
248 case 2:
61113f8b 249 fputs_filtered ("Special ", file);
de57eccd
JM
250 break;
251 case 3:
61113f8b 252 fputs_filtered ("Empty ", file);
de57eccd
JM
253 break;
254 }
255
20a6ec49
MD
256 get_frame_register (frame, (fpreg + 8 - top) % 8 + I387_ST0_REGNUM (tdep),
257 raw);
de57eccd 258
61113f8b 259 fputs_filtered ("0x", file);
de57eccd 260 for (i = 9; i >= 0; i--)
61113f8b 261 fprintf_filtered (file, "%02x", raw[i]);
de57eccd
JM
262
263 if (tag != 3)
27067745 264 print_i387_ext (gdbarch, raw, file);
de57eccd 265
61113f8b 266 fputs_filtered ("\n", file);
de57eccd
JM
267 }
268
f16a25ae 269 fputs_filtered ("\n", file);
de57eccd 270
61113f8b
MK
271 print_i387_status_word (fstat, file);
272 print_i387_control_word (fctrl, file);
273 fprintf_filtered (file, "Tag Word: %s\n",
bb599908 274 hex_string_custom (ftag, 4));
61113f8b 275 fprintf_filtered (file, "Instruction Pointer: %s:",
bb599908
PH
276 hex_string_custom (fiseg, 2));
277 fprintf_filtered (file, "%s\n", hex_string_custom (fioff, 8));
61113f8b 278 fprintf_filtered (file, "Operand Pointer: %s:",
bb599908
PH
279 hex_string_custom (foseg, 2));
280 fprintf_filtered (file, "%s\n", hex_string_custom (fooff, 8));
61113f8b 281 fprintf_filtered (file, "Opcode: %s\n",
bb599908 282 hex_string_custom (fop ? (fop | 0xd800) : 0, 4));
de57eccd 283}
d532c08f
MK
284\f
285
83acabca
DJ
286/* Return nonzero if a value of type TYPE stored in register REGNUM
287 needs any special handling. */
288
289int
0abe36f5 290i387_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type)
83acabca 291{
20a6ec49 292 if (i386_fp_regnum_p (gdbarch, regnum))
83acabca
DJ
293 {
294 /* Floating point registers must be converted unless we are
295 accessing them in their hardware type. */
27067745 296 if (type == i387_ext_type (gdbarch))
83acabca
DJ
297 return 0;
298 else
299 return 1;
300 }
301
302 return 0;
303}
304
d532c08f
MK
305/* Read a value of type TYPE from register REGNUM in frame FRAME, and
306 return its contents in TO. */
307
308void
309i387_register_to_value (struct frame_info *frame, int regnum,
42835c2b 310 struct type *type, gdb_byte *to)
d532c08f 311{
27067745 312 struct gdbarch *gdbarch = get_frame_arch (frame);
b4ad899f 313 gdb_byte from[I386_MAX_REGISTER_SIZE];
d532c08f 314
27067745 315 gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
d532c08f
MK
316
317 /* We only support floating-point values. */
318 if (TYPE_CODE (type) != TYPE_CODE_FLT)
319 {
8a3fe4f8
AC
320 warning (_("Cannot convert floating-point register value "
321 "to non-floating-point type."));
d532c08f
MK
322 return;
323 }
324
83acabca 325 /* Convert to TYPE. */
192285c6 326 get_frame_register (frame, regnum, from);
27067745 327 convert_typed_floating (from, i387_ext_type (gdbarch), to, type);
d532c08f
MK
328}
329
330/* Write the contents FROM of a value of type TYPE into register
331 REGNUM in frame FRAME. */
332
333void
334i387_value_to_register (struct frame_info *frame, int regnum,
42835c2b 335 struct type *type, const gdb_byte *from)
d532c08f 336{
27067745 337 struct gdbarch *gdbarch = get_frame_arch (frame);
b4ad899f 338 gdb_byte to[I386_MAX_REGISTER_SIZE];
d532c08f 339
27067745 340 gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
d532c08f
MK
341
342 /* We only support floating-point values. */
343 if (TYPE_CODE (type) != TYPE_CODE_FLT)
344 {
8a3fe4f8
AC
345 warning (_("Cannot convert non-floating-point type "
346 "to floating-point register value."));
d532c08f
MK
347 return;
348 }
349
83acabca 350 /* Convert from TYPE. */
27067745 351 convert_typed_floating (from, type, to, i387_ext_type (gdbarch));
d532c08f
MK
352 put_frame_register (frame, regnum, to);
353}
354\f
e750d25e 355
786a90bb 356/* Handle FSAVE and FXSAVE formats. */
e750d25e
JT
357
358/* At fsave_offset[REGNUM] you'll find the offset to the location in
359 the data structure used by the "fsave" instruction where GDB
360 register REGNUM is stored. */
361
362static int fsave_offset[] =
363{
5716833c
MK
364 28 + 0 * 10, /* %st(0) ... */
365 28 + 1 * 10,
366 28 + 2 * 10,
367 28 + 3 * 10,
368 28 + 4 * 10,
369 28 + 5 * 10,
370 28 + 6 * 10,
371 28 + 7 * 10, /* ... %st(7). */
372 0, /* `fctrl' (16 bits). */
373 4, /* `fstat' (16 bits). */
374 8, /* `ftag' (16 bits). */
375 16, /* `fiseg' (16 bits). */
376 12, /* `fioff'. */
377 24, /* `foseg' (16 bits). */
378 20, /* `fooff'. */
379 18 /* `fop' (bottom 11 bits). */
e750d25e
JT
380};
381
20a6ec49
MD
382#define FSAVE_ADDR(tdep, fsave, regnum) \
383 (fsave + fsave_offset[regnum - I387_ST0_REGNUM (tdep)])
e750d25e
JT
384\f
385
41d041d6
MK
386/* Fill register REGNUM in REGCACHE with the appropriate value from
387 *FSAVE. This function masks off any of the reserved bits in
388 *FSAVE. */
e750d25e
JT
389
390void
41d041d6 391i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave)
e750d25e 392{
e17a4113
UW
393 struct gdbarch *gdbarch = get_regcache_arch (regcache);
394 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
395 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
b4ad899f 396 const gdb_byte *regs = fsave;
e750d25e
JT
397 int i;
398
5716833c
MK
399 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
400
20a6ec49 401 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
ed504bdf
MK
402 if (regnum == -1 || regnum == i)
403 {
404 if (fsave == NULL)
405 {
5716833c
MK
406 regcache_raw_supply (regcache, i, NULL);
407 continue;
ed504bdf
MK
408 }
409
410 /* Most of the FPU control registers occupy only 16 bits in the
411 fsave area. Give those a special treatment. */
20a6ec49
MD
412 if (i >= I387_FCTRL_REGNUM (tdep)
413 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
ed504bdf 414 {
b4ad899f 415 gdb_byte val[4];
ed504bdf 416
20a6ec49 417 memcpy (val, FSAVE_ADDR (tdep, regs, i), 2);
ed504bdf 418 val[2] = val[3] = 0;
20a6ec49 419 if (i == I387_FOP_REGNUM (tdep))
ed504bdf 420 val[1] &= ((1 << 3) - 1);
5716833c 421 regcache_raw_supply (regcache, i, val);
ed504bdf
MK
422 }
423 else
20a6ec49 424 regcache_raw_supply (regcache, i, FSAVE_ADDR (tdep, regs, i));
ed504bdf 425 }
b87bc0d8
MK
426
427 /* Provide dummy values for the SSE registers. */
20a6ec49 428 for (i = I387_XMM0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
b87bc0d8
MK
429 if (regnum == -1 || regnum == i)
430 regcache_raw_supply (regcache, i, NULL);
20a6ec49 431 if (regnum == -1 || regnum == I387_MXCSR_REGNUM (tdep))
b87bc0d8 432 {
b4ad899f 433 gdb_byte buf[4];
b87bc0d8 434
e17a4113 435 store_unsigned_integer (buf, 4, byte_order, 0x1f80);
20a6ec49 436 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), buf);
b87bc0d8 437 }
e750d25e
JT
438}
439
440/* Fill register REGNUM (if it is a floating-point register) in *FSAVE
63b6c53f
MK
441 with the value from REGCACHE. If REGNUM is -1, do this for all
442 registers. This function doesn't touch any of the reserved bits in
443 *FSAVE. */
e750d25e
JT
444
445void
63b6c53f 446i387_collect_fsave (const struct regcache *regcache, int regnum, void *fsave)
e750d25e 447{
e071d1f6 448 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
b4ad899f 449 gdb_byte *regs = fsave;
e750d25e
JT
450 int i;
451
5716833c
MK
452 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
453
20a6ec49 454 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
e750d25e
JT
455 if (regnum == -1 || regnum == i)
456 {
457 /* Most of the FPU control registers occupy only 16 bits in
458 the fsave area. Give those a special treatment. */
20a6ec49
MD
459 if (i >= I387_FCTRL_REGNUM (tdep)
460 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
e750d25e 461 {
b4ad899f 462 gdb_byte buf[4];
e750d25e 463
5716833c 464 regcache_raw_collect (regcache, i, buf);
e750d25e 465
20a6ec49 466 if (i == I387_FOP_REGNUM (tdep))
e750d25e
JT
467 {
468 /* The opcode occupies only 11 bits. Make sure we
469 don't touch the other bits. */
470 buf[1] &= ((1 << 3) - 1);
20a6ec49 471 buf[1] |= ((FSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
e750d25e 472 }
20a6ec49 473 memcpy (FSAVE_ADDR (tdep, regs, i), buf, 2);
e750d25e
JT
474 }
475 else
20a6ec49 476 regcache_raw_collect (regcache, i, FSAVE_ADDR (tdep, regs, i));
e750d25e
JT
477 }
478}
479\f
480
481/* At fxsave_offset[REGNUM] you'll find the offset to the location in
482 the data structure used by the "fxsave" instruction where GDB
483 register REGNUM is stored. */
484
485static int fxsave_offset[] =
486{
5716833c 487 32, /* %st(0) through ... */
e750d25e
JT
488 48,
489 64,
490 80,
491 96,
492 112,
493 128,
5716833c
MK
494 144, /* ... %st(7) (80 bits each). */
495 0, /* `fctrl' (16 bits). */
496 2, /* `fstat' (16 bits). */
497 4, /* `ftag' (16 bits). */
498 12, /* `fiseg' (16 bits). */
499 8, /* `fioff'. */
500 20, /* `foseg' (16 bits). */
501 16, /* `fooff'. */
502 6, /* `fop' (bottom 11 bits). */
503 160 + 0 * 16, /* %xmm0 through ... */
04c8243f
MK
504 160 + 1 * 16,
505 160 + 2 * 16,
506 160 + 3 * 16,
507 160 + 4 * 16,
508 160 + 5 * 16,
509 160 + 6 * 16,
510 160 + 7 * 16,
511 160 + 8 * 16,
512 160 + 9 * 16,
513 160 + 10 * 16,
514 160 + 11 * 16,
515 160 + 12 * 16,
516 160 + 13 * 16,
517 160 + 14 * 16,
5716833c 518 160 + 15 * 16, /* ... %xmm15 (128 bits each). */
e750d25e
JT
519};
520
20a6ec49
MD
521#define FXSAVE_ADDR(tdep, fxsave, regnum) \
522 (fxsave + fxsave_offset[regnum - I387_ST0_REGNUM (tdep)])
5716833c
MK
523
524/* We made an unfortunate choice in putting %mxcsr after the SSE
525 registers %xmm0-%xmm7 instead of before, since it makes supporting
526 the registers %xmm8-%xmm15 on AMD64 a bit involved. Therefore we
527 don't include the offset for %mxcsr here above. */
528
529#define FXSAVE_MXCSR_ADDR(fxsave) (fxsave + 24)
e750d25e 530
b4ad899f 531static int i387_tag (const gdb_byte *raw);
e750d25e
JT
532\f
533
41d041d6 534/* Fill register REGNUM in REGCACHE with the appropriate
ed504bdf
MK
535 floating-point or SSE register value from *FXSAVE. This function
536 masks off any of the reserved bits in *FXSAVE. */
e750d25e
JT
537
538void
41d041d6 539i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
e750d25e 540{
41d041d6 541 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
b4ad899f 542 const gdb_byte *regs = fxsave;
5716833c
MK
543 int i;
544
545 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
546 gdb_assert (tdep->num_xmm_regs > 0);
dff95cc7 547
20a6ec49 548 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
ed504bdf
MK
549 if (regnum == -1 || regnum == i)
550 {
5716833c 551 if (regs == NULL)
ed504bdf 552 {
5716833c 553 regcache_raw_supply (regcache, i, NULL);
ed504bdf
MK
554 continue;
555 }
932bb524 556
ed504bdf
MK
557 /* Most of the FPU control registers occupy only 16 bits in
558 the fxsave area. Give those a special treatment. */
20a6ec49
MD
559 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
560 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
ed504bdf 561 {
b4ad899f 562 gdb_byte val[4];
ed504bdf 563
20a6ec49 564 memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
ed504bdf 565 val[2] = val[3] = 0;
20a6ec49 566 if (i == I387_FOP_REGNUM (tdep))
ed504bdf 567 val[1] &= ((1 << 3) - 1);
20a6ec49 568 else if (i== I387_FTAG_REGNUM (tdep))
ed504bdf
MK
569 {
570 /* The fxsave area contains a simplified version of
571 the tag word. We have to look at the actual 80-bit
572 FP data to recreate the traditional i387 tag word. */
573
574 unsigned long ftag = 0;
575 int fpreg;
576 int top;
577
20a6ec49
MD
578 top = ((FXSAVE_ADDR (tdep, regs,
579 I387_FSTAT_REGNUM (tdep)))[1] >> 3);
5716833c 580 top &= 0x7;
ed504bdf
MK
581
582 for (fpreg = 7; fpreg >= 0; fpreg--)
583 {
584 int tag;
585
586 if (val[0] & (1 << fpreg))
587 {
20a6ec49
MD
588 int regnum = (fpreg + 8 - top) % 8
589 + I387_ST0_REGNUM (tdep);
590 tag = i387_tag (FXSAVE_ADDR (tdep, regs, regnum));
ed504bdf
MK
591 }
592 else
593 tag = 3; /* Empty */
594
595 ftag |= tag << (2 * fpreg);
596 }
597 val[0] = ftag & 0xff;
598 val[1] = (ftag >> 8) & 0xff;
599 }
5716833c 600 regcache_raw_supply (regcache, i, val);
ed504bdf
MK
601 }
602 else
20a6ec49 603 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
ed504bdf 604 }
5716833c 605
20a6ec49 606 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
5716833c
MK
607 {
608 if (regs == NULL)
20a6ec49 609 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), NULL);
5716833c 610 else
20a6ec49 611 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep),
5716833c
MK
612 FXSAVE_MXCSR_ADDR (regs));
613 }
e750d25e
JT
614}
615
616/* Fill register REGNUM (if it is a floating-point or SSE register) in
80571bff
MK
617 *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for
618 all registers. This function doesn't touch any of the reserved
619 bits in *FXSAVE. */
e750d25e
JT
620
621void
80571bff 622i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave)
e750d25e 623{
e071d1f6 624 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
b4ad899f 625 gdb_byte *regs = fxsave;
5716833c
MK
626 int i;
627
628 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
629 gdb_assert (tdep->num_xmm_regs > 0);
dff95cc7 630
20a6ec49 631 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
e750d25e
JT
632 if (regnum == -1 || regnum == i)
633 {
634 /* Most of the FPU control registers occupy only 16 bits in
635 the fxsave area. Give those a special treatment. */
20a6ec49
MD
636 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
637 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
e750d25e 638 {
b4ad899f 639 gdb_byte buf[4];
e750d25e 640
5716833c 641 regcache_raw_collect (regcache, i, buf);
e750d25e 642
31aeac78
L
643 if (i == I387_FOP_REGNUM (tdep))
644 {
645 /* The opcode occupies only 11 bits. Make sure we
646 don't touch the other bits. */
647 buf[1] &= ((1 << 3) - 1);
648 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
649 }
650 else if (i == I387_FTAG_REGNUM (tdep))
651 {
652 /* Converting back is much easier. */
653
654 unsigned short ftag;
655 int fpreg;
656
657 ftag = (buf[1] << 8) | buf[0];
658 buf[0] = 0;
659 buf[1] = 0;
660
661 for (fpreg = 7; fpreg >= 0; fpreg--)
662 {
663 int tag = (ftag >> (fpreg * 2)) & 3;
664
665 if (tag != 3)
666 buf[0] |= (1 << fpreg);
667 }
668 }
669 memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
670 }
671 else
672 regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
673 }
674
675 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
676 regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
677 FXSAVE_MXCSR_ADDR (regs));
678}
679
680/* `xstate_bv' is at byte offset 512. */
681#define XSAVE_XSTATE_BV_ADDR(xsave) (xsave + 512)
682
683/* At xsave_avxh_offset[REGNUM] you'll find the offset to the location in
684 the upper 128bit of AVX register data structure used by the "xsave"
685 instruction where GDB register REGNUM is stored. */
686
687static int xsave_avxh_offset[] =
688{
689 576 + 0 * 16, /* Upper 128bit of %ymm0 through ... */
690 576 + 1 * 16,
691 576 + 2 * 16,
692 576 + 3 * 16,
693 576 + 4 * 16,
694 576 + 5 * 16,
695 576 + 6 * 16,
696 576 + 7 * 16,
697 576 + 8 * 16,
698 576 + 9 * 16,
699 576 + 10 * 16,
700 576 + 11 * 16,
701 576 + 12 * 16,
702 576 + 13 * 16,
703 576 + 14 * 16,
704 576 + 15 * 16 /* Upper 128bit of ... %ymm15 (128 bits each). */
705};
706
707#define XSAVE_AVXH_ADDR(tdep, xsave, regnum) \
708 (xsave + xsave_avxh_offset[regnum - I387_YMM0H_REGNUM (tdep)])
709
710/* Similar to i387_supply_fxsave, but use XSAVE extended state. */
711
712void
713i387_supply_xsave (struct regcache *regcache, int regnum,
714 const void *xsave)
715{
716 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
717 const gdb_byte *regs = xsave;
718 int i;
719 unsigned int clear_bv;
720 const gdb_byte *p;
721 enum
722 {
723 none = 0x0,
724 x87 = 0x1,
725 sse = 0x2,
726 avxh = 0x4,
727 all = x87 | sse | avxh
728 } regclass;
729
730 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
731 gdb_assert (tdep->num_xmm_regs > 0);
732
733 if (regnum == -1)
734 regclass = all;
735 else if (regnum >= I387_YMM0H_REGNUM (tdep)
736 && regnum < I387_YMMENDH_REGNUM (tdep))
737 regclass = avxh;
738 else if (regnum >= I387_XMM0_REGNUM(tdep)
739 && regnum < I387_MXCSR_REGNUM (tdep))
740 regclass = sse;
741 else if (regnum >= I387_ST0_REGNUM (tdep)
742 && regnum < I387_FCTRL_REGNUM (tdep))
743 regclass = x87;
744 else
745 regclass = none;
746
747 if (regs != NULL && regclass != none)
748 {
749 /* Get `xstat_bv'. */
750 const gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs);
751
752 /* The supported bits in `xstat_bv' are 1 byte. Clear part in
753 vector registers if its bit in xstat_bv is zero. */
754 clear_bv = (~(*xstate_bv_p)) & tdep->xcr0;
755 }
756 else
757 clear_bv = I386_XSTATE_AVX_MASK;
758
759 switch (regclass)
760 {
761 case none:
762 break;
763
764 case avxh:
765 if ((clear_bv & I386_XSTATE_AVX))
766 p = NULL;
767 else
768 p = XSAVE_AVXH_ADDR (tdep, regs, regnum);
769 regcache_raw_supply (regcache, regnum, p);
770 return;
771
772 case sse:
773 if ((clear_bv & I386_XSTATE_SSE))
774 p = NULL;
775 else
776 p = FXSAVE_ADDR (tdep, regs, regnum);
777 regcache_raw_supply (regcache, regnum, p);
778 return;
779
780 case x87:
781 if ((clear_bv & I386_XSTATE_X87))
782 p = NULL;
783 else
784 p = FXSAVE_ADDR (tdep, regs, regnum);
785 regcache_raw_supply (regcache, regnum, p);
786 return;
787
788 case all:
789 /* Hanle the upper YMM registers. */
790 if ((tdep->xcr0 & I386_XSTATE_AVX))
791 {
792 if ((clear_bv & I386_XSTATE_AVX))
793 p = NULL;
794 else
795 p = regs;
796
797 for (i = I387_YMM0H_REGNUM (tdep);
798 i < I387_YMMENDH_REGNUM (tdep); i++)
799 {
800 if (p != NULL)
801 p = XSAVE_AVXH_ADDR (tdep, regs, i);
802 regcache_raw_supply (regcache, i, p);
803 }
804 }
805
806 /* Handle the XMM registers. */
807 if ((tdep->xcr0 & I386_XSTATE_SSE))
808 {
809 if ((clear_bv & I386_XSTATE_SSE))
810 p = NULL;
811 else
812 p = regs;
813
814 for (i = I387_XMM0_REGNUM (tdep);
815 i < I387_MXCSR_REGNUM (tdep); i++)
816 {
817 if (p != NULL)
818 p = FXSAVE_ADDR (tdep, regs, i);
819 regcache_raw_supply (regcache, i, p);
820 }
821 }
822
823 /* Handle the x87 registers. */
824 if ((tdep->xcr0 & I386_XSTATE_X87))
825 {
826 if ((clear_bv & I386_XSTATE_X87))
827 p = NULL;
828 else
829 p = regs;
830
831 for (i = I387_ST0_REGNUM (tdep);
832 i < I387_FCTRL_REGNUM (tdep); i++)
833 {
834 if (p != NULL)
835 p = FXSAVE_ADDR (tdep, regs, i);
836 regcache_raw_supply (regcache, i, p);
837 }
838 }
839 break;
840 }
841
842 /* Only handle x87 control registers. */
843 for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
844 if (regnum == -1 || regnum == i)
845 {
846 if (regs == NULL)
847 {
848 regcache_raw_supply (regcache, i, NULL);
849 continue;
850 }
851
852 /* Most of the FPU control registers occupy only 16 bits in
853 the xsave extended state. Give those a special treatment. */
854 if (i != I387_FIOFF_REGNUM (tdep)
855 && i != I387_FOOFF_REGNUM (tdep))
856 {
857 gdb_byte val[4];
858
859 memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
860 val[2] = val[3] = 0;
861 if (i == I387_FOP_REGNUM (tdep))
862 val[1] &= ((1 << 3) - 1);
863 else if (i== I387_FTAG_REGNUM (tdep))
864 {
865 /* The fxsave area contains a simplified version of
866 the tag word. We have to look at the actual 80-bit
867 FP data to recreate the traditional i387 tag word. */
868
869 unsigned long ftag = 0;
870 int fpreg;
871 int top;
872
873 top = ((FXSAVE_ADDR (tdep, regs,
874 I387_FSTAT_REGNUM (tdep)))[1] >> 3);
875 top &= 0x7;
876
877 for (fpreg = 7; fpreg >= 0; fpreg--)
878 {
879 int tag;
880
881 if (val[0] & (1 << fpreg))
882 {
883 int regnum = (fpreg + 8 - top) % 8
884 + I387_ST0_REGNUM (tdep);
885 tag = i387_tag (FXSAVE_ADDR (tdep, regs, regnum));
886 }
887 else
888 tag = 3; /* Empty */
889
890 ftag |= tag << (2 * fpreg);
891 }
892 val[0] = ftag & 0xff;
893 val[1] = (ftag >> 8) & 0xff;
894 }
895 regcache_raw_supply (regcache, i, val);
896 }
897 else
898 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
899 }
900
901 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
902 {
903 p = regs == NULL ? NULL : FXSAVE_MXCSR_ADDR (regs);
904 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), p);
905 }
906}
907
908/* Similar to i387_collect_fxsave, but use XSAVE extended state. */
909
910void
911i387_collect_xsave (const struct regcache *regcache, int regnum,
912 void *xsave, int gcore)
913{
914 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
915 gdb_byte *regs = xsave;
916 int i;
917 enum
918 {
919 none = 0x0,
920 check = 0x1,
921 x87 = 0x2 | check,
922 sse = 0x4 | check,
923 avxh = 0x8 | check,
924 all = x87 | sse | avxh
925 } regclass;
926
927 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
928 gdb_assert (tdep->num_xmm_regs > 0);
929
930 if (regnum == -1)
931 regclass = all;
932 else if (regnum >= I387_YMM0H_REGNUM (tdep)
933 && regnum < I387_YMMENDH_REGNUM (tdep))
934 regclass = avxh;
935 else if (regnum >= I387_XMM0_REGNUM(tdep)
936 && regnum < I387_MXCSR_REGNUM (tdep))
937 regclass = sse;
938 else if (regnum >= I387_ST0_REGNUM (tdep)
939 && regnum < I387_FCTRL_REGNUM (tdep))
940 regclass = x87;
941 else
942 regclass = none;
943
944 if (gcore)
945 {
946 /* Clear XSAVE extended state. */
947 memset (regs, 0, I386_XSTATE_SIZE (tdep->xcr0));
948
949 /* Update XCR0 and `xstate_bv' with XCR0 for gcore. */
950 if (tdep->xsave_xcr0_offset != -1)
951 memcpy (regs + tdep->xsave_xcr0_offset, &tdep->xcr0, 8);
952 memcpy (XSAVE_XSTATE_BV_ADDR (regs), &tdep->xcr0, 8);
953 }
954
955 if ((regclass & check))
956 {
957 gdb_byte raw[I386_MAX_REGISTER_SIZE];
958 gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs);
959 unsigned int xstate_bv = 0;
960 /* The supported bits in `xstat_bv' are 1 byte. */
961 unsigned int clear_bv = (~(*xstate_bv_p)) & tdep->xcr0;
962 gdb_byte *p;
963
964 /* Clear register set if its bit in xstat_bv is zero. */
965 if (clear_bv)
966 {
967 if ((clear_bv & I386_XSTATE_AVX))
968 for (i = I387_YMM0H_REGNUM (tdep);
969 i < I387_YMMENDH_REGNUM (tdep); i++)
970 memset (XSAVE_AVXH_ADDR (tdep, regs, i), 0, 16);
971
972 if ((clear_bv & I386_XSTATE_SSE))
973 for (i = I387_XMM0_REGNUM (tdep);
974 i < I387_MXCSR_REGNUM (tdep); i++)
975 memset (FXSAVE_ADDR (tdep, regs, i), 0, 16);
976
977 if ((clear_bv & I386_XSTATE_X87))
978 for (i = I387_ST0_REGNUM (tdep);
979 i < I387_FCTRL_REGNUM (tdep); i++)
980 memset (FXSAVE_ADDR (tdep, regs, i), 0, 10);
981 }
982
983 if (regclass == all)
984 {
985 /* Check if any upper YMM registers are changed. */
986 if ((tdep->xcr0 & I386_XSTATE_AVX))
987 for (i = I387_YMM0H_REGNUM (tdep);
988 i < I387_YMMENDH_REGNUM (tdep); i++)
989 {
990 regcache_raw_collect (regcache, i, raw);
991 p = XSAVE_AVXH_ADDR (tdep, regs, i);
992 if (memcmp (raw, p, 16))
993 {
994 xstate_bv |= I386_XSTATE_AVX;
995 memcpy (p, raw, 16);
996 }
997 }
998
999 /* Check if any SSE registers are changed. */
1000 if ((tdep->xcr0 & I386_XSTATE_SSE))
1001 for (i = I387_XMM0_REGNUM (tdep);
1002 i < I387_MXCSR_REGNUM (tdep); i++)
1003 {
1004 regcache_raw_collect (regcache, i, raw);
1005 p = FXSAVE_ADDR (tdep, regs, i);
1006 if (memcmp (raw, p, 16))
1007 {
1008 xstate_bv |= I386_XSTATE_SSE;
1009 memcpy (p, raw, 16);
1010 }
1011 }
1012
1013 /* Check if any X87 registers are changed. */
1014 if ((tdep->xcr0 & I386_XSTATE_X87))
1015 for (i = I387_ST0_REGNUM (tdep);
1016 i < I387_FCTRL_REGNUM (tdep); i++)
1017 {
1018 regcache_raw_collect (regcache, i, raw);
1019 p = FXSAVE_ADDR (tdep, regs, i);
1020 if (memcmp (raw, p, 10))
1021 {
1022 xstate_bv |= I386_XSTATE_X87;
1023 memcpy (p, raw, 10);
1024 }
1025 }
1026 }
1027 else
1028 {
1029 /* Check if REGNUM is changed. */
1030 regcache_raw_collect (regcache, regnum, raw);
1031
1032 switch (regclass)
1033 {
1034 default:
4e4d8374
L
1035 internal_error (__FILE__, __LINE__,
1036 _("invalid i387 regclass"));
31aeac78 1037
40936b0d
L
1038 case avxh:
1039 /* This is an upper YMM register. */
1040 p = XSAVE_AVXH_ADDR (tdep, regs, regnum);
1041 if (memcmp (raw, p, 16))
31aeac78 1042 {
40936b0d
L
1043 xstate_bv |= I386_XSTATE_AVX;
1044 memcpy (p, raw, 16);
1045 }
1046 break;
31aeac78 1047
40936b0d
L
1048 case sse:
1049 /* This is an SSE register. */
1050 p = FXSAVE_ADDR (tdep, regs, regnum);
1051 if (memcmp (raw, p, 16))
1052 {
1053 xstate_bv |= I386_XSTATE_SSE;
1054 memcpy (p, raw, 16);
1055 }
1056 break;
31aeac78 1057
40936b0d
L
1058 case x87:
1059 /* This is an x87 register. */
1060 p = FXSAVE_ADDR (tdep, regs, regnum);
1061 if (memcmp (raw, p, 10))
1062 {
1063 xstate_bv |= I386_XSTATE_X87;
1064 memcpy (p, raw, 10);
31aeac78 1065 }
40936b0d 1066 break;
31aeac78 1067 }
40936b0d
L
1068 }
1069
1070 /* Update the corresponding bits in `xstate_bv' if any SSE/AVX
1071 registers are changed. */
1072 if (xstate_bv)
1073 {
1074 /* The supported bits in `xstat_bv' are 1 byte. */
1075 *xstate_bv_p |= (gdb_byte) xstate_bv;
1076
1077 switch (regclass)
31aeac78 1078 {
40936b0d 1079 default:
4e4d8374
L
1080 internal_error (__FILE__, __LINE__,
1081 _("invalid i387 regclass"));
40936b0d
L
1082
1083 case all:
1084 break;
1085
1086 case x87:
1087 case sse:
1088 case avxh:
1089 /* Register REGNUM has been updated. Return. */
1090 return;
31aeac78 1091 }
40936b0d
L
1092 }
1093 else
1094 {
1095 /* Return if REGNUM isn't changed. */
1096 if (regclass != all)
1097 return;
1098 }
31aeac78
L
1099 }
1100
1101 /* Only handle x87 control registers. */
1102 for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
1103 if (regnum == -1 || regnum == i)
1104 {
1105 /* Most of the FPU control registers occupy only 16 bits in
1106 the xsave extended state. Give those a special treatment. */
1107 if (i != I387_FIOFF_REGNUM (tdep)
1108 && i != I387_FOOFF_REGNUM (tdep))
1109 {
1110 gdb_byte buf[4];
1111
1112 regcache_raw_collect (regcache, i, buf);
1113
20a6ec49 1114 if (i == I387_FOP_REGNUM (tdep))
e750d25e
JT
1115 {
1116 /* The opcode occupies only 11 bits. Make sure we
40936b0d 1117 don't touch the other bits. */
e750d25e 1118 buf[1] &= ((1 << 3) - 1);
20a6ec49 1119 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
e750d25e 1120 }
20a6ec49 1121 else if (i == I387_FTAG_REGNUM (tdep))
e750d25e
JT
1122 {
1123 /* Converting back is much easier. */
1124
1125 unsigned short ftag;
1126 int fpreg;
1127
1128 ftag = (buf[1] << 8) | buf[0];
1129 buf[0] = 0;
1130 buf[1] = 0;
1131
1132 for (fpreg = 7; fpreg >= 0; fpreg--)
1133 {
1134 int tag = (ftag >> (fpreg * 2)) & 3;
1135
1136 if (tag != 3)
1137 buf[0] |= (1 << fpreg);
1138 }
1139 }
20a6ec49 1140 memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
e750d25e
JT
1141 }
1142 else
20a6ec49 1143 regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
e750d25e 1144 }
5716833c 1145
20a6ec49
MD
1146 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
1147 regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
5716833c 1148 FXSAVE_MXCSR_ADDR (regs));
e750d25e
JT
1149}
1150
1151/* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
1152 *RAW. */
1153
1154static int
b4ad899f 1155i387_tag (const gdb_byte *raw)
e750d25e
JT
1156{
1157 int integer;
1158 unsigned int exponent;
1159 unsigned long fraction[2];
1160
1161 integer = raw[7] & 0x80;
1162 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
1163 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
1164 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
1165 | (raw[5] << 8) | raw[4]);
1166
1167 if (exponent == 0x7fff)
1168 {
1169 /* Special. */
1170 return (2);
1171 }
1172 else if (exponent == 0x0000)
1173 {
1174 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
1175 {
1176 /* Zero. */
1177 return (1);
1178 }
1179 else
1180 {
1181 /* Special. */
1182 return (2);
1183 }
1184 }
1185 else
1186 {
1187 if (integer)
1188 {
1189 /* Valid. */
1190 return (0);
1191 }
1192 else
1193 {
1194 /* Special. */
1195 return (2);
1196 }
1197 }
1198}
efb1c01c
MK
1199
1200/* Prepare the FPU stack in REGCACHE for a function return. */
1201
1202void
1203i387_return_value (struct gdbarch *gdbarch, struct regcache *regcache)
1204{
1205 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1206 ULONGEST fstat;
1207
efb1c01c
MK
1208 /* Set the top of the floating-point register stack to 7. The
1209 actual value doesn't really matter, but 7 is what a normal
1210 function return would end up with if the program started out with
1211 a freshly initialized FPU. */
20a6ec49 1212 regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM (tdep), &fstat);
efb1c01c 1213 fstat |= (7 << 11);
20a6ec49 1214 regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM (tdep), fstat);
efb1c01c
MK
1215
1216 /* Mark %st(1) through %st(7) as empty. Since we set the top of the
1217 floating-point register stack to 7, the appropriate value for the
1218 tag word is 0x3fff. */
20a6ec49 1219 regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM (tdep), 0x3fff);
efb1c01c 1220
efb1c01c 1221}
This page took 0.79955 seconds and 4 git commands to generate.