diff options
Diffstat (limited to 'gdb/i387-nat.c')
-rw-r--r-- | gdb/i387-nat.c | 351 |
1 files changed, 0 insertions, 351 deletions
diff --git a/gdb/i387-nat.c b/gdb/i387-nat.c deleted file mode 100644 index 163dcfd..0000000 --- a/gdb/i387-nat.c +++ /dev/null @@ -1,351 +0,0 @@ -/* Native-dependent code for the i387. - Copyright 2000, 2001 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 int val = *(unsigned short *) (FSAVE_ADDR (fsave, regnum)); - - if (regnum == FOP_REGNUM) - { - val &= ((1 << 11) - 1); - supply_register (regnum, (char *) &val); - } - else - supply_register (regnum, (char *) &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) - { - char buf[4]; - - regcache_collect (i, buf); - - if (i == FOP_REGNUM) - { - unsigned short oldval, newval; - - /* The opcode occupies only 11 bits. */ - oldval = (*(unsigned short *) (FSAVE_ADDR (fsave, i))); - newval = *(unsigned short *) buf; - newval &= ((1 << 11) - 1); - newval |= oldval & ~((1 << 11) - 1); - memcpy (FSAVE_ADDR (fsave, i), &newval, 2); - } - else - 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 long val = *(unsigned short *) (FXSAVE_ADDR (fxsave, i)); - - if (i == FOP_REGNUM) - { - val &= ((1 << 11) - 1); - supply_register (i, (char *) &val); - } - 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; - unsigned long fstat; - int fpreg; - int top; - - fstat = *(unsigned short *) (FXSAVE_ADDR (fxsave, FSTAT_REGNUM)); - top = ((fstat >> 11) & 0x7); - - for (fpreg = 7; fpreg >= 0; fpreg--) - { - int tag; - - if (val & (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); - } - supply_register (i, (char *) &ftag); - } - else - supply_register (i, (char *) &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) - { - char buf[4]; - - regcache_collect (i, buf); - - if (i == FOP_REGNUM) - { - unsigned short oldval, newval; - - /* The opcode occupies only 11 bits. */ - oldval = (*(unsigned short *) (FXSAVE_ADDR (fxsave, i))); - newval = *(unsigned short *) buf; - newval &= ((1 << 11) - 1); - newval |= oldval & ~((1 << 11) - 1); - memcpy (FXSAVE_ADDR (fxsave, i), &newval, 2); - } - else if (i == FTAG_REGNUM) - { - /* Converting back is much easier. */ - - unsigned short val = 0; - unsigned short ftag; - int fpreg; - - ftag = *(unsigned short *) buf; - - for (fpreg = 7; fpreg >= 0; fpreg--) - { - int tag = (ftag >> (fpreg * 2)) & 3; - - if (tag != 3) - val |= (1 << fpreg); - } - - memcpy (FXSAVE_ADDR (fxsave, i), &val, 2); - } - else - 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); - } - } -} |