From patchwork Tue Sep 5 18:21:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulrich Weigand X-Patchwork-Id: 22644 Received: (qmail 59558 invoked by alias); 5 Sep 2017 18:21:54 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 59418 invoked by uid 89); 5 Sep 2017 18:21:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 05 Sep 2017 18:21:46 +0000 Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v85IJ9hm046748 for ; Tue, 5 Sep 2017 14:21:45 -0400 Received: from e06smtp11.uk.ibm.com (e06smtp11.uk.ibm.com [195.75.94.107]) by mx0a-001b2d01.pphosted.com with ESMTP id 2csvwp595w-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 05 Sep 2017 14:21:45 -0400 Received: from localhost by e06smtp11.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 5 Sep 2017 19:21:42 +0100 Received: from b06cxnps4075.portsmouth.uk.ibm.com (9.149.109.197) by e06smtp11.uk.ibm.com (192.168.101.141) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 5 Sep 2017 19:21:41 +0100 Received: from d06av24.portsmouth.uk.ibm.com (mk.ibm.com [9.149.105.60]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v85ILe5013303940 for ; Tue, 5 Sep 2017 18:21:40 GMT Received: from d06av24.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2EAA542041 for ; Tue, 5 Sep 2017 19:18:12 +0100 (BST) Received: from d06av24.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0FDA14203F for ; Tue, 5 Sep 2017 19:18:12 +0100 (BST) Received: from oc3748833570.ibm.com (unknown [9.164.150.234]) by d06av24.portsmouth.uk.ibm.com (Postfix) with ESMTP for ; Tue, 5 Sep 2017 19:18:12 +0100 (BST) Received: by oc3748833570.ibm.com (Postfix, from userid 1000) id 622FAD8086F; Tue, 5 Sep 2017 20:21:40 +0200 (CEST) Subject: [RFC][14/19] Target FP: Handle interfaces to scripting languages To: gdb-patches@sourceware.org Date: Tue, 5 Sep 2017 20:21:40 +0200 (CEST) From: "Ulrich Weigand" MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 17090518-0040-0000-0000-000003F5CC41 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17090518-0041-0000-0000-000020964435 Message-Id: <20170905182140.622FAD8086F@oc3748833570.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-09-05_07:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000 definitions=main-1709050267 [RFC][14/19] 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. Bye, Ulrich ChangeLog: * 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. Index: binutils-gdb/gdb/target-float.c =================================================================== --- binutils-gdb.orig/gdb/target-float.c +++ binutils-gdb/gdb/target-float.c @@ -59,6 +59,27 @@ floatformat_from_ulongest (const struct 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. */ @@ -298,6 +319,42 @@ target_float_from_ulongest (gdb_byte *ad 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 Index: binutils-gdb/gdb/target-float.h =================================================================== --- binutils-gdb.orig/gdb/target-float.h +++ binutils-gdb/gdb/target-float.h @@ -42,6 +42,11 @@ extern void target_float_from_longest (g 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: binutils-gdb/gdb/guile/scm-value.c =================================================================== --- binutils-gdb.orig/gdb/guile/scm-value.c +++ binutils-gdb/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" @@ -1024,7 +1025,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); @@ -1043,7 +1045,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) { @@ -1052,7 +1069,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")); Index: binutils-gdb/gdb/guile/scm-math.c =================================================================== --- binutils-gdb.orig/gdb/guile/scm-math.c +++ binutils-gdb/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 * } } 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_n 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")); Index: binutils-gdb/gdb/python/py-value.c =================================================================== --- binutils-gdb.orig/gdb/python/py-value.c +++ binutils-gdb/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)) {