+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.
#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"
}
}
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,
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"));
#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"
= 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);
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)
{
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"));
{
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)
{
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))
{
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. */
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. */
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);