Browse Source
(i387-nat.o): Delete dependency list. (go32-nat.o): Change i387-nat.h to i387-tdep.h. (x86-64-linux-nat.o): Likewise. * i387-nat.c: Delete file, moving contents to... * i387-tdep.c: ...here. * i387-nat.h: Rename... * i387-tdep.h: ...to this. * go32-nat.c: Include i387-tdep.h instead of i387-nat.h. * i386-linux-nat.c: Likewise. * i386bsd-nat.c: Likewise. * i386gnu-nat.c: Likewise. * i386nbsd-nat.c: Likewise. * i386v4-nat.c: Likewise. * x86-64-linux-nat.c: Likewise. * config/i386/fbsd.mh (NATDEPFILES): Remove i387-nat.o. * config/i386/go32.mh (NATDEPFILES): Likewise. * config/i386/i386gnu.mh (NATDEPFILES): Likewise. * config/i386/i386sol2.mh (NATDEPFILES): Likewise. * config/i386/i386v42mp.mh (NATDEPFILES): Likewise. * config/i386/linux.mh (NATDEPFILES): Likewise. * config/i386/nbsd.mh (NATDEPFILES): Likewise. * config/i386/nbsdelf.mh (NATDEPFILES): Likewise. * config/i386/obsd.mh (NATDEPFILES): Likewise. * config/i386/x86-64linux.mh (NATDEPFILES): Likewise.binutils-2_13-branch
22 changed files with 360 additions and 362 deletions
@ -1,4 +1,4 @@ |
|||
# Host: Intel 386 running NetBSD |
|||
NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o i387-nat.o i386bsd-nat.o i386nbsd-nat.o solib.o solib-svr4.o solib-legacy.o |
|||
NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o i386bsd-nat.o i386nbsd-nat.o solib.o solib-svr4.o solib-legacy.o |
|||
XM_FILE= xm-nbsd.h |
|||
NAT_FILE= nm-nbsdelf.h |
|||
|
|||
@ -1,335 +0,0 @@ |
|||
/* Native-dependent code for the i387.
|
|||
Copyright 2000, 2001, 2002 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 |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
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. */ |
|||
|
|||
#include "defs.h" |
|||
#include "inferior.h" |
|||
#include "value.h" |
|||
#include "regcache.h" |
|||
|
|||
#include "i387-nat.h" |
|||
#include "i386-tdep.h" |
|||
|
|||
/* FIXME: kettenis/2000-05-21: Right now more than a few i386 targets
|
|||
define their own routines to manage the floating-point registers in |
|||
GDB's register array. Most (if not all) of these targets use the |
|||
format used by the "fsave" instruction in their communication with |
|||
the OS. They should all be converted to use the routines below. */ |
|||
|
|||
/* At fsave_offset[REGNUM] you'll find the offset to the location in
|
|||
the data structure used by the "fsave" instruction where GDB |
|||
register REGNUM is stored. */ |
|||
|
|||
static int fsave_offset[] = |
|||
{ |
|||
28 + 0 * FPU_REG_RAW_SIZE, /* FP0_REGNUM through ... */ |
|||
28 + 1 * FPU_REG_RAW_SIZE, |
|||
28 + 2 * FPU_REG_RAW_SIZE, |
|||
28 + 3 * FPU_REG_RAW_SIZE, |
|||
28 + 4 * FPU_REG_RAW_SIZE, |
|||
28 + 5 * FPU_REG_RAW_SIZE, |
|||
28 + 6 * FPU_REG_RAW_SIZE, |
|||
28 + 7 * FPU_REG_RAW_SIZE, /* ... FP7_REGNUM. */ |
|||
0, /* FCTRL_REGNUM (16 bits). */ |
|||
4, /* FSTAT_REGNUM (16 bits). */ |
|||
8, /* FTAG_REGNUM (16 bits). */ |
|||
16, /* FISEG_REGNUM (16 bits). */ |
|||
12, /* FIOFF_REGNUM. */ |
|||
24, /* FOSEG_REGNUM. */ |
|||
20, /* FOOFF_REGNUM. */ |
|||
18 /* FOP_REGNUM (bottom 11 bits). */ |
|||
}; |
|||
|
|||
#define FSAVE_ADDR(fsave, regnum) (fsave + fsave_offset[regnum - FP0_REGNUM]) |
|||
|
|||
|
|||
/* Fill register REGNUM in GDB's register array with the appropriate
|
|||
value from *FSAVE. This function masks off any of the reserved |
|||
bits in *FSAVE. */ |
|||
|
|||
void |
|||
i387_supply_register (int regnum, char *fsave) |
|||
{ |
|||
/* Most of the FPU control registers occupy only 16 bits in
|
|||
the fsave area. Give those a special treatment. */ |
|||
if (regnum >= FPC_REGNUM |
|||
&& regnum != FIOFF_REGNUM && regnum != FOOFF_REGNUM) |
|||
{ |
|||
unsigned char val[4]; |
|||
|
|||
memcpy (val, FSAVE_ADDR (fsave, regnum), 2); |
|||
val[2] = val[3] = 0; |
|||
if (regnum == FOP_REGNUM) |
|||
val[1] &= ((1 << 3) - 1); |
|||
supply_register (regnum, val); |
|||
} |
|||
else |
|||
supply_register (regnum, FSAVE_ADDR (fsave, regnum)); |
|||
} |
|||
|
|||
/* Fill GDB's register array with the floating-point register values
|
|||
in *FSAVE. This function masks off any of the reserved |
|||
bits in *FSAVE. */ |
|||
|
|||
void |
|||
i387_supply_fsave (char *fsave) |
|||
{ |
|||
int i; |
|||
|
|||
for (i = FP0_REGNUM; i < XMM0_REGNUM; i++) |
|||
i387_supply_register (i, fsave); |
|||
} |
|||
|
|||
/* Fill register REGNUM (if it is a floating-point register) in *FSAVE
|
|||
with the value in GDB's register array. If REGNUM is -1, do this |
|||
for all registers. This function doesn't touch any of the reserved |
|||
bits in *FSAVE. */ |
|||
|
|||
void |
|||
i387_fill_fsave (char *fsave, int regnum) |
|||
{ |
|||
int i; |
|||
|
|||
for (i = FP0_REGNUM; i < XMM0_REGNUM; i++) |
|||
if (regnum == -1 || regnum == i) |
|||
{ |
|||
/* Most of the FPU control registers occupy only 16 bits in
|
|||
the fsave area. Give those a special treatment. */ |
|||
if (i >= FPC_REGNUM |
|||
&& i != FIOFF_REGNUM && i != FOOFF_REGNUM) |
|||
{ |
|||
unsigned char buf[4]; |
|||
|
|||
regcache_collect (i, buf); |
|||
|
|||
if (i == FOP_REGNUM) |
|||
{ |
|||
/* The opcode occupies only 11 bits. Make sure we
|
|||
don't touch the other bits. */ |
|||
buf[1] &= ((1 << 3) - 1); |
|||
buf[1] |= ((FSAVE_ADDR (fsave, i))[1] & ~((1 << 3) - 1)); |
|||
} |
|||
memcpy (FSAVE_ADDR (fsave, i), buf, 2); |
|||
} |
|||
else |
|||
regcache_collect (i, FSAVE_ADDR (fsave, i)); |
|||
} |
|||
} |
|||
|
|||
|
|||
/* At fxsave_offset[REGNUM] you'll find the offset to the location in
|
|||
the data structure used by the "fxsave" instruction where GDB |
|||
register REGNUM is stored. */ |
|||
|
|||
static int fxsave_offset[] = |
|||
{ |
|||
32, /* FP0_REGNUM through ... */ |
|||
48, |
|||
64, |
|||
80, |
|||
96, |
|||
112, |
|||
128, |
|||
144, /* ... FP7_REGNUM (80 bits each). */ |
|||
0, /* FCTRL_REGNUM (16 bits). */ |
|||
2, /* FSTAT_REGNUM (16 bits). */ |
|||
4, /* FTAG_REGNUM (16 bits). */ |
|||
12, /* FISEG_REGNUM (16 bits). */ |
|||
8, /* FIOFF_REGNUM. */ |
|||
20, /* FOSEG_REGNUM (16 bits). */ |
|||
16, /* FOOFF_REGNUM. */ |
|||
6, /* FOP_REGNUM (bottom 11 bits). */ |
|||
160, /* XMM0_REGNUM through ... */ |
|||
176, |
|||
192, |
|||
208, |
|||
224, |
|||
240, |
|||
256, |
|||
272, /* ... XMM7_REGNUM (128 bits each). */ |
|||
24, /* MXCSR_REGNUM. */ |
|||
}; |
|||
|
|||
#define FXSAVE_ADDR(fxsave, regnum) \ |
|||
(fxsave + fxsave_offset[regnum - FP0_REGNUM]) |
|||
|
|||
static int i387_tag (unsigned char *raw); |
|||
|
|||
|
|||
/* Fill GDB's register array with the floating-point and SSE register
|
|||
values in *FXSAVE. This function masks off any of the reserved |
|||
bits in *FXSAVE. */ |
|||
|
|||
void |
|||
i387_supply_fxsave (char *fxsave) |
|||
{ |
|||
int i; |
|||
|
|||
for (i = FP0_REGNUM; i <= MXCSR_REGNUM; i++) |
|||
{ |
|||
/* Most of the FPU control registers occupy only 16 bits in
|
|||
the fxsave area. Give those a special treatment. */ |
|||
if (i >= FPC_REGNUM && i < XMM0_REGNUM |
|||
&& i != FIOFF_REGNUM && i != FOOFF_REGNUM) |
|||
{ |
|||
unsigned char val[4]; |
|||
|
|||
memcpy (val, FXSAVE_ADDR (fxsave, i), 2); |
|||
val[2] = val[3] = 0; |
|||
if (i == FOP_REGNUM) |
|||
val[1] &= ((1 << 3) - 1); |
|||
else if (i== FTAG_REGNUM) |
|||
{ |
|||
/* The fxsave area contains a simplified version of the
|
|||
tag word. We have to look at the actual 80-bit FP |
|||
data to recreate the traditional i387 tag word. */ |
|||
|
|||
unsigned long ftag = 0; |
|||
int fpreg; |
|||
int top; |
|||
|
|||
top = (((FXSAVE_ADDR (fxsave, FSTAT_REGNUM))[1] >> 3) & 0x7); |
|||
|
|||
for (fpreg = 7; fpreg >= 0; fpreg--) |
|||
{ |
|||
int tag; |
|||
|
|||
if (val[0] & (1 << fpreg)) |
|||
{ |
|||
int regnum = (fpreg + 8 - top) % 8 + FP0_REGNUM; |
|||
tag = i387_tag (FXSAVE_ADDR (fxsave, regnum)); |
|||
} |
|||
else |
|||
tag = 3; /* Empty */ |
|||
|
|||
ftag |= tag << (2 * fpreg); |
|||
} |
|||
val[0] = ftag & 0xff; |
|||
val[1] = (ftag >> 8) & 0xff; |
|||
} |
|||
supply_register (i, val); |
|||
} |
|||
else |
|||
supply_register (i, FXSAVE_ADDR (fxsave, i)); |
|||
} |
|||
} |
|||
|
|||
/* Fill register REGNUM (if it is a floating-point or SSE register) in
|
|||
*FXSAVE with the value in GDB's register array. If REGNUM is -1, do |
|||
this for all registers. This function doesn't touch any of the |
|||
reserved bits in *FXSAVE. */ |
|||
|
|||
void |
|||
i387_fill_fxsave (char *fxsave, int regnum) |
|||
{ |
|||
int i; |
|||
|
|||
for (i = FP0_REGNUM; i <= MXCSR_REGNUM; i++) |
|||
if (regnum == -1 || regnum == i) |
|||
{ |
|||
/* Most of the FPU control registers occupy only 16 bits in
|
|||
the fxsave area. Give those a special treatment. */ |
|||
if (i >= FPC_REGNUM && i < XMM0_REGNUM |
|||
&& i != FIOFF_REGNUM && i != FDOFF_REGNUM) |
|||
{ |
|||
unsigned char buf[4]; |
|||
|
|||
regcache_collect (i, buf); |
|||
|
|||
if (i == FOP_REGNUM) |
|||
{ |
|||
/* The opcode occupies only 11 bits. Make sure we
|
|||
don't touch the other bits. */ |
|||
buf[1] &= ((1 << 3) - 1); |
|||
buf[1] |= ((FXSAVE_ADDR (fxsave, i))[1] & ~((1 << 3) - 1)); |
|||
} |
|||
else if (i == FTAG_REGNUM) |
|||
{ |
|||
/* Converting back is much easier. */ |
|||
|
|||
unsigned short ftag; |
|||
int fpreg; |
|||
|
|||
ftag = (buf[1] << 8) | buf[0]; |
|||
buf[0] = 0; |
|||
buf[1] = 0; |
|||
|
|||
for (fpreg = 7; fpreg >= 0; fpreg--) |
|||
{ |
|||
int tag = (ftag >> (fpreg * 2)) & 3; |
|||
|
|||
if (tag != 3) |
|||
buf[0] |= (1 << fpreg); |
|||
} |
|||
} |
|||
memcpy (FXSAVE_ADDR (fxsave, i), buf, 2); |
|||
} |
|||
else |
|||
regcache_collect (i, FXSAVE_ADDR (fxsave, i)); |
|||
} |
|||
} |
|||
|
|||
/* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
|
|||
*RAW. */ |
|||
|
|||
static int |
|||
i387_tag (unsigned char *raw) |
|||
{ |
|||
int integer; |
|||
unsigned int exponent; |
|||
unsigned long fraction[2]; |
|||
|
|||
integer = raw[7] & 0x80; |
|||
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]); |
|||
|
|||
if (exponent == 0x7fff) |
|||
{ |
|||
/* Special. */ |
|||
return (2); |
|||
} |
|||
else if (exponent == 0x0000) |
|||
{ |
|||
if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer) |
|||
{ |
|||
/* Zero. */ |
|||
return (1); |
|||
} |
|||
else |
|||
{ |
|||
/* Special. */ |
|||
return (2); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
if (integer) |
|||
{ |
|||
/* Valid. */ |
|||
return (0); |
|||
} |
|||
else |
|||
{ |
|||
/* Special. */ |
|||
return (2); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue