This is the mail archive of the gdb@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Unifying the x86 FPU register sets



I agree that the floating-point stuff in tm-linux.h is not the way it
should be.  Yes, the way LD_I387 and the conversion stuff are defined
isn't correct.  But for now, we should focus on getting tm-i386.h the
way we all want it.  If we do that right, then tm-linux.h will be
straightforward to fix.

I'm having a hard time following a lot of the discussion about
floating-point formats.  Here is my present understanding of
how things work; please correct me if I say something wrong.

There are three forms floating-point values can take on as they pass
through GDB:
- the register file form
- the `struct value' form
- the host DOUBLEST form

The register file form should be bit-for-bit identical with the way
the processor stores them, because the register file's role is to be a
direct reflection of the processor's state.  The REGISTER_RAW_SIZE
macro gives the number of bytes a floating-point value occupies in
this form.  GDB has no macro describing the types of registers in the
register file.

GDB uses the `struct value' form for variable values, intermediate
values in expression evaluation, and so on.  REGISTER_VIRTUAL_TYPE
gives the type of this form; REGISTER_CONVERTIBLE,
REGISTER_CONVERT_TO_VIRTUAL, and REGISTER_CONVERT_TO_RAW control the
conversion between the register file form and this form, done by
value_of_register, value_from_register, and value_assign.

GDB converts a `struct value' to the host DOUBLEST form whenever it
actually wants to operate on a floating-point value.  This conversion
is controlled by {TARGET,HOST}_LONG_DOUBLE_FORMAT and
TARGET_{EXTRACT,STORE}_FLOATING, and carried out by functions like
value_as_double, unpack_double, extract_floating, and store_floating.

(This last conversion is controversial, since it loses information;
ideally, GDB would perform the operations in the target's format,
using some software implementation of IEEE floating point arithmetic.)


It's worth noting that the first conversions, to and from the `struct
value' form, never need to be lossy, because `struct value' can hold
the value in raw target format.  REGISTER_VIRTUAL_TYPE just needs to
correctly describe the registers.



So, here's my understanding of folks' suggestions about tm-i386.h:

- REGISTER_VIRTUAL_TYPE should be some type from tm-i387.c, dedicated
  to describing FPU registers.  That way, it's not dependent on today's
  compiler's interpretation of `long double'.

- REGISTER_VIRTUAL_TYPE should be 12 bytes long, and
  REGISTER_CONVERT_TO_{VIRTUAL,RAW} should simply account for the
  position of the 10-byte value within the 12-byte space.

  It makes me a little uncomfortable to have REGISTER_VIRTUAL_TYPE
  specify a 12-byte size, while floatformat_i387_ext is a ten-byte
  format, but I think it should work fine.

- {TARGET,HOST}_LONG_DOUBLE_{FORMAT,BITS} should be defined as
  appropriate in the right tm-*.h and xm-*.h files, not in tm-i386.h.
  The latter doesn't know what compiler you're using, and so can't say
  how long its types are.

The implications carry on to Linux as follows:
 
- Once those definitions are corrected in tm-linux.h, the
  TARGET_{EXTRACT,STORE}_FLOATING macros will never be used, because
  the earlier clauses in extract_floating and store_floating will
  apply, so we can delete the TARGET_{EXTRACT,STORE}_FLOATING
  definitions from tm-linux.h.

- But tm-linux.h is the only target in GDB that defines them, so we
  can remove all references to them from GDB completely.


It looks like Mark's patch has already done this.  I'll take a look.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]