This is the mail archive of the gdb@sources.redhat.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: extract_floating() vs floatformat_to_doublest()


> 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 ----

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