From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14628 invoked by alias); 9 May 2002 23:45:52 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 14618 invoked from network); 9 May 2002 23:45:50 -0000 Received: from unknown (HELO dr-evil.shagadelic.org) (208.176.2.162) by sources.redhat.com with SMTP; 9 May 2002 23:45:50 -0000 Received: by dr-evil.shagadelic.org (Postfix, from userid 7518) id 9DFF59869; Thu, 9 May 2002 16:45:46 -0700 (PDT) Date: Thu, 09 May 2002 16:45:00 -0000 From: Jason R Thorpe To: gdb-patches@sources.redhat.com Subject: [PATCH/RFA] Move i387 register supply/fill to i387-tdep.c Message-ID: <20020509164546.R3435@dr-evil.shagadelic.org> Reply-To: thorpej@wasabisystems.com Mail-Followup-To: Jason R Thorpe , gdb-patches@sources.redhat.com Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="y0Ed1hDcWxc3B7cn" Content-Disposition: inline User-Agent: Mutt/1.2.5i Organization: Wasabi Systems, Inc. X-SW-Source: 2002-05/txt/msg00306.txt.bz2 --y0Ed1hDcWxc3B7cn Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 1507 This is a re-submit of an earlier patch, which takes into account Mark's recent changes to i387-nat.c. Basically, this moves all of the register supply/fill stuff for i387 from i387-nat.c to i387-tdep.c, to facilitate cross-debugging of core files. This renders i387-nat.c empty, and so it is removed in this patch. OK to commit? * Makefile.in (ALLDEPFILES): Remove i387-nat.c. (i387-nat.o): Delete rule. * 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. -- -- Jason R. Thorpe --y0Ed1hDcWxc3B7cn Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=i387-patch Content-length: 33399 Index: go32-nat.c =================================================================== RCS file: /cvs/src/src/gdb/go32-nat.c,v retrieving revision 1.32 diff -u -r1.32 go32-nat.c --- go32-nat.c 19 Apr 2002 19:28:48 -0000 1.32 +++ go32-nat.c 9 May 2002 23:33:58 -0000 @@ -29,7 +29,7 @@ #include "gdbcmd.h" #include "floatformat.h" #include "buildsym.h" -#include "i387-nat.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 -u -r1.35 i386-linux-nat.c --- i386-linux-nat.c 24 Feb 2002 22:14:33 -0000 1.35 +++ i386-linux-nat.c 9 May 2002 23:33:58 -0000 @@ -57,7 +57,7 @@ #include "gregset.h" /* Prototypes for i387_supply_fsave etc. */ -#include "i387-nat.h" +#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 -u -r1.11 i386bsd-nat.c --- i386bsd-nat.c 5 Jan 2002 18:36:32 -0000 1.11 +++ i386bsd-nat.c 9 May 2002 23:33:58 -0000 @@ -148,7 +148,7 @@ regcache_collect (i, REG_ADDR (gregsetp, i)); } -#include "i387-nat.h" +#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.9 diff -u -r1.9 i386gnu-nat.c --- i386gnu-nat.c 24 Apr 2002 21:44:46 -0000 1.9 +++ i386gnu-nat.c 9 May 2002 23:33:59 -0000 @@ -34,9 +34,9 @@ #include #include "i386-tdep.h" +#include "i387-tdep.h" #include "gnu-nat.h" -#include "i387-nat.h" #ifdef HAVE_SYS_PROCFS_H # include Index: i386nbsd-nat.c =================================================================== RCS file: /cvs/src/src/gdb/i386nbsd-nat.c,v retrieving revision 1.10 diff -u -r1.10 i386nbsd-nat.c --- i386nbsd-nat.c 5 Jan 2002 18:36:32 -0000 1.10 +++ i386nbsd-nat.c 9 May 2002 23:33:59 -0000 @@ -39,7 +39,7 @@ #include "gregset.h" /* Prototypes for i387_supply_fsave etc. */ -#include "i387-nat.h" +#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 -u -r1.9 i386v4-nat.c --- i386v4-nat.c 13 Feb 2002 08:10:30 -0000 1.9 +++ i386v4-nat.c 9 May 2002 23:33:59 -0000 @@ -27,7 +27,7 @@ #ifdef HAVE_SYS_REG_H #include #endif -#include "i387-nat.h" +#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 6 May 2002 11:39:51 -0000 1.10 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -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); - } - } -} 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 +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. */ - -#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 */ Index: i387-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/i387-tdep.c,v retrieving revision 1.16 diff -u -r1.16 i387-tdep.c --- i387-tdep.c 12 Nov 2001 22:27:35 -0000 1.16 +++ i387-tdep.c 9 May 2002 23:33:59 -0000 @@ -388,3 +388,327 @@ 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) + { + 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); + } + } +} 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 9 May 2002 23:33:59 -0000 @@ -0,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.11 diff -u -r1.11 x86-64-linux-nat.c --- x86-64-linux-nat.c 7 May 2002 11:22:54 -0000 1.11 +++ x86-64-linux-nat.c 9 May 2002 23:34:00 -0000 @@ -25,7 +25,7 @@ #include "inferior.h" #include "gdbcore.h" #include "regcache.h" -#include "i387-nat.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 -u -r1.11 fbsd.mh --- config/i386/fbsd.mh 31 Mar 2002 17:47:17 -0000 1.11 +++ config/i386/fbsd.mh 9 May 2002 23:34:00 -0000 @@ -4,4 +4,4 @@ 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 +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 -u -r1.5 go32.mh --- config/i386/go32.mh 18 Jan 2002 04:50:59 -0000 1.5 +++ config/i386/go32.mh 9 May 2002 23:34:01 -0000 @@ -7,7 +7,7 @@ XM_FILE= xm-go32.h NAT_FILE= nm-go32.h -NATDEPFILES= go32-nat.o i386-nat.o i387-nat.o +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.7 diff -u -r1.7 i386gnu.mh --- config/i386/i386gnu.mh 24 Apr 2002 21:44:47 -0000 1.7 +++ config/i386/i386gnu.mh 9 May 2002 23:34:01 -0000 @@ -1,5 +1,5 @@ # Host: Intel 386 running the GNU Hurd -NATDEPFILES= i386gnu-nat.o i387-nat.o gnu-nat.o corelow.o core-regset.o \ +NATDEPFILES= i386gnu-nat.o gnu-nat.o corelow.o core-regset.o \ fork-child.o solib.o solib-svr4.o solib-legacy.o \ notify_S.o process_reply_S.o msg_reply_S.o \ msg_U.o exc_request_U.o exc_request_S.o Index: config/i386/i386sol2.mh =================================================================== RCS file: /cvs/src/src/gdb/config/i386/i386sol2.mh,v retrieving revision 1.4 diff -u -r1.4 i386sol2.mh --- config/i386/i386sol2.mh 14 Feb 2002 08:13:33 -0000 1.4 +++ config/i386/i386sol2.mh 9 May 2002 23:34:01 -0000 @@ -4,5 +4,5 @@ XM_CLIBS= -lsocket -lnsl NAT_FILE= nm-i386sol2.h -NATDEPFILES= core-regset.o fork-child.o i386v4-nat.o i387-nat.o corelow.o \ +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 -u -r1.7 i386v42mp.mh --- config/i386/i386v42mp.mh 11 Apr 2002 18:13:21 -0000 1.7 +++ config/i386/i386v42mp.mh 9 May 2002 23:34:01 -0000 @@ -14,7 +14,7 @@ # 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 \ +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 -u -r1.11 linux.mh --- config/i386/linux.mh 18 Jan 2002 04:50:59 -0000 1.11 +++ config/i386/linux.mh 9 May 2002 23:34:01 -0000 @@ -4,7 +4,7 @@ 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 \ + 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 -u -r1.12 nbsd.mh --- config/i386/nbsd.mh 18 Jan 2002 04:50:59 -0000 1.12 +++ config/i386/nbsd.mh 9 May 2002 23:34:01 -0000 @@ -6,7 +6,7 @@ # 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 +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 -u -r1.8 nbsdelf.mh --- config/i386/nbsdelf.mh 18 Jan 2002 04:50:59 -0000 1.8 +++ config/i386/nbsdelf.mh 9 May 2002 23:34:01 -0000 @@ -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 Index: config/i386/obsd.mh =================================================================== RCS file: /cvs/src/src/gdb/config/i386/obsd.mh,v retrieving revision 1.2 diff -u -r1.2 obsd.mh --- config/i386/obsd.mh 18 Jan 2002 04:50:59 -0000 1.2 +++ config/i386/obsd.mh 9 May 2002 23:34:01 -0000 @@ -4,4 +4,4 @@ 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 +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 -u -r1.5 x86-64linux.mh --- config/i386/x86-64linux.mh 21 Feb 2002 12:48:36 -0000 1.5 +++ config/i386/x86-64linux.mh 9 May 2002 23:34:01 -0000 @@ -5,7 +5,7 @@ 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 \ + proc-service.o thread-db.o lin-lwp.o \ linux-proc.o gcore.o LOADLIBES = -ldl -rdynamic --y0Ed1hDcWxc3B7cn--