From patchwork Fri Jun 3 21:03:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paul E. Murphy" X-Patchwork-Id: 630029 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3rLxR6365rz9t7N for ; Sat, 4 Jun 2016 07:04:01 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b=oPvlAxzp; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:subject:to:cc:message-id:date :mime-version:content-type; q=dns; s=default; b=WyyNqvVmQ5fUsiKc zZT4q9Rs0aq+w3g3UlfGgUzO/TCMpMYFlTTN+S2yClTW/cj0a23/145sKjd2hc0/ FHFHfY2dX9Yz4vYgVOye2Z6nrT1HaSPuWOkQNPVON+AimupVcZfegwGG686Z1Wxf lKX1gQ5WvT9I75V3d2FI4N/Kc2o= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:subject:to:cc:message-id:date :mime-version:content-type; s=default; bh=s1SHtwF8KcGoIwWnzMZ4hr mrvmQ=; b=oPvlAxzpgQB7NTjnjICiDynjIWf9BxTEHUdDuzFb0nUCxFYu0cB3Do 5ss5W2iFKR179eSPSGgcBYiNLaFX0zhDXHME/qOXUfbPJN1Jf4iZd4tTOippjoGI EoqJRrgr54KLBXGgVpeVDJDwjVt2rTR7tn/0nkNBD8QGmX0CTf7gA= Received: (qmail 81587 invoked by alias); 3 Jun 2016 21:03:54 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 81570 invoked by uid 89); 3 Jun 2016 21:03:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.0 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=F, lc, ls, TYPE X-HELO: e36.co.us.ibm.com X-IBM-Helo: d03dlp03.boulder.ibm.com X-IBM-MailFrom: murphyp@linux.vnet.ibm.com X-IBM-RcptTo: joseph@codesourcery.com;libc-alpha@sourceware.org From: "Paul E. Murphy" Subject: [RFC] tgmath.h and math/Makefile refactor To: "libc-alpha@sourceware.org" Cc: Joseph Myers Message-ID: <563977bd-5bb8-97ed-f722-3527c600426d@linux.vnet.ibm.com> Date: Fri, 3 Jun 2016 16:03:34 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.0 MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16060321-0021-0000-0000-000052782180 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused These are two separate smaller patches, inching towards the goal of supporting more FP types in libm. I spent some time trying to figure out tgmath.h, and how it might look with support for arbitrary types. It assumes __builtin_types_compatible_p and Statement Expr's are supported by GCC (I'm not sure when these were added). These macros might make a good basis for supporting the classification macros in math.h. The potential Makefile changes by comparison are rather self-explanatory. From 49154ceabd6b421c3a004ce1bcfaabfbefa1edaa Mon Sep 17 00:00:00 2001 From: "Paul E. Murphy" Date: Fri, 3 Jun 2016 15:44:05 -0500 Subject: [PATCH 2/2] [RFC] Rewrite tgmath.h helper macros To support more types, these need to be extensible to additional FP types. This is ugly. This assumes __builtin_types_compatible_p() exists on much older GCC variants. --- math/tgmath.h | 240 +++++++++++++++++----------------------------------------- 1 file changed, 71 insertions(+), 169 deletions(-) diff --git a/math/tgmath.h b/math/tgmath.h index ea2b611..f137326 100644 --- a/math/tgmath.h +++ b/math/tgmath.h @@ -66,179 +66,81 @@ __tgmath_real_type_sub (__typeof__ ((__typeof__ (expr)) 0), \ __floating_type (__typeof__ (expr))) +/* Type promotion macros. */ +# define __TGT1(v) __tgmath_real_type(v) +# define __TGT2(v1, v2) __typeof ((__TGT1 (v1)) 0 + (__TGT1 (v2)) 0) +# define __TGT3(v1, v2, v3) __typeof ((__TGT2 (v1, v2)) 0 + (__TGT1 (v3)) 0) + +# define __TGCMPLXTYPE(t) __typeof ((__TGT1 (t)) 0 + _Complex_I) +# define __TGREALTYPE(t) __typeof (__real__ (__TGT1 (t)) 0) +# define __TGISCMPLX(v) (sizeof (v) != sizeof (__real__ (v))) + +# define __TGTTEMP(TYPE,FUNC,type,...) \ + else if (__builtin_types_compatible_p (type, TYPE)) \ + _ret = FUNC (__VA_ARGS__); + +# define __TG_ELIF_TYPE(M, FUNC, type, ...) \ + __TGTTEMP (M long double, __tgml (FUNC), type, __VA_ARGS__) \ + __TGTTEMP (M double, FUNC, type, __VA_ARGS__) \ + __TGTTEMP (M float, FUNC ## f, type, __VA_ARGS__) + +# define __TGTEMP_BASE(M, it, rt, f, ...) \ + ({ \ + __typeof__ (rt) _ret = 0; \ + if(0) \ + {} \ + __TG_ELIF_TYPE (M, f, it, __VA_ARGS__) \ + else \ + _ret = f (__VA_ARGS__); \ + _ret; \ + }) + +# define __TGTEMP_REAL(it, rt, f, ...) \ + __TGTEMP_BASE (, it, rt, f, __VA_ARGS__) + +# define __TGTEMP_REAL_CMPLX(it, rt, f, cf, ...) \ + ({ \ + __typeof__ (rt) _ret = 0; \ + if (__TGISCMPLX ((it) 0)) \ + _ret = __TGTEMP_BASE (_Complex, it, rt, cf, __VA_ARGS__); \ + else \ + _ret = __TGTEMP_BASE (, it, rt, f, __VA_ARGS__); \ + _ret; \ + }) /* We have two kinds of generic macros: to support functions which are only defined on real valued parameters and those which are defined for complex functions as well. */ -# define __TGMATH_UNARY_REAL_ONLY(Val, Fct) \ - (__extension__ ((sizeof (Val) == sizeof (double) \ - || __builtin_classify_type (Val) != 8) \ - ? (__tgmath_real_type (Val)) Fct (Val) \ - : (sizeof (Val) == sizeof (float)) \ - ? (__tgmath_real_type (Val)) Fct##f (Val) \ - : (__tgmath_real_type (Val)) __tgml(Fct) (Val))) - -# define __TGMATH_UNARY_REAL_RET_ONLY(Val, RetType, Fct) \ - (__extension__ ((sizeof (Val) == sizeof (double) \ - || __builtin_classify_type (Val) != 8) \ - ? (RetType) Fct (Val) \ - : (sizeof (Val) == sizeof (float)) \ - ? (RetType) Fct##f (Val) \ - : (RetType) __tgml(Fct) (Val))) - -# define __TGMATH_BINARY_FIRST_REAL_ONLY(Val1, Val2, Fct) \ - (__extension__ ((sizeof (Val1) == sizeof (double) \ - || __builtin_classify_type (Val1) != 8) \ - ? (__tgmath_real_type (Val1)) Fct (Val1, Val2) \ - : (sizeof (Val1) == sizeof (float)) \ - ? (__tgmath_real_type (Val1)) Fct##f (Val1, Val2) \ - : (__tgmath_real_type (Val1)) __tgml(Fct) (Val1, Val2))) - -# define __TGMATH_BINARY_REAL_ONLY(Val1, Val2, Fct) \ - (__extension__ (((sizeof (Val1) > sizeof (double) \ - || sizeof (Val2) > sizeof (double)) \ - && __builtin_classify_type ((Val1) + (Val2)) == 8) \ - ? (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0)) \ - __tgml(Fct) (Val1, Val2) \ - : (sizeof (Val1) == sizeof (double) \ - || sizeof (Val2) == sizeof (double) \ - || __builtin_classify_type (Val1) != 8 \ - || __builtin_classify_type (Val2) != 8) \ - ? (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0)) \ - Fct (Val1, Val2) \ - : (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0)) \ - Fct##f (Val1, Val2))) - -# define __TGMATH_TERNARY_FIRST_SECOND_REAL_ONLY(Val1, Val2, Val3, Fct) \ - (__extension__ (((sizeof (Val1) > sizeof (double) \ - || sizeof (Val2) > sizeof (double)) \ - && __builtin_classify_type ((Val1) + (Val2)) == 8) \ - ? (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0)) \ - __tgml(Fct) (Val1, Val2, Val3) \ - : (sizeof (Val1) == sizeof (double) \ - || sizeof (Val2) == sizeof (double) \ - || __builtin_classify_type (Val1) != 8 \ - || __builtin_classify_type (Val2) != 8) \ - ? (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0)) \ - Fct (Val1, Val2, Val3) \ - : (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0)) \ - Fct##f (Val1, Val2, Val3))) - -# define __TGMATH_TERNARY_REAL_ONLY(Val1, Val2, Val3, Fct) \ - (__extension__ (((sizeof (Val1) > sizeof (double) \ - || sizeof (Val2) > sizeof (double) \ - || sizeof (Val3) > sizeof (double)) \ - && __builtin_classify_type ((Val1) + (Val2) + (Val3)) \ - == 8) \ - ? (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0 \ - + (__tgmath_real_type (Val3)) 0)) \ - __tgml(Fct) (Val1, Val2, Val3) \ - : (sizeof (Val1) == sizeof (double) \ - || sizeof (Val2) == sizeof (double) \ - || sizeof (Val3) == sizeof (double) \ - || __builtin_classify_type (Val1) != 8 \ - || __builtin_classify_type (Val2) != 8 \ - || __builtin_classify_type (Val3) != 8) \ - ? (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0 \ - + (__tgmath_real_type (Val3)) 0)) \ - Fct (Val1, Val2, Val3) \ - : (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0 \ - + (__tgmath_real_type (Val3)) 0)) \ - Fct##f (Val1, Val2, Val3))) - -/* XXX This definition has to be changed as soon as the compiler understands - the imaginary keyword. */ -# define __TGMATH_UNARY_REAL_IMAG(Val, Fct, Cfct) \ - (__extension__ ((sizeof (__real__ (Val)) == sizeof (double) \ - || __builtin_classify_type (__real__ (Val)) != 8) \ - ? ((sizeof (__real__ (Val)) == sizeof (Val)) \ - ? (__tgmath_real_type (Val)) Fct (Val) \ - : (__tgmath_real_type (Val)) Cfct (Val)) \ - : (sizeof (__real__ (Val)) == sizeof (float)) \ - ? ((sizeof (__real__ (Val)) == sizeof (Val)) \ - ? (__tgmath_real_type (Val)) Fct##f (Val) \ - : (__tgmath_real_type (Val)) Cfct##f (Val)) \ - : ((sizeof (__real__ (Val)) == sizeof (Val)) \ - ? (__tgmath_real_type (Val)) __tgml(Fct) (Val) \ - : (__tgmath_real_type (Val)) __tgml(Cfct) (Val)))) - -# define __TGMATH_UNARY_IMAG(Val, Cfct) \ - (__extension__ ((sizeof (__real__ (Val)) == sizeof (double) \ - || __builtin_classify_type (__real__ (Val)) != 8) \ - ? (__typeof__ ((__tgmath_real_type (Val)) 0 \ - + _Complex_I)) Cfct (Val) \ - : (sizeof (__real__ (Val)) == sizeof (float)) \ - ? (__typeof__ ((__tgmath_real_type (Val)) 0 \ - + _Complex_I)) Cfct##f (Val) \ - : (__typeof__ ((__tgmath_real_type (Val)) 0 \ - + _Complex_I)) __tgml(Cfct) (Val))) - -/* XXX This definition has to be changed as soon as the compiler understands - the imaginary keyword. */ -# define __TGMATH_UNARY_REAL_IMAG_RET_REAL(Val, Fct, Cfct) \ - (__extension__ ((sizeof (__real__ (Val)) == sizeof (double) \ - || __builtin_classify_type (__real__ (Val)) != 8) \ - ? ((sizeof (__real__ (Val)) == sizeof (Val)) \ - ? (__typeof__ (__real__ (__tgmath_real_type (Val)) 0))\ - Fct (Val) \ - : (__typeof__ (__real__ (__tgmath_real_type (Val)) 0))\ - Cfct (Val)) \ - : (sizeof (__real__ (Val)) == sizeof (float)) \ - ? ((sizeof (__real__ (Val)) == sizeof (Val)) \ - ? (__typeof__ (__real__ (__tgmath_real_type (Val)) 0))\ - Fct##f (Val) \ - : (__typeof__ (__real__ (__tgmath_real_type (Val)) 0))\ - Cfct##f (Val)) \ - : ((sizeof (__real__ (Val)) == sizeof (Val)) \ - ? (__typeof__ (__real__ (__tgmath_real_type (Val)) 0))\ - __tgml(Fct) (Val) \ - : (__typeof__ (__real__ (__tgmath_real_type (Val)) 0))\ - __tgml(Cfct) (Val)))) - -/* XXX This definition has to be changed as soon as the compiler understands - the imaginary keyword. */ -# define __TGMATH_BINARY_REAL_IMAG(Val1, Val2, Fct, Cfct) \ - (__extension__ (((sizeof (__real__ (Val1)) > sizeof (double) \ - || sizeof (__real__ (Val2)) > sizeof (double)) \ - && __builtin_classify_type (__real__ (Val1) \ - + __real__ (Val2)) == 8) \ - ? ((sizeof (__real__ (Val1)) == sizeof (Val1) \ - && sizeof (__real__ (Val2)) == sizeof (Val2)) \ - ? (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0)) \ - __tgml(Fct) (Val1, Val2) \ - : (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0)) \ - __tgml(Cfct) (Val1, Val2)) \ - : (sizeof (__real__ (Val1)) == sizeof (double) \ - || sizeof (__real__ (Val2)) == sizeof (double) \ - || __builtin_classify_type (__real__ (Val1)) != 8 \ - || __builtin_classify_type (__real__ (Val2)) != 8) \ - ? ((sizeof (__real__ (Val1)) == sizeof (Val1) \ - && sizeof (__real__ (Val2)) == sizeof (Val2)) \ - ? (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0)) \ - Fct (Val1, Val2) \ - : (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0)) \ - Cfct (Val1, Val2)) \ - : ((sizeof (__real__ (Val1)) == sizeof (Val1) \ - && sizeof (__real__ (Val2)) == sizeof (Val2)) \ - ? (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0)) \ - Fct##f (Val1, Val2) \ - : (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0)) \ - Cfct##f (Val1, Val2)))) +# define __TGMATH_UNARY_REAL_ONLY(V,Fct) \ + __TGTEMP_REAL (__TGT1 (V), __TGT1 (V), Fct, V) + +# define __TGMATH_UNARY_REAL_RET_ONLY(V, RetType, Fct) \ + __TGTEMP_REAL (__TGT1 (V), RetType, Fct, V) + +# define __TGMATH_BINARY_FIRST_REAL_ONLY(V1, V2, Fct) \ + __TGTEMP_REAL (__TGT1 (V1), __TGT1 (V1), Fct, V1, V2) + +# define __TGMATH_BINARY_REAL_ONLY(V1, V2, Fct) \ + __TGTEMP_REAL (__TGT2 (V1, V2), __TGT2 (V1, V2), Fct, V1, V2) + +# define __TGMATH_TERNARY_FIRST_SECOND_REAL_ONLY(V1, V2, V3, Fct) \ + __TGTEMP_REAL (__TGT2 (V1, V2), __TGT2 (V1, V2), Fct, V1, V2, V3) + +# define __TGMATH_TERNARY_REAL_ONLY(V1, V2, V3, F) \ + __TGTEMP_REAL (__TGT3 (V1, V2, V3), __TGT3 (V1, V2, V3), F, V1, V2, V3) + +# define __TGMATH_UNARY_REAL_IMAG(V, Fct, Cfct) \ + __TGTEMP_REAL_CMPLX (__TGT1 (V), __TGT1 (V), Fct, Cfct, V) + +# define __TGMATH_UNARY_IMAG(V, Cfct) \ + __TGTEMP_REAL_CMPLX (__TGT1 (V), __TGCMPLXTYPE (V), Cfct, Cfct, V) + +# define __TGMATH_UNARY_REAL_IMAG_RET_REAL(V, Fct, Cfct) \ + __TGTEMP_REAL_CMPLX (__TGT1 (V), __TGREALTYPE (V), Fct, Cfct, V) + +# define __TGMATH_BINARY_REAL_IMAG(V1, V2, F, CF) \ + __TGTEMP_REAL_CMPLX (__TGT2 (V1, V2), __TGT2 (V1, V2), F, CF, V1, V2) + #else # error "Unsupported compiler; you cannot use " #endif -- 2.4.11