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]

[rfa(arm)/rfc] Eliminate HOST_{FLOAT,DOUBLE,...}_FORMAT


Hello,

The attatched should catch a few eyebrows :-)

The existing GDB tries to be smart about converting host/target floating 
point values - if it thinks that host-float == target-float then it just 
does a move instead of a conversion.

This patch eliminates the short cut.  Instead the conversion is always 
routed through floatformat_{to,from}_doublest().  The most telling 
comment and the reason this will probably catch a few eyebrows can be 
found in i387-tdep.c:

!   /* Avoid call to floatformat_to_doublest if possible to preserve as
!      much information as possible.  */

To me, the comment doesn't make sense.  If sizeof (host long double) == 
size of (target long double) and information is still being lost then I 
think floatformat_* has a bug.

As a side effect it also cleans up the ARM target-float -> 
target->double conversion so that it is more portable (well I think it is).

Comments?  Approval for the ARM part?  I can/should separate the arm 
part out.

	Andrew



2001-06-29  Andrew Cagney  <ac131313@redhat.com>

	* defs.h (HOST_LONG_DOUBLE_FORMAT): Delete macro.
	(HOST_DOUBLE_FORMAT): Ditto.
	(HOST_FLOAT_FORMAT): Ditto.
	* arm-tdep.c (SWAP_TARGET_AND_HOST): Delete macro.

	* findvar.c (extract_floating, store_floating): Always use
	floatformat_to_doublest and floatformat_from_doublest.
	* i387-tdep.c (print_i387_value): Ditto.
	* arm-tdep.c (arm_push_arguments): Ditto.
	* arm-linux-tdep.c (arm_linux_push_arguments): Ditto.  Use target
	and not host float formats.
	
	* config/arm/tm-arm.h: Include "floatformat.h".

Index: arm-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-linux-tdep.c,v
retrieving revision 1.8
diff -p -r1.8 arm-linux-tdep.c
*** arm-linux-tdep.c	2001/03/01 01:39:20	1.8
--- arm-linux-tdep.c	2001/06/29 05:44:41
*************** arm_linux_push_arguments (int nargs, val
*** 159,165 ****
      {
        int len;
        char *val;
-       double dbl_arg;
        CORE_ADDR regval;
        enum type_code typecode;
        struct type *arg_type, *target_type;
--- 159,164 ----
*************** arm_linux_push_arguments (int nargs, val
*** 182,192 ****
  	  /* Float argument in buffer is in host format.  Read it and 
  	     convert to DOUBLEST, and store it in target double.  */
  	  DOUBLEST dblval;
! 	  
  	  len = TARGET_DOUBLE_BIT / TARGET_CHAR_BIT;
! 	  floatformat_to_doublest (HOST_FLOAT_FORMAT, val, &dblval);
! 	  store_floating (&dbl_arg, len, dblval);
! 	  val = (char *) &dbl_arg;
  	}
  
        /* If the argument is a pointer to a function, and it is a Thumb
--- 181,190 ----
  	  /* Float argument in buffer is in host format.  Read it and 
  	     convert to DOUBLEST, and store it in target double.  */
  	  DOUBLEST dblval;
! 	  floatformat_to_doublest (TARGET_FLOAT_FORMAT, val, &dblval);
  	  len = TARGET_DOUBLE_BIT / TARGET_CHAR_BIT;
! 	  val = alloca (len);
! 	  floatformat_from_doublest (TARGET_DOUBLE_FORMAT, &dblval, val);
  	}
  
        /* If the argument is a pointer to a function, and it is a Thumb
Index: arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.12
diff -p -r1.12 arm-tdep.c
*** arm-tdep.c	2001/03/06 08:21:05	1.12
--- arm-tdep.c	2001/06/29 05:44:46
*************** struct frame_extra_info
*** 117,140 ****
  #define MAKE_THUMB_ADDR(addr)	((addr) | 1)
  #define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1)
  
- #define SWAP_TARGET_AND_HOST(buffer,len) 				\
-   do									\
-     {									\
-       if (TARGET_BYTE_ORDER != HOST_BYTE_ORDER)				\
- 	{								\
- 	  char tmp;							\
- 	  char *p = (char *)(buffer);					\
- 	  char *q = ((char *)(buffer)) + len - 1;		   	\
- 	  for (; p < q; p++, q--)				 	\
- 	    {								\
- 	      tmp = *q;							\
- 	      *q = *p;							\
- 	      *p = tmp;							\
- 	    }								\
- 	}								\
-     }									\
-   while (0)
- 
  /* Will a function return an aggregate type in memory or in a
     register?  Return 0 if an aggregate type can be returned in a
     register, 1 if it must be returned in memory.  */
--- 117,122 ----
*************** arm_push_arguments (int nargs, value_ptr
*** 1309,1315 ****
      {
        int len;
        char *val;
-       double dbl_arg;
        CORE_ADDR regval;
        enum type_code typecode;
        struct type *arg_type, *target_type;
--- 1291,1296 ----
*************** arm_push_arguments (int nargs, value_ptr
*** 1329,1350 ****
           calling the function.  */
        if (TYPE_CODE_FLT == typecode && REGISTER_SIZE == len)
  	{
! 	  float f;
! 	  double d;
! 	  char * bufo = (char *) &d;
! 	  char * bufd = (char *) &dbl_arg;
! 
! 	  len = sizeof (double);
! 	  f = *(float *) val;
! 	  SWAP_TARGET_AND_HOST (&f, sizeof (float));  /* adjust endianess */
! 	  d = f;
! 	  /* We must revert the longwords so they get loaded into the
! 	     the right registers. */
! 	  memcpy (bufd, bufo + len / 2, len / 2);
! 	  SWAP_TARGET_AND_HOST (bufd, len / 2);  /* adjust endianess */
! 	  memcpy (bufd + len / 2, bufo, len / 2);
! 	  SWAP_TARGET_AND_HOST (bufd + len / 2, len / 2); /* adjust endianess */
! 	  val = (char *) &dbl_arg;
  	}
  #if 1
        /* I don't know why this code was disable. The only logical use
--- 1310,1320 ----
           calling the function.  */
        if (TYPE_CODE_FLT == typecode && REGISTER_SIZE == len)
  	{
! 	  DOUBLEST d;
! 	  floatformat_to_doublest (TARGET_FLOAT_FORMAT, val, &d);
! 	  len = TARGET_DOUBLE_BIT / HOST_CHAR_BIT;
! 	  val = alloca (len);
! 	  floatformat_from_doublest (TARGET_DOUBLE_FORMAT, &d, val);
  	}
  #if 1
        /* I don't know why this code was disable. The only logical use
Index: defs.h
===================================================================
RCS file: /cvs/src/src/gdb/defs.h,v
retrieving revision 1.56
diff -p -r1.56 defs.h
*** defs.h	2001/06/28 04:31:36	1.56
--- defs.h	2001/06/29 05:44:51
*************** extern void store_address (void *, int, 
*** 1267,1303 ****
  
  extern void store_typed_address (void *buf, struct type *type, CORE_ADDR addr);
  
- /* Setup definitions for host and target floating point formats.  We need to
-    consider the format for `float', `double', and `long double' for both target
-    and host.  We need to do this so that we know what kind of conversions need
-    to be done when converting target numbers to and from the hosts DOUBLEST
-    data type.  */
- 
  /* This is used to indicate that we don't know the format of the floating point
     number.  Typically, this is useful for native ports, where the actual format
     is irrelevant, since no conversions will be taking place.  */
  
  extern const struct floatformat floatformat_unknown;
- 
- #if HOST_BYTE_ORDER == BIG_ENDIAN
- #ifndef HOST_FLOAT_FORMAT
- #define HOST_FLOAT_FORMAT &floatformat_ieee_single_big
- #endif
- #ifndef HOST_DOUBLE_FORMAT
- #define HOST_DOUBLE_FORMAT &floatformat_ieee_double_big
- #endif
- #else /* LITTLE_ENDIAN */
- #ifndef HOST_FLOAT_FORMAT
- #define HOST_FLOAT_FORMAT &floatformat_ieee_single_little
- #endif
- #ifndef HOST_DOUBLE_FORMAT
- #define HOST_DOUBLE_FORMAT &floatformat_ieee_double_little
- #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
--- 1267,1277 ----
Index: findvar.c
===================================================================
RCS file: /cvs/src/src/gdb/findvar.c,v
retrieving revision 1.19
diff -p -r1.19 findvar.c
*** findvar.c	2001/03/06 08:21:07	1.19
--- findvar.c	2001/06/29 05:44:52
*************** store_typed_address (void *buf, struct t
*** 290,302 ****
  
  
  /* 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 (void *addr, int len)
  {
--- 290,297 ----
  
  
  /* Extract a floating-point number from a target-order byte-stream at ADDR.
!    Returns the value as type DOUBLEST.  */
  
  DOUBLEST
  extract_floating (void *addr, int len)
  {
*************** extract_floating (void *addr, int len)
*** 304,342 ****
  
    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
      {
--- 299,313 ----
  
    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
      {
*************** store_floating (void *addr, int len, DOU
*** 351,382 ****
  {
    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
      {
--- 322,336 ----
  {
    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: i387-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i387-tdep.c,v
retrieving revision 1.9
diff -p -r1.9 i387-tdep.c
*** i387-tdep.c	2001/03/09 16:14:55	1.9
--- i387-tdep.c	2001/06/29 05:44:53
*************** static void
*** 160,181 ****
  print_i387_value (char *raw)
  {
    DOUBLEST value;
! 
!   /* Avoid call to floatformat_to_doublest if possible to preserve as
!      much information as possible.  */
! 
! #ifdef HAVE_LONG_DOUBLE
!   if (sizeof (value) == sizeof (long double)
!       && HOST_LONG_DOUBLE_FORMAT == &floatformat_i387_ext)
!     {
!       /* Copy straight over, but take care of the padding.  */
!       memcpy (&value, raw, FPU_REG_RAW_SIZE);
!       memset ((char *) &value + FPU_REG_RAW_SIZE, 0,
! 	      sizeof (value) - FPU_REG_RAW_SIZE);
!     }
!   else
! #endif
!     floatformat_to_doublest (&floatformat_i387_ext, raw, &value);
  
    /* We try to print 19 digits.  The last digit may or may not contain
       garbage, but we'd better print one too many.  We need enough room
--- 160,166 ----
  print_i387_value (char *raw)
  {
    DOUBLEST value;
!   floatformat_to_doublest (&floatformat_i387_ext, raw, &value);
  
    /* We try to print 19 digits.  The last digit may or may not contain
       garbage, but we'd better print one too many.  We need enough room
Index: config/arm/tm-arm.h
===================================================================
RCS file: /cvs/src/src/gdb/config/arm/tm-arm.h,v
retrieving revision 1.6
diff -p -r1.6 tm-arm.h
*** tm-arm.h	2001/03/14 23:23:09	1.6
--- tm-arm.h	2001/06/29 05:44:56
***************
*** 23,28 ****
--- 23,29 ----
  #define TM_ARM_H
  
  #include "regcache.h"
+ #include "floatformat.h"
  
  /* Forward declarations for prototypes.  */
  struct type;

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