This is the mail archive of the gdb-cvs@sourceware.org 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]
Other format: [Raw text]

[binutils-gdb] Target FP: Handle interfaces to scripting languages


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=14ad9311720fc17bd646b2ff08483fe60a489959

commit 14ad9311720fc17bd646b2ff08483fe60a489959
Author: Ulrich Weigand <ulrich.weigand@de.ibm.com>
Date:   Mon Nov 6 16:00:47 2017 +0100

    Target FP: Handle interfaces to scripting languages
    
    The last remaing use for DOUBLEST is in the code that interfaces to the
    scripting languages (Python and Guile).  The problem here is that we
    expose interfaces to convert a GDB value to and from native values of
    floating-point type in those languages, and those by definition use
    the host floating-point format.
    
    While we cannot completely eliminate conversions to/from the host
    floating-point format here, we still need to get rid of the uses
    of value_as_double / value_from_double, since those will go away.
    
    This patch implements two new target-float.c routine:
     - target_float_to_host_double
     - target_float_from_host_double
    which convert to/from a host "double".  Those should only ever be
    used where a host "double" is mandated by an external interface.
    
    gdb/ChangeLog:
    2017-11-06  Ulrich Weigand  <uweigand@de.ibm.com>
    
    	* target-float.c (floatformat_to_host_double): New function.
    	(floatformat_from_host_double): Likewise.
    	(target_float_to_host_double): Likewise.
    	(target_float_from_host_double): Likewise.
    	* target-float.h (target_float_to_host_double): Add prototype.
    	(target_float_from_host_double): Likewise.
    
    	* guile/scm-value.c: Include "target-float.h".
    	(gdbscm_value_to_real): Use target_float_to_host_double.
    	Handle integer source values via value_as_long.
    	* guile/scm-math.c: Include "target-float.h".  Do not include
    	"doublest.h", "dfp.h", and "expression.h".
    	(vlscm_convert_typed_number): Use target_float_from_host_double.
    	(vlscm_convert_number): Likewise.
    
    	* python/py-value.c (valpy_float): Use target_float_to_host_double.
    	(convert_value_from_python): Use target_float_from_host_double.

Diff:
---
 gdb/ChangeLog         | 20 ++++++++++++++++++
 gdb/guile/scm-math.c  | 20 +++++++++++++-----
 gdb/guile/scm-value.c | 23 ++++++++++++++++++---
 gdb/python/py-value.c | 10 ++++++---
 gdb/target-float.c    | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/target-float.h    |  5 +++++
 6 files changed, 124 insertions(+), 11 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ad8e029..8f0432a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,25 @@
 2017-11-06  Ulrich Weigand  <uweigand@de.ibm.com>
 
+	* target-float.c (floatformat_to_host_double): New function.
+	(floatformat_from_host_double): Likewise.
+	(target_float_to_host_double): Likewise.
+	(target_float_from_host_double): Likewise.
+	* target-float.h (target_float_to_host_double): Add prototype.
+	(target_float_from_host_double): Likewise.
+
+	* guile/scm-value.c: Include "target-float.h".
+	(gdbscm_value_to_real): Use target_float_to_host_double.
+	Handle integer source values via value_as_long.
+	* guile/scm-math.c: Include "target-float.h".  Do not include
+	"doublest.h", "dfp.h", and "expression.h".
+	(vlscm_convert_typed_number): Use target_float_from_host_double.
+	(vlscm_convert_number): Likewise.
+
+	* python/py-value.c (valpy_float): Use target_float_to_host_double.
+	(convert_value_from_python): Use target_float_from_host_double.
+
+2017-11-06  Ulrich Weigand  <uweigand@de.ibm.com>
+
 	* ada-lang.c (cast_to_fixed): Reimplement in target arithmetic.
 	(cast_from_fixed): Likewise.
 	(ada_scaling_type): New function.
diff --git a/gdb/guile/scm-math.c b/gdb/guile/scm-math.c
index c4dfe71..ef27d68 100644
--- a/gdb/guile/scm-math.c
+++ b/gdb/guile/scm-math.c
@@ -24,9 +24,7 @@
 #include "arch-utils.h"
 #include "charset.h"
 #include "cp-abi.h"
-#include "doublest.h" /* Needed by dfp.h.  */
-#include "expression.h" /* Needed by dfp.h.  */
-#include "dfp.h"
+#include "target-float.h"
 #include "symtab.h" /* Needed by language.h.  */
 #include "language.h"
 #include "valprint.h"
@@ -599,7 +597,13 @@ vlscm_convert_typed_number (const char *func_name, int obj_arg_pos, SCM obj,
 	}
     }
   else if (TYPE_CODE (type) == TYPE_CODE_FLT)
-    return value_from_double (type, scm_to_double (obj));
+    {
+      struct value *value = allocate_value (type);
+      target_float_from_host_double (value_contents_raw (value),
+				     value_type (value),
+				     scm_to_double (obj));
+      return value;
+    }
   else
     {
       *except_scmp = gdbscm_make_type_error (func_name, obj_arg_pos, obj,
@@ -679,7 +683,13 @@ vlscm_convert_number (const char *func_name, int obj_arg_pos, SCM obj,
 				   gdbscm_scm_to_ulongest (obj));
     }
   else if (scm_is_real (obj))
-    return value_from_double (bt->builtin_double, scm_to_double (obj));
+    {
+      struct value *value = allocate_value (bt->builtin_double);
+      target_float_from_host_double (value_contents_raw (value),
+				     value_type (value),
+				     scm_to_double (obj));
+      return value;
+    }
 
   *except_scmp = gdbscm_make_out_of_range_error (func_name, obj_arg_pos, obj,
 			_("value not a number representable on the target"));
diff --git a/gdb/guile/scm-value.c b/gdb/guile/scm-value.c
index 3732666..0cf7547 100644
--- a/gdb/guile/scm-value.c
+++ b/gdb/guile/scm-value.c
@@ -24,6 +24,7 @@
 #include "arch-utils.h"
 #include "charset.h"
 #include "cp-abi.h"
+#include "target-float.h"
 #include "infcall.h"
 #include "symtab.h" /* Needed by language.h.  */
 #include "language.h"
@@ -1019,7 +1020,8 @@ gdbscm_value_to_real (SCM self)
     = vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
   struct value *value = v_smob->value;
   struct type *type;
-  DOUBLEST d = 0;
+  double d = 0;
+  struct value *check = nullptr;
 
   type = value_type (value);
 
@@ -1038,7 +1040,22 @@ gdbscm_value_to_real (SCM self)
 
   TRY
     {
-      d = value_as_double (value);
+      if (is_floating_value (value))
+	{
+	  d = target_float_to_host_double (value_contents (value), type);
+	  check = allocate_value (type);
+	  target_float_from_host_double (value_contents_raw (check), type, d);
+	}
+      else if (TYPE_UNSIGNED (type))
+	{
+	  d = (ULONGEST) value_as_long (value);
+	  check = value_from_ulongest (type, (ULONGEST) d);
+	}
+      else
+	{
+	  d = value_as_long (value);
+	  check = value_from_longest (type, (LONGEST) d);
+	}
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -1047,7 +1064,7 @@ gdbscm_value_to_real (SCM self)
   END_CATCH
 
   /* TODO: Is there a better way to check if the value fits?  */
-  if (d != (double) d)
+  if (!value_equal (value, check))
     gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
 			       _("number can't be converted to a double"));
 
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 16c7650..11f1fc9 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -1560,10 +1560,10 @@ valpy_float (PyObject *self)
     {
       type = check_typedef (type);
 
-      if (TYPE_CODE (type) != TYPE_CODE_FLT)
+      if (TYPE_CODE (type) != TYPE_CODE_FLT || !is_floating_value (value))
 	error (_("Cannot convert value to float."));
 
-      d = value_as_double (value);
+      d = target_float_to_host_double (value_contents (value), type);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -1681,7 +1681,11 @@ convert_value_from_python (PyObject *obj)
 	  double d = PyFloat_AsDouble (obj);
 
 	  if (! PyErr_Occurred ())
-	    value = value_from_double (builtin_type_pyfloat, d);
+	    {
+	      value = allocate_value (builtin_type_pyfloat);
+	      target_float_from_host_double (value_contents_raw (value),
+					     value_type (value), d);
+	    }
 	}
       else if (gdbpy_is_string (obj))
 	{
diff --git a/gdb/target-float.c b/gdb/target-float.c
index ad04f8f..d2c1064 100644
--- a/gdb/target-float.c
+++ b/gdb/target-float.c
@@ -59,6 +59,27 @@ floatformat_from_ulongest (const struct floatformat *fmt, gdb_byte *addr,
   floatformat_from_doublest (fmt, &d, addr);
 }
 
+/* Convert the byte-stream ADDR, interpreted as floating-point format FMT,
+   to a floating-point value in the host "double" format.  */
+static double
+floatformat_to_host_double (const struct floatformat *fmt,
+			    const gdb_byte *addr)
+{
+  DOUBLEST d;
+  floatformat_to_doublest (fmt, addr, &d);
+  return (double) d;
+}
+
+/* Convert floating-point value VAL in the host "double" format to a target
+   floating-number of format FMT and store it as byte-stream ADDR.  */
+static void
+floatformat_from_host_double (const struct floatformat *fmt, gdb_byte *addr,
+			      double val)
+{
+  DOUBLEST d = (DOUBLEST) val;
+  floatformat_from_doublest (fmt, &d, addr);
+}
+
 /* Convert a floating-point number of format FROM_FMT from the target
    byte-stream FROM to a floating-point number of format TO_FMT, and
    store it to the target byte-stream TO.  */
@@ -299,6 +320,42 @@ target_float_from_ulongest (gdb_byte *addr, const struct type *type,
   gdb_assert_not_reached ("unexpected type code");
 }
 
+/* Convert the byte-stream ADDR, interpreted as floating-point type TYPE,
+   to a floating-point value in the host "double" format.  */
+double
+target_float_to_host_double (const gdb_byte *addr,
+			     const struct type *type)
+{
+  if (TYPE_CODE (type) == TYPE_CODE_FLT)
+    return floatformat_to_host_double (floatformat_from_type (type), addr);
+
+  /* We don't support conversions between target decimal floating-point
+     types and the host double type here.  */
+
+  gdb_assert_not_reached ("unexpected type code");
+}
+
+/* Convert floating-point value VAL in the host "double" format to a target
+   floating-number of type TYPE and store it as byte-stream ADDR.  */
+void
+target_float_from_host_double (gdb_byte *addr, const struct type *type,
+			       double val)
+{
+  /* Ensure possible padding bytes in the target buffer are zeroed out.  */
+  memset (addr, 0, TYPE_LENGTH (type));
+
+  if (TYPE_CODE (type) == TYPE_CODE_FLT)
+    {
+      floatformat_from_host_double (floatformat_from_type (type), addr, val);
+      return;
+    }
+
+  /* We don't support conversions between target decimal floating-point
+     types and the host double type here.  */
+
+  gdb_assert_not_reached ("unexpected type code");
+}
+
 /* Convert a floating-point number of type FROM_TYPE from the target
    byte-stream FROM to a floating-point number of type TO_TYPE, and
    store it to the target byte-stream TO.  */
diff --git a/gdb/target-float.h b/gdb/target-float.h
index 466dd1b..4ac88ef 100644
--- a/gdb/target-float.h
+++ b/gdb/target-float.h
@@ -42,6 +42,11 @@ extern void target_float_from_longest (gdb_byte *addr,
 extern void target_float_from_ulongest (gdb_byte *addr,
 					const struct type *type,
 					ULONGEST val);
+extern double target_float_to_host_double (const gdb_byte *addr,
+					   const struct type *type);
+extern void target_float_from_host_double (gdb_byte *addr,
+					   const struct type *type,
+					   double val);
 extern void target_float_convert (const gdb_byte *from,
 				  const struct type *from_type,
 				  gdb_byte *to, const struct type *to_type);


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