From patchwork Tue Nov 21 17:55:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulrich Weigand X-Patchwork-Id: 24416 Received: (qmail 72104 invoked by alias); 21 Nov 2017 17:55:38 -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 72092 invoked by uid 89); 21 Nov 2017 17:55:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, KB_WAM_FROM_NAME_SINGLEWORD, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=notion, AUTO, 20162017, doubles 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, 21 Nov 2017 17:55:35 +0000 Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id vALHtCp3104811 for ; Tue, 21 Nov 2017 12:55:34 -0500 Received: from e06smtp11.uk.ibm.com (e06smtp11.uk.ibm.com [195.75.94.107]) by mx0a-001b2d01.pphosted.com with ESMTP id 2ecpgxjdta-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 21 Nov 2017 12:55:33 -0500 Received: from localhost by e06smtp11.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 21 Nov 2017 17:55:31 -0000 Received: from b06cxnps4074.portsmouth.uk.ibm.com (9.149.109.196) by e06smtp11.uk.ibm.com (192.168.101.141) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 21 Nov 2017 17:55:29 -0000 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id vALHtSZH21626920 for ; Tue, 21 Nov 2017 17:55:28 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 585EEA4057 for ; Tue, 21 Nov 2017 17:50:10 +0000 (GMT) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3E181A404D for ; Tue, 21 Nov 2017 17:50:10 +0000 (GMT) Received: from oc3748833570.ibm.com (unknown [9.152.213.29]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTP for ; Tue, 21 Nov 2017 17:50:10 +0000 (GMT) Received: by oc3748833570.ibm.com (Postfix, from userid 1000) id 61390D8014D; Tue, 21 Nov 2017 18:55:28 +0100 (CET) Subject: [pushed][PowerPC] Detect different long double floating-point formats To: gdb-patches@sourceware.org Date: Tue, 21 Nov 2017 18:55:28 +0100 (CET) From: "Ulrich Weigand" MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 17112117-0040-0000-0000-00000411072A X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17112117-0041-0000-0000-000020B3D186 Message-Id: <20171121175528.61390D8014D@oc3748833570.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-11-21_06:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1711210236 Hello, current versions of GCC support switching the format used for "long double" to either IBM double double or IEEE-128. The resulting binary is marked via different setting of the Tag_GNU_Power_ABI_FP GNU attribute. This patch checks this attribute to detect the format of the default "long double" type and sets GDB's notion of the format accordingly. The patch also adds support for the "__ibm128" type, which always uses IBM double double format independent of the format used for "long double". A new test case verifies that all three types, "long double", "__float128", and "__ibm128" are correctly detected in all three compiler settings, the default setting, -mabi=ieeelongdouble, and -mabi=ibmlongdouble. Tested on powerpc64le-linux. Bye, Ulrich gdb/ChangeLog: * ppc-tdep.h (enum powerpc_long_double_abi): New data type. (struct gdbarch_tdep): New member long_double_abi. * rs6000-tdep.c (rs6000_gdbarch_init): Initialize long_double_abi member of tdep struct based on Tag_GNU_Power_ABI_FP attribute. * ppc-linux-tdep.c (ppc_linux_init_abi): Install long double data format depending on long_double_abi tdep member. (ppc_floatformat_for_type): Handle __ibm128 type. gdb/testsuite/ChangeLog: * gdb.arch/ppc-longdouble.exp: New file. * gdb.arch/ppc-longdouble.c: Likewise. diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index ee80a71..0e43a64 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -1623,12 +1623,17 @@ ppc_floatformat_for_type (struct gdbarch *gdbarch, const char *name, int len) { if (len == 128 && name) - if (strcmp (name, "__float128") == 0 - || strcmp (name, "_Float128") == 0 - || strcmp (name, "_Float64x") == 0 - || strcmp (name, "complex _Float128") == 0 - || strcmp (name, "complex _Float64x") == 0) - return floatformats_ia64_quad; + { + if (strcmp (name, "__float128") == 0 + || strcmp (name, "_Float128") == 0 + || strcmp (name, "_Float64x") == 0 + || strcmp (name, "complex _Float128") == 0 + || strcmp (name, "complex _Float64x") == 0) + return floatformats_ia64_quad; + + if (strcmp (name, "__ibm128") == 0) + return floatformats_ibm_long_double; + } return default_floatformat_for_type (gdbarch, name, len); } @@ -1648,12 +1653,15 @@ ppc_linux_init_abi (struct gdbarch_info info, linux_init_abi (info, gdbarch); /* PPC GNU/Linux uses either 64-bit or 128-bit long doubles; where - 128-bit, they are IBM long double, not IEEE quad long double as - in the System V ABI PowerPC Processor Supplement. We can safely - let them default to 128-bit, since the debug info will give the - size of type actually used in each case. */ + 128-bit, they can be either IBM long double or IEEE quad long double. + The 64-bit long double case will be detected automatically using + the size specified in debug info. We use a .gnu.attribute flag + to distinguish between the IBM long double and IEEE quad cases. */ set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT); - set_gdbarch_long_double_format (gdbarch, floatformats_ibm_long_double); + if (tdep->long_double_abi == POWERPC_LONG_DOUBLE_IEEE128) + set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad); + else + set_gdbarch_long_double_format (gdbarch, floatformats_ibm_long_double); /* Support for floating-point data type variants. */ set_gdbarch_floatformat_for_type (gdbarch, ppc_floatformat_for_type); diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h index 4ae5c7f..3d1e327 100644 --- a/gdb/ppc-tdep.h +++ b/gdb/ppc-tdep.h @@ -202,6 +202,15 @@ enum powerpc_vector_abi POWERPC_VEC_LAST }; +/* long double ABI version used by the inferior. */ +enum powerpc_long_double_abi +{ + POWERPC_LONG_DOUBLE_AUTO, + POWERPC_LONG_DOUBLE_IBM128, + POWERPC_LONG_DOUBLE_IEEE128, + POWERPC_LONG_DOUBLE_LAST +}; + struct gdbarch_tdep { int wordsize; /* Size in bytes of fixed-point word. */ @@ -209,6 +218,9 @@ struct gdbarch_tdep enum powerpc_elf_abi elf_abi; /* ELF ABI version. */ + /* Format to use for the "long double" data type. */ + enum powerpc_long_double_abi long_double_abi; + /* How to pass vector arguments. Never set to AUTO or LAST. */ enum powerpc_vector_abi vector_abi; diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 6c44995..456dbcc 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -5949,6 +5949,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) bfd abfd; enum auto_boolean soft_float_flag = powerpc_soft_float_global; int soft_float; + enum powerpc_long_double_abi long_double_abi = POWERPC_LONG_DOUBLE_AUTO; enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global; enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO; int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0, @@ -6271,7 +6272,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (soft_float_flag == AUTO_BOOLEAN_AUTO && from_elf_exec) { switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU, - Tag_GNU_Power_ABI_FP)) + Tag_GNU_Power_ABI_FP) & 3) { case 1: soft_float_flag = AUTO_BOOLEAN_FALSE; @@ -6284,6 +6285,22 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } } + if (long_double_abi == POWERPC_LONG_DOUBLE_AUTO && from_elf_exec) + { + switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU, + Tag_GNU_Power_ABI_FP) >> 2) + { + case 1: + long_double_abi = POWERPC_LONG_DOUBLE_IBM128; + break; + case 3: + long_double_abi = POWERPC_LONG_DOUBLE_IEEE128; + break; + default: + break; + } + } + if (vector_abi == POWERPC_VEC_AUTO && from_elf_exec) { switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU, @@ -6365,6 +6382,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) continue; if (tdep && tdep->soft_float != soft_float) continue; + if (tdep && tdep->long_double_abi != long_double_abi) + continue; if (tdep && tdep->vector_abi != vector_abi) continue; if (tdep && tdep->wordsize == wordsize) @@ -6387,6 +6406,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->wordsize = wordsize; tdep->elf_abi = elf_abi; tdep->soft_float = soft_float; + tdep->long_double_abi = long_double_abi; tdep->vector_abi = vector_abi; gdbarch = gdbarch_alloc (&info, tdep); diff --git a/gdb/testsuite/gdb.arch/ppc-longdouble.c b/gdb/testsuite/gdb.arch/ppc-longdouble.c new file mode 100644 index 0000000..17296bf --- /dev/null +++ b/gdb/testsuite/gdb.arch/ppc-longdouble.c @@ -0,0 +1,38 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2017 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include + +long double ld; +__float128 float128; +__ibm128 ibm128; + +/* FIXME: GCC will only emit a .gnu.attribute section specifying the + long double ABI if long double is used in a function prototype. */ +void test (long double x) +{ +} + +int main() +{ + ld = 1.375l; + float128 = 2.375l; + ibm128 = 3.375l; + + return 0; +} diff --git a/gdb/testsuite/gdb.arch/ppc-longdouble.exp b/gdb/testsuite/gdb.arch/ppc-longdouble.exp new file mode 100644 index 0000000..66c8f54 --- /dev/null +++ b/gdb/testsuite/gdb.arch/ppc-longdouble.exp @@ -0,0 +1,58 @@ +# Copyright 2016-2017 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +if ![istarget "powerpc*"] then { + verbose "Skipping powerpc long-double floating point tests." + return +} + +standard_testfile + +proc do_test { name {opts {}} } { + global srcdir subdir srcfile binfile + set ccopts {debug quiet} + foreach opt $opts {lappend ccopts "additional_flags=$opt"} + set lines [gdb_compile "${srcdir}/${subdir}/${srcfile}" "$binfile.$name" executable $ccopts] + # We get this warning even with the nowarnings option ... + regsub -all "(^|\n)\[^\n\]*using \[^\n\]* extended precision long double" $lines "" lines + if { $lines != "" } then { + return + } + + clean_restart ${binfile}.${name} + + if ![runto_main] then { + return + } + + # Run to the breakpoint at return. + gdb_breakpoint [gdb_get_line_number "return"] + gdb_continue_to_breakpoint "return" + + # Print the value of ld + gdb_test "print ld" ".* = 1\\.375.*" "the value of ld is 1.375 ($name)" + # Print the value of float128 + gdb_test "print float128" ".* = 2\\.375.*" "the value of float128 is 2.375 ($name)" + # Print the value of ibm128 + gdb_test "print ibm128" ".* = 3\\.375.*" "the value of ibm128 is 3.375 ($name)" +} + +# Verify that we correctly detect the floating-point format used for +# long double. Re-run the test with -mabi=ieeelongdouble and mabi=ibmlongdouble + +do_test default { -mfloat128 } +do_test ieee128 { -mfloat128 -mabi=ieeelongdouble } +do_test ibm128 { -mfloat128 -mabi=ibmlongdouble } +