Replace abort with internal_error.
[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));
b4ad899f 208 gdb_byte buf[4];
1d70089a
MK
209 ULONGEST fctrl;
210 ULONGEST fstat;
211 ULONGEST ftag;
212 ULONGEST fiseg;
213 ULONGEST fioff;
214 ULONGEST foseg;
215 ULONGEST fooff;
216 ULONGEST fop;
de57eccd
JM
217 int fpreg;
218 int top;
219
5716833c
MK
220 gdb_assert (gdbarch == get_frame_arch (frame));
221
20a6ec49
MD
222 fctrl = get_frame_register_unsigned (frame, I387_FCTRL_REGNUM (tdep));
223 fstat = get_frame_register_unsigned (frame, I387_FSTAT_REGNUM (tdep));
224 ftag = get_frame_register_unsigned (frame, I387_FTAG_REGNUM (tdep));
225 fiseg = get_frame_register_unsigned (frame, I387_FISEG_REGNUM (tdep));
226 fioff = get_frame_register_unsigned (frame, I387_FIOFF_REGNUM (tdep));
227 foseg = get_frame_register_unsigned (frame, I387_FOSEG_REGNUM (tdep));
228 fooff = get_frame_register_unsigned (frame, I387_FOOFF_REGNUM (tdep));
229 fop = get_frame_register_unsigned (frame, I387_FOP_REGNUM (tdep));
1d70089a 230
de57eccd
JM
231 top = ((fstat >> 11) & 7);
232
233 for (fpreg = 7; fpreg >= 0; fpreg--)
234 {
b4ad899f 235 gdb_byte raw[I386_MAX_REGISTER_SIZE];
de57eccd
JM
236 int tag = (ftag >> (fpreg * 2)) & 3;
237 int i;
238
61113f8b 239 fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg);
de57eccd
JM
240
241 switch (tag)
242 {
243 case 0:
61113f8b 244 fputs_filtered ("Valid ", file);
de57eccd
JM
245 break;
246 case 1:
61113f8b 247 fputs_filtered ("Zero ", file);
de57eccd
JM
248 break;
249 case 2:
61113f8b 250 fputs_filtered ("Special ", file);
de57eccd
JM
251 break;
252 case 3:
61113f8b 253 fputs_filtered ("Empty ", file);
de57eccd
JM
254 break;
255 }
256
20a6ec49
MD
257 get_frame_register (frame, (fpreg + 8 - top) % 8 + I387_ST0_REGNUM (tdep),
258 raw);
de57eccd 259
61113f8b 260 fputs_filtered ("0x", file);
de57eccd 261 for (i = 9; i >= 0; i--)
61113f8b 262 fprintf_filtered (file, "%02x", raw[i]);
de57eccd
JM
263
264 if (tag != 3)
27067745 265 print_i387_ext (gdbarch, raw, file);
de57eccd 266
61113f8b 267 fputs_filtered ("\n", file);
de57eccd
JM
268 }
269
f16a25ae 270 fputs_filtered ("\n", file);
de57eccd 271
61113f8b
MK
272 print_i387_status_word (fstat, file);
273 print_i387_control_word (fctrl, file);
274 fprintf_filtered (file, "Tag Word: %s\n",
bb599908 275 hex_string_custom (ftag, 4));
61113f8b 276 fprintf_filtered (file, "Instruction Pointer: %s:",
bb599908
PH
277 hex_string_custom (fiseg, 2));
278 fprintf_filtered (file, "%s\n", hex_string_custom (fioff, 8));
61113f8b 279 fprintf_filtered (file, "Operand Pointer: %s:",
bb599908
PH
280 hex_string_custom (foseg, 2));
281 fprintf_filtered (file, "%s\n", hex_string_custom (fooff, 8));
61113f8b 282 fprintf_filtered (file, "Opcode: %s\n",
bb599908 283 hex_string_custom (fop ? (fop | 0xd800) : 0, 4));
de57eccd 284}
d532c08f
MK
285\f
286
83acabca
DJ
287/* Return nonzero if a value of type TYPE stored in register REGNUM
288 needs any special handling. */
289
290int
0abe36f5 291i387_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type)
83acabca 292{
20a6ec49 293 if (i386_fp_regnum_p (gdbarch, regnum))
83acabca
DJ
294 {
295 /* Floating point registers must be converted unless we are
296 accessing them in their hardware type. */
27067745 297 if (type == i387_ext_type (gdbarch))
83acabca
DJ
298 return 0;
299 else
300 return 1;
301 }
302
303 return 0;
304}
305
d532c08f
MK
306/* Read a value of type TYPE from register REGNUM in frame FRAME, and
307 return its contents in TO. */
308
309void
310i387_register_to_value (struct frame_info *frame, int regnum,
42835c2b 311 struct type *type, gdb_byte *to)
d532c08f 312{
27067745 313 struct gdbarch *gdbarch = get_frame_arch (frame);
b4ad899f 314 gdb_byte from[I386_MAX_REGISTER_SIZE];
d532c08f 315
27067745 316 gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
d532c08f
MK
317
318 /* We only support floating-point values. */
319 if (TYPE_CODE (type) != TYPE_CODE_FLT)
320 {
8a3fe4f8
AC
321 warning (_("Cannot convert floating-point register value "
322 "to non-floating-point type."));
d532c08f
MK
323 return;
324 }
325
83acabca 326 /* Convert to TYPE. */
192285c6 327 get_frame_register (frame, regnum, from);
27067745 328 convert_typed_floating (from, i387_ext_type (gdbarch), to, type);
d532c08f
MK
329}
330
331/* Write the contents FROM of a value of type TYPE into register
332 REGNUM in frame FRAME. */
333
334void
335i387_value_to_register (struct frame_info *frame, int regnum,
42835c2b 336 struct type *type, const gdb_byte *from)
d532c08f 337{
27067745 338 struct gdbarch *gdbarch = get_frame_arch (frame);
b4ad899f 339 gdb_byte to[I386_MAX_REGISTER_SIZE];
d532c08f 340
27067745 341 gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
d532c08f
MK
342
343 /* We only support floating-point values. */
344 if (TYPE_CODE (type) != TYPE_CODE_FLT)
345 {
8a3fe4f8
AC
346 warning (_("Cannot convert non-floating-point type "
347 "to floating-point register value."));
d532c08f
MK
348 return;
349 }
350
83acabca 351 /* Convert from TYPE. */
27067745 352 convert_typed_floating (from, type, to, i387_ext_type (gdbarch));
d532c08f
MK
353 put_frame_register (frame, regnum, to);
354}
355\f
e750d25e 356
786a90bb 357/* Handle FSAVE and FXSAVE formats. */
e750d25e
JT
358
359/* At fsave_offset[REGNUM] you'll find the offset to the location in
360 the data structure used by the "fsave" instruction where GDB
361 register REGNUM is stored. */
362
363static int fsave_offset[] =
364{
5716833c
MK
365 28 + 0 * 10, /* %st(0) ... */
366 28 + 1 * 10,
367 28 + 2 * 10,
368 28 + 3 * 10,
369 28 + 4 * 10,
370 28 + 5 * 10,
371 28 + 6 * 10,
372 28 + 7 * 10, /* ... %st(7). */
373 0, /* `fctrl' (16 bits). */
374 4, /* `fstat' (16 bits). */
375 8, /* `ftag' (16 bits). */
376 16, /* `fiseg' (16 bits). */
377 12, /* `fioff'. */
378 24, /* `foseg' (16 bits). */
379 20, /* `fooff'. */
380 18 /* `fop' (bottom 11 bits). */
e750d25e
JT
381};
382
20a6ec49
MD
383#define FSAVE_ADDR(tdep, fsave, regnum) \
384 (fsave + fsave_offset[regnum - I387_ST0_REGNUM (tdep)])
e750d25e
JT
385\f
386
41d041d6
MK
387/* Fill register REGNUM in REGCACHE with the appropriate value from
388 *FSAVE. This function masks off any of the reserved bits in
389 *FSAVE. */
e750d25e
JT
390
391void
41d041d6 392i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave)
e750d25e 393{
e17a4113
UW
394 struct gdbarch *gdbarch = get_regcache_arch (regcache);
395 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
396 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
b4ad899f 397 const gdb_byte *regs = fsave;
e750d25e
JT
398 int i;
399
5716833c
MK
400 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
401
20a6ec49 402 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
ed504bdf
MK
403 if (regnum == -1 || regnum == i)
404 {
405 if (fsave == NULL)
406 {
5716833c
MK
407 regcache_raw_supply (regcache, i, NULL);
408 continue;
ed504bdf
MK
409 }
410
411 /* Most of the FPU control registers occupy only 16 bits in the
412 fsave area. Give those a special treatment. */
20a6ec49
MD
413 if (i >= I387_FCTRL_REGNUM (tdep)
414 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
ed504bdf 415 {
b4ad899f 416 gdb_byte val[4];
ed504bdf 417
20a6ec49 418 memcpy (val, FSAVE_ADDR (tdep, regs, i), 2);
ed504bdf 419 val[2] = val[3] = 0;
20a6ec49 420 if (i == I387_FOP_REGNUM (tdep))
ed504bdf 421 val[1] &= ((1 << 3) - 1);
5716833c 422 regcache_raw_supply (regcache, i, val);
ed504bdf
MK
423 }
424 else
20a6ec49 425 regcache_raw_supply (regcache, i, FSAVE_ADDR (tdep, regs, i));
ed504bdf 426 }
b87bc0d8
MK
427
428 /* Provide dummy values for the SSE registers. */
20a6ec49 429 for (i = I387_XMM0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
b87bc0d8
MK
430 if (regnum == -1 || regnum == i)
431 regcache_raw_supply (regcache, i, NULL);
20a6ec49 432 if (regnum == -1 || regnum == I387_MXCSR_REGNUM (tdep))
b87bc0d8 433 {
b4ad899f 434 gdb_byte buf[4];
b87bc0d8 435
e17a4113 436 store_unsigned_integer (buf, 4, byte_order, 0x1f80);
20a6ec49 437 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), buf);
b87bc0d8 438 }
e750d25e
JT
439}
440
441/* Fill register REGNUM (if it is a floating-point register) in *FSAVE
63b6c53f
MK
442 with the value from REGCACHE. If REGNUM is -1, do this for all
443 registers. This function doesn't touch any of the reserved bits in
444 *FSAVE. */
e750d25e
JT
445
446void
63b6c53f 447i387_collect_fsave (const struct regcache *regcache, int regnum, void *fsave)
e750d25e 448{
e071d1f6 449 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
b4ad899f 450 gdb_byte *regs = fsave;
e750d25e
JT
451 int i;
452
5716833c
MK
453 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
454
20a6ec49 455 for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
e750d25e
JT
456 if (regnum == -1 || regnum == i)
457 {
458 /* Most of the FPU control registers occupy only 16 bits in
459 the fsave area. Give those a special treatment. */
20a6ec49
MD
460 if (i >= I387_FCTRL_REGNUM (tdep)
461 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
e750d25e 462 {
b4ad899f 463 gdb_byte buf[4];
e750d25e 464
5716833c 465 regcache_raw_collect (regcache, i, buf);
e750d25e 466
20a6ec49 467 if (i == I387_FOP_REGNUM (tdep))
e750d25e
JT
468 {
469 /* The opcode occupies only 11 bits. Make sure we
470 don't touch the other bits. */
471 buf[1] &= ((1 << 3) - 1);
20a6ec49 472 buf[1] |= ((FSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
e750d25e 473 }
20a6ec49 474 memcpy (FSAVE_ADDR (tdep, regs, i), buf, 2);
e750d25e
JT
475 }
476 else
20a6ec49 477 regcache_raw_collect (regcache, i, FSAVE_ADDR (tdep, regs, i));
e750d25e
JT
478 }
479}
480\f
481
482/* At fxsave_offset[REGNUM] you'll find the offset to the location in
483 the data structure used by the "fxsave" instruction where GDB
484 register REGNUM is stored. */
485
486static int fxsave_offset[] =
487{
5716833c 488 32, /* %st(0) through ... */
e750d25e
JT
489 48,
490 64,
491 80,
492 96,
493 112,
494 128,
5716833c
MK
495 144, /* ... %st(7) (80 bits each). */
496 0, /* `fctrl' (16 bits). */
497 2, /* `fstat' (16 bits). */
498 4, /* `ftag' (16 bits). */
499 12, /* `fiseg' (16 bits). */
500 8, /* `fioff'. */
501 20, /* `foseg' (16 bits). */
502 16, /* `fooff'. */
503 6, /* `fop' (bottom 11 bits). */
504 160 + 0 * 16, /* %xmm0 through ... */
04c8243f
MK
505 160 + 1 * 16,
506 160 + 2 * 16,
507 160 + 3 * 16,
508 160 + 4 * 16,
509 160 + 5 * 16,
510 160 + 6 * 16,
511 160 + 7 * 16,
512 160 + 8 * 16,
513 160 + 9 * 16,
514 160 + 10 * 16,
515 160 + 11 * 16,
516 160 + 12 * 16,
517 160 + 13 * 16,
518 160 + 14 * 16,
5716833c 519 160 + 15 * 16, /* ... %xmm15 (128 bits each). */
e750d25e
JT
520};
521
20a6ec49
MD
522#define FXSAVE_ADDR(tdep, fxsave, regnum) \
523 (fxsave + fxsave_offset[regnum - I387_ST0_REGNUM (tdep)])
5716833c
MK
524
525/* We made an unfortunate choice in putting %mxcsr after the SSE
526 registers %xmm0-%xmm7 instead of before, since it makes supporting
527 the registers %xmm8-%xmm15 on AMD64 a bit involved. Therefore we
528 don't include the offset for %mxcsr here above. */
529
530#define FXSAVE_MXCSR_ADDR(fxsave) (fxsave + 24)
e750d25e 531
b4ad899f 532static int i387_tag (const gdb_byte *raw);
e750d25e
JT
533\f
534
41d041d6 535/* Fill register REGNUM in REGCACHE with the appropriate
ed504bdf
MK
536 floating-point or SSE register value from *FXSAVE. This function
537 masks off any of the reserved bits in *FXSAVE. */
e750d25e
JT
538
539void
41d041d6 540i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
e750d25e 541{
41d041d6 542 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
b4ad899f 543 const gdb_byte *regs = fxsave;
5716833c
MK
544 int i;
545
546 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
547 gdb_assert (tdep->num_xmm_regs > 0);
dff95cc7 548
20a6ec49 549 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
ed504bdf
MK
550 if (regnum == -1 || regnum == i)
551 {
5716833c 552 if (regs == NULL)
ed504bdf 553 {
5716833c 554 regcache_raw_supply (regcache, i, NULL);
ed504bdf
MK
555 continue;
556 }
932bb524 557
ed504bdf
MK
558 /* Most of the FPU control registers occupy only 16 bits in
559 the fxsave area. Give those a special treatment. */
20a6ec49
MD
560 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
561 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
ed504bdf 562 {
b4ad899f 563 gdb_byte val[4];
ed504bdf 564
20a6ec49 565 memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
ed504bdf 566 val[2] = val[3] = 0;
20a6ec49 567 if (i == I387_FOP_REGNUM (tdep))
ed504bdf 568 val[1] &= ((1 << 3) - 1);
20a6ec49 569 else if (i== I387_FTAG_REGNUM (tdep))
ed504bdf
MK
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
20a6ec49
MD
579 top = ((FXSAVE_ADDR (tdep, regs,
580 I387_FSTAT_REGNUM (tdep)))[1] >> 3);
5716833c 581 top &= 0x7;
ed504bdf
MK
582
583 for (fpreg = 7; fpreg >= 0; fpreg--)
584 {
585 int tag;
586
587 if (val[0] & (1 << fpreg))
588 {
20a6ec49
MD
589 int regnum = (fpreg + 8 - top) % 8
590 + I387_ST0_REGNUM (tdep);
591 tag = i387_tag (FXSAVE_ADDR (tdep, regs, regnum));
ed504bdf
MK
592 }
593 else
594 tag = 3; /* Empty */
595
596 ftag |= tag << (2 * fpreg);
597 }
598 val[0] = ftag & 0xff;
599 val[1] = (ftag >> 8) & 0xff;
600 }
5716833c 601 regcache_raw_supply (regcache, i, val);
ed504bdf
MK
602 }
603 else
20a6ec49 604 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
ed504bdf 605 }
5716833c 606
20a6ec49 607 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
5716833c
MK
608 {
609 if (regs == NULL)
20a6ec49 610 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), NULL);
5716833c 611 else
20a6ec49 612 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep),
5716833c
MK
613 FXSAVE_MXCSR_ADDR (regs));
614 }
e750d25e
JT
615}
616
617/* Fill register REGNUM (if it is a floating-point or SSE register) in
80571bff
MK
618 *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for
619 all registers. This function doesn't touch any of the reserved
620 bits in *FXSAVE. */
e750d25e
JT
621
622void
80571bff 623i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave)
e750d25e 624{
e071d1f6 625 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
b4ad899f 626 gdb_byte *regs = fxsave;
5716833c
MK
627 int i;
628
629 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
630 gdb_assert (tdep->num_xmm_regs > 0);
dff95cc7 631
20a6ec49 632 for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
e750d25e
JT
633 if (regnum == -1 || regnum == i)
634 {
635 /* Most of the FPU control registers occupy only 16 bits in
636 the fxsave area. Give those a special treatment. */
20a6ec49
MD
637 if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
638 && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
e750d25e 639 {
b4ad899f 640 gdb_byte buf[4];
e750d25e 641
5716833c 642 regcache_raw_collect (regcache, i, buf);
e750d25e 643
31aeac78
L
644 if (i == I387_FOP_REGNUM (tdep))
645 {
646 /* The opcode occupies only 11 bits. Make sure we
647 don't touch the other bits. */
648 buf[1] &= ((1 << 3) - 1);
649 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
650 }
651 else if (i == I387_FTAG_REGNUM (tdep))
652 {
653 /* Converting back is much easier. */
654
655 unsigned short ftag;
656 int fpreg;
657
658 ftag = (buf[1] << 8) | buf[0];
659 buf[0] = 0;
660 buf[1] = 0;
661
662 for (fpreg = 7; fpreg >= 0; fpreg--)
663 {
664 int tag = (ftag >> (fpreg * 2)) & 3;
665
666 if (tag != 3)
667 buf[0] |= (1 << fpreg);
668 }
669 }
670 memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
671 }
672 else
673 regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
674 }
675
676 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
677 regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
678 FXSAVE_MXCSR_ADDR (regs));
679}
680
681/* `xstate_bv' is at byte offset 512. */
682#define XSAVE_XSTATE_BV_ADDR(xsave) (xsave + 512)
683
684/* At xsave_avxh_offset[REGNUM] you'll find the offset to the location in
685 the upper 128bit of AVX register data structure used by the "xsave"
686 instruction where GDB register REGNUM is stored. */
687
688static int xsave_avxh_offset[] =
689{
690 576 + 0 * 16, /* Upper 128bit of %ymm0 through ... */
691 576 + 1 * 16,
692 576 + 2 * 16,
693 576 + 3 * 16,
694 576 + 4 * 16,
695 576 + 5 * 16,
696 576 + 6 * 16,
697 576 + 7 * 16,
698 576 + 8 * 16,
699 576 + 9 * 16,
700 576 + 10 * 16,
701 576 + 11 * 16,
702 576 + 12 * 16,
703 576 + 13 * 16,
704 576 + 14 * 16,
705 576 + 15 * 16 /* Upper 128bit of ... %ymm15 (128 bits each). */
706};
707
708#define XSAVE_AVXH_ADDR(tdep, xsave, regnum) \
709 (xsave + xsave_avxh_offset[regnum - I387_YMM0H_REGNUM (tdep)])
710
711/* Similar to i387_supply_fxsave, but use XSAVE extended state. */
712
713void
714i387_supply_xsave (struct regcache *regcache, int regnum,
715 const void *xsave)
716{
717 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
718 const gdb_byte *regs = xsave;
719 int i;
720 unsigned int clear_bv;
721 const gdb_byte *p;
722 enum
723 {
724 none = 0x0,
725 x87 = 0x1,
726 sse = 0x2,
727 avxh = 0x4,
728 all = x87 | sse | avxh
729 } regclass;
730
731 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
732 gdb_assert (tdep->num_xmm_regs > 0);
733
734 if (regnum == -1)
735 regclass = all;
736 else if (regnum >= I387_YMM0H_REGNUM (tdep)
737 && regnum < I387_YMMENDH_REGNUM (tdep))
738 regclass = avxh;
739 else if (regnum >= I387_XMM0_REGNUM(tdep)
740 && regnum < I387_MXCSR_REGNUM (tdep))
741 regclass = sse;
742 else if (regnum >= I387_ST0_REGNUM (tdep)
743 && regnum < I387_FCTRL_REGNUM (tdep))
744 regclass = x87;
745 else
746 regclass = none;
747
748 if (regs != NULL && regclass != none)
749 {
750 /* Get `xstat_bv'. */
751 const gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs);
752
753 /* The supported bits in `xstat_bv' are 1 byte. Clear part in
754 vector registers if its bit in xstat_bv is zero. */
755 clear_bv = (~(*xstate_bv_p)) & tdep->xcr0;
756 }
757 else
758 clear_bv = I386_XSTATE_AVX_MASK;
759
760 switch (regclass)
761 {
762 case none:
763 break;
764
765 case avxh:
766 if ((clear_bv & I386_XSTATE_AVX))
767 p = NULL;
768 else
769 p = XSAVE_AVXH_ADDR (tdep, regs, regnum);
770 regcache_raw_supply (regcache, regnum, p);
771 return;
772
773 case sse:
774 if ((clear_bv & I386_XSTATE_SSE))
775 p = NULL;
776 else
777 p = FXSAVE_ADDR (tdep, regs, regnum);
778 regcache_raw_supply (regcache, regnum, p);
779 return;
780
781 case x87:
782 if ((clear_bv & I386_XSTATE_X87))
783 p = NULL;
784 else
785 p = FXSAVE_ADDR (tdep, regs, regnum);
786 regcache_raw_supply (regcache, regnum, p);
787 return;
788
789 case all:
790 /* Hanle the upper YMM registers. */
791 if ((tdep->xcr0 & I386_XSTATE_AVX))
792 {
793 if ((clear_bv & I386_XSTATE_AVX))
794 p = NULL;
795 else
796 p = regs;
797
798 for (i = I387_YMM0H_REGNUM (tdep);
799 i < I387_YMMENDH_REGNUM (tdep); i++)
800 {
801 if (p != NULL)
802 p = XSAVE_AVXH_ADDR (tdep, regs, i);
803 regcache_raw_supply (regcache, i, p);
804 }
805 }
806
807 /* Handle the XMM registers. */
808 if ((tdep->xcr0 & I386_XSTATE_SSE))
809 {
810 if ((clear_bv & I386_XSTATE_SSE))
811 p = NULL;
812 else
813 p = regs;
814
815 for (i = I387_XMM0_REGNUM (tdep);
816 i < I387_MXCSR_REGNUM (tdep); i++)
817 {
818 if (p != NULL)
819 p = FXSAVE_ADDR (tdep, regs, i);
820 regcache_raw_supply (regcache, i, p);
821 }
822 }
823
824 /* Handle the x87 registers. */
825 if ((tdep->xcr0 & I386_XSTATE_X87))
826 {
827 if ((clear_bv & I386_XSTATE_X87))
828 p = NULL;
829 else
830 p = regs;
831
832 for (i = I387_ST0_REGNUM (tdep);
833 i < I387_FCTRL_REGNUM (tdep); i++)
834 {
835 if (p != NULL)
836 p = FXSAVE_ADDR (tdep, regs, i);
837 regcache_raw_supply (regcache, i, p);
838 }
839 }
840 break;
841 }
842
843 /* Only handle x87 control registers. */
844 for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
845 if (regnum == -1 || regnum == i)
846 {
847 if (regs == NULL)
848 {
849 regcache_raw_supply (regcache, i, NULL);
850 continue;
851 }
852
853 /* Most of the FPU control registers occupy only 16 bits in
854 the xsave extended state. Give those a special treatment. */
855 if (i != I387_FIOFF_REGNUM (tdep)
856 && i != I387_FOOFF_REGNUM (tdep))
857 {
858 gdb_byte val[4];
859
860 memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
861 val[2] = val[3] = 0;
862 if (i == I387_FOP_REGNUM (tdep))
863 val[1] &= ((1 << 3) - 1);
864 else if (i== I387_FTAG_REGNUM (tdep))
865 {
866 /* The fxsave area contains a simplified version of
867 the tag word. We have to look at the actual 80-bit
868 FP data to recreate the traditional i387 tag word. */
869
870 unsigned long ftag = 0;
871 int fpreg;
872 int top;
873
874 top = ((FXSAVE_ADDR (tdep, regs,
875 I387_FSTAT_REGNUM (tdep)))[1] >> 3);
876 top &= 0x7;
877
878 for (fpreg = 7; fpreg >= 0; fpreg--)
879 {
880 int tag;
881
882 if (val[0] & (1 << fpreg))
883 {
884 int regnum = (fpreg + 8 - top) % 8
885 + I387_ST0_REGNUM (tdep);
886 tag = i387_tag (FXSAVE_ADDR (tdep, regs, regnum));
887 }
888 else
889 tag = 3; /* Empty */
890
891 ftag |= tag << (2 * fpreg);
892 }
893 val[0] = ftag & 0xff;
894 val[1] = (ftag >> 8) & 0xff;
895 }
896 regcache_raw_supply (regcache, i, val);
897 }
898 else
899 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
900 }
901
902 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
903 {
904 p = regs == NULL ? NULL : FXSAVE_MXCSR_ADDR (regs);
905 regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), p);
906 }
907}
908
909/* Similar to i387_collect_fxsave, but use XSAVE extended state. */
910
911void
912i387_collect_xsave (const struct regcache *regcache, int regnum,
913 void *xsave, int gcore)
914{
915 struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
916 gdb_byte *regs = xsave;
917 int i;
918 enum
919 {
920 none = 0x0,
921 check = 0x1,
922 x87 = 0x2 | check,
923 sse = 0x4 | check,
924 avxh = 0x8 | check,
925 all = x87 | sse | avxh
926 } regclass;
927
928 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
929 gdb_assert (tdep->num_xmm_regs > 0);
930
931 if (regnum == -1)
932 regclass = all;
933 else if (regnum >= I387_YMM0H_REGNUM (tdep)
934 && regnum < I387_YMMENDH_REGNUM (tdep))
935 regclass = avxh;
936 else if (regnum >= I387_XMM0_REGNUM(tdep)
937 && regnum < I387_MXCSR_REGNUM (tdep))
938 regclass = sse;
939 else if (regnum >= I387_ST0_REGNUM (tdep)
940 && regnum < I387_FCTRL_REGNUM (tdep))
941 regclass = x87;
942 else
943 regclass = none;
944
945 if (gcore)
946 {
947 /* Clear XSAVE extended state. */
948 memset (regs, 0, I386_XSTATE_SIZE (tdep->xcr0));
949
950 /* Update XCR0 and `xstate_bv' with XCR0 for gcore. */
951 if (tdep->xsave_xcr0_offset != -1)
952 memcpy (regs + tdep->xsave_xcr0_offset, &tdep->xcr0, 8);
953 memcpy (XSAVE_XSTATE_BV_ADDR (regs), &tdep->xcr0, 8);
954 }
955
956 if ((regclass & check))
957 {
958 gdb_byte raw[I386_MAX_REGISTER_SIZE];
959 gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs);
960 unsigned int xstate_bv = 0;
961 /* The supported bits in `xstat_bv' are 1 byte. */
962 unsigned int clear_bv = (~(*xstate_bv_p)) & tdep->xcr0;
963 gdb_byte *p;
964
965 /* Clear register set if its bit in xstat_bv is zero. */
966 if (clear_bv)
967 {
968 if ((clear_bv & I386_XSTATE_AVX))
969 for (i = I387_YMM0H_REGNUM (tdep);
970 i < I387_YMMENDH_REGNUM (tdep); i++)
971 memset (XSAVE_AVXH_ADDR (tdep, regs, i), 0, 16);
972
973 if ((clear_bv & I386_XSTATE_SSE))
974 for (i = I387_XMM0_REGNUM (tdep);
975 i < I387_MXCSR_REGNUM (tdep); i++)
976 memset (FXSAVE_ADDR (tdep, regs, i), 0, 16);
977
978 if ((clear_bv & I386_XSTATE_X87))
979 for (i = I387_ST0_REGNUM (tdep);
980 i < I387_FCTRL_REGNUM (tdep); i++)
981 memset (FXSAVE_ADDR (tdep, regs, i), 0, 10);
982 }
983
984 if (regclass == all)
985 {
986 /* Check if any upper YMM registers are changed. */
987 if ((tdep->xcr0 & I386_XSTATE_AVX))
988 for (i = I387_YMM0H_REGNUM (tdep);
989 i < I387_YMMENDH_REGNUM (tdep); i++)
990 {
991 regcache_raw_collect (regcache, i, raw);
992 p = XSAVE_AVXH_ADDR (tdep, regs, i);
993 if (memcmp (raw, p, 16))
994 {
995 xstate_bv |= I386_XSTATE_AVX;
996 memcpy (p, raw, 16);
997 }
998 }
999
1000 /* Check if any SSE registers are changed. */
1001 if ((tdep->xcr0 & I386_XSTATE_SSE))
1002 for (i = I387_XMM0_REGNUM (tdep);
1003 i < I387_MXCSR_REGNUM (tdep); i++)
1004 {
1005 regcache_raw_collect (regcache, i, raw);
1006 p = FXSAVE_ADDR (tdep, regs, i);
1007 if (memcmp (raw, p, 16))
1008 {
1009 xstate_bv |= I386_XSTATE_SSE;
1010 memcpy (p, raw, 16);
1011 }
1012 }
1013
1014 /* Check if any X87 registers are changed. */
1015 if ((tdep->xcr0 & I386_XSTATE_X87))
1016 for (i = I387_ST0_REGNUM (tdep);
1017 i < I387_FCTRL_REGNUM (tdep); i++)
1018 {
1019 regcache_raw_collect (regcache, i, raw);
1020 p = FXSAVE_ADDR (tdep, regs, i);
1021 if (memcmp (raw, p, 10))
1022 {
1023 xstate_bv |= I386_XSTATE_X87;
1024 memcpy (p, raw, 10);
1025 }
1026 }
1027 }
1028 else
1029 {
1030 /* Check if REGNUM is changed. */
1031 regcache_raw_collect (regcache, regnum, raw);
1032
1033 switch (regclass)
1034 {
1035 default:
4e4d8374
L
1036 internal_error (__FILE__, __LINE__,
1037 _("invalid i387 regclass"));
31aeac78 1038
40936b0d
L
1039 case avxh:
1040 /* This is an upper YMM register. */
1041 p = XSAVE_AVXH_ADDR (tdep, regs, regnum);
1042 if (memcmp (raw, p, 16))
31aeac78 1043 {
40936b0d
L
1044 xstate_bv |= I386_XSTATE_AVX;
1045 memcpy (p, raw, 16);
1046 }
1047 break;
31aeac78 1048
40936b0d
L
1049 case sse:
1050 /* This is an SSE register. */
1051 p = FXSAVE_ADDR (tdep, regs, regnum);
1052 if (memcmp (raw, p, 16))
1053 {
1054 xstate_bv |= I386_XSTATE_SSE;
1055 memcpy (p, raw, 16);
1056 }
1057 break;
31aeac78 1058
40936b0d
L
1059 case x87:
1060 /* This is an x87 register. */
1061 p = FXSAVE_ADDR (tdep, regs, regnum);
1062 if (memcmp (raw, p, 10))
1063 {
1064 xstate_bv |= I386_XSTATE_X87;
1065 memcpy (p, raw, 10);
31aeac78 1066 }
40936b0d 1067 break;
31aeac78 1068 }
40936b0d
L
1069 }
1070
1071 /* Update the corresponding bits in `xstate_bv' if any SSE/AVX
1072 registers are changed. */
1073 if (xstate_bv)
1074 {
1075 /* The supported bits in `xstat_bv' are 1 byte. */
1076 *xstate_bv_p |= (gdb_byte) xstate_bv;
1077
1078 switch (regclass)
31aeac78 1079 {
40936b0d 1080 default:
4e4d8374
L
1081 internal_error (__FILE__, __LINE__,
1082 _("invalid i387 regclass"));
40936b0d
L
1083
1084 case all:
1085 break;
1086
1087 case x87:
1088 case sse:
1089 case avxh:
1090 /* Register REGNUM has been updated. Return. */
1091 return;
31aeac78 1092 }
40936b0d
L
1093 }
1094 else
1095 {
1096 /* Return if REGNUM isn't changed. */
1097 if (regclass != all)
1098 return;
1099 }
31aeac78
L
1100 }
1101
1102 /* Only handle x87 control registers. */
1103 for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
1104 if (regnum == -1 || regnum == i)
1105 {
1106 /* Most of the FPU control registers occupy only 16 bits in
1107 the xsave extended state. Give those a special treatment. */
1108 if (i != I387_FIOFF_REGNUM (tdep)
1109 && i != I387_FOOFF_REGNUM (tdep))
1110 {
1111 gdb_byte buf[4];
1112
1113 regcache_raw_collect (regcache, i, buf);
1114
20a6ec49 1115 if (i == I387_FOP_REGNUM (tdep))
e750d25e
JT
1116 {
1117 /* The opcode occupies only 11 bits. Make sure we
40936b0d 1118 don't touch the other bits. */
e750d25e 1119 buf[1] &= ((1 << 3) - 1);
20a6ec49 1120 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
e750d25e 1121 }
20a6ec49 1122 else if (i == I387_FTAG_REGNUM (tdep))
e750d25e
JT
1123 {
1124 /* Converting back is much easier. */
1125
1126 unsigned short ftag;
1127 int fpreg;
1128
1129 ftag = (buf[1] << 8) | buf[0];
1130 buf[0] = 0;
1131 buf[1] = 0;
1132
1133 for (fpreg = 7; fpreg >= 0; fpreg--)
1134 {
1135 int tag = (ftag >> (fpreg * 2)) & 3;
1136
1137 if (tag != 3)
1138 buf[0] |= (1 << fpreg);
1139 }
1140 }
20a6ec49 1141 memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
e750d25e
JT
1142 }
1143 else
20a6ec49 1144 regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
e750d25e 1145 }
5716833c 1146
20a6ec49
MD
1147 if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
1148 regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
5716833c 1149 FXSAVE_MXCSR_ADDR (regs));
e750d25e
JT
1150}
1151
1152/* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
1153 *RAW. */
1154
1155static int
b4ad899f 1156i387_tag (const gdb_byte *raw)
e750d25e
JT
1157{
1158 int integer;
1159 unsigned int exponent;
1160 unsigned long fraction[2];
1161
1162 integer = raw[7] & 0x80;
1163 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
1164 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
1165 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
1166 | (raw[5] << 8) | raw[4]);
1167
1168 if (exponent == 0x7fff)
1169 {
1170 /* Special. */
1171 return (2);
1172 }
1173 else if (exponent == 0x0000)
1174 {
1175 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
1176 {
1177 /* Zero. */
1178 return (1);
1179 }
1180 else
1181 {
1182 /* Special. */
1183 return (2);
1184 }
1185 }
1186 else
1187 {
1188 if (integer)
1189 {
1190 /* Valid. */
1191 return (0);
1192 }
1193 else
1194 {
1195 /* Special. */
1196 return (2);
1197 }
1198 }
1199}
efb1c01c
MK
1200
1201/* Prepare the FPU stack in REGCACHE for a function return. */
1202
1203void
1204i387_return_value (struct gdbarch *gdbarch, struct regcache *regcache)
1205{
1206 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1207 ULONGEST fstat;
1208
efb1c01c
MK
1209 /* Set the top of the floating-point register stack to 7. The
1210 actual value doesn't really matter, but 7 is what a normal
1211 function return would end up with if the program started out with
1212 a freshly initialized FPU. */
20a6ec49 1213 regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM (tdep), &fstat);
efb1c01c 1214 fstat |= (7 << 11);
20a6ec49 1215 regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM (tdep), fstat);
efb1c01c
MK
1216
1217 /* Mark %st(1) through %st(7) as empty. Since we set the top of the
1218 floating-point register stack to 7, the appropriate value for the
1219 tag word is 0x3fff. */
20a6ec49 1220 regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM (tdep), 0x3fff);
efb1c01c 1221
efb1c01c 1222}
This page took 1.20033 seconds and 4 git commands to generate.