From patchwork Tue Sep 5 18:21:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulrich Weigand X-Patchwork-Id: 22643 Received: (qmail 58854 invoked by alias); 5 Sep 2017 18:21:48 -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 58808 invoked by uid 89); 5 Sep 2017 18:21:48 -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=SMALL X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0b-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.158.5) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 05 Sep 2017 18:21:42 +0000 Received: from pps.filterd (m0098413.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v85IJ5W7023450 for ; Tue, 5 Sep 2017 14:21:40 -0400 Received: from e06smtp15.uk.ibm.com (e06smtp15.uk.ibm.com [195.75.94.111]) by mx0b-001b2d01.pphosted.com with ESMTP id 2csvj7e6gt-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 05 Sep 2017 14:21:40 -0400 Received: from localhost by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 5 Sep 2017 19:21:38 +0100 Received: from b06cxnps4076.portsmouth.uk.ibm.com (9.149.109.198) by e06smtp15.uk.ibm.com (192.168.101.145) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 5 Sep 2017 19:21:36 +0100 Received: from d06av26.portsmouth.uk.ibm.com (d06av26.portsmouth.uk.ibm.com [9.149.105.62]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v85ILZXW16515268 for ; Tue, 5 Sep 2017 18:21:35 GMT Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 68A3BAE051 for ; Tue, 5 Sep 2017 19:16:52 +0100 (BST) Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4A379AE045 for ; Tue, 5 Sep 2017 19:16:52 +0100 (BST) Received: from oc3748833570.ibm.com (unknown [9.164.150.234]) by d06av26.portsmouth.uk.ibm.com (Postfix) with ESMTP for ; Tue, 5 Sep 2017 19:16:52 +0100 (BST) Received: by oc3748833570.ibm.com (Postfix, from userid 1000) id 5FF0AD8086F; Tue, 5 Sep 2017 20:21:35 +0200 (CEST) Subject: [RFC][13/19] Target FP: Perform Ada fixed-point scaling in target format To: gdb-patches@sourceware.org Date: Tue, 5 Sep 2017 20:21:35 +0200 (CEST) From: "Ulrich Weigand" MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 17090518-0020-0000-0000-000003B3CDA9 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17090518-0021-0000-0000-000042443838 Message-Id: <20170905182135.5FF0AD8086F@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][13/19] Target FP: Perform Ada fixed-point scaling in target format One of the few still remaining uses of DOUBLEST in GDB is the Ada front-end code that handles scaling of Ada fixed-point types. The target format for those types is some integer format; to convert those values to standard floating-point representation, that integer needs to be multiplied by a rational scale factor, given as a pair of numerator and denominator. To avoid having to deal with long integer arithmetic, the current Ada front-end code currently performs those scaling operations in host DOUBLEST arithmetic. To eliminate this use of DOUBLEST, this patch changes the front-end to instead perform those operations in the *target* floating-point format (chosing to use the target "long double"). The implementation is mostly straight-forward, using value_cast and value_binop to perform the target operations. Scanning in the scale numerator and denominator is now done into a host "long long" instead of a DOUBLEST, which should be large enough to hold all possible values. (Otherwise, this can be replaced by target-format target_float_from_string operations as well.) Printing fixed-point types and values should be completely unchanges, using target_float_to_string with the same format strings as current code. Bye, Ulrich ChangeLog: * ada-lang.c (cast_to_fixed): Reimplement in target arithmetic. (cast_to_fixed): Likewise. (ada_scaling_type): New function. (ada_delta): Return value instead of DOUBLEST. Perform target arithmetic instead of host arithmetic. (scaling_factor): Rename to ... (ada_scaling_factor) ... this. Return value instead of DOUBLEST. Perform target arithmetic instead of host arithmetic. (ada_fixed_to_float): Remove. (ada_float_to_fixed): Remove. * ada-lang.h (ada_fixed_to_float): Remove. (ada_float_to_fixed): Remove. (ada_delta): Return value instead of DOUBLEST. (ada_scaling_factor): Add prototype. * ada-typeprint.c: Include "target-float.h". (print_fixed_point_type): Perform target arithmetic instead of host arithmetic. * ada-valprint.c: Include "target-float.h". (ada_val_print_num): Perform target arithmetic instead of host arithmetic for fixed-point types. Index: binutils-gdb/gdb/ada-lang.c =================================================================== --- binutils-gdb.orig/gdb/ada-lang.c +++ binutils-gdb/gdb/ada-lang.c @@ -9566,33 +9566,29 @@ unwrap_value (struct value *val) } static struct value * -cast_to_fixed (struct type *type, struct value *arg) +cast_from_fixed (struct type *type, struct value *arg) { - LONGEST val; - - if (type == value_type (arg)) - return arg; - else if (ada_is_fixed_point_type (value_type (arg))) - val = ada_float_to_fixed (type, - ada_fixed_to_float (value_type (arg), - value_as_long (arg))); - else - { - DOUBLEST argd = value_as_double (arg); - - val = ada_float_to_fixed (type, argd); - } + struct value *scale = ada_scaling_factor (value_type (arg)); + arg = value_cast (value_type (scale), arg); - return value_from_longest (type, val); + arg = value_binop (arg, scale, BINOP_MUL); + return value_cast (type, arg); } static struct value * -cast_from_fixed (struct type *type, struct value *arg) +cast_to_fixed (struct type *type, struct value *arg) { - DOUBLEST val = ada_fixed_to_float (value_type (arg), - value_as_long (arg)); + if (type == value_type (arg)) + return arg; + + struct value *scale = ada_scaling_factor (type); + if (ada_is_fixed_point_type (value_type (arg))) + arg = cast_from_fixed (value_type (scale), arg); + else + arg = value_cast (value_type (scale), arg); - return value_from_double (type, val); + arg = value_binop (arg, scale, BINOP_DIV); + return value_cast (type, arg); } /* Given two array types T1 and T2, return nonzero iff both arrays @@ -11474,68 +11470,57 @@ ada_is_system_address_type (struct type } /* Assuming that TYPE is the representation of an Ada fixed-point - type, return its delta, or -1 if the type is malformed and the + type, return the target floating-point type to be used to represent + of this type during internal computation. */ + +static struct type * +ada_scaling_type (struct type *type) +{ + return builtin_type (get_type_arch (type))->builtin_long_double; +} + +/* Assuming that TYPE is the representation of an Ada fixed-point + type, return its delta, or NULL if the type is malformed and the delta cannot be determined. */ -DOUBLEST +struct value * ada_delta (struct type *type) { const char *encoding = fixed_type_info (type); - DOUBLEST num, den; + struct type *scale_type = ada_scaling_type (type); - /* Strictly speaking, num and den are encoded as integer. However, - they may not fit into a long, and they will have to be converted - to DOUBLEST anyway. So scan them as DOUBLEST. */ - if (sscanf (encoding, "_%" DOUBLEST_SCAN_FORMAT "_%" DOUBLEST_SCAN_FORMAT, - &num, &den) < 2) - return -1.0; + long long num, den; + + if (sscanf (encoding, "_%lld_%lld", &num, &den) < 2) + return nullptr; else - return num / den; + return value_binop (value_from_longest (scale_type, num), + value_from_longest (scale_type, den), BINOP_DIV); } /* Assuming that ada_is_fixed_point_type (TYPE), return the scaling factor ('SMALL value) associated with the type. */ -static DOUBLEST -scaling_factor (struct type *type) +struct value * +ada_scaling_factor (struct type *type) { const char *encoding = fixed_type_info (type); - DOUBLEST num0, den0, num1, den1; + struct type *scale_type = ada_scaling_type (type); + + long long num0, den0, num1, den1; int n; - /* Strictly speaking, num's and den's are encoded as integer. However, - they may not fit into a long, and they will have to be converted - to DOUBLEST anyway. So scan them as DOUBLEST. */ - n = sscanf (encoding, - "_%" DOUBLEST_SCAN_FORMAT "_%" DOUBLEST_SCAN_FORMAT - "_%" DOUBLEST_SCAN_FORMAT "_%" DOUBLEST_SCAN_FORMAT, + n = sscanf (encoding, "_%lld_%lld_%lld_%lld", &num0, &den0, &num1, &den1); if (n < 2) - return 1.0; + return value_from_longest (scale_type, 1); else if (n == 4) - return num1 / den1; + return value_binop (value_from_longest (scale_type, num1), + value_from_longest (scale_type, den1), BINOP_DIV); else - return num0 / den0; -} - - -/* Assuming that X is the representation of a value of fixed-point - type TYPE, return its floating-point equivalent. */ - -DOUBLEST -ada_fixed_to_float (struct type *type, LONGEST x) -{ - return (DOUBLEST) x *scaling_factor (type); -} - -/* The representation of a fixed-point value of type TYPE - corresponding to the value X. */ - -LONGEST -ada_float_to_fixed (struct type *type, DOUBLEST x) -{ - return (LONGEST) (x / scaling_factor (type) + 0.5); + return value_binop (value_from_longest (scale_type, num0), + value_from_longest (scale_type, den0), BINOP_DIV); } Index: binutils-gdb/gdb/ada-lang.h =================================================================== --- binutils-gdb.orig/gdb/ada-lang.h +++ binutils-gdb/gdb/ada-lang.h @@ -305,11 +305,9 @@ extern int ada_is_fixed_point_type (stru extern int ada_is_system_address_type (struct type *); -extern DOUBLEST ada_delta (struct type *); +extern struct value *ada_delta (struct type *); -extern DOUBLEST ada_fixed_to_float (struct type *, LONGEST); - -extern LONGEST ada_float_to_fixed (struct type *, DOUBLEST); +extern struct value *ada_scaling_factor (struct type *); extern struct type *ada_system_address_type (void); Index: binutils-gdb/gdb/ada-typeprint.c =================================================================== --- binutils-gdb.orig/gdb/ada-typeprint.c +++ binutils-gdb/gdb/ada-typeprint.c @@ -31,6 +31,7 @@ #include "demangle.h" #include "c-lang.h" #include "typeprint.h" +#include "target-float.h" #include "ada-lang.h" #include @@ -360,16 +361,23 @@ print_enum_type (struct type *type, stru static void print_fixed_point_type (struct type *type, struct ui_file *stream) { - DOUBLEST delta = ada_delta (type); - DOUBLEST small = ada_fixed_to_float (type, 1); + struct value *delta = ada_delta (type); + struct value *small = ada_scaling_factor (type); - if (delta < 0.0) + if (delta == nullptr) fprintf_filtered (stream, "delta ??"); else { - fprintf_filtered (stream, "delta %g", (double) delta); - if (delta != small) - fprintf_filtered (stream, " <'small = %g>", (double) small); + std::string str; + str = target_float_to_string (value_contents (delta), + value_type (delta), "%g"); + fprintf_filtered (stream, "delta %s", str.c_str()); + if (!value_equal (delta, small)) + { + str = target_float_to_string (value_contents (small), + value_type (small), "%g"); + fprintf_filtered (stream, " <'small = %s>", str.c_str()); + } } } Index: binutils-gdb/gdb/ada-valprint.c =================================================================== --- binutils-gdb.orig/gdb/ada-valprint.c +++ binutils-gdb/gdb/ada-valprint.c @@ -31,6 +31,7 @@ #include "c-lang.h" #include "infcall.h" #include "objfiles.h" +#include "target-float.h" static int print_field_values (struct type *, const gdb_byte *, int, @@ -796,10 +797,15 @@ ada_val_print_num (struct type *type, co { if (ada_is_fixed_point_type (type)) { - LONGEST v = unpack_long (type, valaddr + offset_aligned); - - fprintf_filtered (stream, TYPE_LENGTH (type) < 4 ? "%.11g" : "%.17g", - (double) ada_fixed_to_float (type, v)); + struct value *scale = ada_scaling_factor (type); + struct value *v = value_from_contents (type, valaddr + offset_aligned); + v = value_cast (value_type (scale), v); + v = value_binop (v, scale, BINOP_MUL); + + const char *fmt = TYPE_LENGTH (type) < 4 ? "%.11g" : "%.17g"; + std::string str + = target_float_to_string (value_contents (v), value_type (v), fmt); + fputs_filtered (str.c_str (), stream); return; } else if (TYPE_CODE (type) == TYPE_CODE_RANGE)