This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
Re: extract_floating() vs floatformat_to_doublest()
- To: Andrew Cagney <ac131313 at cygnus dot com>
- Subject: Re: extract_floating() vs floatformat_to_doublest()
- From: Andrew Cagney <ac131313 at cygnus dot com>
- Date: Wed, 01 Aug 2001 19:00:00 -0400
- Cc: gdb at sources dot redhat dot com
- References: <3B687538.9020500@cygnus.com>
> Hello,
>
> Now that I've isolated the doublest code (doublest.[hc]), the next step is to rationalize the number of interfaces available for doing floating point conversion. Currently there are:
>
> floatformat_to_doublest()
> extract_floating()
> and
> floatformat_from_doublest()
> store_floating()
>
> I've two possabilities in mind:
>
> o dump extract/store floating
> (fixing floatformat_*_doublest())
>
> o dump floatformat_*_doublest
> (possibly replace *_floating()
> with extract,store_floatformat())
>
> my current preference is the former. Does anyone have a compelling argument for the latter?
To make this more concrete (and hopefully easier to understand :-) see
the attatched. It implements part of the former. It also illustrates
how everything should be routed through the host conversion routines
before falling back to the software FP conversion code.
Andrew
2001-08-01 Andrew Cagney <ac131313@redhat.com>
* doublest.c (convert_doublest_to_floatformat): Rename
floatformat_from_doublest. Make static.
(convert_floatformat_to_doublest): Rename floatformat_to_doublest.
Make static.
(floatformat_to_doublest): New function.
(floatformat_from_doublest): New function.
(host_float_format, host_double_format, host_long_double_format):
New static variables.
(store_floating, extract_floating): Always use
floatformat_to_doublest and floatformat_from_doublest.
* doublest.h (HOST_LONG_DOUBLE_FORMAT): Delete macro.
Index: doublest.c
===================================================================
RCS file: /cvs/src/src/gdb/doublest.c,v
retrieving revision 1.2
diff -p -r1.2 doublest.c
*** doublest.c 2001/08/01 22:11:43 1.2
--- doublest.c 2001/08/01 22:53:07
*************** get_field (unsigned char *data, enum flo
*** 104,113 ****
FROM is the address of the extended float.
Store the DOUBLEST in *TO. */
! void
! floatformat_to_doublest (const struct floatformat *fmt,
! const void *from,
! DOUBLEST *to)
{
unsigned char *ufrom = (unsigned char *) from;
DOUBLEST dto;
--- 104,113 ----
FROM is the address of the extended float.
Store the DOUBLEST in *TO. */
! static void
! convert_floatformat_to_doublest (const struct floatformat *fmt,
! const void *from,
! DOUBLEST *to)
{
unsigned char *ufrom = (unsigned char *) from;
DOUBLEST dto;
*************** ldfrexp (long double value, int *eptr)
*** 325,334 ****
and store where TO points. Neither FROM nor TO have any alignment
restrictions. */
! void
! floatformat_from_doublest (CONST struct floatformat *fmt,
! const DOUBLEST *from,
! void *to)
{
DOUBLEST dfrom;
int exponent;
--- 325,334 ----
and store where TO points. Neither FROM nor TO have any alignment
restrictions. */
! static void
! convert_doublest_to_floatformat (CONST struct floatformat *fmt,
! const DOUBLEST *from,
! void *to)
{
DOUBLEST dfrom;
int exponent;
*************** floatformat_mantissa (const struct float
*** 533,592 ****
! /* Extract a floating-point number from a target-order byte-stream at ADDR.
! Returns the value as type DOUBLEST.
! If the host and target formats agree, we just copy the raw data into the
! appropriate type of variable and return, letting the host increase precision
! as necessary. Otherwise, we call the conversion routine and let it do the
! dirty work. */
DOUBLEST
extract_floating (const void *addr, int len)
{
DOUBLEST dretval;
-
if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT)
{
! if (HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT)
! {
! float retval;
!
! memcpy (&retval, addr, sizeof (retval));
! return retval;
! }
! else
! floatformat_to_doublest (TARGET_FLOAT_FORMAT, addr, &dretval);
}
else if (len * TARGET_CHAR_BIT == TARGET_DOUBLE_BIT)
{
! if (HOST_DOUBLE_FORMAT == TARGET_DOUBLE_FORMAT)
! {
! double retval;
!
! memcpy (&retval, addr, sizeof (retval));
! return retval;
! }
! else
! floatformat_to_doublest (TARGET_DOUBLE_FORMAT, addr, &dretval);
}
else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT)
{
! if (HOST_LONG_DOUBLE_FORMAT == TARGET_LONG_DOUBLE_FORMAT)
! {
! DOUBLEST retval;
!
! memcpy (&retval, addr, sizeof (retval));
! return retval;
! }
! else
! floatformat_to_doublest (TARGET_LONG_DOUBLE_FORMAT, addr, &dretval);
}
else
{
error ("Can't deal with a floating point number of %d bytes.", len);
}
-
return dretval;
}
--- 533,634 ----
! /* Convert TO/FROM target to the hosts DOUBLEST floating-point format.
!
! If the host and target formats agree, we just copy the raw data
! into the appropriate type of variable and return, letting the host
! increase precision as necessary. Otherwise, we call the conversion
! routine and let it do the dirty work. */
!
! #ifndef HOST_FLOAT_FORMAT
! #define HOST_FLOAT_FORMAT 0
! #endif
! #ifndef HOST_DOUBLE_FORMAT
! #define HOST_DOUBLE_FORMAT 0
! #endif
! #ifndef HOST_LONG_DOUBLE_FORMAT
! #define HOST_LONG_DOUBLE_FORMAT 0
! #endif
!
! static const struct floatformat *host_float_format = HOST_FLOAT_FORMAT;
! static const struct floatformat *host_double_format = HOST_DOUBLE_FORMAT;
! static const struct floatformat *host_long_double_format = HOST_LONG_DOUBLE_FORMAT;
!
! void
! floatformat_to_doublest (const struct floatformat *fmt,
! const void *in, DOUBLEST *out)
! {
! gdb_assert (fmt != NULL);
! if (fmt == host_float_format)
! {
! float val;
! memcpy (&val, in, sizeof (val));
! *out = val;
! }
! else if (fmt == host_double_format)
! {
! double val;
! memcpy (&val, in, sizeof (val));
! *out = val;
! }
! else if (fmt == host_long_double_format)
! {
! long double val;
! memcpy (&val, in, sizeof (val));
! *out = val;
! }
! else
! convert_floatformat_to_doublest (fmt, in, out);
! }
!
! void
! floatformat_from_doublest (const struct floatformat *fmt,
! const DOUBLEST *in, void *out)
! {
! gdb_assert (fmt != NULL);
! if (fmt == host_float_format)
! {
! float val = *in;
! memcpy (out, &val, sizeof (val));
! }
! else if (fmt == host_double_format)
! {
! double val = *in;
! memcpy (out, &val, sizeof (val));
! }
! else if (fmt == host_long_double_format)
! {
! long double val = *in;
! memcpy (out, &val, sizeof (val));
! }
! else
! convert_doublest_to_floatformat (fmt, in, out);
! }
!
! /* Extract/store a floating-point number from a target-order
! byte-stream at ADDR. Returns the value as type DOUBLEST. */
DOUBLEST
extract_floating (const void *addr, int len)
{
DOUBLEST dretval;
if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT)
{
! floatformat_to_doublest (TARGET_FLOAT_FORMAT, addr, &dretval);
}
else if (len * TARGET_CHAR_BIT == TARGET_DOUBLE_BIT)
{
! floatformat_to_doublest (TARGET_DOUBLE_FORMAT, addr, &dretval);
}
else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT)
{
! floatformat_to_doublest (TARGET_LONG_DOUBLE_FORMAT, addr, &dretval);
}
else
{
error ("Can't deal with a floating point number of %d bytes.", len);
}
return dretval;
}
*************** store_floating (void *addr, int len, DOU
*** 595,626 ****
{
if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT)
{
! if (HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT)
! {
! float floatval = val;
!
! memcpy (addr, &floatval, sizeof (floatval));
! }
! else
! floatformat_from_doublest (TARGET_FLOAT_FORMAT, &val, addr);
}
else if (len * TARGET_CHAR_BIT == TARGET_DOUBLE_BIT)
{
! if (HOST_DOUBLE_FORMAT == TARGET_DOUBLE_FORMAT)
! {
! double doubleval = val;
!
! memcpy (addr, &doubleval, sizeof (doubleval));
! }
! else
! floatformat_from_doublest (TARGET_DOUBLE_FORMAT, &val, addr);
}
else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT)
{
! if (HOST_LONG_DOUBLE_FORMAT == TARGET_LONG_DOUBLE_FORMAT)
! memcpy (addr, &val, sizeof (val));
! else
! floatformat_from_doublest (TARGET_LONG_DOUBLE_FORMAT, &val, addr);
}
else
{
--- 637,651 ----
{
if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT)
{
! floatformat_from_doublest (TARGET_FLOAT_FORMAT, &val, addr);
}
else if (len * TARGET_CHAR_BIT == TARGET_DOUBLE_BIT)
{
! floatformat_from_doublest (TARGET_DOUBLE_FORMAT, &val, addr);
}
else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT)
{
! floatformat_from_doublest (TARGET_LONG_DOUBLE_FORMAT, &val, addr);
}
else
{
Index: doublest.h
===================================================================
RCS file: /cvs/src/src/gdb/doublest.h,v
retrieving revision 1.2
diff -p -r1.2 doublest.h
*** doublest.h 2001/08/01 22:11:43 1.2
--- doublest.h 2001/08/01 22:53:07
*************** extern const struct floatformat floatfor
*** 53,62 ****
#endif
#endif
- #ifndef HOST_LONG_DOUBLE_FORMAT
- #define HOST_LONG_DOUBLE_FORMAT &floatformat_unknown
- #endif
-
/* Use `long double' if the host compiler supports it. (Note that this is not
necessarily any longer than `double'. On SunOS/gcc, it's the same as
double.) This is necessary because GDB internally converts all floating
--- 53,58 ----