* Re: x86 fpu
[not found] ` <npemerjigt.fsf@zwingli.cygnus.com>
@ 1999-10-19 16:43 ` Mark Kettenis
0 siblings, 0 replies; 2+ messages in thread
From: Mark Kettenis @ 1999-10-19 16:43 UTC (permalink / raw)
To: jimb; +Cc: hjl, gdb
From: Jim Blandy <jimb@cygnus.com>
Date: 19 Oct 1999 13:47:30 -0500
> I saw some changes for x86. But I didn't see changes to enable x86
> FPU support on Linux. Is that true?
That's right. See the prior discussion on this list. I'm still
soliciting comments from x86 maintainers on the code. Once people
have had a chance to look it over, then we'll be adding generic x86
FPU support, which Linux will use.
But some FPU support is already present in the current code. You
should be able to look at the FPU registers (via the "info registers"
command or their individual names) and modify their values. The "info
float" command won't work yet though. This should be fixed in the
near future by having the generic x86 FPU support that Jim is talking
about.
HJ, what else will have to happen with GDB before you will consider
dropping your special Linux GDB based on 4.17? IMHO we should make
sure that the Linux community starts doing their GDB development based
on the current CVS version as soom as possible.
Mark
From hjl@lucon.org Tue Oct 19 16:52:00 1999
From: hjl@lucon.org (H.J. Lu)
To: kettenis@wins.uva.nl (Mark Kettenis)
Cc: gdb@sourceware.cygnus.com
Subject: Re: x86 fpu
Date: Tue, 19 Oct 1999 16:52:00 -0000
Message-id: <19991019235249.917DC1B494@ocean.lucon.org>
References: <199910192343.BAA00273@delius.kettenis.local>
X-SW-Source: 1999-q4/msg00061.html
Content-length: 640
>
> HJ, what else will have to happen with GDB before you will consider
> dropping your special Linux GDB based on 4.17? IMHO we should make
> sure that the Linux community starts doing their GDB development based
> on the current CVS version as soom as possible.
>
My Linux gdb has supports for
1. x86 fpu.
2. "better" x86 hw watchpoint. It is different from the normal x86
hw watchpoint which I don't like.
3. linuxthreads support for alpha and powerpc.
4. regex in glibc 2.
I have patches for #2, #3 and #4. Since there is a backlog for
x86 changes, I want to wait until #1 is done before I submit them.
--
H.J. Lu (hjl@gnu.org)
From jimb@cygnus.com Tue Oct 19 21:23:00 1999
From: Jim Blandy <jimb@cygnus.com>
To: jtc@redback.com
Cc: gdb@sourceware.cygnus.com
Subject: Re: Unifying the x86 FPU register sets
Date: Tue, 19 Oct 1999 21:23:00 -0000
Message-id: <np4sfmk6dq.fsf@zwingli.cygnus.com>
References: <199910151716.MAA03441@zwingli.cygnus.com> <5m7lkks1wi.fsf@jtc.redbacknetworks.com> <npvh84j7t2.fsf@zwingli.cygnus.com> <5mwvsjoyu0.fsf@jtc.redbacknetworks.com>
X-SW-Source: 1999-q4/msg00062.html
Content-length: 1192
> Jim> Yes. It's my understanding that we can accomplish this with the
> Jim> gdbarch mechanism.
>
> I was checking the rs6000/powerpc target (the other target I'm most
> familiar with), and NUM_REGS and REGISTER_BYTES are both set to the
> largest number for any powerpc varient. There is no REGISTER_NAMES
> array, being replaced by a REGISTER_NAME() function which returns ""
> for registers not present for the selected varient. This seems a
> easy enough thing to do now before adding HAVE_FPU_REGS, etc. to
> derived target's tm-* headers.
I'm concerned about changing NUM_REGS for x86 targets which are not
actively maintained, or whose maintainers aren't participating in this
discussion. I would like to be able to promise, "If you haven't
changed your target's code, then all the changes visible to your
configuration should be backwards-compatible."
I don't see how to do that without parameterizing the register file.
Perhaps the two parameters I chose --- HAVE_I387_REGS and
HAVE_SSE_REGS --- are not the best; perhaps simply something like
EXPANDED_I386_REGISTER_FILE, enabling the full set, would be better.
If you can see another way to deal with this, I'm all ears.
From jimb@cygnus.com Tue Oct 19 21:28:00 1999
From: Jim Blandy <jimb@cygnus.com>
To: hjl@lucon.org (H.J. Lu)
Cc: gdb@sourceware.cygnus.com
Subject: Hardware watchpoints
Date: Tue, 19 Oct 1999 21:28:00 -0000
Message-id: <np3dv6k64w.fsf@zwingli.cygnus.com>
References: <19991019235249.917DC1B494@ocean.lucon.org>
X-SW-Source: 1999-q4/msg00063.html
Content-length: 625
> My Linux gdb has supports for ...
> 2. "better" x86 hw watchpoint. It is different from the normal x86
> hw watchpoint which I don't like.
I wonder, would it be possible to watch expressions like foo.x by
having can_use_hardware_watchpoint ignore lval_memory values which are
still lazy? If a value is lazy, that means GDB never actually fetched
it, but instead just used its address.
Evaluating the expression foo.x, I think, produces two values: one for
'foo', which is lazy, and a second for the '.x' member of the first
value, which is no longer lazy.
This would remove the need for part of H.J.'s change, I think.
From Peter.Schauer@regent.e-technik.tu-muenchen.de Wed Oct 20 01:40:00 1999
From: "Peter.Schauer" <Peter.Schauer@regent.e-technik.tu-muenchen.de>
To: capveg@cs.umd.edu (Rob)
Cc: gdb@sourceware.cygnus.com, capveg@cs.umd.edu
Subject: Re: fix to noexec_user_stack on solaris 2.{6,7}
Date: Wed, 20 Oct 1999 01:40:00 -0000
Message-id: <199910200839.KAA17702@reisser.regent.e-technik.tu-muenchen.de>
References: <199910192229.SAA04909@xor.cs.umd.edu>
X-SW-Source: 1999-q4/msg00064.html
Content-length: 1835
This will break calling of functions that return a structure or union.
As per sparc calling conventions the call must looks like this:
call fun,0
nop
unimp <size of returned struct>
Setting CALL_DUMMY_LOCATION to AT_ENTRY_POINT doesn't handle this case.
When I was looking at the problem a long time ago, I had no idea how to
solve it properly.
> [Initial apologies if this has been dealt with. I wasn't able
> to find a FAQ, and a searches for "noexec" and "user stack" turned
> up nothing]
>
> Hi,
>
> I recently started running my solaris 2.6 boxes with the
> noexec_user_stack option that prevents anyone from executing code
> off of the data segment of a process. This is a great security
> feature, and has been relatively painless. I ran into a problem
> with the gdb feature "call" and "print proc()", but seem to
> have gotten around it by putting:
>
> #define CALL_DUMMY_LOCATION AT_ENTRY_POINT
> #define CALL_DUMMY_ADDRESS() entry_point_address ()
>
> at the end of gdb-4.18/gdb/config/sparc/tm-sun4sol2.h
>
> So my questions are:
> - has someone already fixed this, and I have a shiny new wheel?
> - is this a proper fix? I have read only enough of the gdb code
> to get this working...
> - does this break anything else my limited tests
> haven't found?
> - would it be possible/advisable to get a ./configure
> option of "--non-executable-data-stack" to
> enable this? I know linux has a similar patch
> to turn of the user stack, so this is useful
> for other architectures.
>
> Assuming I am on the right track, I can submit a patch. I
> just wanted to get some sanity checks first :)~
>
> TIA, and for what its worth, gdb is a great program, so thanks!
>
>
> - Rob
> .
>
>
>
>
--
Peter Schauer pes@regent.e-technik.tu-muenchen.de
From eliz@gnu.org Wed Oct 20 06:47:00 1999
From: Eli Zaretskii <eliz@gnu.org>
To: Jim Blandy <jimb@cygnus.com>
Cc: gdb@sourceware.cygnus.com
Subject: Re: Unifying the x86 FPU register sets
Date: Wed, 20 Oct 1999 06:47:00 -0000
Message-id: <199910201347.JAA28369@mescaline.gnu.org>
References: <199910151716.MAA03441@zwingli.cygnus.com> <5m7lkks1wi.fsf@jtc.redbacknetworks.com> <npvh84j7t2.fsf@zwingli.cygnus.com> <5mwvsjoyu0.fsf@jtc.redbacknetworks.com>
X-SW-Source: 1999-q4/msg00065.html
Content-length: 7053
Sorry for the late start, but you guys caught me off-guard: this issue
lays dormant for such a long time that I began reading the messages
once every other day, then every third day...
Anyway, these comments are only by inspection of Jim's patch for now
(I will try to actually build GDB with these changes later this week):
1) Comment no.1:
+ #define FIRST_FPU_CTRL_REGNUM 24
+ #define FCTRL_REGNUM 24 /* FPU control word */
+ #define FPC_REGNUM 24 /* old name for FCTRL_REGNUM */
+ #define FSTAT_REGNUM 25 /* FPU status word */
+ #define FTAG_REGNUM 26 /* FPU register tag word */
+ #define FCS_REGNUM 27 /* FPU instruction's code segment selector
Why does this define an old name for the FP control register, but not
for the rest? If back-compatibility (a Good Idea, IMHO), then let's
be consistent. tm-go32.h has these:
#define FPCWD_REGNUM FPC_REGNUM
#define FPSWD_REGNUM 25 /* 80387 status register */
#define FPTWD_REGNUM 26 /* 80387 tag register */
#define FPIPO_REGNUM 29 /* 80387 instruction pointer offset reg */
#define FPIPS_REGNUM 27 /* 80387 instruction pointer selector reg */
#define FPOOS_REGNUM 30 /* 80387 operand pointer offset reg */
#define FPOPS_REGNUM 28 /* 80387 operand pointer selector reg */
However, if DJGPP is the only platform which defines anything beyond
FPC_REGNUM, then we may stop bothering about the rest (DJGPP itself
doesn't use any of the rest, even though they are defined).
2) Comment no.2:
! #define REGISTER_VIRTUAL_TYPE(N) \
! (((N) == PC_REGNUM || (N) == FP_REGNUM || (N) == SP_REGNUM) \
! ? lookup_pointer_type (builtin_type_void) \
! : IS_FP_REGNUM(N) ? builtin_type_double \
! : IS_SSE_REGNUM(N) ? builtin_type_v4sf \
! : builtin_type_int)
Why are FP registers treated as type `double'? x87 uses long double,
not double, and tm-go32.h says this:
#define REGISTER_VIRTUAL_TYPE(N) \
((N < FP0_REGNUM) ? builtin_type_int : \
(N < FPC_REGNUM) ? builtin_type_long_double : builtin_type_int)
i386-tdep.c clearly uses 10 bytes when it initializes
i386_register_byte[], so I gather that other x86 targets also support
the full 80-bit width of FP registers, right? Don't we want all the
80 bits in "info float"?
3) Comment no.3:
!
! #define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
! { \
! double val; \
! i387_to_double ((FROM), (char *)&val); \
! store_floating ((TO), TYPE_LENGTH (TYPE), val); \
! }
Same here: long double is not supported.
Also, if REGISTER_CONVERTIBLE(REGNUM) is zero, you could simply use
memcpy, it is faster.
This also applies to REGISTER_CONVERT_TO_RAW.
4) Several comments to Jim's message and the discussion that ensued:
Jim> Since we're doing our own layout, we have the opportunity to set
Jim> aside the weird packing used by the FSAVE instruction, and have the
Jim> registers hold something more meaningful. Thus, I've split out the
Jim> instruction segment selector and the opcode bits, previously
Jim> different bitfields of the $fcs register, into two separate
Jim> registers.
I think we need to discuss this a bit. Please note that the FP
registers are printed by GDB in two different ways: one is with the
command "info float", the other with "info all-registers". I agree
that "info float" should present the information in a manner suitable
for debugging numerical code, i.e., the opcode should be separated
from the instruction selector, and its missing 5 bits should be added
to the printed value; but I think that "info all-registers" should
print the registers *exactly* as the CPU stores them.
Of course, this comment is only relevant to how we _print_ the
registers, not how we maintain them internally.
Jim> The instruction (code) segment and offset are $fcs and $fcoff.
Jim> The data operand segment and offset are $fds and $fdoff.
I suggest $fcseg and $fcoff, $fdseg and $fdoff, instead. People who
work a lot with seg:off pairs will recofnise `seg', but not `s'.
Jim> I have not included support for the MMX or 3DNow! registers.
Jim> [...] I want to leave taht for a separate discussion.
I agree that MMX etc. is a separate problem. I would think that they
deserve a separate command, e.g. "info mmx", just like the FP
registers do.
(FWIW, the DJGPP debug infrastructure already supports MMX, it just
isn't exposed to GDB, since GDB doesn't yet know about MMX.)
Jim> We could make the control registers (except $fdoff and $fcoff)
Jim> sixteen-bit values. But that makes more work for platforms that do
Jim> use FSAVE's 32-bit format; I assume those are the majority.
AFAIK, FSAVE does use 32 bits to store the control, status and tag
words, but the high 16 bits are undefined. Isn't it dangerous to copy
all 32 bits to GDB's structures? The DJGPP version doesn't copy the
high 16 bits from the buffer stored by FSAVE; if other platforms do
that as well, we already have, in effect, 16-bit control registers.
Mark> For now, GDB on the Hurd will happily display what's in the
Mark> reserved bits that follow the control, status, and tag word
Mark> and the operand pointer segment selector in the data structure
Mark> used by FSAVE and FRESTOR
I don't think this is right. A user should see only the bits that are
defined by the CPU spec. For all we know, the rest might be random
junk.
The DJGPP version displays 16 bits only for these registers.
Jim> [...] the new SSE FXSAVE and FXRSTOR instructions save state in
Jim> a different format, incompatible with FSAVE and FRSTOR, so
Jim> either the OS interfaces will be changing, or the old ones will
Jim> be emulated by code which changes from day to day.
There's another possibility: to use FXSAVE/FXRSTOR only for commands
that handle the SSE XMMi registers, and leave the current code for the
rest. That way, we don't need to bother about reconciling the two
formats.
Mark> So Intel has come up with yet another set of special purpose
Mark> instructions that diddle with the floating point stuff?
Not only FXSAVE uses a different layout of the saved state, it also
does NOT perform the equivalent of FINIT. In other words, it saves
the state without changing it, so you don't need to FXRSTOR right
after it, in case you need to preserve the state.
Jim> I'm curious what Linux decides to do with the P-III support.
I'm confused--why is this relevant? Are you talking about changes
that could affect how ptrace lays out the FP registers? If not, what
do we care about Linux support of Pentium III?
Mark> What remains to be written is the function that prints the
Mark> output for the "info float" command.
Jim> I'm easy to please here, but Eli Zaretskii had opinions on how
Jim> this ought to work
I suggest to look at the thread we had discussing this back then. If
memory serves, I posted a suggestion for the format of "info float",
based on Bill Metzenthen's code originally written for i387-tdep.c.
And let's not forget that "info all-registers" also prints the FP
registers, but in a different form.
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: x86 fpu
[not found] <199910210657.XAA08245@andros.cygnus.com>
@ 1999-10-21 7:50 ` H.J. Lu
0 siblings, 0 replies; 2+ messages in thread
From: H.J. Lu @ 1999-10-21 7:50 UTC (permalink / raw)
To: Stan Shebs; +Cc: jtc, gdb
>
>
> Date: Wed, 20 Oct 1999 23:06:00 -0700 (PDT)
> From: hjl@lucon.org (H.J. Lu)
>
> [...] It is a pain for me to maintain my
> private versions. But I hate to see the Linux people nowhere to
> go for help. Do you really honestly believe that a new official
> version should be made whenever a serious Linux related bug is
> fixed or we have to live with the bug which mainly affects Linux?
>
> That's not necessarily a bad idea... If one were to look at which
> platform has the largest number of GDB-using programmers these days,
> it would most likely be GNU/Linux by far. Why can't the GDB release
Please also remember that the GNU tools are the only ones GNU/Linux
get. If they don't work for us, we have to find a workaround one way
or the other.
> schedule be adjusted to accommodate the majority of users?
I am glad to see it is happening for gdb. Finally I can get rid of my
Linux version of gdb. I wish I could say the same for other tools.
BTW, I have sent in a patch for cplus-dem.c to the gcc patches mailing
list. It is/will be used by some of GNU/Linux tools. However, I have
a feeling that it will take forever to get accepted.
>
> I have been sending my patches to the appropriate people. But they
> don't work only for Linux. My patches have to wait, but Linux cann't.
> It is not that unusual to take a few months or more for my patches
> to be installed. What do we do?
>
> This is the genesis of the situation. Patch submissions should be
> acted upon promptly, whether to accept or reject. It's my
> responsibility to see that this happens, and if I fail at that,
> I'm not going to fault anyone for coming up with workarounds like
> splinter versions.
Sometimes, it takes a splinter version to get things done and we have
to take the consequences. I am not proud of the Linux C library 5. I
wish it had never happened. But without it, we may never have Linux
nor glibc 2 today.
>
> I hope everybody agrees that patch turnaround has improved over the
> past several months. It's still not where it should be; if you feel a
> worthy patch is being ignored, please send me mail with lots of
> capital letters and exclamation points, or call me on the phone at
> +1 408 542 9678.
I will send in a few patches after x86 fpu is resolved.
>
> I will work with everyone to merge my changes. But it doesn't mean
> I will stop working for the Linux community. We have different
> priorities. That is life.
>
> This should not be true however. I used to think this myself, until
> RMS pointed out that since Linux is one of the official kernels for
> the GNU system, GDB support for it ought to be a higher priority than
> support for non-GNU systems. Of course, GDB is still free software
> like always, and I still want to encourage people to contribute
> improvements for non-GNU systems as well.
>
> Lately, Jim Blandy and Jim Kingdon have stepped up to the task of
> making sure the FSF version of GDB is fully functional for GNU/Linux,
> and there has been considerable progress, as witness the discussion of
> x86 float support. Also, Scott Bambrough has been hard at work on
> Netwinder (ARM) support, and Kevin Buettner is on PowerPC. At this
> rate, I expect that the upcoming 5.0 release will be the version of
> choice for GNU/Linux.
First is glibc, now is gdb. What are the next? binutils and gcc? I
am not holding my breath.
Thanks.
--
H.J. Lu (hjl@gnu.org)
From eliz@gnu.org Thu Oct 21 08:20:00 1999
From: Eli Zaretskii <eliz@gnu.org>
To: Mark Kettenis <kettenis@wins.uva.nl>
Cc: jtc@redback.com, jimb@cygnus.com, gdb@sourceware.cygnus.com
Subject: Re: Unifying the x86 FPU register sets
Date: Thu, 21 Oct 1999 08:20:00 -0000
Message-id: <199910211520.LAA21979@mescaline.gnu.org>
References: <199910151716.MAA03441@zwingli.cygnus.com> <5mwvsjoyu0.fsf@jtc.redbacknetworks.com> <199910211332.PAA00729@delius.kettenis.local>
X-SW-Source: 1999-q4/msg00094.html
Content-length: 822
> Note that in `tm-go32.h' there is a
>
> #undef TARGET_LONG_DOUBLE_BIT
> #define TARGET_LONG_DOUBLE_BIT 96
>
> So DJGPP is already treating the 80-bit extended types as a 96-bit
> type.
Why, of course! ;-) That's because somebody noticed, a long time ago,
that this is required in order to get 80-bit registers supported.
> Then it will be very easy to support the i387 data registers as `long
> doubles' on hosts that have an equivalent type, without the LD_387
> kludge that's now used by DJGPP and Linux/i386.
I'm not sure. There's a related issue of whether the library supports
long double in scanf and printf families of functions. (There's also
the issue of the compiler support for long double, but it's a
non-issue for DJGPP and Linux ;-)
Would your suggestion handle all of these considerations?
From Grant.Edwards@comtrol.com Thu Oct 21 09:03:00 1999
From: Grant.Edwards@comtrol.com
To: gdb@sourceware.cygnus.com
Subject: RDI target issues
Date: Thu, 21 Oct 1999 09:03:00 -0000
Message-id: <19991021110315.A3542@comtrol.com>
X-SW-Source: 1999-q4/msg00095.html
Content-length: 1431
I've been working on getting gdb 4.18 (arm-elf) to work with the
rdi target. I've had to make some changes to the rdi library
code from ARM (in the rdi-share directory):
1) Disable heartbeat functionality, since it makes the JTAG
interface boxes from both ARM and EPI fall over..
2) Fix the code that was throwing away error codes returned
by the JTAG boxes with the "stopped" message.
3) Added a considerable amount of logging functionality (this
still needs to be cleaned up and made run-timeconfigurable).
I've also had to make changes to gdb code in remote-rdi.c::
1) Make sure the ADP device is closed before attempting to
open it.
2) Allow target options to be passed to Adp_OpenDevice.
3) Changed the way that log messages from remote are handled
(this goes along with #3 above, and still needs work).
4) Disable automatic setting of breakpoints on interrupt
vectors.
Question:
Change 4 only needs to happen if the target platform has ROM at
address 0. Otherwise, (RAM ad address 0) the old behavior is
probably best. How should this option be configured by the
user? Right now, the parameters to the "target rdi" gdb
command are just passed on to the Adp_OpenDevice routine from
ARM. I could parse those options and strip out the ones I want
to handle in remote-rdi.c before passing them on to the RDI
library.
Comments?
--
Grant Edwards
Grant.Edwards@comtrol.com
From kettenis@wins.uva.nl Thu Oct 21 09:13:00 1999
From: Mark Kettenis <kettenis@wins.uva.nl>
To: eliz@gnu.org
Cc: jtc@redback.com, jimb@cygnus.com, gdb@sourceware.cygnus.com
Subject: Re: Unifying the x86 FPU register sets
Date: Thu, 21 Oct 1999 09:13:00 -0000
Message-id: <199910211613.SAA03931@delius.kettenis.local>
References: <199910211504.LAA20217@mescaline.gnu.org>
X-SW-Source: 1999-q4/msg00096.html
Content-length: 1991
[ Sorry Eli, but I guess you know why you receive this message another
time ;-)]
Date: Thu, 21 Oct 1999 11:04:53 -0400
From: Eli Zaretskii <eliz@gnu.org>
< 5mwvsjoyu0.fsf@jtc.redbacknetworks.com > < 199910211332.PAA00729@delius.kettenis.local >
Subject: Re: Unifying the x86 FPU register sets
--text follows this line--
> Note that in `tm-go32.h' there is a
>
> #undef TARGET_LONG_DOUBLE_BIT
> #define TARGET_LONG_DOUBLE_BIT 96
>
> So DJGPP is already treating the 80-bit extended types as a 96-bit
> type.
Why, of course! ;-) That's because somebody noticed, a long time ago,
that this is required in order to get 80-bit registers supported.
Apparently the Linux people didn't notice it ;-).
> Then it will be very easy to support the i387 data registers as `long
> doubles' on hosts that have an equivalent type, without the LD_387
> kludge that's now used by DJGPP and Linux/i386.
I'm not sure. There's a related issue of whether the library supports
long double in scanf and printf families of functions. (There's also
the issue of the compiler support for long double, but it's a
non-issue for DJGPP and Linux ;-)
Would your suggestion handle all of these considerations?
Yes!
The nice thing is that GDB already has all the code that is necessary
to handle this. If the compiler doesn't support a 80/96-bit `long
double' type, the registers are converted to ordinary doubles right
away. Printing those should be no problem. If the compiler does
support a 80/96-bit `long double' type, the registers are padded to
96-bits. Before printing, these are converted to the representation
the host uses, taking in account endianness and other representation
details. If the library on the host supports printing long double
(PRINTF_HAS_LONG_DOUBLE) it is printed with full precision. If not,
then the result is converted to double before printing. See
valprint.c:print_floating() for details.
Mark
From kettenis@wins.uva.nl Thu Oct 21 09:34:00 1999
From: Mark Kettenis <kettenis@wins.uva.nl>
To: gdb@sourceware.cygnus.com
Cc: jtc@redback.com, jimb@cygnus.com, eliz@gnu.org, gdb-patches@sourceware.cygnus.com
Subject: x86 FPU support: "info float" and `long double'
Date: Thu, 21 Oct 1999 09:34:00 -0000
Message-id: <199910211634.SAA03952@delius.kettenis.local>
X-SW-Source: 1999-q4/msg00097.html
Content-length: 17926
OK, here is my attempt at implementing the "info float" comment and
prividing proper long double support without any hacks. Once this is
in we should remove the Linux-specific TARGET_{EXTRACT|STORE}_FLOATING
hooks that were introduced in findvar.c, and try to find a better
solution for TARGET_ANALYZE_FLOATING.
The output for "info float" is almost identical to DJGPP. The FP
registers are printed in physical order with "=>" indicating the top
of stack. Printing the opcode mnemonic is not so easy. I looked at
libopcode, but I could not find an appropriate entry-point.
Anyway, the output looks like:
(gdb) info float
status 0x3800: flags 0000; top 7;
control 0x37f: 64 bit; NEAR; mask INVAL DENOR DIVZ OVERF UNDER LOS;
last FP instruction: opcode 0xdd05; pc 0x23:0x8048495; operand 0x2b:0x8048f04
regno tag msb lsb value
=> 7: valid 4000c90fdaa22168c000 3.141592653589793116
6: empty 3ff7d100000000000000 0.006378173828125
5: empty 40098000000000000000 1024
4: empty 3fff8000000000000000 1
3: empty 3fff8000000000000000 1
2: empty 3ffb9d8909ff2e48e8c0 0.076921537494659423997
1: empty 3ffbdaf3e93361992eb3 0.10691053569844352396
0: empty 00000000000000000000 0
(gdb)
Suggestions for improvement are welcome!
I don't know if this stuff is ready for inclusion yet. Given the size
of the patch a copyright assignment is probably needed. I'll try to
assign past and future changes as soon as possible.
If Jim is still making changes to the register file layout, I'll keep
track of his changes and resend the patch.
Mark
1999-10-21 Mark Kettenis <kettenis@gnu.org>
* i387-tdep.c: Strip PARAMS.
(i387_float_info): New function.
(i387_register_virtual_type): New function.
(i387_register_convert_to_virtual, i387_register_convert_to_raw):
New functions.
(i387_extract_floating, i387_store_floating): Removed.
* config/i386/tm-i386.h (TARGET_LONG_DOUBLE_BIT,
TARGET_LONG_DOUBLE_FORMAT): New definitions.
TARGET_ANALYZE_FLOATING: Moved here from config/i386/tm-linux.h.
(i387_register_virtual_type): New declaration.
(REGISTER_VIRTUAL_TYPE): Call i387_register_virtual_type to get
data type of FP data registers.
(i387_to_double, double_to_i387): Removed declarations.
(i387_register_convert_to_virtual, i387_register_convert_to_raw):
New declarations.
(REGISTER_CONVERT_TO_VIRTUAL): Let
i387_register_convert_to_virtual handle the conversion.
(REGISTER_CONVERT_TO_RAW): Let i387_register_convert_to_raw handle
the conversion.
[HAVE_I387_REGS] (i387_float_info): New declaration.
[HAVE_I387_REGS] (FLOAT_INFO): New define.
* config/i386/tm-linux.h (TARGET_LONG_DOUBLE_BIT,
TARGET_EXTRACT_FLOATING, TARGET_STORE_FLOATING,
REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW,
REGISTER_VIRTUAL_TYPE): Remove definitions.
(TARGET_ANALYZE_FLOATING): Moved to config/i386/tm-i386.h.
(i387_extract_floating, i387_store_floating): Remove declarations.
(LD_I387): Do not define.
Index: gdb/gdb/i387-tdep.c
===================================================================
RCS file: /var/cvsroot/gdb/gdb/i387-tdep.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 i387-tdep.c
--- gdb/gdb/i387-tdep.c 1999/10/02 19:51:09 1.1.1.4
+++ gdb/gdb/i387-tdep.c 1999/10/21 15:57:28
@@ -1,5 +1,5 @@
/* Intel 387 floating point stuff.
- Copyright (C) 1988, 1989, 1991, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1989, 1991, 1998, 1999 Free Software Foundation, Inc.
This file is part of GDB.
@@ -26,34 +26,31 @@
#include "gdbcore.h"
#include "floatformat.h"
-void i387_to_double PARAMS ((char *, char *));
-void double_to_i387 PARAMS ((char *, char *));
+static void print_387_control_bits (unsigned int control);
+static void print_387_status_bits (unsigned int status);
-static void print_387_control_bits PARAMS ((unsigned int control));
-static void print_387_status_bits PARAMS ((unsigned int status));
+\f
+/* FIXME: Eliminate the next two functions when we have the time to
+ change all the callers. */
-/* FIXME: Eliminate these routines when we have the time to change all
- the callers. */
+void i387_to_double (char *from, char *to);
+void double_to_i387 (char *from, char *to);
void
-i387_to_double (from, to)
- char *from;
- char *to;
+i387_to_double (char *from, char *to)
{
floatformat_to_double (&floatformat_i387_ext, from, (double *) to);
}
void
-double_to_i387 (from, to)
- char *from;
- char *to;
+double_to_i387 (char *from, char *to)
{
floatformat_from_double (&floatformat_i387_ext, (double *) from, to);
}
+\f
static void
-print_387_control_bits (control)
- unsigned int control;
+print_387_control_bits (unsigned int control)
{
switch ((control >> 8) & 3)
{
@@ -108,9 +105,10 @@
local_hex_string (control & 0xe080));
}
+/* FIXME: Make this static once we have converted all i386 targets to
+ use the GDB register file. */
void
-print_387_control_word (control)
- unsigned int control;
+print_387_control_word (unsigned int control)
{
printf_filtered ("control %s:", local_hex_string(control & 0xffff));
print_387_control_bits (control);
@@ -118,8 +116,7 @@
}
static void
-print_387_status_bits (status)
- unsigned int status;
+print_387_status_bits (unsigned int status)
{
printf_unfiltered (" flags %d%d%d%d; ",
(status & 0x4000) != 0,
@@ -140,53 +137,141 @@
}
}
+/* FIXME: Make this static once we have converted all i386 targets to
+ use the GDB register file. */
void
-print_387_status_word (status)
- unsigned int status;
+print_387_status_word (unsigned int status)
{
printf_filtered ("status %s:", local_hex_string (status & 0xffff));
print_387_status_bits (status);
puts_unfiltered ("\n");
}
-#ifdef LD_I387
-int
-i387_extract_floating (PTR addr, int len, DOUBLEST *dretptr)
+/* Print out the i387 floating poin state. */
+void
+i387_float_info (void)
{
- if (len == TARGET_LONG_DOUBLE_BIT / 8)
+ unsigned int fctrl;
+ unsigned int fstat;
+ unsigned int ftag;
+ unsigned int fcs;
+ unsigned int fcoff;
+ unsigned int fds;
+ unsigned int fdoff;
+ unsigned int fop;
+ int fpreg;
+ int top;
+
+ read_register_gen (FCTRL_REGNUM, (char *) &fctrl);
+ read_register_gen (FSTAT_REGNUM, (char *) &fstat);
+ read_register_gen (FTAG_REGNUM, (char *) &ftag);
+ read_register_gen (FCS_REGNUM, (char *) &fcs);
+ read_register_gen (FCOFF_REGNUM, (char *) &fcoff);
+ read_register_gen (FDS_REGNUM, (char *) &fds);
+ read_register_gen (FDOFF_REGNUM, (char *) &fdoff);
+ read_register_gen (FOP_REGNUM, (char *) &fop);
+
+ print_387_status_word (fstat);
+ print_387_control_word (fctrl);
+ printf_unfiltered ("last FP instruction: ");
+ printf_unfiltered ("opcode %s; ",
+ local_hex_string (fop ? (fop | 0xd800) : 0));
+ printf_unfiltered ("pc %s:", local_hex_string (fcs));
+ printf_unfiltered ("%s; ", local_hex_string (fcoff));
+ printf_unfiltered ("operand %s", local_hex_string (fds));
+ printf_unfiltered (":%s\n", local_hex_string (fdoff));
+
+ top = ((fstat >> 11) & 7);
+
+ printf_unfiltered ("regno tag msb lsb value\n");
+ for (fpreg = 7; fpreg >= 0; fpreg--)
{
- if (HOST_LONG_DOUBLE_FORMAT == TARGET_LONG_DOUBLE_FORMAT)
- {
- DOUBLEST retval;
+ unsigned char raw[FPU_REG_RAW_SIZE];
+ DOUBLEST value;
+ int i;
+
+ printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
- memcpy (dretptr, addr, sizeof (retval));
+ switch ((ftag >> (fpreg * 2)) & 3)
+ {
+ case 0:
+ printf_unfiltered ("valid ");
+ break;
+ case 1:
+ printf_unfiltered ("zero ");
+ break;
+ case 2:
+ printf_unfiltered ("special ");
+ break;
+ case 3:
+ printf_unfiltered ("empty ");
+ break;
}
- else
- floatformat_to_doublest (TARGET_LONG_DOUBLE_FORMAT, addr, dretptr);
- return 1;
+ read_register_gen ((fpreg + 8 - top) % 8 + FP0_REGNUM, raw);
+
+ for (i = 9; i >= 0; i--)
+ printf_unfiltered ("%02x", raw[i]);
+
+ floatformat_to_doublest (&floatformat_i387_ext, raw, &value);
+
+#ifdef PRINTF_HAS_LONG_DOUBLE
+ printf_unfiltered (" %.20Lg\n", (long double) value);
+#else
+ printf_unfiltered (" %.20g\n", (double) value);
+#endif
}
- else
- return 0;
}
-int
-i387_store_floating (PTR addr, int len, DOUBLEST val)
+\f
+/* Return the "standard" data type of data in the FPU data registers.
+ We use `long double' if the host has them in a representation
+ equivalent with the i387 extended format, and `double' otherwise. */
+struct type *
+i387_register_virtual_type (void)
{
- if (len == TARGET_LONG_DOUBLE_BIT / 8)
- {
- /* This `if' may be totally stupid. I just put it in here to be
- absolutely sure I'm preserving the semantics of the code I'm
- frobbing, while I try to maintain portability boundaries; I
- don't actually know exactly what it's doing. -JimB, May 1999 */
- if (HOST_LONG_DOUBLE_FORMAT == TARGET_LONG_DOUBLE_FORMAT)
- memcpy (addr, &val, sizeof (val));
- else
- floatformat_from_doublest (TARGET_LONG_DOUBLE_FORMAT, &val, addr);
+#ifdef HAVE_LONG_DOUBLE
+ if (sizeof (long double) == (TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT))
+ return builtin_type_long_double;
+#endif
+ return builtin_type_double;
+}
- return 1;
+/* Convert REGNUM, which raw contents are stored in FROM to "standard"
+ data type TYPE and store the result into TO. */
+void
+i387_register_convert_to_virtual (int regnum, struct type *type,
+ char *from, char *to)
+{
+#ifdef HAVE_LONG_DOUBLE
+ if (type == builtin_type_long_double)
+ {
+ memset (to, 0, REGISTER_VIRTUAL_SIZE (regnum));
+ memcpy (to, from, REGISTER_RAW_SIZE (regnum));
}
+ else
+#endif
+ {
+ double val;
+ floatformat_to_double (&floatformat_i387_ext, from, &val);
+ floatformat_from_double (&floatformat_ieee_double_little, &val, to);
+ }
+}
+
+/* Convert the "standard" data type TYPE stored in FROM and store the
+ result in REGNUM whose raw contents live at TO. */
+void
+i387_register_convert_to_raw (struct type *type, int regnum,
+ char *from, char *to)
+{
+#ifdef HAVE_LONG_DOUBLE
+ if (type == builtin_type_long_double)
+ memcpy (to, from, REGISTER_RAW_SIZE (regnum));
else
- return 0;
+#endif
+ {
+ double val;
+ floatformat_to_double (&floatformat_ieee_double_little, from, &val);
+ floatformat_from_double (&floatformat_i387_ext, &val, to);
+ }
}
-#endif /* LD_I387 */
Index: gdb/gdb/config/i386/tm-i386.h
===================================================================
RCS file: /var/cvsroot/gdb/gdb/config/i386/tm-i386.h,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 tm-i386.h
--- gdb/gdb/config/i386/tm-i386.h 1999/10/20 10:44:05 1.1.1.7
+++ gdb/gdb/config/i386/tm-i386.h 1999/10/21 15:08:56
@@ -1,5 +1,5 @@
/* Macro definitions for GDB on an Intel i[345]86.
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc.
This file is part of GDB.
@@ -222,43 +222,75 @@
/* Largest value REGISTER_VIRTUAL_SIZE can have. */
#define MAX_REGISTER_VIRTUAL_SIZE 16
+/* Although the i387 has a 80-bit extended floating point type, almost
+ all systems supported by GCC use 96-bit and extra padding for
+ alignment. The exception seems to be OSF/1, where `long double' is
+ the same as `double', but there is no OSF/1 support in GDB. */
+#define TARGET_LONG_DOUBLE_BIT 96
+#define TARGET_LONG_DOUBLE_FORMAT &floatformat_i387_ext
+
+/* Detect NaNs for the i387 extended floating point format.
+ FIXME: This is not very well hought out and should be replaced by
+ NaN classification based on floatformat.h, fully integrated in GDB. */
+#define TARGET_ANALYZE_FLOATING \
+ do \
+ { \
+ if (len == 10) \
+ { \
+ unsigned expon; \
+ \
+ low = extract_unsigned_integer (valaddr, 4); \
+ high = extract_unsigned_integer (valaddr + 4, 4); \
+ expon = extract_unsigned_integer (valaddr + 8, 2); \
+ \
+ nonnegative = ((expon & 0x8000) == 0); \
+ is_nan = ((expon & 0x7fff) == 0x7fff) \
+ && ((high & 0x80000000) == 0x80000000) \
+ && (((high & 0x7fffffff) | low) != 0); \
+ } \
+ else \
+ is_nan = 0; \
+ } \
+ while (0)
+
/* Return the GDB type object for the "standard" data type of data in
register N. Perhaps si and di should go here, but potentially they
could be used for things other than address. */
+/* Return the "standard" data type of data in the FPU data registers.
+ We use `long double' if the host has them in a representation
+ equivalent with the i387 extended format, and `double' otherwise. */
+extern struct type *i387_register_virtual_type (void);
+
#define REGISTER_VIRTUAL_TYPE(N) \
(((N) == PC_REGNUM || (N) == FP_REGNUM || (N) == SP_REGNUM) \
? lookup_pointer_type (builtin_type_void) \
- : IS_FP_REGNUM(N) ? builtin_type_double \
+ : IS_FP_REGNUM(N) ? i387_register_virtual_type () \
: IS_SSE_REGNUM(N) ? builtin_type_v4sf \
: builtin_type_int)
+
+/* Convert the 80-bit FPU data registers to the "standard" data type
+ and back. */
+extern void i387_register_convert_to_virtual (int regnum, struct type *type,
+ char *from, char *to);
+extern void i387_register_convert_to_raw (struct type *type, int regnum,
+ char *from, char *to);
+
+#undef REGISTER_CONVERT_TO_VIRTUAL
+#define REGISTER_CONVERT_TO_VIRTUAL(regnum, type, from, to) \
+ i387_register_convert_to_virtual ((regnum), (type), (from), (to))
+
+#undef REGISTER_CONVERT_TO_RAW
+#define REGISTER_CONVERT_TO_RAW(type, regnum, from, to) \
+ i387_register_convert_to_raw ((type), (regnum), (from), (to))
-/* REGISTER_CONVERTIBLE(N) is true iff register N's virtual format is
- different from its raw format. Note that this definition assumes
- that the host supports IEEE 32-bit floats, since it doesn't say
- that SSE registers need conversion. Even if we can't find a
- counterexample, this is still sloppy. */
-#define REGISTER_CONVERTIBLE(n) (IS_FP_REGNUM (n))
-
-/* Convert data from raw format for register REGNUM in buffer FROM
- to virtual format with type TYPE in buffer TO. */
-extern void i387_to_double (char *, char *);
-
-#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
-{ \
- double val; \
- i387_to_double ((FROM), (char *)&val); \
- store_floating ((TO), TYPE_LENGTH (TYPE), val); \
-}
-
-extern void double_to_i387 (char *, char *);
-
-#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \
-{ \
- double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \
- double_to_i387((char *)&val, (TO)); \
-}
+/* Print out the i387 floating point state. */
+#ifdef HAVE_I387_REGS
+extern void i387_float_info (void);
+#define FLOAT_INFO { i387_float_info (); }
+#endif
+\f
/* Store the address of the place in which to copy the structure the
subroutine will return. This is called from call_function. */
Index: gdb/gdb/config/i386/tm-linux.h
===================================================================
RCS file: /var/cvsroot/gdb/gdb/config/i386/tm-linux.h,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 tm-linux.h
--- gdb/gdb/config/i386/tm-linux.h 1999/10/20 10:44:05 1.1.1.5
+++ gdb/gdb/config/i386/tm-linux.h 1999/10/21 15:09:22
@@ -1,5 +1,5 @@
/* Definitions to target GDB to GNU/Linux on 386.
- Copyright 1992, 1993 Free Software Foundation, Inc.
+ Copyright 1992, 1993, 1999 Free Software Foundation, Inc.
This file is part of GDB.
@@ -41,59 +41,6 @@
#define LOW_RETURN_REGNUM 0 /* holds low four bytes of result */
#define HIGH_RETURN_REGNUM 2 /* holds high four bytes of result */
-
-/* This should probably move to tm-i386.h. */
-#define TARGET_LONG_DOUBLE_BIT 80
-
-#if defined(HAVE_LONG_DOUBLE) && defined(HOST_I386)
-/* The host and target are i386 machines and the compiler supports
- long doubles. Long doubles on the host therefore have the same
- layout as a 387 FPU stack register. */
-#define LD_I387
-
-extern int i387_extract_floating (PTR addr, int len, long double *dretptr);
-extern int i387_store_floating (PTR addr, int len, long double val);
-
-#define TARGET_EXTRACT_FLOATING i387_extract_floating
-#define TARGET_STORE_FLOATING i387_store_floating
-
-#define TARGET_ANALYZE_FLOATING \
- do \
- { \
- unsigned expon; \
- \
- low = extract_unsigned_integer (valaddr, 4); \
- high = extract_unsigned_integer (valaddr + 4, 4); \
- expon = extract_unsigned_integer (valaddr + 8, 2); \
- \
- nonnegative = ((expon & 0x8000) == 0); \
- is_nan = ((expon & 0x7fff) == 0x7fff) \
- && ((high & 0x80000000) == 0x80000000) \
- && (((high & 0x7fffffff) | low) != 0); \
- } \
- while (0)
-
-#undef REGISTER_CONVERT_TO_VIRTUAL
-#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
-{ \
- long double val = *((long double *)FROM); \
- store_floating ((TO), TYPE_LENGTH (TYPE), val); \
-}
-
-#undef REGISTER_CONVERT_TO_RAW
-#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \
-{ \
- long double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \
- *((long double *)TO) = val; \
-}
-
-/* Return the GDB type object for the "standard" data type
- of data in register N. */
-#undef REGISTER_VIRTUAL_TYPE
-#define REGISTER_VIRTUAL_TYPE(N) \
- (IS_FP_REGNUM (N) ? builtin_type_long_double : builtin_type_int)
-
-#endif
/* The following works around a problem with /usr/include/sys/procfs.h */
#define sys_quotactl 1
From hjl@lucon.org Thu Oct 21 10:13:00 1999
From: hjl@lucon.org (H.J. Lu)
To: kettenis@wins.uva.nl (Mark Kettenis)
Cc: gdb@sourceware.cygnus.com, jtc@redback.com, jimb@cygnus.com, eliz@gnu.org, gdb-patches@sourceware.cygnus.com
Subject: Re: x86 FPU support: "info float" and `long double'
Date: Thu, 21 Oct 1999 10:13:00 -0000
Message-id: <19991021171307.87FEC1B493@ocean.lucon.org>
References: <199910211634.SAA03952@delius.kettenis.local>
X-SW-Source: 1999-q4/msg00098.html
Content-length: 2762
> (gdb) info float
> status 0x3800: flags 0000; top 7;
> control 0x37f: 64 bit; NEAR; mask INVAL DENOR DIVZ OVERF UNDER LOS;
> last FP instruction: opcode 0xdd05; pc 0x23:0x8048495; operand 0x2b:0x8048f04
> regno tag msb lsb value
> => 7: valid 4000c90fdaa22168c000 3.141592653589793116
> 6: empty 3ff7d100000000000000 0.006378173828125
> 5: empty 40098000000000000000 1024
> 4: empty 3fff8000000000000000 1
> 3: empty 3fff8000000000000000 1
> 2: empty 3ffb9d8909ff2e48e8c0 0.076921537494659423997
> 1: empty 3ffbdaf3e93361992eb3 0.10691053569844352396
> 0: empty 00000000000000000000 0
> (gdb)
>
> Suggestions for improvement are welcome!
>
My current gdb has
(gdb) info float
st0: 0x3ffed6d6d6d6d6d6d800 Empty Normal 0.8392156862745098200307
st1: 0x00000000000000000000 Empty Zero 0
st2: 0x00000000000000000000 Empty Zero 0
st3: 0x00000000000000000000 Empty Zero 0
st4: 0x00000000000000000000 Empty Zero 0
st5: 0x3ffe8000000000000000 Empty Normal 0.5
st6: 0x4003b000000000000000 Empty Normal 22
st7: 0x4003b000000000000000 Empty Normal 22
fctrl: 0x037f 64 bit; NEAR; mask INVAL DENOR DIVZ OVERF UNDER LOS;
fstat: 0x0000 flags 0000; top 0;
ftag: 0xffff
fip: 0x00000000
fcs: 0x00000000
fopoff: 0x00000000
fopsel: 0x0000
It is also the same as yours. However, I have an extra field for stack
register:
st0: 0x3ffed6d6d6d6d6d6d800 Empty Normal 0.8392156862745098200307
^^^^^^
It shouldn't be hard to add. I am enclosing the relevant code here.
H.J.
----
expon = extract_unsigned_integer (raw_regs + REGISTER_BYTE (regnum)
+ 8, 2);
sign = expon & 0x8000;
expon &= 0x7fff;
ms = extract_unsigned_integer (raw_regs + REGISTER_BYTE (regnum) + 4, 4);
ls = extract_signed_integer (raw_regs + REGISTER_BYTE (regnum), 4);
norm = ms & 0x80000000;
if ( expon == 0 )
{
if ( ms | ls )
{
/* Denormal or Pseudodenormal. */
if ( norm )
puts_unfiltered ("Pseudo ");
else
puts_unfiltered ("Denorm ");
}
else
{
/* Zero. */
puts_unfiltered ("Zero ");
}
}
else if ( expon == 0x7fff )
{
/* Infinity, NaN or unsupported. */
if ( (ms == 0x80000000) &&
(ls == 0) )
{
puts_unfiltered ("Infty ");
}
else if ( norm )
{
if ( ms & 0x40000000 )
puts_unfiltered ("QNaN ");
else
puts_unfiltered ("SNaN ");
}
else
{
puts_unfiltered ("Unsupp ");
}
}
else
{
/* Normal or unsupported. */
if ( norm )
puts_unfiltered ("Normal ");
else
puts_unfiltered ("Unsupp ");
}
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~1999-10-21 7:50 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <19991019182843.E7C093FC1@valinux.com>
[not found] ` <npemerjigt.fsf@zwingli.cygnus.com>
1999-10-19 16:43 ` x86 fpu Mark Kettenis
[not found] <199910210657.XAA08245@andros.cygnus.com>
1999-10-21 7:50 ` H.J. Lu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox