This is the mail archive of the gdb-patches@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]

[rfc] revamp floatformat_{to,from}_doublest() {fetch,store}_floating()


Hello,

Per my posts on gdb@, this patch revamps the functions

	floatformat_to_doublest()
	floatformat_from_doublest()
and 
fetch_floating()
	store_floating()

so that they all consistently try to use host and then software when 
performing FP conversions.

I'll check this in in a few days (after I've also tried it on an x86 host).

	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/08 04:01:26
*************** 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/08 04:01:26
*************** 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]