Index: Makefile.in =================================================================== RCS file: /cvs/src/src/gdb/Makefile.in,v retrieving revision 1.169 diff -c -r1.169 Makefile.in *** Makefile.in 9 Apr 2002 03:06:13 -0000 1.169 --- Makefile.in 11 Apr 2002 22:43:31 -0000 *************** *** 1184,1190 **** i386-tdep.c i386b-nat.c i386mach-nat.c i386v-nat.c i386-linux-nat.c \ i386aix-nat.c i386m3-nat.c i386v4-nat.c i386ly-tdep.c \ i386bsd-nat.c i386bsd-tdep.c i386fbsd-nat.c \ ! i387-tdep.c i387-nat.c \ i386-linux-tdep.c i386-nat.c \ i960-tdep.c \ ia64-linux-nat.c ia64-linux-tdep.c ia64-tdep.c \ --- 1184,1190 ---- i386-tdep.c i386b-nat.c i386mach-nat.c i386v-nat.c i386-linux-nat.c \ i386aix-nat.c i386m3-nat.c i386v4-nat.c i386ly-tdep.c \ i386bsd-nat.c i386bsd-tdep.c i386fbsd-nat.c \ ! i387-tdep.c \ i386-linux-tdep.c i386-nat.c \ i960-tdep.c \ ia64-linux-nat.c ia64-linux-tdep.c ia64-tdep.c \ *************** *** 1611,1619 **** i387-tdep.o: i387-tdep.c $(floatformat_h) $(defs_h) $(gdbcore_h) \ $(inferior_h) $(language_h) $(regcache_h) $(doublest_h) i386-tdep.h - - i387-nat.o: i387-nat.c $(defs_h) $(inferior_h) $(value_h) $(regcache_h) \ - i387-nat.h i960-tdep.o: i960-tdep.c $(floatformat_h) $(defs_h) $(expression_h) \ $(frame_h) $(gdbtypes_h) $(symtab_h) $(value_h) $(gdbcore_h) \ --- 1611,1616 ---- Index: go32-nat.c =================================================================== RCS file: /cvs/src/src/gdb/go32-nat.c,v retrieving revision 1.31 diff -c -r1.31 go32-nat.c *** go32-nat.c 27 Mar 2002 21:35:35 -0000 1.31 --- go32-nat.c 11 Apr 2002 22:43:33 -0000 *************** *** 29,35 **** #include "gdbcmd.h" #include "floatformat.h" #include "buildsym.h" ! #include "i387-nat.h" #include "i386-tdep.h" #include "value.h" #include "regcache.h" --- 29,35 ---- #include "gdbcmd.h" #include "floatformat.h" #include "buildsym.h" ! #include "i387-tdep.h" #include "i386-tdep.h" #include "value.h" #include "regcache.h" Index: i386-linux-nat.c =================================================================== RCS file: /cvs/src/src/gdb/i386-linux-nat.c,v retrieving revision 1.35 diff -c -r1.35 i386-linux-nat.c *** i386-linux-nat.c 24 Feb 2002 22:14:33 -0000 1.35 --- i386-linux-nat.c 11 Apr 2002 22:43:34 -0000 *************** *** 57,63 **** #include "gregset.h" /* Prototypes for i387_supply_fsave etc. */ ! #include "i387-nat.h" /* Defines for XMM0_REGNUM etc. */ #include "i386-tdep.h" --- 57,63 ---- #include "gregset.h" /* Prototypes for i387_supply_fsave etc. */ ! #include "i387-tdep.h" /* Defines for XMM0_REGNUM etc. */ #include "i386-tdep.h" Index: i386bsd-nat.c =================================================================== RCS file: /cvs/src/src/gdb/i386bsd-nat.c,v retrieving revision 1.11 diff -c -r1.11 i386bsd-nat.c *** i386bsd-nat.c 5 Jan 2002 18:36:32 -0000 1.11 --- i386bsd-nat.c 11 Apr 2002 22:43:34 -0000 *************** *** 148,154 **** regcache_collect (i, REG_ADDR (gregsetp, i)); } ! #include "i387-nat.h" /* Fill GDB's register array with the floating-point register values in *FPREGSETP. */ --- 148,154 ---- regcache_collect (i, REG_ADDR (gregsetp, i)); } ! #include "i387-tdep.h" /* Fill GDB's register array with the floating-point register values in *FPREGSETP. */ Index: i386gnu-nat.c =================================================================== RCS file: /cvs/src/src/gdb/i386gnu-nat.c,v retrieving revision 1.8 diff -c -r1.8 i386gnu-nat.c *** i386gnu-nat.c 19 Jan 2002 12:51:04 -0000 1.8 --- i386gnu-nat.c 11 Apr 2002 22:43:34 -0000 *************** *** 34,42 **** #include #include "i386-tdep.h" #include "gnu-nat.h" - #include "i387-nat.h" /* Offset to the thread_state_t location where REG is stored. */ --- 34,42 ---- #include #include "i386-tdep.h" + #include "i387-tdep.h" #include "gnu-nat.h" /* Offset to the thread_state_t location where REG is stored. */ Index: i386nbsd-nat.c =================================================================== RCS file: /cvs/src/src/gdb/i386nbsd-nat.c,v retrieving revision 1.10 diff -c -r1.10 i386nbsd-nat.c *** i386nbsd-nat.c 5 Jan 2002 18:36:32 -0000 1.10 --- i386nbsd-nat.c 11 Apr 2002 22:43:34 -0000 *************** *** 39,45 **** #include "gregset.h" /* Prototypes for i387_supply_fsave etc. */ ! #include "i387-nat.h" struct md_core { --- 39,45 ---- #include "gregset.h" /* Prototypes for i387_supply_fsave etc. */ ! #include "i387-tdep.h" struct md_core { Index: i386v4-nat.c =================================================================== RCS file: /cvs/src/src/gdb/i386v4-nat.c,v retrieving revision 1.9 diff -c -r1.9 i386v4-nat.c *** i386v4-nat.c 13 Feb 2002 08:10:30 -0000 1.9 --- i386v4-nat.c 11 Apr 2002 22:43:34 -0000 *************** *** 27,33 **** #ifdef HAVE_SYS_REG_H #include #endif ! #include "i387-nat.h" #ifdef HAVE_SYS_PROCFS_H --- 27,33 ---- #ifdef HAVE_SYS_REG_H #include #endif ! #include "i387-tdep.h" #ifdef HAVE_SYS_PROCFS_H Index: i387-nat.c =================================================================== RCS file: i387-nat.c diff -N i387-nat.c *** i387-nat.c 27 Dec 2001 15:22:27 -0000 1.9 --- /dev/null 1 Jan 1970 00:00:00 -0000 *************** *** 1,346 **** - /* 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) - { - if (i == FOP_REGNUM) - { - unsigned short oldval, newval; - - /* The opcode occupies only 11 bits. */ - oldval = (*(unsigned short *) (FSAVE_ADDR (fsave, i))); - newval = *(unsigned short *) ®isters[REGISTER_BYTE (i)]; - newval &= ((1 << 11) - 1); - newval |= oldval & ~((1 << 11) - 1); - memcpy (FSAVE_ADDR (fsave, i), &newval, 2); - } - else - memcpy (FSAVE_ADDR (fsave, i), ®isters[REGISTER_BYTE (i)], 2); - } - else - memcpy (FSAVE_ADDR (fsave, i), ®isters[REGISTER_BYTE (i)], - REGISTER_RAW_SIZE (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) - { - if (i == FOP_REGNUM) - { - unsigned short oldval, newval; - - /* The opcode occupies only 11 bits. */ - oldval = (*(unsigned short *) (FXSAVE_ADDR (fxsave, i))); - newval = *(unsigned short *) ®isters[REGISTER_BYTE (i)]; - 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 *) ®isters[REGISTER_BYTE (i)]; - - 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), - ®isters[REGISTER_BYTE (i)], 2); - } - else - memcpy (FXSAVE_ADDR (fxsave, i), ®isters[REGISTER_BYTE (i)], - REGISTER_RAW_SIZE (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); - } - } - } --- 0 ---- Index: i387-nat.h =================================================================== RCS file: i387-nat.h diff -N i387-nat.h *** i387-nat.h 17 Mar 2001 23:02:10 -0000 1.4 --- /dev/null 1 Jan 1970 00:00:00 -0000 *************** *** 1,56 **** - /* 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. */ - - #ifndef I387_NAT_H - #define I387_NAT_H - - /* 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. */ - - extern void i387_supply_register (int regnum, char *fsave); - - /* Fill GDB's register array with the floating-point register values - in *FSAVE. This function masks off any of the reserved - bits in *FSAVE. */ - - extern void i387_supply_fsave (char *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. */ - - extern void i387_fill_fsave (char *fsave, int regnum); - - /* 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. */ - - extern void i387_supply_fxsave (char *fxsave); - - /* 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. */ - - extern void i387_fill_fxsave (char *fxsave, int regnum); - - #endif /* i387-nat.h */ --- 0 ---- Index: i387-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/i387-tdep.c,v retrieving revision 1.16 diff -c -r1.16 i387-tdep.c *** i387-tdep.c 12 Nov 2001 22:27:35 -0000 1.16 --- i387-tdep.c 11 Apr 2002 22:43:34 -0000 *************** *** 388,390 **** --- 388,709 ---- printf_filtered ("Opcode: %s\n", local_hex_string_custom (fop ? (fop | 0xd800) : 0, "04")); } + + /* 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) + { + if (i == FOP_REGNUM) + { + unsigned short oldval, newval; + + /* The opcode occupies only 11 bits. */ + oldval = (*(unsigned short *) (FSAVE_ADDR (fsave, i))); + newval = *(unsigned short *) ®isters[REGISTER_BYTE (i)]; + newval &= ((1 << 11) - 1); + newval |= oldval & ~((1 << 11) - 1); + memcpy (FSAVE_ADDR (fsave, i), &newval, 2); + } + else + memcpy (FSAVE_ADDR (fsave, i), ®isters[REGISTER_BYTE (i)], 2); + } + else + memcpy (FSAVE_ADDR (fsave, i), ®isters[REGISTER_BYTE (i)], + REGISTER_RAW_SIZE (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) + { + if (i == FOP_REGNUM) + { + unsigned short oldval, newval; + + /* The opcode occupies only 11 bits. */ + oldval = (*(unsigned short *) (FXSAVE_ADDR (fxsave, i))); + newval = *(unsigned short *) ®isters[REGISTER_BYTE (i)]; + 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 *) ®isters[REGISTER_BYTE (i)]; + + 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), + ®isters[REGISTER_BYTE (i)], 2); + } + else + memcpy (FXSAVE_ADDR (fxsave, i), ®isters[REGISTER_BYTE (i)], + REGISTER_RAW_SIZE (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); + } + } + } Index: i387-tdep.h =================================================================== RCS file: i387-tdep.h diff -N i387-tdep.h *** /dev/null 1 Jan 1970 00:00:00 -0000 --- i387-tdep.h 11 Apr 2002 22:43:34 -0000 *************** *** 0 **** --- 1,56 ---- + /* Target-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. */ + + #ifndef I387_TDEP_H + #define I387_TDEP_H + + /* 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. */ + + extern void i387_supply_register (int regnum, char *fsave); + + /* Fill GDB's register array with the floating-point register values + in *FSAVE. This function masks off any of the reserved + bits in *FSAVE. */ + + extern void i387_supply_fsave (char *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. */ + + extern void i387_fill_fsave (char *fsave, int regnum); + + /* 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. */ + + extern void i387_supply_fxsave (char *fxsave); + + /* 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. */ + + extern void i387_fill_fxsave (char *fxsave, int regnum); + + #endif /* i387-tdep.h */ Index: x86-64-linux-nat.c =================================================================== RCS file: /cvs/src/src/gdb/x86-64-linux-nat.c,v retrieving revision 1.9 diff -c -r1.9 x86-64-linux-nat.c *** x86-64-linux-nat.c 10 Apr 2002 12:12:33 -0000 1.9 --- x86-64-linux-nat.c 11 Apr 2002 22:43:35 -0000 *************** *** 25,31 **** #include "inferior.h" #include "gdbcore.h" #include "regcache.h" ! #include "i387-nat.h" #include "gdb_assert.h" #include "x86-64-tdep.h" --- 25,31 ---- #include "inferior.h" #include "gdbcore.h" #include "regcache.h" ! #include "i387-tdep.h" #include "gdb_assert.h" #include "x86-64-tdep.h" Index: config/i386/fbsd.mh =================================================================== RCS file: /cvs/src/src/gdb/config/i386/fbsd.mh,v retrieving revision 1.11 diff -c -r1.11 fbsd.mh *** config/i386/fbsd.mh 31 Mar 2002 17:47:17 -0000 1.11 --- config/i386/fbsd.mh 11 Apr 2002 22:43:36 -0000 *************** *** 4,7 **** NAT_FILE= nm-fbsd.h # NOTE: Do not spread NATDEPFILES over several lines - it hurts BSD make. ! NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-svr4.o solib-legacy.o corelow.o core-aout.o core-regset.o i386-nat.o i387-nat.o i386bsd-nat.o i386fbsd-nat.o gcore.o fbsd-proc.o --- 4,7 ---- NAT_FILE= nm-fbsd.h # NOTE: Do not spread NATDEPFILES over several lines - it hurts BSD make. ! NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-svr4.o solib-legacy.o corelow.o core-aout.o core-regset.o i386-nat.o i386bsd-nat.o i386fbsd-nat.o gcore.o fbsd-proc.o Index: config/i386/go32.mh =================================================================== RCS file: /cvs/src/src/gdb/config/i386/go32.mh,v retrieving revision 1.5 diff -c -r1.5 go32.mh *** config/i386/go32.mh 18 Jan 2002 04:50:59 -0000 1.5 --- config/i386/go32.mh 11 Apr 2002 22:43:36 -0000 *************** *** 7,13 **** XM_FILE= xm-go32.h NAT_FILE= nm-go32.h ! NATDEPFILES= go32-nat.o i386-nat.o i387-nat.o TERMCAP= HOST_IPC= --- 7,13 ---- XM_FILE= xm-go32.h NAT_FILE= nm-go32.h ! NATDEPFILES= go32-nat.o i386-nat.o TERMCAP= HOST_IPC= Index: config/i386/i386gnu.mh =================================================================== RCS file: /cvs/src/src/gdb/config/i386/i386gnu.mh,v retrieving revision 1.6 diff -c -r1.6 i386gnu.mh *** config/i386/i386gnu.mh 18 Jan 2002 04:50:59 -0000 1.6 --- config/i386/i386gnu.mh 11 Apr 2002 22:43:36 -0000 *************** *** 1,5 **** # Host: Intel 386 running the GNU Hurd ! NATDEPFILES= i386gnu-nat.o i387-nat.o gnu-nat.o fork-child.o solib.o solib-svr4.o solib-legacy.o corelow.o notify_S.o process_reply_S.o msg_reply_S.o msg_U.o exc_request_U.o exc_request_S.o XM_FILE= xm-i386gnu.h NAT_FILE= nm-gnu.h MH_CFLAGS = -D_GNU_SOURCE --- 1,5 ---- # Host: Intel 386 running the GNU Hurd ! NATDEPFILES= i386gnu-nat.o gnu-nat.o fork-child.o solib.o solib-svr4.o solib-legacy.o corelow.o notify_S.o process_reply_S.o msg_reply_S.o msg_U.o exc_request_U.o exc_request_S.o XM_FILE= xm-i386gnu.h NAT_FILE= nm-gnu.h MH_CFLAGS = -D_GNU_SOURCE Index: config/i386/i386sol2.mh =================================================================== RCS file: /cvs/src/src/gdb/config/i386/i386sol2.mh,v retrieving revision 1.4 diff -c -r1.4 i386sol2.mh *** config/i386/i386sol2.mh 14 Feb 2002 08:13:33 -0000 1.4 --- config/i386/i386sol2.mh 11 Apr 2002 22:43:36 -0000 *************** *** 4,8 **** XM_CLIBS= -lsocket -lnsl NAT_FILE= nm-i386sol2.h ! NATDEPFILES= core-regset.o fork-child.o i386v4-nat.o i387-nat.o corelow.o \ procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o gcore.o --- 4,8 ---- XM_CLIBS= -lsocket -lnsl NAT_FILE= nm-i386sol2.h ! NATDEPFILES= core-regset.o fork-child.o i386v4-nat.o corelow.o \ procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o gcore.o Index: config/i386/i386v42mp.mh =================================================================== RCS file: /cvs/src/src/gdb/config/i386/i386v42mp.mh,v retrieving revision 1.7 diff -c -r1.7 i386v42mp.mh *** config/i386/i386v42mp.mh 11 Apr 2002 18:13:21 -0000 1.7 --- config/i386/i386v42mp.mh 11 Apr 2002 22:43:36 -0000 *************** *** 14,20 **** # continuation character (backslash) to extend a commented line. As a # consequence, make considers subsequent tab-indented lines to be # some sort of error. ! NATDEPFILES= corelow.o core-regset.o fork-child.o i386v4-nat.o i387-nat.o \ gcore.o solib.o solib-svr4.o solib-legacy.o procfs.o proc-api.o \ proc-events.o proc-flags.o proc-why.o uw-thread.o --- 14,20 ---- # continuation character (backslash) to extend a commented line. As a # consequence, make considers subsequent tab-indented lines to be # some sort of error. ! NATDEPFILES= corelow.o core-regset.o fork-child.o i386v4-nat.o \ gcore.o solib.o solib-svr4.o solib-legacy.o procfs.o proc-api.o \ proc-events.o proc-flags.o proc-why.o uw-thread.o Index: config/i386/linux.mh =================================================================== RCS file: /cvs/src/src/gdb/config/i386/linux.mh,v retrieving revision 1.11 diff -c -r1.11 linux.mh *** config/i386/linux.mh 18 Jan 2002 04:50:59 -0000 1.11 --- config/i386/linux.mh 11 Apr 2002 22:43:36 -0000 *************** *** 4,10 **** NAT_FILE= nm-linux.h NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o linux-proc.o \ ! core-aout.o i386-nat.o i386-linux-nat.o i387-nat.o \ proc-service.o thread-db.o lin-lwp.o linux-proc.o gcore.o # The dynamically loaded libthread_db needs access to symbols in the --- 4,10 ---- NAT_FILE= nm-linux.h NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o linux-proc.o \ ! core-aout.o i386-nat.o i386-linux-nat.o \ proc-service.o thread-db.o lin-lwp.o linux-proc.o gcore.o # The dynamically loaded libthread_db needs access to symbols in the Index: config/i386/nbsd.mh =================================================================== RCS file: /cvs/src/src/gdb/config/i386/nbsd.mh,v retrieving revision 1.12 diff -c -r1.12 nbsd.mh *** config/i386/nbsd.mh 18 Jan 2002 04:50:59 -0000 1.12 --- config/i386/nbsd.mh 11 Apr 2002 22:43:36 -0000 *************** *** 6,12 **** # continuation character (backslash) to extend a commented line. As a # consequence, BSD make considers subsequent tab-indented lines to be # "unassociated shell commands". ! NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o i387-nat.o i386bsd-nat.o i386nbsd-nat.o solib.o solib-sunos.o XM_FILE= xm-nbsd.h NAT_FILE= nm-nbsd.h --- 6,12 ---- # continuation character (backslash) to extend a commented line. As a # consequence, BSD make considers subsequent tab-indented lines to be # "unassociated shell commands". ! NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o i386bsd-nat.o i386nbsd-nat.o solib.o solib-sunos.o XM_FILE= xm-nbsd.h NAT_FILE= nm-nbsd.h Index: config/i386/nbsdelf.mh =================================================================== RCS file: /cvs/src/src/gdb/config/i386/nbsdelf.mh,v retrieving revision 1.8 diff -c -r1.8 nbsdelf.mh *** config/i386/nbsdelf.mh 18 Jan 2002 04:50:59 -0000 1.8 --- config/i386/nbsdelf.mh 11 Apr 2002 22:43:36 -0000 *************** *** 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 XM_FILE= xm-nbsd.h NAT_FILE= nm-nbsdelf.h --- 1,4 ---- # Host: Intel 386 running NetBSD ! 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 Index: config/i386/obsd.mh =================================================================== RCS file: /cvs/src/src/gdb/config/i386/obsd.mh,v retrieving revision 1.2 diff -c -r1.2 obsd.mh *** config/i386/obsd.mh 18 Jan 2002 04:50:59 -0000 1.2 --- config/i386/obsd.mh 11 Apr 2002 22:43:36 -0000 *************** *** 4,7 **** NAT_FILE= nm-obsd.h # NOTE: Do not spread NATDEPFILES over several lines - it hurts BSD make. ! NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-sunos.o corelow.o core-aout.o i386-nat.o i387-nat.o i386bsd-nat.o --- 4,7 ---- NAT_FILE= nm-obsd.h # NOTE: Do not spread NATDEPFILES over several lines - it hurts BSD make. ! NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-sunos.o corelow.o core-aout.o i386-nat.o i386bsd-nat.o Index: config/i386/x86-64linux.mh =================================================================== RCS file: /cvs/src/src/gdb/config/i386/x86-64linux.mh,v retrieving revision 1.5 diff -c -r1.5 x86-64linux.mh *** config/i386/x86-64linux.mh 21 Feb 2002 12:48:36 -0000 1.5 --- config/i386/x86-64linux.mh 11 Apr 2002 22:43:36 -0000 *************** *** 5,11 **** NAT_FILE= nm-x86-64.h NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \ core-aout.o i386-nat.o x86-64-linux-nat.o \ ! i387-nat.o proc-service.o thread-db.o lin-lwp.o \ linux-proc.o gcore.o LOADLIBES = -ldl -rdynamic --- 5,11 ---- NAT_FILE= nm-x86-64.h NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \ core-aout.o i386-nat.o x86-64-linux-nat.o \ ! proc-service.o thread-db.o lin-lwp.o \ linux-proc.o gcore.o LOADLIBES = -ldl -rdynamic