/* i387-specific utility functions, for the remote server for GDB.
- Copyright 2000, 2001, 2002, 2005
+ Copyright (C) 2000, 2001, 2002, 2005, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "server.h"
#include "i387-fp.h"
struct i387_fsave {
/* All these are only sixteen bits, plus padding, except for fop (which
is only eleven bits), and fooff / fioff (which are 32 bits each). */
- unsigned int fctrl;
- unsigned int fstat;
- unsigned int ftag;
+ unsigned short fctrl;
+ unsigned short pad1;
+ unsigned short fstat;
+ unsigned short pad2;
+ unsigned short ftag;
+ unsigned short pad3;
unsigned int fioff;
unsigned short fiseg;
unsigned short fop;
unsigned int fooff;
- unsigned int foseg;
+ unsigned short foseg;
+ unsigned short pad4;
/* Space for eight 80-bit FP values. */
unsigned char st_space[80];
unsigned short ftag;
unsigned short fop;
unsigned int fioff;
- unsigned int fiseg;
+ unsigned short fiseg;
+ unsigned short pad1;
unsigned int fooff;
- unsigned int foseg;
+ unsigned short foseg;
+ unsigned short pad12;
unsigned int mxcsr;
-
- unsigned int _pad1;
+ unsigned int pad3;
/* Space for eight 80-bit FP values in 128-bit spaces. */
unsigned char st_space[128];
/* Some registers are 16-bit. */
collect_register_by_name ("fctrl", &val);
- *(unsigned short *) &fp->fctrl = val;
+ fp->fctrl = val;
collect_register_by_name ("fstat", &val);
val &= 0xFFFF;
- *(unsigned short *) &fp->fstat = val;
+ fp->fstat = val;
collect_register_by_name ("ftag", &val);
val &= 0xFFFF;
- *(unsigned short *) &fp->ftag = val;
+ fp->ftag = val;
collect_register_by_name ("fiseg", &val);
val &= 0xFFFF;
- *(unsigned short *) &fp->fiseg = val;
+ fp->fiseg = val;
collect_register_by_name ("foseg", &val);
val &= 0xFFFF;
- *(unsigned short *) &fp->foseg = val;
+ fp->foseg = val;
}
void
supply_register_by_name ("fioff", &fp->fioff);
supply_register_by_name ("fooff", &fp->fooff);
-
+
/* Some registers are 16-bit. */
val = fp->fctrl & 0xFFFF;
supply_register_by_name ("fctrl", &val);
val = fp->foseg & 0xFFFF;
supply_register_by_name ("foseg", &val);
+ /* fop has only 11 valid bits. */
val = (fp->fop) & 0x7FF;
supply_register_by_name ("fop", &val);
}
collect_register_by_name ("fioff", &fp->fioff);
collect_register_by_name ("fooff", &fp->fooff);
collect_register_by_name ("mxcsr", &fp->mxcsr);
-
+
/* This one's 11 bits... */
collect_register_by_name ("fop", &val2);
fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
/* Some registers are 16-bit. */
collect_register_by_name ("fctrl", &val);
- *(unsigned short *) &fp->fctrl = val;
+ fp->fctrl = val;
collect_register_by_name ("fstat", &val);
- val &= 0xFFFF;
- *(unsigned short *) &fp->fstat = val;
+ fp->fstat = val;
/* Convert to the simplifed tag form stored in fxsave data. */
collect_register_by_name ("ftag", &val);
val &= 0xFFFF;
+ val2 = 0;
for (i = 7; i >= 0; i--)
{
int tag = (val >> (i * 2)) & 3;
if (tag != 3)
val2 |= (1 << i);
}
- *(unsigned short *) &fp->ftag = val2;
+ fp->ftag = val2;
collect_register_by_name ("fiseg", &val);
- val &= 0xFFFF;
- *(unsigned short *) &fp->fiseg = val;
+ fp->fiseg = val;
collect_register_by_name ("foseg", &val);
- val &= 0xFFFF;
- *(unsigned short *) &fp->foseg = val;
+ fp->foseg = val;
}
static int
exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
- | (raw[5] << 8) | raw[4]);
+ | (raw[5] << 8) | raw[4]);
if (exponent == 0x7fff)
{
else if (exponent == 0x0000)
{
if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
- {
- /* Zero. */
- return (1);
- }
+ {
+ /* Zero. */
+ return (1);
+ }
else
- {
- /* Special. */
- return (2);
- }
+ {
+ /* Special. */
+ return (2);
+ }
}
else
{
if (integer)
- {
- /* Valid. */
- return (0);
- }
+ {
+ /* Valid. */
+ return (0);
+ }
else
- {
- /* Special. */
- return (2);
- }
+ {
+ /* Special. */
+ return (2);
+ }
}
}
supply_register_by_name ("fioff", &fp->fioff);
supply_register_by_name ("fooff", &fp->fooff);
supply_register_by_name ("mxcsr", &fp->mxcsr);
-
+
/* Some registers are 16-bit. */
val = fp->fctrl & 0xFFFF;
supply_register_by_name ("fctrl", &val);
for (i = 7; i >= 0; i--)
{
int tag;
- if (val & (1 << i))
+ if (fp->ftag & (1 << i))
tag = i387_ftag (fp, (i + 8 - top) % 8);
else
tag = 3;