From patchwork Fri Dec 15 04:10:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Meissner X-Patchwork-Id: 848921 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-469286-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="IFKL7UNl"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yycSB3gP0z9t1t for ; Fri, 15 Dec 2017 15:11:14 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:mime-version:content-type:message-id; q=dns; s= default; b=rbWQDfIBvRpQqPczGkxgXyEiDX7WS4KOC0cU8oHuTcdCprzO0mRAY aroQ4PcLg5ykBhsP6zYBnRCHUF+2M+Zm9eIf5LOhDSWN4Zym99Vmi3IjdM1/IKM2 PwRPNoHqhjQqj6W1qJLpA4kAHiE4Sro98lhgoieT8KJhksLxw5xPIo= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:mime-version:content-type:message-id; s= default; bh=ESLKZQ0R0rLzntP8UsthuakjgLg=; b=IFKL7UNlyyn1llLZysWH fQtevd89aArjc+AwXE0RIMN+PTV8ApdWSmzqTt1TXIjMWN16jOeRHzmCWNUUFOzA sUTYHLdpDdrX58HixhYQQ7RPS8pFNPZUE+Phm6hSK5n9wbVQiMXHo2iuZrTjnMxH hvy29i56hbdu8jF86cRU6ug= Received: (qmail 81042 invoked by alias); 15 Dec 2017 04:11:06 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 81028 invoked by uid 89); 15 Dec 2017 04:11:05 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=tau 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; Fri, 15 Dec 2017 04:11:02 +0000 Received: from pps.filterd (m0098416.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id vBF4AqMF184964 for ; Thu, 14 Dec 2017 23:11:01 -0500 Received: from e34.co.us.ibm.com (e34.co.us.ibm.com [32.97.110.152]) by mx0b-001b2d01.pphosted.com with ESMTP id 2ev2nd06y2-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Thu, 14 Dec 2017 23:10:55 -0500 Received: from localhost by e34.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 14 Dec 2017 21:10:17 -0700 Received: from b03cxnp08028.gho.boulder.ibm.com (9.17.130.20) by e34.co.us.ibm.com (192.168.1.134) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 14 Dec 2017 21:10:14 -0700 Received: from b03ledav001.gho.boulder.ibm.com (b03ledav001.gho.boulder.ibm.com [9.17.130.232]) by b03cxnp08028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id vBF4AEHX3867064; Thu, 14 Dec 2017 21:10:14 -0700 Received: from b03ledav001.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6FFB06E038; Thu, 14 Dec 2017 21:10:14 -0700 (MST) Received: from ibm-tiger.the-meissners.org (unknown [9.32.77.111]) by b03ledav001.gho.boulder.ibm.com (Postfix) with ESMTP id 4C1626E035; Thu, 14 Dec 2017 21:10:14 -0700 (MST) Received: by ibm-tiger.the-meissners.org (Postfix, from userid 500) id A2F3849517; Thu, 14 Dec 2017 23:10:13 -0500 (EST) Date: Thu, 14 Dec 2017 23:10:13 -0500 From: Michael Meissner To: GCC Patches , Segher Boessenkool , David Edelsohn , Bill Schmidt Subject: [PATCH, libgcc] Fix PowerPC libgcc issues with -mabi=ieeelongdouble Mail-Followup-To: Michael Meissner , GCC Patches , Segher Boessenkool , David Edelsohn , Bill Schmidt MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-12-10) X-TM-AS-GCONF: 00 x-cbid: 17121504-0016-0000-0000-000007FA24EB X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00008206; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000244; SDB=6.00960394; UDB=6.00485788; IPR=6.00740410; BA=6.00005741; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00018552; XFM=3.00000015; UTC=2017-12-15 04:10:15 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17121504-0017-0000-0000-00003CA800C4 Message-Id: <20171215041013.GA15916@ibm-tiger.the-meissners.org> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-12-15_02:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1712150056 X-IsSubscribed: yes I am working on some patches to optionally enable multilibs for the PowerPC long double support to be switchable between IBM extended double and IEEE 128-bit floating point. While the patches to actually enable the multlibs need some more tweaking, it did point up an issue in the libgcc _Float128 and IBM extended double functions. These patches use the correct types for IBM extended double and __float128 if the IEEE default is used. I have built the compiler with bootstrap builds and there were no regressions in running the tests on a little endian power8 system. In addition, I had fixed the previous changes to _divkc3.c and _mulkc3.c so that these functions now include soft-fp.h and quad-float128.h, which provides the appropriate prototypes. I have also done a bootstrap build with my preliminary multilib patches, and it built fine with both -mabi=ieeelongdouble and -mabi=ibmlongdouble configurations. Can I apply these patches to libgcc? 2017-12-14 Michael Meissner * config/rs6000/_divkc3.c: Switch to using soft-fp.h and quad-float128.h include files and use the types that they define, instead of hand-rolling the types. * config/rs6000/_mulkc3.c: Likewise. * config/rs6000/ibm-ldouble.c: If we have __float128/_Float128, use __ieee128 for the IBM extended double type instead of long double. Change all functions. * config/rs6000/quad-float128.h (IBM128_TYPE): Always use __ieee128. (CVT_FLOAT128_TO_IBM128): Use long double instead of __float128 on systems where the default long double is IEEE 128-bit floating point. * config/rs6000/extendkftf2-sw.c (extendkftf2_sw): Likewise. * config/rs6000/trunctfkf2-sw.c (__trunctfkf2_sw): Likewise. Index: libgcc/config/rs6000/_divkc3.c =================================================================== --- libgcc/config/rs6000/_divkc3.c (revision 255658) +++ libgcc/config/rs6000/_divkc3.c (working copy) @@ -23,12 +23,12 @@ see the files COPYING3 and COPYING.RUNTI /* This is a temporary specialization of code from libgcc/libgcc2.c. */ -typedef float KFtype __attribute__ ((mode (KF))); -typedef __complex float KCtype __attribute__ ((mode (KC))); +#include "soft-fp.h" +#include "quad-float128.h" -#define COPYSIGN(x,y) __builtin_copysignq (x, y) -#define INFINITY __builtin_infq () -#define FABS __builtin_fabsq +#define COPYSIGN(x,y) __builtin_copysignf128 (x, y) +#define INFINITY __builtin_inff128 () +#define FABS __builtin_fabsf128 #define isnan __builtin_isnan #define isinf __builtin_isinf #define isfinite __builtin_isfinite @@ -37,13 +37,11 @@ typedef __complex float KCtype __attribu #define __divkc3 __divkc3_sw #endif -extern KCtype __divkc3 (KFtype, KFtype, KFtype, KFtype); - -KCtype -__divkc3 (KFtype a, KFtype b, KFtype c, KFtype d) +TCtype +__divkc3 (TFtype a, TFtype b, TFtype c, TFtype d) { - KFtype denom, ratio, x, y; - KCtype res; + TFtype denom, ratio, x, y; + TCtype res; /* ??? We can get better behavior from logarithmic scaling instead of the division. But that would mean starting to link libgcc against Index: libgcc/config/rs6000/ibm-ldouble.c =================================================================== --- libgcc/config/rs6000/ibm-ldouble.c (revision 255658) +++ libgcc/config/rs6000/ibm-ldouble.c (working copy) @@ -56,6 +56,15 @@ see the files COPYING3 and COPYING.RUNTI #define nonfinite(a) unlikely (! isless (fabs (a), inf ())) +/* If we have __float128/_Float128, use __ibm128 instead of long double. On + other systems, use long double, because __ibm128 might not have been + created. */ +#ifdef __FLOAT128__ +#define IBM128_TYPE __ibm128 +#else +#define IBM128_TYPE long double +#endif + /* Define ALIASNAME as a strong alias for NAME. */ # define strong_alias(name, aliasname) _strong_alias(name, aliasname) # define _strong_alias(name, aliasname) \ @@ -65,10 +74,10 @@ see the files COPYING3 and COPYING.RUNTI but GCC currently generates poor code when a union is used to turn a long double into a pair of doubles. */ -long double __gcc_qadd (double, double, double, double); -long double __gcc_qsub (double, double, double, double); -long double __gcc_qmul (double, double, double, double); -long double __gcc_qdiv (double, double, double, double); +IBM128_TYPE __gcc_qadd (double, double, double, double); +IBM128_TYPE __gcc_qsub (double, double, double, double); +IBM128_TYPE __gcc_qmul (double, double, double, double); +IBM128_TYPE __gcc_qdiv (double, double, double, double); #if defined __ELF__ && defined SHARED \ && (defined __powerpc64__ || !(defined __linux__ || defined __gnu_hurd__)) @@ -88,17 +97,17 @@ __asm__ (".symver __gcc_qadd,_xlqadd@GCC ".symver .__gcc_qdiv,._xlqdiv@GCC_3.4"); #endif -/* Combine two 'double' values into one 'long double' and return the result. */ -static inline long double +/* Combine two 'double' values into one 'IBM128_TYPE' and return the result. */ +static inline IBM128_TYPE pack_ldouble (double dh, double dl) { -#if defined (__LONG_DOUBLE_128__) \ +#if defined (__LONG_DOUBLE_128__) && defined (__LONG_DOUBLE_IBM128__) \ && !(defined (_SOFT_FLOAT) || defined (__NO_FPRS__)) return __builtin_pack_longdouble (dh, dl); #else union { - long double ldval; + IBM128_TYPE ldval; double dval[2]; } x; x.dval[0] = dh; @@ -107,8 +116,8 @@ pack_ldouble (double dh, double dl) #endif } -/* Add two 'long double' values and return the result. */ -long double +/* Add two 'IBM128_TYPE' values and return the result. */ +IBM128_TYPE __gcc_qadd (double a, double aa, double c, double cc) { double xh, xl, z, q, zz; @@ -147,7 +156,7 @@ __gcc_qadd (double a, double aa, double return pack_ldouble (xh, xl); } -long double +IBM128_TYPE __gcc_qsub (double a, double b, double c, double d) { return __gcc_qadd (a, b, -c, -d); @@ -157,7 +166,7 @@ __gcc_qsub (double a, double b, double c static double fmsub (double, double, double); #endif -long double +IBM128_TYPE __gcc_qmul (double a, double b, double c, double d) { double xh, xl, t, tau, u, v, w; @@ -181,7 +190,7 @@ __gcc_qmul (double a, double b, double c tau += v + w; /* Add in other second-order terms. */ u = t + tau; - /* Construct long double result. */ + /* Construct IBM128_TYPE result. */ if (nonfinite (u)) return u; xh = u; @@ -189,7 +198,7 @@ __gcc_qmul (double a, double b, double c return pack_ldouble (xh, xl); } -long double +IBM128_TYPE __gcc_qdiv (double a, double b, double c, double d) { double xh, xl, s, sigma, t, tau, u, v, w; @@ -226,7 +235,7 @@ __gcc_qdiv (double a, double b, double c tau = ((v-sigma)+w)/c; /* Correction to t. */ u = t + tau; - /* Construct long double result. */ + /* Construct IBM128_TYPE result. */ if (nonfinite (u)) return u; xh = u; @@ -236,32 +245,32 @@ __gcc_qdiv (double a, double b, double c #if defined (_SOFT_DOUBLE) && defined (__LONG_DOUBLE_128__) -long double __gcc_qneg (double, double); +IBM128_TYPE __gcc_qneg (double, double); int __gcc_qeq (double, double, double, double); int __gcc_qne (double, double, double, double); int __gcc_qge (double, double, double, double); int __gcc_qle (double, double, double, double); -long double __gcc_stoq (float); -long double __gcc_dtoq (double); +IBM128_TYPE __gcc_stoq (float); +IBM128_TYPE __gcc_dtoq (double); float __gcc_qtos (double, double); double __gcc_qtod (double, double); int __gcc_qtoi (double, double); unsigned int __gcc_qtou (double, double); -long double __gcc_itoq (int); -long double __gcc_utoq (unsigned int); +IBM128_TYPE __gcc_itoq (int); +IBM128_TYPE __gcc_utoq (unsigned int); extern int __eqdf2 (double, double); extern int __ledf2 (double, double); extern int __gedf2 (double, double); -/* Negate 'long double' value and return the result. */ -long double +/* Negate 'IBM128_TYPE' value and return the result. */ +IBM128_TYPE __gcc_qneg (double a, double aa) { return pack_ldouble (-a, -aa); } -/* Compare two 'long double' values for equality. */ +/* Compare two 'IBM128_TYPE' values for equality. */ int __gcc_qeq (double a, double aa, double c, double cc) { @@ -272,7 +281,7 @@ __gcc_qeq (double a, double aa, double c strong_alias (__gcc_qeq, __gcc_qne); -/* Compare two 'long double' values for less than or equal. */ +/* Compare two 'IBM128_TYPE' values for less than or equal. */ int __gcc_qle (double a, double aa, double c, double cc) { @@ -283,7 +292,7 @@ __gcc_qle (double a, double aa, double c strong_alias (__gcc_qle, __gcc_qlt); -/* Compare two 'long double' values for greater than or equal. */ +/* Compare two 'IBM128_TYPE' values for greater than or equal. */ int __gcc_qge (double a, double aa, double c, double cc) { @@ -294,35 +303,35 @@ __gcc_qge (double a, double aa, double c strong_alias (__gcc_qge, __gcc_qgt); -/* Convert single to long double. */ -long double +/* Convert single to IBM128_TYPE. */ +IBM128_TYPE __gcc_stoq (float a) { return pack_ldouble ((double) a, 0.0); } -/* Convert double to long double. */ -long double +/* Convert double to IBM128_TYPE. */ +IBM128_TYPE __gcc_dtoq (double a) { return pack_ldouble (a, 0.0); } -/* Convert long double to single. */ +/* Convert IBM128_TYPE to single. */ float __gcc_qtos (double a, double aa __attribute__ ((__unused__))) { return (float) a; } -/* Convert long double to double. */ +/* Convert IBM128_TYPE to double. */ double __gcc_qtod (double a, double aa __attribute__ ((__unused__))) { return a; } -/* Convert long double to int. */ +/* Convert IBM128_TYPE to int. */ int __gcc_qtoi (double a, double aa) { @@ -330,7 +339,7 @@ __gcc_qtoi (double a, double aa) return (int) z; } -/* Convert long double to unsigned int. */ +/* Convert IBM128_TYPE to unsigned int. */ unsigned int __gcc_qtou (double a, double aa) { @@ -338,15 +347,15 @@ __gcc_qtou (double a, double aa) return (unsigned int) z; } -/* Convert int to long double. */ -long double +/* Convert int to IBM128_TYPE. */ +IBM128_TYPE __gcc_itoq (int a) { return __gcc_dtoq ((double) a); } -/* Convert unsigned int to long double. */ -long double +/* Convert unsigned int to IBM128_TYPE. */ +IBM128_TYPE __gcc_utoq (unsigned int a) { return __gcc_dtoq ((double) a); @@ -361,7 +370,7 @@ int __gcc_qunord (double, double, double extern int __eqdf2 (double, double); extern int __unorddf2 (double, double); -/* Compare two 'long double' values for unordered. */ +/* Compare two 'IBM128_TYPE' values for unordered. */ int __gcc_qunord (double a, double aa, double c, double cc) { @@ -389,7 +398,7 @@ fmsub (double a, double b, double c) FP_DECL_Q(V); FP_DECL_D(R); double r; - long double u, x, y, z; + IBM128_TYPE u, x, y, z; FP_INIT_ROUNDMODE; FP_UNPACK_RAW_D (A, a); Index: libgcc/config/rs6000/quad-float128.h =================================================================== --- libgcc/config/rs6000/quad-float128.h (revision 255658) +++ libgcc/config/rs6000/quad-float128.h (working copy) @@ -51,12 +51,7 @@ typedef __complex float TCtype __attribu #include -#ifdef __LONG_DOUBLE_IEEE128__ -#define IBM128_TYPE __ibm128 - -#else -#define IBM128_TYPE long double -#endif +#define IBM128_TYPE __ibm128 /* Add prototypes of the library functions created. In case the appropriate int/long types are not declared in scope by the time quad.h is included, @@ -185,7 +180,7 @@ union ibm128_union { #define CVT_FLOAT128_TO_IBM128(RESULT, VALUE) \ { \ double __high, __low; \ - __float128 __value = (VALUE); \ + TFtype __value = (VALUE); \ union ibm128_union u; \ \ __high = (double) __value; \ @@ -196,7 +191,7 @@ union ibm128_union { { \ double __high_temp; \ \ - __low = (double) (__value - (__float128) __high); \ + __low = (double) (__value - (TFtype) __high); \ /* Renormalize low/high and move them into canonical IBM long \ double form. */ \ __high_temp = __high + __low; \ @@ -220,13 +215,13 @@ union ibm128_union { \ /* Handle the special cases of NAN and infinity. */ \ if (__builtin_isnan (__high) || __builtin_isinf (__high)) \ - RESULT = (__float128) __high; \ + RESULT = (TFtype) __high; \ \ /* If low is 0.0, there no need to do the add. In addition, \ avoiding the add produces the correct sign if high is -0.0. */ \ else if (__low == 0.0) \ - RESULT = (__float128) __high; \ + RESULT = (TFtype) __high; \ \ else \ - RESULT = ((__float128) __high) + ((__float128) __low); \ + RESULT = ((TFtype) __high) + ((TFtype) __low); \ } Index: libgcc/config/rs6000/extendkftf2-sw.c =================================================================== --- libgcc/config/rs6000/extendkftf2-sw.c (revision 255658) +++ libgcc/config/rs6000/extendkftf2-sw.c (working copy) @@ -44,7 +44,7 @@ #endif IBM128_TYPE -__extendkftf2_sw (__float128 value) +__extendkftf2_sw (TFtype value) { IBM128_TYPE ret; Index: libgcc/config/rs6000/trunctfkf2-sw.c =================================================================== --- libgcc/config/rs6000/trunctfkf2-sw.c (revision 255658) +++ libgcc/config/rs6000/trunctfkf2-sw.c (working copy) @@ -43,10 +43,10 @@ #define __trunctfkf2_sw __trunctfkf2 #endif -__float128 +TFtype __trunctfkf2_sw (IBM128_TYPE value) { - __float128 ret; + TFtype ret; CVT_IBM128_TO_FLOAT128 (ret, value); return ret; Index: libgcc/config/rs6000/_mulkc3.c =================================================================== --- libgcc/config/rs6000/_mulkc3.c (revision 255658) +++ libgcc/config/rs6000/_mulkc3.c (working copy) @@ -23,11 +23,11 @@ see the files COPYING3 and COPYING.RUNTI /* This is a temporary specialization of code from libgcc/libgcc2.c. */ -typedef float KFtype __attribute__ ((mode (KF))); -typedef __complex float KCtype __attribute__ ((mode (KC))); +#include "soft-fp.h" +#include "quad-float128.h" -#define COPYSIGN(x,y) __builtin_copysignq (x, y) -#define INFINITY __builtin_infq () +#define COPYSIGN(x,y) __builtin_copysignf128 (x, y) +#define INFINITY __builtin_inff128 () #define isnan __builtin_isnan #define isinf __builtin_isinf @@ -35,13 +35,11 @@ typedef __complex float KCtype __attribu #define __mulkc3 __mulkc3_sw #endif -extern KCtype __mulkc3 (KFtype, KFtype, KFtype, KFtype); - -KCtype -__mulkc3 (KFtype a, KFtype b, KFtype c, KFtype d) +TCtype +__mulkc3 (TFtype a, TFtype b, TFtype c, TFtype d) { - KFtype ac, bd, ad, bc, x, y; - KCtype res; + TFtype ac, bd, ad, bc, x, y; + TCtype res; ac = a * c; bd = b * d;